├── concepts ├── .keep ├── fundamentals │ ├── .meta │ │ └── config.json │ └── links.json ├── nums-strs │ ├── .meta │ │ └── config.json │ └── links.json ├── patterns │ ├── .meta │ │ └── config.json │ └── links.json └── TODO.md ├── exercises ├── .keep ├── practice │ ├── .keep │ ├── hello-world │ │ ├── .meta │ │ │ ├── example.awk │ │ │ ├── config.json │ │ │ └── tests.toml │ │ ├── hello-world.awk │ │ ├── test-hello-world.bats │ │ └── .docs │ │ │ └── instructions.md │ ├── bob │ │ ├── bob.awk │ │ ├── .docs │ │ │ ├── introduction.md │ │ │ └── instructions.md │ │ └── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ ├── clock │ │ ├── clock.awk │ │ ├── .docs │ │ │ └── instructions.md │ │ └── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ ├── darts │ │ ├── darts.awk │ │ └── .meta │ │ │ ├── example.awk │ │ │ └── config.json │ ├── etl │ │ ├── etl.awk │ │ ├── .docs │ │ │ ├── instructions.append.md │ │ │ ├── introduction.md │ │ │ └── instructions.md │ │ └── .meta │ │ │ ├── example.awk │ │ │ ├── config.json │ │ │ └── tests.toml │ ├── forth │ │ ├── forth.awk │ │ ├── .meta │ │ │ └── config.json │ │ └── .docs │ │ │ └── instructions.md │ ├── leap │ │ ├── leap.awk │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ └── .meta │ │ │ ├── example.awk │ │ │ └── config.json │ ├── luhn │ │ ├── luhn.awk │ │ ├── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ │ └── .docs │ │ │ └── introduction.md │ ├── poker │ │ ├── poker.awk │ │ ├── .docs │ │ │ └── instructions.md │ │ └── .meta │ │ │ └── config.json │ ├── say │ │ ├── say.awk │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ └── .meta │ │ │ └── config.json │ ├── sieve │ │ ├── sieve.awk │ │ ├── .docs │ │ │ └── introduction.md │ │ └── .meta │ │ │ ├── config.json │ │ │ ├── example.awk │ │ │ └── tests.toml │ ├── wordy │ │ ├── wordy.awk │ │ └── .meta │ │ │ └── config.json │ ├── yacht │ │ ├── yacht.awk │ │ ├── .meta │ │ │ └── config.json │ │ └── .docs │ │ │ └── introduction.md │ ├── acronym │ │ ├── acronym.awk │ │ ├── .meta │ │ │ ├── example.awk │ │ │ └── config.json │ │ └── .docs │ │ │ └── instructions.md │ ├── bowling │ │ ├── bowling.awk │ │ └── .meta │ │ │ └── config.json │ ├── change │ │ ├── change.awk │ │ ├── .docs │ │ │ └── instructions.md │ │ └── .meta │ │ │ └── config.json │ ├── diamond │ │ ├── diamond.awk │ │ └── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ ├── grains │ │ ├── grains.awk │ │ ├── .meta │ │ │ ├── example.awk │ │ │ └── config.json │ │ └── .docs │ │ │ ├── introduction.md │ │ │ └── instructions.md │ ├── hamming │ │ ├── hamming.awk │ │ ├── .meta │ │ │ ├── example.awk │ │ │ └── config.json │ │ └── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ ├── isogram │ │ ├── isogram.awk │ │ ├── .docs │ │ │ ├── instructions.append.md │ │ │ └── instructions.md │ │ └── .meta │ │ │ ├── example.awk │ │ │ └── config.json │ ├── meetup │ │ ├── meetup.awk │ │ └── .meta │ │ │ └── config.json │ ├── pangram │ │ ├── pangram.awk │ │ ├── .meta │ │ │ ├── example.awk │ │ │ └── config.json │ │ └── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ ├── proverb │ │ ├── proverb.awk │ │ ├── .meta │ │ │ ├── example.awk │ │ │ ├── config.json │ │ │ └── tests.toml │ │ └── .docs │ │ │ └── instructions.md │ ├── two-fer │ │ ├── two-fer.awk │ │ ├── .meta │ │ │ ├── example.awk │ │ │ ├── config.json │ │ │ └── tests.toml │ │ └── .docs │ │ │ ├── introduction.md │ │ │ └── instructions.md │ ├── allergies │ │ ├── allergies.awk │ │ └── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ ├── book-store │ │ ├── book-store.awk │ │ └── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ ├── eliuds-eggs │ │ ├── pop-count.awk │ │ ├── .meta │ │ │ ├── example.awk │ │ │ ├── config.json │ │ │ └── tests.toml │ │ ├── .docs │ │ │ └── instructions.md │ │ └── test-pop-count.bats │ ├── gigasecond │ │ ├── gigasecond.awk │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── instructions.append.md │ │ └── .meta │ │ │ ├── example.awk │ │ │ └── config.json │ ├── knapsack │ │ ├── knapsack.awk │ │ ├── .docs │ │ │ ├── introduction.md │ │ │ └── instructions.md │ │ └── .meta │ │ │ └── config.json │ ├── pig-latin │ │ ├── pig-latin.awk │ │ ├── .docs │ │ │ └── introduction.md │ │ └── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ ├── rectangles │ │ ├── rectangles.awk │ │ ├── .meta │ │ │ └── config.json │ │ └── .docs │ │ │ └── instructions.md │ ├── space-age │ │ ├── space-age.awk │ │ └── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ ├── tournament │ │ ├── tournament.awk │ │ ├── .docs │ │ │ └── instructions.append.md │ │ └── .meta │ │ │ └── config.json │ ├── two-bucket │ │ ├── two-bucket.awk │ │ └── .meta │ │ │ └── config.json │ ├── word-count │ │ ├── word-count.awk │ │ ├── .meta │ │ │ ├── example.awk │ │ │ └── config.json │ │ └── .docs │ │ │ └── introduction.md │ ├── flower-field │ │ ├── flower-field.awk │ │ ├── .meta │ │ │ └── config.json │ │ └── .docs │ │ │ ├── introduction.md │ │ │ └── instructions.md │ ├── high-scores │ │ ├── high-scores.awk │ │ ├── .docs │ │ │ └── instructions.md │ │ └── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ ├── minesweeper │ │ ├── minesweeper.awk │ │ ├── .docs │ │ │ ├── introduction.md │ │ │ └── instructions.md │ │ └── .meta │ │ │ └── config.json │ ├── ocr-numbers │ │ ├── ocr-numbers.awk │ │ └── .meta │ │ │ └── config.json │ ├── phone-number │ │ ├── phone-number.awk │ │ ├── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ │ └── .docs │ │ │ └── introduction.md │ ├── queen-attack │ │ ├── queen-attack.awk │ │ └── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ ├── affine-cipher │ │ ├── affine-cipher.awk │ │ └── .meta │ │ │ └── config.json │ ├── crypto-square │ │ ├── crypto-square.awk │ │ └── .meta │ │ │ ├── example.awk │ │ │ └── config.json │ ├── isbn-verifier │ │ ├── isbn-verifier.awk │ │ └── .meta │ │ │ ├── example.awk │ │ │ └── config.json │ ├── prime-factors │ │ ├── prime-factors.awk │ │ ├── .meta │ │ │ ├── example.awk │ │ │ └── config.json │ │ └── .docs │ │ │ └── instructions.md │ ├── reverse-string │ │ ├── reverse-string.awk │ │ ├── .meta │ │ │ ├── example.awk │ │ │ └── config.json │ │ └── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ ├── roman-numerals │ │ ├── roman-numerals.awk │ │ ├── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ │ └── .docs │ │ │ └── instructions.md │ ├── saddle-points │ │ ├── saddle-points.awk │ │ ├── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ │ └── .docs │ │ │ ├── introduction.md │ │ │ └── instructions.md │ ├── scrabble-score │ │ ├── scrabble-score.awk │ │ ├── .docs │ │ │ ├── introduction.md │ │ │ └── instructions.md │ │ └── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ ├── matching-brackets │ │ ├── matching-brackets.awk │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ └── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ ├── pascals-triangle │ │ ├── pascals-triangle.awk │ │ └── .meta │ │ │ ├── example.awk │ │ │ └── config.json │ ├── rna-transcription │ │ ├── rna-transcription.awk │ │ ├── .meta │ │ │ ├── example.awk │ │ │ ├── config.json │ │ │ └── tests.toml │ │ └── .docs │ │ │ ├── introduction.md │ │ │ └── instructions.md │ ├── secret-handshake │ │ ├── secret-handshake.awk │ │ ├── .docs │ │ │ ├── instructions.append.md │ │ │ └── introduction.md │ │ └── .meta │ │ │ └── config.json │ ├── collatz-conjecture │ │ ├── collatz-conjecture.awk │ │ ├── .docs │ │ │ └── instructions.md │ │ └── .meta │ │ │ ├── example.awk │ │ │ └── config.json │ ├── killer-sudoku-helper │ │ ├── killer-sudoku-helper.awk │ │ └── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ ├── protein-translation │ │ ├── protein-translation.awk │ │ └── .meta │ │ │ └── config.json │ ├── resistor-color-duo │ │ ├── resistor-color-duo.awk │ │ └── .meta │ │ │ ├── example.awk │ │ │ └── config.json │ ├── resistor-color-trio │ │ ├── resistor-color-trio.awk │ │ └── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ ├── difference-of-squares │ │ ├── difference-of-squares.awk │ │ ├── .meta │ │ │ ├── example.awk │ │ │ └── config.json │ │ └── .docs │ │ │ └── instructions.md │ ├── largest-series-product │ │ ├── largest-series-product.awk │ │ ├── .docs │ │ │ └── introduction.md │ │ └── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ ├── automated-readability-index │ │ ├── automated-readability-index.awk │ │ └── .meta │ │ │ └── config.json │ ├── raindrops │ │ ├── .docs │ │ │ ├── introduction.md │ │ │ ├── instructions.append.md │ │ │ └── instructions.md │ │ ├── raindrops.awk │ │ └── .meta │ │ │ ├── example.awk │ │ │ └── config.json │ ├── anagram │ │ ├── anagram.awk │ │ ├── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ │ └── .docs │ │ │ ├── introduction.md │ │ │ └── instructions.md │ ├── food-chain │ │ ├── food-chain.awk │ │ └── .meta │ │ │ └── config.json │ ├── nth-prime │ │ ├── nth-prime.awk │ │ ├── .docs │ │ │ └── instructions.md │ │ └── .meta │ │ │ ├── config.json │ │ │ ├── tests.toml │ │ │ └── example.awk │ ├── series │ │ ├── series.awk │ │ ├── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ │ └── .docs │ │ │ └── instructions.md │ ├── house │ │ ├── house.awk │ │ └── .meta │ │ │ └── config.json │ ├── triangle │ │ ├── triangle.awk │ │ └── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ ├── grep │ │ ├── grep.awk │ │ ├── .docs │ │ │ └── instructions.append.md │ │ └── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ ├── atbash-cipher │ │ ├── atbash-cipher.awk │ │ └── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ ├── binary-search │ │ ├── binary-search.awk │ │ ├── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ │ └── .docs │ │ │ └── introduction.md │ ├── spiral-matrix │ │ ├── spiral-matrix.awk │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ └── .meta │ │ │ ├── example.awk │ │ │ ├── config.json │ │ │ └── tests.toml │ ├── armstrong-numbers │ │ ├── armstrong-numbers.awk │ │ ├── .meta │ │ │ ├── example.awk │ │ │ └── config.json │ │ └── .docs │ │ │ └── instructions.md │ ├── sum-of-multiples │ │ ├── sum-of-multiples.awk │ │ ├── .docs │ │ │ └── introduction.md │ │ └── .meta │ │ │ ├── example.awk │ │ │ └── config.json │ ├── grade-school │ │ ├── grade-school.awk │ │ └── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ ├── kindergarten-garden │ │ ├── kindergarten-garden.awk │ │ ├── .docs │ │ │ └── introduction.md │ │ └── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ ├── pythagorean-triplet │ │ ├── pythagorean-triplet.awk │ │ ├── .meta │ │ │ ├── example.awk │ │ │ └── config.json │ │ └── .docs │ │ │ └── instructions.md │ ├── rotational-cipher │ │ ├── rotational-cipher.awk │ │ ├── .docs │ │ │ └── instructions.append.md │ │ └── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ ├── run-length-encoding │ │ ├── run-length-encoding.awk │ │ ├── .meta │ │ │ └── config.json │ │ └── .docs │ │ │ └── instructions.md │ ├── simple-cipher │ │ ├── simple-cipher.awk │ │ └── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ ├── all-your-base │ │ ├── all-your-base.awk │ │ ├── .meta │ │ │ └── config.json │ │ └── .docs │ │ │ ├── introduction.md │ │ │ └── instructions.md │ ├── bottle-song │ │ ├── bottle-song.awk │ │ └── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ ├── variable-length-quantity │ │ ├── variable-length-quantity.awk │ │ ├── .docs │ │ │ └── hints.md │ │ └── .meta │ │ │ └── config.json │ ├── beer-song │ │ ├── beer-song.awk │ │ └── .meta │ │ │ ├── config.json │ │ │ └── example.awk │ ├── robot-simulator │ │ ├── robot-simulator.awk │ │ ├── .meta │ │ │ └── config.json │ │ └── .docs │ │ │ └── instructions.md │ ├── mazy-mice │ │ ├── mazy-mice.awk │ │ ├── .docs │ │ │ └── introduction.md │ │ └── .meta │ │ │ └── config.json │ ├── list-ops │ │ ├── .meta │ │ │ └── config.json │ │ ├── array-utils.awk │ │ └── .docs │ │ │ └── instructions.append.md │ └── matrix │ │ ├── matrix.awk │ │ ├── .meta │ │ ├── config.json │ │ └── example.awk │ │ └── .docs │ │ └── instructions.md ├── concept │ ├── basics │ │ ├── .docs │ │ │ └── introduction.md.tpl │ │ ├── passwd │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── design.md │ │ │ └── exemplar.sh │ │ └── basics.sh │ ├── simple-report │ │ ├── .docs │ │ │ ├── introduction.md.tpl │ │ │ ├── hints.md │ │ │ └── instructions.md │ │ ├── input.csv │ │ ├── simple-report.awk │ │ ├── .meta │ │ │ ├── exemplar.awk │ │ │ ├── config.json │ │ │ └── design.md │ │ └── test-simple-report.bats │ └── vehicle-purchase │ │ ├── .docs │ │ ├── introduction.md.tpl │ │ └── hints.md │ │ ├── .meta │ │ ├── exemplar.awk │ │ └── config.json │ │ └── vehicle-purchase.awk └── shared │ └── .docs │ └── help.md ├── docs ├── SNIPPET.txt ├── RESOURCES.md ├── TESTS.md └── LEARNING.md ├── bin ├── ci └── pr ├── .gitignore ├── .github ├── workflows │ ├── run-configlet-sync.yml │ ├── configlet.yml │ ├── sync-labels.yml │ ├── ping-cross-track-maintainers-team.yml │ ├── ci.yml │ └── no-important-files-changed.yml └── CODEOWNERS └── .appends └── .github └── labels.yml /concepts/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /exercises/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /exercises/practice/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/SNIPPET.txt: -------------------------------------------------------------------------------- 1 | BEGIN {print "Hello World!"} 2 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/.meta/example.awk: -------------------------------------------------------------------------------- 1 | BEGIN {print "Hello, World!"} 2 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/hello-world.awk: -------------------------------------------------------------------------------- 1 | BEGIN {print "Goodbye, Mars!"} 2 | -------------------------------------------------------------------------------- /exercises/concept/basics/.docs/introduction.md.tpl: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | %{concept:fundamentals} 4 | -------------------------------------------------------------------------------- /bin/ci: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # invoked by .github/workflows/ci.yml 3 | 4 | bin/validate_exercises 5 | -------------------------------------------------------------------------------- /exercises/concept/simple-report/.docs/introduction.md.tpl: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | %{concept:nums-strs} 4 | -------------------------------------------------------------------------------- /exercises/concept/vehicle-purchase/.docs/introduction.md.tpl: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | %{concept:patterns} 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bin/configlet 2 | bin/configlet.exe 3 | 4 | # gawk debugger files 5 | .gawkrc 6 | .gawk_history 7 | -------------------------------------------------------------------------------- /exercises/concept/simple-report/input.csv: -------------------------------------------------------------------------------- 1 | 1,north,7,5,9,5 2 | 2,east,8,3,4,9 3 | 3,south,9,9,9,7 4 | 4,west,4,0,6,8 5 | -------------------------------------------------------------------------------- /exercises/practice/bob/bob.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/clock/clock.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/darts/darts.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/etl/etl.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/forth/forth.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/leap/leap.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/luhn/luhn.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/poker/poker.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/say/say.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/sieve/sieve.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/wordy/wordy.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/yacht/yacht.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/acronym/acronym.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/bowling/bowling.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/change/change.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/diamond/diamond.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/grains/grains.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/hamming/hamming.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/isogram/isogram.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/meetup/meetup.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/pangram/pangram.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/proverb/proverb.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/two-fer/two-fer.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/allergies/allergies.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/book-store/book-store.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/eliuds-eggs/pop-count.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/gigasecond/gigasecond.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/knapsack/knapsack.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/pig-latin/pig-latin.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/rectangles/rectangles.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/space-age/space-age.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/tournament/tournament.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/two-bucket/two-bucket.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/word-count/word-count.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/flower-field/flower-field.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/high-scores/high-scores.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/leap/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to determine whether a given year is a leap year. 4 | -------------------------------------------------------------------------------- /exercises/practice/leap/.meta/example.awk: -------------------------------------------------------------------------------- 1 | $1 % 4 == 0 && ($1 % 100 != 0 || $1 % 400 == 0) {print "true"; next} 2 | {print "false"} 3 | -------------------------------------------------------------------------------- /exercises/practice/minesweeper/minesweeper.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/ocr-numbers/ocr-numbers.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/phone-number/phone-number.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/queen-attack/queen-attack.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/affine-cipher/affine-cipher.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/crypto-square/crypto-square.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/isbn-verifier/isbn-verifier.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/prime-factors/prime-factors.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/reverse-string/reverse-string.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/roman-numerals/roman-numerals.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/saddle-points/saddle-points.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/scrabble-score/scrabble-score.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/two-fer/.meta/example.awk: -------------------------------------------------------------------------------- 1 | BEGIN {name = "you"} 2 | NF {name = $0} 3 | END {print "One for " name ", one for me."} 4 | -------------------------------------------------------------------------------- /concepts/fundamentals/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "AWK Fundamentals", 3 | "authors": ["glennj"], 4 | "contributors": ["IsaacG"] 5 | } 6 | -------------------------------------------------------------------------------- /exercises/practice/matching-brackets/matching-brackets.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/pascals-triangle/pascals-triangle.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/rna-transcription.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/secret-handshake/secret-handshake.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/collatz-conjecture/collatz-conjecture.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/killer-sudoku-helper/killer-sudoku-helper.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/protein-translation/protein-translation.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color-duo/resistor-color-duo.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color-trio/resistor-color-trio.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/difference-of-squares/difference-of-squares.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/largest-series-product/largest-series-product.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/reverse-string/.meta/example.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | FS = "" 3 | } 4 | { 5 | for (i = NF; i; i--) 6 | out = out $i 7 | print out 8 | } 9 | -------------------------------------------------------------------------------- /concepts/nums-strs/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "AWK data types: Numbers and Strings", 3 | "authors": ["glennj"], 4 | "contributors": ["IsaacG"] 5 | } 6 | -------------------------------------------------------------------------------- /exercises/practice/automated-readability-index/automated-readability-index.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | print "Implement this solution" > "/dev/stderr" 3 | exit 1 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/isogram/.docs/instructions.append.md: -------------------------------------------------------------------------------- 1 | # Instructions append 2 | 3 | If the given string is an isogram, return `"true"`, otherwise return `"false"`. 4 | -------------------------------------------------------------------------------- /exercises/concept/simple-report/simple-report.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | # define the field separator 3 | } 4 | 5 | { 6 | # generate and print the output for each record 7 | } 8 | -------------------------------------------------------------------------------- /exercises/practice/raindrops/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Raindrops is a slightly more complex version of the FizzBuzz challenge, a classic interview question. 4 | -------------------------------------------------------------------------------- /exercises/practice/collatz-conjecture/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Given a positive integer, return the number of steps it takes to reach 1 according to the rules of the Collatz Conjecture. 4 | -------------------------------------------------------------------------------- /concepts/patterns/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "More about Patterns", 3 | "authors": [ 4 | "glennj" 5 | ], 6 | "contributors": [ 7 | "IsaacG", 8 | "booniepepper" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /exercises/practice/anagram/anagram.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - key 3 | 4 | BEGIN { 5 | print "Implement this solution" > "/dev/stderr" 6 | exit 1 7 | } 8 | -------------------------------------------------------------------------------- /exercises/practice/food-chain/food-chain.awk: -------------------------------------------------------------------------------- 1 | # Variables declared on the command line 2 | # start 3 | # end 4 | 5 | BEGIN { 6 | print "Implement this solution" > "/dev/stderr" 7 | exit 1 8 | } 9 | -------------------------------------------------------------------------------- /exercises/practice/nth-prime/nth-prime.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - n 3 | 4 | BEGIN { 5 | print "Implement this solution" > "/dev/stderr" 6 | exit 1 7 | } 8 | -------------------------------------------------------------------------------- /exercises/practice/series/series.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - len 3 | 4 | BEGIN { 5 | print "Implement this solution" > "/dev/stderr" 6 | exit 1 7 | } 8 | -------------------------------------------------------------------------------- /exercises/concept/simple-report/.meta/exemplar.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | FS = "," 3 | } 4 | 5 | { 6 | n1 = $3 $4 7 | n2 = $5 $6 8 | avg = (n1 + n2) / 2 9 | print "#" $1 ", " $2 " = " avg 10 | } 11 | -------------------------------------------------------------------------------- /exercises/practice/house/house.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - start, end 3 | 4 | BEGIN { 5 | print "Implement this solution" > "/dev/stderr" 6 | exit 1 7 | } 8 | -------------------------------------------------------------------------------- /exercises/practice/proverb/.meta/example.awk: -------------------------------------------------------------------------------- 1 | { 2 | for (i = 1; i < NF; i++) 3 | print "For want of a " $i " the " $(i + 1) " was lost." 4 | } 5 | NF { 6 | print "And all for the want of a " $1 "." 7 | } 8 | -------------------------------------------------------------------------------- /exercises/practice/raindrops/raindrops.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - num 3 | 4 | BEGIN { 5 | print "Implement this solution" > "/dev/stderr" 6 | exit 1 7 | } 8 | -------------------------------------------------------------------------------- /exercises/practice/triangle/triangle.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - type 3 | 4 | BEGIN { 5 | print "Implement this solution" > "/dev/stderr" 6 | exit 1 7 | } 8 | -------------------------------------------------------------------------------- /exercises/practice/grep/grep.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - flags 3 | # - pattern 4 | 5 | BEGIN { 6 | print "Implement this solution" > "/dev/stderr" 7 | exit 1 8 | } 9 | -------------------------------------------------------------------------------- /exercises/practice/atbash-cipher/atbash-cipher.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # -direction 3 | 4 | BEGIN { 5 | print "Implement this solution" > "/dev/stderr" 6 | exit 1 7 | } 8 | -------------------------------------------------------------------------------- /exercises/practice/binary-search/binary-search.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - value 3 | 4 | BEGIN { 5 | print "Implement this solution" > "/dev/stderr" 6 | exit 1 7 | } 8 | -------------------------------------------------------------------------------- /exercises/practice/eliuds-eggs/.meta/example.awk: -------------------------------------------------------------------------------- 1 | { 2 | count = 0 3 | num = 0 + $1 4 | while (num > 0) { 5 | count += and(num, 1) 6 | num = rshift(num, 1) 7 | } 8 | print count 9 | } 10 | -------------------------------------------------------------------------------- /exercises/practice/spiral-matrix/spiral-matrix.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - size 3 | 4 | BEGIN { 5 | print "Implement this solution" > "/dev/stderr" 6 | exit 1 7 | } 8 | -------------------------------------------------------------------------------- /exercises/practice/armstrong-numbers/armstrong-numbers.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - num 3 | 4 | BEGIN { 5 | print "Implement this solution" > "/dev/stderr" 6 | exit 1 7 | } 8 | -------------------------------------------------------------------------------- /exercises/practice/sum-of-multiples/sum-of-multiples.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - limit 3 | 4 | BEGIN { 5 | print "Implement this solution" > "/dev/stderr" 6 | exit 1 7 | } 8 | -------------------------------------------------------------------------------- /exercises/practice/grade-school/grade-school.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - action 3 | # - grade 4 | 5 | BEGIN { 6 | print "Implement this solution" > "/dev/stderr" 7 | exit 1 8 | } 9 | -------------------------------------------------------------------------------- /exercises/practice/kindergarten-garden/kindergarten-garden.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - name 3 | 4 | BEGIN { 5 | print "Implement this solution" > "/dev/stderr" 6 | exit 1 7 | } 8 | -------------------------------------------------------------------------------- /exercises/practice/pythagorean-triplet/pythagorean-triplet.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - sum 3 | 4 | BEGIN { 5 | print "Implement this solution" > "/dev/stderr" 6 | exit 1 7 | } 8 | -------------------------------------------------------------------------------- /exercises/practice/rotational-cipher/rotational-cipher.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - distance 3 | 4 | BEGIN { 5 | print "Implement this solution" > "/dev/stderr" 6 | exit 1 7 | } 8 | -------------------------------------------------------------------------------- /exercises/practice/run-length-encoding/run-length-encoding.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - type 3 | 4 | BEGIN { 5 | print "Implement this solution" > "/dev/stderr" 6 | exit 1 7 | } 8 | -------------------------------------------------------------------------------- /exercises/practice/simple-cipher/simple-cipher.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - type 3 | # - key 4 | 5 | BEGIN { 6 | print "Implement this solution" > "/dev/stderr" 7 | exit 1 8 | } 9 | -------------------------------------------------------------------------------- /exercises/practice/all-your-base/all-your-base.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - ibase 3 | # - obase 4 | 5 | BEGIN { 6 | print "Implement this solution" > "/dev/stderr" 7 | exit 1 8 | } 9 | -------------------------------------------------------------------------------- /exercises/practice/bottle-song/bottle-song.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - startBottles 3 | # - takeDown 4 | 5 | BEGIN { 6 | print "Implement this solution" > "/dev/stderr" 7 | exit 1 8 | } 9 | -------------------------------------------------------------------------------- /exercises/practice/darts/.meta/example.awk: -------------------------------------------------------------------------------- 1 | { 2 | distance = sqrt($1 ^ 2 + $2 ^ 2) 3 | if (distance <= 1) { print 10 } 4 | else if (distance <= 5) { print 5 } 5 | else if (distance <= 10) { print 1 } 6 | else { print 0 } 7 | } 8 | -------------------------------------------------------------------------------- /exercises/practice/variable-length-quantity/variable-length-quantity.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - action 3 | 4 | BEGIN { 5 | print "Implement this solution" > "/dev/stderr" 6 | exit 1 7 | } 8 | -------------------------------------------------------------------------------- /exercises/practice/beer-song/beer-song.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - verse 3 | # - start 4 | # - stop 5 | 6 | BEGIN { 7 | print "Implement this solution" > "/dev/stderr" 8 | exit 1 9 | } 10 | -------------------------------------------------------------------------------- /exercises/practice/robot-simulator/robot-simulator.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - x 3 | # - y 4 | # - dir 5 | 6 | BEGIN { 7 | print "Implement this solution" > "/dev/stderr" 8 | exit 1 9 | } 10 | -------------------------------------------------------------------------------- /exercises/practice/poker/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Pick the best hand(s) from a list of poker hands. 4 | 5 | See [Wikipedia][poker-hands] for an overview of poker hands. 6 | 7 | [poker-hands]: https://en.wikipedia.org/wiki/List_of_poker_hands 8 | -------------------------------------------------------------------------------- /exercises/practice/clock/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Implement a clock that handles times without dates. 4 | 5 | You should be able to add and subtract minutes to it. 6 | 7 | Two clocks that represent the same time should be equal to each other. 8 | -------------------------------------------------------------------------------- /exercises/practice/mazy-mice/mazy-mice.awk: -------------------------------------------------------------------------------- 1 | # 2 | # These variables are initialized on the command line (using '-v'): 3 | # - Rows 4 | # - Cols 5 | # - Seed (optional) 6 | # 7 | BEGIN { 8 | print "Implement this solution" > "/dev/stderr" 9 | exit 1 10 | } 11 | -------------------------------------------------------------------------------- /.github/workflows/run-configlet-sync.yml: -------------------------------------------------------------------------------- 1 | name: Run Configlet Sync 2 | 3 | on: 4 | workflow_dispatch: 5 | schedule: 6 | - cron: '0 0 15 * *' 7 | 8 | jobs: 9 | call-gha-workflow: 10 | uses: exercism/github-actions/.github/workflows/configlet-sync.yml@main 11 | -------------------------------------------------------------------------------- /exercises/practice/reverse-string/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to reverse a given string. 4 | 5 | Some examples: 6 | 7 | - Turn `"stressed"` into `"desserts"`. 8 | - Turn `"strops"` into `"sports"`. 9 | - Turn `"racecar"` into `"racecar"`. 10 | -------------------------------------------------------------------------------- /exercises/practice/word-count/.meta/example.awk: -------------------------------------------------------------------------------- 1 | # this variable makes the exercise almost trivial 2 | BEGIN { FPAT = "[[:alnum:]]+('[[:alpha:]]+)?" } 3 | { for (i = 1; i <= NF; i++) count[tolower($i)]++ } 4 | END { for (word in count) printf "%s: %d\n", word, count[word] } 5 | -------------------------------------------------------------------------------- /exercises/concept/simple-report/.docs/hints.md: -------------------------------------------------------------------------------- 1 | # Hints 2 | 3 | ## Task 1: Generate the report 4 | 5 | - Use string contatenation to join the number fields. 6 | - Use arithmetic to calculate the average. 7 | - Use the `print` statement and string contatenation to generate the output line. 8 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Code owners 2 | .github/CODEOWNERS @exercism/maintainers-admin 3 | 4 | # Changes to `fetch-configlet` should be made in the `exercism/configlet` repo 5 | bin/fetch-configlet @exercism/maintainers-admin 6 | bin/fetch-configlet.ps1 @exercism/maintainers-admin 7 | -------------------------------------------------------------------------------- /exercises/practice/raindrops/.docs/instructions.append.md: -------------------------------------------------------------------------------- 1 | # Append 2 | 3 | ## Your awk program 4 | 5 | The tests invoke your program with `gawk`, passing a value into an awk variable, but providing **no filenames or redirected input**. 6 | You'll need to implement the logic inside the `BEGIN` block. 7 | -------------------------------------------------------------------------------- /exercises/practice/mazy-mice/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Meet Mickey and Minerva, two clever mice who love to navigate their way through a maze to find cheese. They enjoy a good challenge, but with only their tiny mouse brains, they prefer if there is only one correct path to the cheese. 4 | -------------------------------------------------------------------------------- /.github/workflows/configlet.yml: -------------------------------------------------------------------------------- 1 | name: Configlet 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - main 8 | workflow_dispatch: 9 | 10 | permissions: 11 | contents: read 12 | 13 | jobs: 14 | configlet: 15 | uses: exercism/github-actions/.github/workflows/configlet.yml@main 16 | -------------------------------------------------------------------------------- /exercises/practice/scrabble-score/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | [Scrabble][wikipedia] is a word game where players place letter tiles on a board to form words. 4 | Each letter has a value. 5 | A word's score is the sum of its letters' values. 6 | 7 | [wikipedia]: https://en.wikipedia.org/wiki/Scrabble 8 | -------------------------------------------------------------------------------- /exercises/practice/sum-of-multiples/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You work for a company that makes an online, fantasy-survival game. 4 | 5 | When a player finishes a level, they are awarded energy points. 6 | The amount of energy awarded depends on which magical items the player found while exploring that level. 7 | -------------------------------------------------------------------------------- /concepts/patterns/links.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "Pattern Elements", 4 | "url": "https://www.gnu.org/software/gawk/manual/html_node/Pattern-Overview.html" 5 | }, 6 | { 7 | "description": "Truth Values", 8 | "url": "https://www.gnu.org/software/gawk/manual/html_node/Truth-Values.html" 9 | } 10 | ] 11 | -------------------------------------------------------------------------------- /exercises/concept/vehicle-purchase/.meta/exemplar.awk: -------------------------------------------------------------------------------- 1 | BEGIN {FS = ","} 2 | 3 | $1 == "needs_license" && $2 ~ /car|truck/ {print "true"} 4 | 5 | $1 == "resell_price" && $3 < 3 {print $2 * 0.8} 6 | $1 == "resell_price" && 3 <= $3 && $3 <= 10 {print $2 * 0.7} 7 | $1 == "resell_price" && $3 > 10 {print $2 * 0.5} 8 | -------------------------------------------------------------------------------- /exercises/practice/eliuds-eggs/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to count the number of 1 bits in the binary representation of a number. 4 | 5 | ## Restrictions 6 | 7 | Keep your hands off that bit-count functionality provided by your standard library! 8 | Solve this one yourself using other basic tools instead. 9 | -------------------------------------------------------------------------------- /exercises/practice/grains/.meta/example.awk: -------------------------------------------------------------------------------- 1 | $1 == "total" { 2 | # This needs the `-M` option for arbitrary precision arithmetic. 3 | print ((2 ^ 64) - 1) 4 | next 5 | } 6 | $1 < 1 || $1 > 64 { 7 | print "square must be between 1 and 64" > "/dev/stderr" 8 | exit 1 9 | } 10 | { 11 | print 2 ^ ($1 - 1) 12 | } 13 | -------------------------------------------------------------------------------- /exercises/practice/collatz-conjecture/.meta/example.awk: -------------------------------------------------------------------------------- 1 | $1 < 1 { 2 | print "Error: Only positive numbers are allowed" > "/dev/stderr" 3 | exit 1 4 | } 5 | 6 | { 7 | n = $1 8 | steps = 0 9 | while (n > 1) { 10 | steps++ 11 | n = (n % 2 == 0) ? n / 2 : 3 * n + 1 12 | } 13 | print steps 14 | } 15 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/test-hello-world.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | load bats-extra 3 | 4 | @test "Say Hi!" { 5 | run gawk -f hello-world.awk 6 | 7 | # the program's exit status should be success (0) 8 | assert_success 9 | 10 | # program's output should be the expected text 11 | assert_output "Hello, World!" 12 | } 13 | -------------------------------------------------------------------------------- /exercises/practice/minesweeper/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | [Minesweeper][wikipedia] is a popular game where the user has to find the mines using numeric hints that indicate how many mines are directly adjacent (horizontally, vertically, diagonally) to a square. 4 | 5 | [wikipedia]: https://en.wikipedia.org/wiki/Minesweeper_(video_game) 6 | -------------------------------------------------------------------------------- /exercises/practice/matching-brackets/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Given a string containing brackets `[]`, braces `{}`, parentheses `()`, or any combination thereof, verify that any and all pairs are matched and nested correctly. 4 | Any other characters should be ignored. 5 | For example, `"{what is (42)}?"` is balanced and `"[text}"` is not. 6 | -------------------------------------------------------------------------------- /exercises/practice/pangram/.meta/example.awk: -------------------------------------------------------------------------------- 1 | function is_pangram(str, letters, letter, chars, n, i) { 2 | n = split(str, chars, "") 3 | for (i = 1; i <= n; i++) 4 | if (chars[i] ~ /[[:alpha:]]/) 5 | letters[tolower(chars[i])] = 1 6 | return length(letters) == 26 7 | } 8 | 9 | {print is_pangram($0) ? "true" : "false"} 10 | -------------------------------------------------------------------------------- /exercises/practice/raindrops/.meta/example.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - num 3 | 4 | BEGIN { 5 | result = "" 6 | if (num % 3 == 0) result = result "Pling" 7 | if (num % 5 == 0) result = result "Plang" 8 | if (num % 7 == 0) result = result "Plong" 9 | print result ? result : num 10 | } 11 | -------------------------------------------------------------------------------- /exercises/practice/etl/.docs/instructions.append.md: -------------------------------------------------------------------------------- 1 | # placeholder 2 | 3 | ## About the tests 4 | 5 | AWK is very often used as an ETL tool (read the input, process it, and write a "report"). 6 | Very often, in practice the input format is somewhat tricky. 7 | This exercise will try to mimic this, using inconsistent input formats that your program will have to normalize. 8 | -------------------------------------------------------------------------------- /exercises/practice/tournament/.docs/instructions.append.md: -------------------------------------------------------------------------------- 1 | # placeholder 2 | 3 | ## Sorting in AWK 4 | 5 | Refer to the [`high-scores` exercise instructions][high-score] 6 | for a discussion on sorting techniques. 7 | 8 | For this exercise, a user-defined sorting function is warranted. 9 | 10 | [high-score]: https://exercism.org/tracks/awk/exercises/high-scores 11 | -------------------------------------------------------------------------------- /exercises/practice/nth-prime/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Given a number n, determine what the nth prime is. 4 | 5 | By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13. 6 | 7 | If your language provides methods in the standard library to deal with prime numbers, pretend they don't exist and implement them yourself. 8 | -------------------------------------------------------------------------------- /exercises/practice/acronym/.meta/example.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | # field separator is whitespace or hyphen 3 | FS = "[[:blank:]-]+" 4 | } 5 | { 6 | acr = "" 7 | for (i=1; i<=NF; i++) { 8 | gsub(/[^[:alpha:]]/, "", $i) # remove non-letters 9 | acr = acr substr($i, 1, 1) # and take the first letter 10 | } 11 | print toupper(acr) 12 | } 13 | -------------------------------------------------------------------------------- /exercises/practice/forth/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "forth.awk" 8 | ], 9 | "test": [ 10 | "test-forth.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Implement an evaluator for a very simple subset of Forth." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/isbn-verifier/.meta/example.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | FPAT = "[0-9]|X$" 3 | } 4 | !/^[-0-9]*X?$/ || NF != 10 { 5 | print "false" 6 | next 7 | } 8 | $NF == "X" { 9 | $NF = 10 10 | } 11 | { 12 | check_sum = 0 13 | for (i = 1; i <= NF; ++i) { 14 | check_sum += (11 - i) * $i 15 | } 16 | print check_sum % 11 ? "false" : "true" 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/minesweeper/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "minesweeper.awk" 8 | ], 9 | "test": [ 10 | "test-minesweeper.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Add the numbers to a minesweeper board." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/rectangles/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "rectangles.awk" 8 | ], 9 | "test": [ 10 | "test-rectangles.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Count the rectangles in an ASCII diagram." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/pascals-triangle/.meta/example.awk: -------------------------------------------------------------------------------- 1 | $1 > 0 { 2 | triangle[1][1] = 1 3 | print "1" 4 | 5 | for (i = 2; i <= $1; i++) { 6 | for (j = 1; j <= i; j++) { 7 | triangle[i][j] = 0 + triangle[i-1][j-1] + triangle[i-1][j] 8 | printf "%s%d", (j == 1 ? "" : " "), triangle[i][j] 9 | } 10 | print "" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /exercises/practice/tournament/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "IsaacG" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "tournament.awk" 8 | ], 9 | "test": [ 10 | "test-tournament.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Tally the results of a small football competition." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/concept/basics/passwd: -------------------------------------------------------------------------------- 1 | root:x:0:0:root:/root:/bin/bash 2 | john:x:1001:1001:John Doe:/home/john:/bin/bash 3 | jane:x:1002:1002:Jane Doe:/home/jane:/bin/bash 4 | mark:x:1003:1003:Mark Smith:/home/mark:/bin/zsh 5 | susan:x:1004:1004:Susan Johnson:/invalid/home:/bin/bash 6 | peter:x:1005:1005:Peter Wong:/home/peter:/bin/false 7 | bill:x:1006:1004:Bill Gates:/invalid/steve:/usr/local/bin/pwsh 8 | -------------------------------------------------------------------------------- /exercises/practice/bob/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Bob is a [lackadaisical][] teenager. 4 | He likes to think that he's very cool. 5 | And he definitely doesn't get excited about things. 6 | That wouldn't be cool. 7 | 8 | When people talk to him, his responses are pretty limited. 9 | 10 | [lackadaisical]: https://www.collinsdictionary.com/dictionary/english/lackadaisical 11 | -------------------------------------------------------------------------------- /exercises/practice/flower-field/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj", 4 | "IsaacG" 5 | ], 6 | "files": { 7 | "solution": [ 8 | "flower-field.awk" 9 | ], 10 | "test": [ 11 | "test-flower-field.bats" 12 | ], 13 | "example": [ 14 | ".meta/example.awk" 15 | ] 16 | }, 17 | "blurb": "Mark all the flowers in a garden." 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/isogram/.meta/example.awk: -------------------------------------------------------------------------------- 1 | { 2 | print isIsogram($0) 3 | } 4 | 5 | function isIsogram(string) { 6 | gsub(/[^a-zA-Z]+/, "", string) 7 | string = tolower(string) 8 | split(string, chars, "") 9 | for (i in chars) { 10 | if (unique_chars[chars[i]] == 1) { 11 | return "false" 12 | } 13 | unique_chars[chars[i]] = 1 14 | } 15 | return "true" 16 | } 17 | -------------------------------------------------------------------------------- /exercises/practice/secret-handshake/.docs/instructions.append.md: -------------------------------------------------------------------------------- 1 | # placeholder 2 | 3 | ## Bitwise operators in AWK 4 | 5 | AWK does not have the common bitwise _operators_ that many other languages have (like `&` and `|`). 6 | Instead GNU awk provides [bitwise _functions_][bit-funcs]. 7 | 8 | [bit-funcs]: https://www.gnu.org/software/gawk/manual/html_node/Bitwise-Functions.html#Bitwise-Functions 9 | -------------------------------------------------------------------------------- /exercises/practice/gigasecond/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to determine the date and time one gigasecond after a certain date. 4 | 5 | A gigasecond is one thousand million seconds. 6 | That is a one with nine zeros after it. 7 | 8 | If you were born on _January 24th, 2015 at 22:00 (10:00:00pm)_, then you would be a gigasecond old on _October 2nd, 2046 at 23:46:40 (11:46:40pm)_. 9 | -------------------------------------------------------------------------------- /exercises/practice/say/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Given a number, your task is to express it in English words exactly as your friend should say it out loud. 4 | Yaʻqūb expects to use numbers from 0 up to 999,999,999,999. 5 | 6 | Examples: 7 | 8 | - 0 → zero 9 | - 1 → one 10 | - 12 → twelve 11 | - 123 → one hundred twenty-three 12 | - 1,234 → one thousand two hundred thirty-four 13 | -------------------------------------------------------------------------------- /exercises/practice/word-count/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You teach English as a foreign language to high school students. 4 | 5 | You've decided to base your entire curriculum on TV shows. 6 | You need to analyze which words are used, and how often they're repeated. 7 | 8 | This will let you choose the simplest shows to start with, and to gradually increase the difficulty as time passes. 9 | -------------------------------------------------------------------------------- /exercises/practice/etl/.meta/example.awk: -------------------------------------------------------------------------------- 1 | { 2 | gsub(/"/, "") 3 | n = split($0, items, /[:,][[:blank:]]*/) 4 | for (i = 2; i <= n; i++) 5 | if (items[i] ~ /^[[:alpha:]]$/) 6 | score[tolower(items[i])] = items[1] 7 | } 8 | 9 | END { 10 | PROCINFO["sorted_in"] = "@ind_str_asc" 11 | OFS = "," 12 | for (letter in score) 13 | print letter, score[letter] 14 | } 15 | -------------------------------------------------------------------------------- /exercises/practice/grains/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | There once was a wise servant who saved the life of a prince. 4 | The king promised to pay whatever the servant could dream up. 5 | Knowing that the king loved chess, the servant told the king he would like to have grains of wheat. 6 | One grain on the first square of a chessboard, with the number of grains doubling on each successive square. 7 | -------------------------------------------------------------------------------- /exercises/practice/armstrong-numbers/.meta/example.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - num 3 | 4 | function is_armstrong(num, len, sum) { 5 | len = split(num, digits, "") 6 | for (i=1; i <= len; i++) { 7 | sum += digits[i] ^ len 8 | } 9 | return sum == num 10 | } 11 | 12 | BEGIN { 13 | print is_armstrong(num) ? "true" : "false" 14 | } 15 | 16 | -------------------------------------------------------------------------------- /exercises/practice/grains/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Calculate the number of grains of wheat on a chessboard. 4 | 5 | A chessboard has 64 squares. 6 | Square 1 has one grain, square 2 has two grains, square 3 has four grains, and so on, doubling each time. 7 | 8 | Write code that calculates: 9 | 10 | - the number of grains on a given square 11 | - the total number of grains on the chessboard 12 | -------------------------------------------------------------------------------- /exercises/practice/high-scores/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Manage a game player's High Score list. 4 | 5 | Your task is to build a high-score component of the classic Frogger game, one of the highest selling and most addictive games of all time, and a classic of the arcade era. 6 | Your task is to write methods that return the highest score from the list, the last added score and the three highest scores. 7 | -------------------------------------------------------------------------------- /exercises/concept/simple-report/test-simple-report.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | load bats-extra 3 | 4 | @test "Generate the report" { 5 | ## task 1 6 | run gawk -f simple-report.awk input.csv 7 | 8 | assert_success 9 | assert_line --index 0 "#1, north = 85" 10 | assert_line --index 1 "#2, east = 66" 11 | assert_line --index 2 "#3, south = 98" 12 | assert_line --index 3 "#4, west = 54" 13 | } 14 | -------------------------------------------------------------------------------- /exercises/practice/largest-series-product/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You work for a government agency that has intercepted a series of encrypted communication signals from a group of bank robbers. 4 | The signals contain a long sequence of digits. 5 | Your team needs to use various digital signal processing techniques to analyze the signals and identify any patterns that may indicate the planning of a heist. 6 | -------------------------------------------------------------------------------- /exercises/practice/list-ops/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "list-ops.awk" 8 | ], 9 | "test": [ 10 | "test-list-ops.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ], 15 | "editor": [ 16 | "array-utils.awk" 17 | ] 18 | }, 19 | "blurb": "Implement basic list operations." 20 | } 21 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color-duo/.meta/example.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | split("black brown red orange yellow green blue violet grey white", colors) 3 | } 4 | 5 | function value(color) { 6 | for (i = 1; i <= length(colors); i++) 7 | if (colors[i] == color) 8 | return i - 1 9 | print("invalid color") 10 | exit(1) 11 | } 12 | 13 | { 14 | print(value($1) * 10 + value($2)) 15 | } 16 | 17 | -------------------------------------------------------------------------------- /exercises/practice/all-your-base/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "IsaacG" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "all-your-base.awk" 8 | ], 9 | "test": [ 10 | "test-all-your-base.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Convert a number, represented as a sequence of digits in one base, to any other base." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/clock/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "rabestro" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "clock.awk" 8 | ], 9 | "test": [ 10 | "test-clock.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Implement a clock that handles times without dates.", 17 | "source": "Pairing session with Erin Drummond" 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/pangram/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to figure out if a sentence is a pangram. 4 | 5 | A pangram is a sentence using every letter of the alphabet at least once. 6 | It is case insensitive, so it doesn't matter if a letter is lower-case (e.g. `k`) or upper-case (e.g. `K`). 7 | 8 | For this exercise, a sentence is a pangram if it contains each of the 26 letters in the English alphabet. 9 | -------------------------------------------------------------------------------- /exercises/practice/matching-brackets/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "IsaacG" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "matching-brackets.awk" 8 | ], 9 | "test": [ 10 | "test-matching-brackets.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Make sure the brackets and braces all match.", 17 | "source": "Ginna Baker" 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/prime-factors/.meta/example.awk: -------------------------------------------------------------------------------- 1 | { 2 | remaining = $1 3 | candidate = 2 4 | while (remaining > 1) { 5 | if (remaining % candidate == 0) { 6 | if (out) { 7 | out = out " " 8 | } 9 | out = out candidate 10 | remaining /= candidate 11 | } else { 12 | candidate++ 13 | } 14 | } 15 | print(out) 16 | } 17 | -------------------------------------------------------------------------------- /exercises/practice/protein-translation/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "IsaacG" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "protein-translation.awk" 8 | ], 9 | "test": [ 10 | "test-protein-translation.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Translate RNA sequences into proteins.", 17 | "source": "Tyler Long" 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/high-scores/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "high-scores.awk" 8 | ], 9 | "test": [ 10 | "test-high-scores.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Manage a player's High Score list.", 17 | "source": "Tribute to the eighties' arcade game Frogger" 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/matrix/matrix.awk: -------------------------------------------------------------------------------- 1 | @namespace "matrix" 2 | 3 | function read(filename, matrix_var) { 4 | print "Implement this solution" > "/dev/stderr" 5 | exit 1 6 | } 7 | 8 | function row(matrix_var, row_num) { 9 | print "Implement this solution" > "/dev/stderr" 10 | exit 1 11 | } 12 | 13 | function column(matrix_var, column_num) { 14 | print "Implement this solution" > "/dev/stderr" 15 | exit 1 16 | } 17 | -------------------------------------------------------------------------------- /exercises/practice/reverse-string/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Reversing strings (reading them from right to left, rather than from left to right) is a surprisingly common task in programming. 4 | 5 | For example, in bioinformatics, reversing the sequence of DNA or RNA strings is often important for various analyses, such as finding complementary strands or identifying palindromic sequences that have biological significance. 6 | -------------------------------------------------------------------------------- /exercises/concept/vehicle-purchase/vehicle-purchase.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | FS = "," # comma is the field separator 3 | } 4 | 5 | # Task 1: When the first field is "needs_license", 6 | # print "true" if the second field contains "car" or "truck". 7 | 8 | # Task 2: When the first field is "resell_price", 9 | # print the resell value of the original price (second field) 10 | # given the age of the car (third field). 11 | -------------------------------------------------------------------------------- /.github/workflows/sync-labels.yml: -------------------------------------------------------------------------------- 1 | name: Tools 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - .github/labels.yml 9 | - .github/workflows/sync-labels.yml 10 | workflow_dispatch: 11 | schedule: 12 | - cron: 0 0 1 * * # First day of each month 13 | 14 | permissions: 15 | issues: write 16 | 17 | jobs: 18 | sync-labels: 19 | uses: exercism/github-actions/.github/workflows/labels.yml@main 20 | -------------------------------------------------------------------------------- /exercises/practice/acronym/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "acronym.awk" 8 | ], 9 | "test": [ 10 | "test-acronym.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Convert a long phrase to its acronym.", 17 | "source": "Julien Vanier", 18 | "source_url": "https://github.com/monkbroc" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/robot-simulator/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "robot-simulator.awk" 8 | ], 9 | "test": [ 10 | "test-robot-simulator.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Write a robot simulator.", 17 | "source": "Inspired by an interview question at a famous company." 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/say/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Your friend Yaʻqūb works the counter at the busiest deli in town, slicing, weighing, and wrapping orders for a never-ending line of hungry customers. 4 | To keep things moving, each customer takes a numbered ticket when they arrive. 5 | 6 | When it’s time to call the next person, Yaʻqūb reads their number out loud, always in full English words to make sure everyone hears it clearly. 7 | -------------------------------------------------------------------------------- /docs/RESOURCES.md: -------------------------------------------------------------------------------- 1 | # Resources 2 | 3 | The [Gawk: Effective AWK Programming][book] book serves both as a tutorial and a reference manual. 4 | 5 | The wikipedia [AWK page][wiki-books] has a list of books and other resources. 6 | 7 | The [awk info page][so] at Stack Overflow. 8 | 9 | 10 | 11 | [book]: https://www.gnu.org/software/gawk/manual 12 | [wiki-books]: https://en.wikipedia.org/wiki/AWK#Books 13 | [so]: https://stackoverflow.com/tags/awk/info 14 | -------------------------------------------------------------------------------- /exercises/concept/basics/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "basics.sh" 8 | ], 9 | "test": [ 10 | "test-basics.bats" 11 | ], 12 | "exemplar": [ 13 | ".meta/exemplar.sh" 14 | ], 15 | "editor": [ 16 | "passwd" 17 | ] 18 | }, 19 | "blurb": "Introduction to fundamental AWK concepts", 20 | "source": "ChatGPT conversation" 21 | } 22 | -------------------------------------------------------------------------------- /exercises/practice/pangram/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "pangram.awk" 8 | ], 9 | "test": [ 10 | "test-pangram.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Determine if a sentence is a pangram.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Pangram" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/variable-length-quantity/.docs/hints.md: -------------------------------------------------------------------------------- 1 | # placeholder 2 | 3 | ## General 4 | 5 | - The `strtonum` [string function][string-func] can convert a hexidecimal string to a decimal number. 6 | - The [bitwise functions][bitwise-func] will be helpful. 7 | 8 | [string-func]: https://www.gnu.org/software/gawk/manual/html_node/String-Functions.html 9 | [bitwise-func]: https://www.gnu.org/software/gawk/manual/html_node/Bitwise-Functions.html 10 | -------------------------------------------------------------------------------- /exercises/practice/hamming/.meta/example.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | FS = "" # each char is a separate field 3 | } 4 | NR == 1 { 5 | len = NF 6 | for (i=1; i<=NF; i++) 7 | first[i] = $i 8 | next 9 | } 10 | len != NF { 11 | print "strands must be of equal length" >"/dev/stderr" 12 | exit 1 13 | } 14 | { 15 | diff = 0 16 | for (i=1; i<=NF; i++) 17 | if ($i != first[i]) 18 | diff++ 19 | print diff 20 | } 21 | -------------------------------------------------------------------------------- /exercises/practice/isogram/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "SimaDovakin" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "isogram.awk" 8 | ], 9 | "test": [ 10 | "test-isogram.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Determine if a word or phrase is an isogram.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Isogram" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/meetup/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "meetup.awk" 8 | ], 9 | "test": [ 10 | "test-meetup.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Calculate the date of meetups.", 17 | "source": "Jeremy Hinegardner mentioned a Boulder meetup that happens on the Wednesteenth of every month" 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/two-fer/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "two-fer.awk" 8 | ], 9 | "test": [ 10 | "test-two-fer.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Create a sentence of the form \"One for X, one for me.\".", 17 | "source_url": "https://github.com/exercism/problem-specifications/issues/757" 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/kindergarten-garden/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | The kindergarten class is learning about growing plants. 4 | The teacher thought it would be a good idea to give the class seeds to plant and grow in the dirt. 5 | To this end, the children have put little cups along the window sills and planted one type of plant in each cup. 6 | The children got to pick their favorites from four available types of seeds: grass, clover, radishes, and violets. 7 | -------------------------------------------------------------------------------- /exercises/practice/darts/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "IsaacG" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "darts.awk" 8 | ], 9 | "test": [ 10 | "test-darts.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Calculate the points scored in a single toss of a Darts game.", 17 | "source": "Inspired by an exercise created by a professor Della Paolera in Argentina" 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/isogram/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Determine if a word or phrase is an isogram. 4 | 5 | An isogram (also known as a "non-pattern word") is a word or phrase without a repeating letter, however spaces and hyphens are allowed to appear multiple times. 6 | 7 | Examples of isograms: 8 | 9 | - lumberjacks 10 | - background 11 | - downstream 12 | - six-year-old 13 | 14 | The word _isograms_, however, is not an isogram, because the s repeats. 15 | -------------------------------------------------------------------------------- /exercises/practice/binary-search/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "binary-search.awk" 8 | ], 9 | "test": [ 10 | "test-binary-search.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Implement a binary search algorithm.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Binary_search_algorithm" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/sum-of-multiples/.meta/example.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - limit 3 | 4 | { 5 | # Find all multiples of each input, from multiple to limit. 6 | for (i = 1; i <= NF; i++) 7 | if ($i) 8 | for (j = $i; j < limit; j += $i) 9 | multiples[j] = 1 10 | 11 | # Sum up the multiples. 12 | sum = 0 13 | for (i in multiples) 14 | sum += i 15 | 16 | print sum 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/yacht/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "yacht.awk" 8 | ], 9 | "test": [ 10 | "test-yacht.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Score a single throw of dice in the game Yacht.", 17 | "source": "James Kilfiger, using Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Yacht_(dice_game)" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/grade-school/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "grade-school.awk" 8 | ], 9 | "test": [ 10 | "test-grade-school.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Given students' names along with the grade that they are in, create a roster for the school.", 17 | "source": "A pairing session with Phil Battos at gSchool" 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/sieve/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You bought a big box of random computer parts at a garage sale. 4 | You've started putting the parts together to build custom computers. 5 | 6 | You want to test the performance of different combinations of parts, and decide to create your own benchmarking program to see how your computers compare. 7 | You choose the famous "Sieve of Eratosthenes" algorithm, an ancient algorithm, but one that should push your computers to the limits. 8 | -------------------------------------------------------------------------------- /exercises/concept/simple-report/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "contributors": [ 6 | "IsaacG" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "simple-report.awk" 11 | ], 12 | "test": [ 13 | "test-simple-report.bats" 14 | ], 15 | "exemplar": [ 16 | ".meta/exemplar.awk" 17 | ], 18 | "editor": [ 19 | "input.csv" 20 | ] 21 | }, 22 | "blurb": "Generate a simple report from an input CSV file." 23 | } 24 | -------------------------------------------------------------------------------- /concepts/fundamentals/links.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "The AWK language", 4 | "url": "https://www.gnu.org/software/gawk/manual/html_node/Getting-Started.html#Getting-Started" 5 | }, 6 | { 7 | "description": "How Input Is Split into Records", 8 | "url": "https://www.gnu.org/software/gawk/manual/html_node/Records.html" 9 | }, 10 | { 11 | "description": "Truth Values", 12 | "url": "https://www.gnu.org/software/gawk/manual/html_node/Truth-Values.html" 13 | } 14 | ] 15 | -------------------------------------------------------------------------------- /docs/TESTS.md: -------------------------------------------------------------------------------- 1 | # Tests 2 | 3 | You can use the online editor on the Exercism website to solve the exercises. 4 | Or, download the exercises to your computer, solve them locally and then submit them to Exercism. 5 | 6 | If you want to work locally, you'll need the [`bats`][bats] program. 7 | Please refer to the [Testing on the Bash track][test-bash] page for the installation instructions. 8 | 9 | [bats]: https://github.com/bats-core/bats-core 10 | [test-bash]: https://exercism.org/docs/tracks/bash/tests 11 | -------------------------------------------------------------------------------- /exercises/concept/basics/.meta/design.md: -------------------------------------------------------------------------------- 1 | # Design 2 | 3 | ## Goal 4 | 5 | The goal of this exercise is to teach the student the basics of programming in AWK. 6 | 7 | ## Learning objectives 8 | 9 | - pattern/action pairs 10 | - records and fields 11 | - BEGIN and END 12 | - builtin variables 13 | 14 | ## Out of scope 15 | 16 | - variables 17 | - functions 18 | 19 | ## Concepts 20 | 21 | The Concepts this exercise unlocks are: 22 | 23 | - `fundamentals` 24 | 25 | ## Prerequisites 26 | 27 | none 28 | -------------------------------------------------------------------------------- /exercises/practice/armstrong-numbers/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "armstrong-numbers.awk" 8 | ], 9 | "test": [ 10 | "test-armstrong-numbers.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Determine if a number is an Armstrong number.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Narcissistic_number" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/roman-numerals/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "roman-numerals.awk" 8 | ], 9 | "test": [ 10 | "test-roman-numerals.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Convert modern Arabic numbers into Roman numerals.", 17 | "source": "The Roman Numeral Kata", 18 | "source_url": "https://codingdojo.org/kata/RomanNumerals/" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/run-length-encoding/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "run-length-encoding.awk" 8 | ], 9 | "test": [ 10 | "test-run-length-encoding.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Implement run-length encoding and decoding.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Run-length_encoding" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/word-count/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "word-count.awk" 8 | ], 9 | "test": [ 10 | "test-word-count.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Given a phrase, count the occurrences of each word in that phrase.", 17 | "source": "This is a classic toy problem, but we were reminded of it by seeing it in the Go Tour." 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/hamming/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "hamming.awk" 8 | ], 9 | "test": [ 10 | "test-hamming.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Calculate the Hamming distance between two DNA strands.", 17 | "source": "The Calculating Point Mutations problem at Rosalind", 18 | "source_url": "https://rosalind.info/problems/hamm/" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/house/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "rabestro" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "house.awk" 8 | ], 9 | "test": [ 10 | "test-house.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Output the nursery rhyme 'This is the House that Jack Built'.", 17 | "source": "British nursery rhyme", 18 | "source_url": "https://en.wikipedia.org/wiki/This_Is_The_House_That_Jack_Built" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/luhn/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "luhn.awk" 8 | ], 9 | "test": [ 10 | "test-luhn.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Given a number determine whether or not it is valid per the Luhn formula.", 17 | "source": "The Luhn Algorithm on Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Luhn_algorithm" 19 | } 20 | -------------------------------------------------------------------------------- /docs/LEARNING.md: -------------------------------------------------------------------------------- 1 | # Learning 2 | 3 | For a quick overview of the language, refer to the [awk info page][so] on Stack Overflow. 4 | 5 | Some other learning resources: 6 | 7 | * [Awk.Info](https://web.archive.org/web/20160505033644/http://awk.info/) 8 | * [Learn X in Y minutes: awk](https://learnxinyminutes.com/docs/awk/) 9 | * [Awk tutorial](https://www.grymoire.com/Unix/Awk.html) 10 | * [The GNU Awk User's Guide](https://www.gnu.org/software/gawk/manual/) 11 | 12 | [so]: https://stackoverflow.com/tags/awk/info 13 | -------------------------------------------------------------------------------- /exercises/practice/crypto-square/.meta/example.awk: -------------------------------------------------------------------------------- 1 | { 2 | plainText = tolower(gensub(/[^[:alnum:]]/, "", "g")) 3 | 4 | len = length(plainText) 5 | side = int(sqrt(len)) 6 | cols = side * side < len ? side + 1 : side 7 | rows = side * cols < len ? side + 1 : side 8 | 9 | NF=0 10 | for (i = 0; i < rows * cols; ++i) { 11 | symbol = i >= len ? " " : substr(plainText, i + 1, 1) 12 | chunk = 1 + i % cols 13 | $chunk = $chunk symbol 14 | } 15 | print 16 | } 17 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/.meta/example.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | FS = "" 3 | translation["G"] = "C" 4 | translation["C"] = "G" 5 | translation["A"] = "U" 6 | translation["T"] = "A" 7 | 8 | } 9 | 10 | { 11 | out = "" 12 | for (i = 1; i <= NF; i++) { 13 | if ($i in translation) { 14 | out = out translation[$i] 15 | } else { 16 | print("Invalid nucleotide detected.") 17 | exit(1) 18 | } 19 | } 20 | print(out) 21 | } 22 | -------------------------------------------------------------------------------- /exercises/practice/two-fer/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | In some English accents, when you say "two for" quickly, it sounds like "two fer". 4 | Two-for-one is a way of saying that if you buy one, you also get one for free. 5 | So the phrase "two-fer" often implies a two-for-one offer. 6 | 7 | Imagine a bakery that has a holiday offer where you can buy two cookies for the price of one ("two-fer one!"). 8 | You take the offer and (very generously) decide to give the extra cookie to someone else in the queue. 9 | -------------------------------------------------------------------------------- /exercises/practice/anagram/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "anagram.awk" 8 | ], 9 | "test": [ 10 | "test-anagram.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Given a word and a list of possible anagrams, select the correct sublist.", 17 | "source": "Inspired by the Extreme Startup game", 18 | "source_url": "https://github.com/rchatley/extreme_startup" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/bottle-song/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "rabestro" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "bottle-song.awk" 8 | ], 9 | "test": [ 10 | "test-bottle-song.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Produce the lyrics to the popular children's repetitive song: Ten Green Bottles.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Ten_Green_Bottles" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/change/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Determine the fewest number of coins to give a customer so that the sum of their values equals the correct amount of change. 4 | 5 | ## Examples 6 | 7 | - An amount of 15 with available coin values [1, 5, 10, 25, 100] should return one coin of value 5 and one coin of value 10, or [5, 10]. 8 | - An amount of 40 with available coin values [1, 5, 10, 25, 100] should return one coin of value 5, one coin of value 10, and one coin of value 25, or [5, 10, 25]. 9 | -------------------------------------------------------------------------------- /exercises/practice/grep/.docs/instructions.append.md: -------------------------------------------------------------------------------- 1 | # To `grep` or not to `grep`, that is the question 2 | 3 | ## AWK-track adjustments to the requirements 4 | 5 | You are not forced to implement proper command line parsing: the flags are 6 | provided in a space-separated string that is straightforward to split apart. 7 | ```sh 8 | gawk -f grep.awk -v flags="l v" -v pattern="hello" file1.txt file2.txt 9 | ``` 10 | 11 | Like real grep, your program will return a **non-zero exit status** when _no matches are found_. 12 | -------------------------------------------------------------------------------- /exercises/practice/knapsack/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Lhakpa is a [Sherpa][sherpa] mountain guide and porter. 4 | After months of careful planning, the expedition Lhakpa works for is about to leave. 5 | She will be paid the value she carried to the base camp. 6 | 7 | In front of her are many items, each with a value and weight. 8 | Lhakpa would gladly take all of the items, but her knapsack can only hold so much weight. 9 | 10 | [sherpa]: https://en.wikipedia.org/wiki/Sherpa_people#Mountaineering 11 | -------------------------------------------------------------------------------- /exercises/practice/leap/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "leap.awk" 8 | ], 9 | "test": [ 10 | "test-leap.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Determine whether a given year is a leap year.", 17 | "source": "CodeRanch Cattle Drive, Assignment 3", 18 | "source_url": "https://web.archive.org/web/20240907033714/https://coderanch.com/t/718816/Leap" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/poker/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "rabestro" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "poker.awk" 8 | ], 9 | "test": [ 10 | "test-poker.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Pick the best hand(s) from a list of poker hands.", 17 | "source": "Inspired by the training course from Udacity.", 18 | "source_url": "https://www.udacity.com/course/design-of-computer-programs--cs212" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/scrabble-score/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "scrabble-score.awk" 8 | ], 9 | "test": [ 10 | "test-scrabble-score.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Given a word, compute the Scrabble score for that word.", 17 | "source": "Inspired by the Extreme Startup game", 18 | "source_url": "https://github.com/rchatley/extreme_startup" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/secret-handshake/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You are starting a secret coding club with some friends and friends-of-friends. 4 | Not everyone knows each other, so you and your friends have decided to create a secret handshake that you can use to recognize that someone is a member. 5 | You don't want anyone who isn't in the know to be able to crack the code. 6 | 7 | You've designed the code so that one person says a number between 1 and 31, and the other person turns it into a series of actions. 8 | -------------------------------------------------------------------------------- /exercises/concept/simple-report/.meta/design.md: -------------------------------------------------------------------------------- 1 | # Design 2 | 3 | ## Goal 4 | 5 | Describe numbers and strings in AWK, and perform operations on numbers and strings. 6 | 7 | ## Learning objectives 8 | 9 | - number data type 10 | - arithmetic operators 11 | - string data type 12 | - string operators 13 | 14 | ## Out of scope 15 | 16 | - builtin numeric and string functions 17 | 18 | ## Concepts 19 | 20 | The Concepts this exercise unlocks are: 21 | 22 | - `nums-strs` 23 | 24 | ## Prerequisites 25 | 26 | - fundamentals 27 | -------------------------------------------------------------------------------- /exercises/practice/bowling/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "rabestro" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "bowling.awk" 8 | ], 9 | "test": [ 10 | "test-bowling.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Score a bowling game.", 17 | "source": "The Bowling Game Kata from UncleBob", 18 | "source_url": "https://web.archive.org/web/20221001111000/http://butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/collatz-conjecture/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "collatz-conjecture.awk" 8 | ], 9 | "test": [ 10 | "test-collatz-conjecture.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Calculate the number of steps to reach 1 using the Collatz conjecture.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Collatz_conjecture" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/food-chain/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "food-chain.awk" 8 | ], 9 | "test": [ 10 | "test-food-chain.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Generate the lyrics of the song 'I Know an Old Lady Who Swallowed a Fly'.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/There_Was_an_Old_Lady_Who_Swallowed_a_Fly" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/sieve/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "sieve.awk" 8 | ], 9 | "test": [ 10 | "test-sieve.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Use the Sieve of Eratosthenes to find all the primes from 2 up to a given number.", 17 | "source": "Sieve of Eratosthenes at Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/simple-cipher/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "rabestro" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "simple-cipher.awk" 8 | ], 9 | "test": [ 10 | "test-simple-cipher.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Implement the Vigenère cipher, a simple substitution cipher.", 17 | "source": "Substitution Cipher at Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Substitution_cipher" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/atbash-cipher/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "IsaacG" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "atbash-cipher.awk" 8 | ], 9 | "test": [ 10 | "test-atbash-cipher.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Create an implementation of the Atbash cipher, an ancient encryption system created in the Middle East.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Atbash" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/rotational-cipher/.docs/instructions.append.md: -------------------------------------------------------------------------------- 1 | # placeholder 2 | 3 | ## ASCII values 4 | 5 | This exercise requires converting ASCII characters to and from their numeric value. 6 | GNU awk's [ordchr extension][ordchr] provides this functionality. To add the 7 | `ord()` and `chr()` functions, load the `ordchr` extension by adding a `@load` 8 | directive to the top of your file: 9 | 10 | ``` 11 | @load "ordchr" 12 | ``` 13 | 14 | [ordchr]: https://www.gnu.org/software/gawk/manual/gawk.html#Extension-Sample-Ord 15 | -------------------------------------------------------------------------------- /exercises/practice/series/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "IsaacG" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "series.awk" 8 | ], 9 | "test": [ 10 | "test-series.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Given a string of digits, output all the contiguous substrings of length `n` in that string.", 17 | "source": "A subset of the Problem 8 at Project Euler", 18 | "source_url": "https://projecteuler.net/problem=8" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/affine-cipher/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "affine-cipher.awk" 8 | ], 9 | "test": [ 10 | "test-affine-cipher.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Create an implementation of the Affine cipher, an ancient encryption algorithm from the Middle East.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Affine_cipher" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/saddle-points/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "rabestro" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "saddle-points.awk" 8 | ], 9 | "test": [ 10 | "test-saddle-points.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Detect saddle points in a matrix.", 17 | "source": "J Dalbey's Programming Practice problems", 18 | "source_url": "https://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/triangle/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "IsaacG" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "triangle.awk" 8 | ], 9 | "test": [ 10 | "test-triangle.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Determine if a triangle is equilateral, isosceles, or scalene.", 17 | "source": "The Ruby Koans triangle project, parts 1 & 2", 18 | "source_url": "https://web.archive.org/web/20220831105330/http://rubykoans.com" 19 | } 20 | -------------------------------------------------------------------------------- /.github/workflows/ping-cross-track-maintainers-team.yml: -------------------------------------------------------------------------------- 1 | name: Ping cross-track maintainers team 2 | 3 | on: 4 | pull_request_target: 5 | types: 6 | - opened 7 | 8 | permissions: 9 | pull-requests: write 10 | 11 | jobs: 12 | ping: 13 | if: github.repository_owner == 'exercism' # Stops this job from running on forks 14 | uses: exercism/github-actions/.github/workflows/ping-cross-track-maintainers-team.yml@main 15 | secrets: 16 | github_membership_token: ${{ secrets.COMMUNITY_CONTRIBUTIONS_WORKFLOW_TOKEN }} 17 | -------------------------------------------------------------------------------- /exercises/practice/pig-latin/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Your parents have challenged you and your sibling to a game of two-on-two basketball. 4 | Confident they'll win, they let you score the first couple of points, but then start taking over the game. 5 | Needing a little boost, you start speaking in [Pig Latin][pig-latin], which is a made-up children's language that's difficult for non-children to understand. 6 | This will give you the edge to prevail over your parents! 7 | 8 | [pig-latin]: https://en.wikipedia.org/wiki/Pig_latin 9 | -------------------------------------------------------------------------------- /exercises/practice/pythagorean-triplet/.meta/example.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - sum 3 | 4 | BEGIN { 5 | OFS="," 6 | 7 | limit = int(sum / 3) 8 | for (a = 3; a <= limit; ++a) { 9 | numerator = sum * sum - 2 * sum * a 10 | denominator = 2 * (sum - a) 11 | if (numerator % denominator != 0) continue 12 | b = numerator / denominator 13 | if (a >= b) break 14 | c = sum - a - b 15 | print a, b, c 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/rotational-cipher/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "IsaacG" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "rotational-cipher.awk" 8 | ], 9 | "test": [ 10 | "test-rotational-cipher.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Create an implementation of the rotational cipher, also sometimes called the Caesar cipher.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Caesar_cipher" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/two-bucket/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "two-bucket.awk" 8 | ], 9 | "test": [ 10 | "test-two-bucket.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Given two buckets of different size, demonstrate how to measure an exact number of liters.", 17 | "source": "Water Pouring Problem", 18 | "source_url": "https://demonstrations.wolfram.com/WaterPouringProblem/" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/beer-song/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "beer-song.awk" 8 | ], 9 | "test": [ 10 | "test-beer-song.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Produce the lyrics to that beloved classic, that field-trip favorite: 99 Bottles of Beer on the Wall.", 17 | "source": "Learn to Program by Chris Pine", 18 | "source_url": "https://pine.fm/LearnToProgram/?Chapter=06" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/pascals-triangle/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "pascals-triangle.awk" 8 | ], 9 | "test": [ 10 | "test-pascals-triangle.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Compute Pascal's triangle up to a given number of rows.", 17 | "source": "Pascal's Triangle at Wolfram Math World", 18 | "source_url": "https://www.wolframalpha.com/input/?i=Pascal%27s+triangle" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/proverb/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "rabestro" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "proverb.awk" 8 | ], 9 | "test": [ 10 | "test-proverb.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "For want of a horseshoe nail, a kingdom was lost, or so the saying goes. Output the full text of this proverbial rhyme.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/For_Want_of_a_Nail" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/spiral-matrix/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to return a square matrix of a given size. 4 | 5 | The matrix should be filled with natural numbers, starting from 1 in the top-left corner, increasing in an inward, clockwise spiral order, like these examples: 6 | 7 | ## Examples 8 | 9 | ### Spiral matrix of size 3 10 | 11 | ```text 12 | 1 2 3 13 | 8 9 4 14 | 7 6 5 15 | ``` 16 | 17 | ### Spiral matrix of size 4 18 | 19 | ```text 20 | 1 2 3 4 21 | 12 13 14 5 22 | 11 16 15 6 23 | 10 9 8 7 24 | ``` 25 | -------------------------------------------------------------------------------- /exercises/practice/etl/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "etl.awk" 8 | ], 9 | "test": [ 10 | "test-etl.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Change the data format for scoring a game to more easily add other languages.", 17 | "source": "Based on an exercise by the JumpstartLab team for students at The Turing School of Software and Design.", 18 | "source_url": "https://turing.edu" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/gigasecond/.meta/example.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | Gigasecond = 1000000000 3 | UTC = 1 4 | } 5 | 6 | /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/ { 7 | # add the time and carry on 8 | $1 = $1 "T00:00:00" 9 | } 10 | 11 | /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}$/ { 12 | # https://www.gnu.org/software/gawk/manual/html_node/Time-Functions.html 13 | datespec = gensub(/[-T:]/, " ", "g") 14 | epoch = mktime(datespec, UTC) 15 | if (epoch != -1) 16 | print strftime("%FT%T", Gigasecond + epoch, UTC) 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/nth-prime/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "IsaacG" 4 | ], 5 | "contributors": [ 6 | "glennj" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "nth-prime.awk" 11 | ], 12 | "test": [ 13 | "test-nth-prime.bats" 14 | ], 15 | "example": [ 16 | ".meta/example.awk" 17 | ] 18 | }, 19 | "blurb": "Given a number n, determine what the nth prime is.", 20 | "source": "A variation on Problem 7 at Project Euler", 21 | "source_url": "https://projecteuler.net/problem=7" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color-duo/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "IsaacG" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "resistor-color-duo.awk" 8 | ], 9 | "test": [ 10 | "test-resistor-color-duo.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Convert color codes, as used on resistors, to a numeric value.", 17 | "source": "Maud de Vries, Erik Schierboom", 18 | "source_url": "https://github.com/exercism/problem-specifications/issues/1464" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/diamond/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "diamond.awk" 8 | ], 9 | "test": [ 10 | "test-diamond.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Given a letter, print a diamond starting with 'A' with the supplied letter at the widest point.", 17 | "source": "Seb Rose", 18 | "source_url": "https://web.archive.org/web/20220807163751/http://claysnow.co.uk/recycling-tests-in-tdd/" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/difference-of-squares/.meta/example.awk: -------------------------------------------------------------------------------- 1 | function square_of_sum(n, sum, i) { 2 | sum = 0 3 | for (i = 1; i <= n; i++) { 4 | sum += i 5 | } 6 | return sum * sum 7 | } 8 | 9 | function sum_of_squares(n, sum, i) { 10 | sum = 0 11 | for (i = 1; i <= n; i++) { 12 | sum += i * i 13 | } 14 | return sum 15 | } 16 | 17 | function difference(n) { 18 | return square_of_sum(n) - sum_of_squares(n) 19 | } 20 | 21 | BEGIN { FS = "," } 22 | 23 | { 24 | f = $1 25 | print @f($2) 26 | } 27 | -------------------------------------------------------------------------------- /exercises/practice/gigasecond/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "gigasecond.awk" 8 | ], 9 | "test": [ 10 | "test-gigasecond.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Given a moment, determine the moment that would be after a gigasecond has passed.", 17 | "source": "Chapter 9 in Chris Pine's online Learn to Program tutorial.", 18 | "source_url": "https://pine.fm/LearnToProgram/?Chapter=09" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/pythagorean-triplet/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "rabestro" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "pythagorean-triplet.awk" 8 | ], 9 | "test": [ 10 | "test-pythagorean-triplet.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Given an integer N, find all Pythagorean triplets for which a + b + c = N.", 17 | "source": "A variation of Problem 9 from Project Euler", 18 | "source_url": "https://projecteuler.net/problem=9" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/wordy/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "wordy.awk" 8 | ], 9 | "test": [ 10 | "test-wordy.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Parse and evaluate simple math word problems returning the answer as an integer.", 17 | "source": "Inspired by one of the generated questions in the Extreme Startup game.", 18 | "source_url": "https://github.com/rchatley/extreme_startup" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/concept/vehicle-purchase/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "contributors": [ 6 | "IsaacG", 7 | "kotp" 8 | ], 9 | "files": { 10 | "solution": [ 11 | "vehicle-purchase.awk" 12 | ], 13 | "test": [ 14 | "test-vehicle-purchase.bats" 15 | ], 16 | "exemplar": [ 17 | ".meta/exemplar.awk" 18 | ] 19 | }, 20 | "forked_from": [ 21 | "javascript/vehicle-purchase" 22 | ], 23 | "blurb": "Learn about AWK patterns while preparing for your next vehicle purchase." 24 | } 25 | -------------------------------------------------------------------------------- /exercises/practice/bob/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "bob.awk" 8 | ], 9 | "test": [ 10 | "test-bob.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Bob is a lackadaisical teenager. In conversation, his responses are very limited.", 17 | "source": "Inspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial.", 18 | "source_url": "https://pine.fm/LearnToProgram/?Chapter=06" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "hello-world.awk" 8 | ], 9 | "test": [ 10 | "test-hello-world.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Exercism's classic introductory exercise. Just say \"Hello, World!\".", 17 | "source": "This is an exercise to introduce users to using Exercism", 18 | "source_url": "https://en.wikipedia.org/wiki/%22Hello,_world!%22_program" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/ocr-numbers/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "ocr-numbers.awk" 8 | ], 9 | "test": [ 10 | "test-ocr-numbers.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Given a 3 x 4 grid of pipes, underscores, and spaces, determine which number is represented, or whether it is garbled.", 17 | "source": "Inspired by the Bank OCR kata", 18 | "source_url": "https://codingdojo.org/kata/BankOCR/" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/pythagorean-triplet/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Description 2 | 3 | A Pythagorean triplet is a set of three natural numbers, {a, b, c}, for which, 4 | 5 | ```text 6 | a² + b² = c² 7 | ``` 8 | 9 | and such that, 10 | 11 | ```text 12 | a < b < c 13 | ``` 14 | 15 | For example, 16 | 17 | ```text 18 | 3² + 4² = 5². 19 | ``` 20 | 21 | Given an input integer N, find all Pythagorean triplets for which `a + b + c = N`. 22 | 23 | For example, with N = 1000, there is exactly one Pythagorean triplet for which `a + b + c = 1000`: `{200, 375, 425}`. 24 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color-trio/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "IsaacG" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "resistor-color-trio.awk" 8 | ], 9 | "test": [ 10 | "test-resistor-color-trio.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Convert color codes, as used on resistors, to a human-readable label.", 17 | "source": "Maud de Vries, Erik Schierboom", 18 | "source_url": "https://github.com/exercism/problem-specifications/issues/1549" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/reverse-string/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "IsaacG" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "reverse-string.awk" 8 | ], 9 | "test": [ 10 | "test-reverse-string.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Reverse a given string.", 17 | "source": "Introductory challenge to reverse an input string", 18 | "source_url": "https://medium.freecodecamp.org/how-to-reverse-a-string-in-javascript-in-3-different-ways-75e4763c68cb" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/say/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "say.awk" 8 | ], 9 | "test": [ 10 | "test-say.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Given a number from 0 to 999,999,999,999, spell out that number in English.", 17 | "source": "A variation on the JavaRanch CattleDrive, Assignment 4", 18 | "source_url": "https://web.archive.org/web/20240907035912/https://coderanch.com/wiki/718804" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/variable-length-quantity/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "variable-length-quantity.awk" 8 | ], 9 | "test": [ 10 | "test-variable-length-quantity.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Implement variable length quantity encoding and decoding.", 17 | "source": "A poor Splice developer having to implement MIDI encoding/decoding.", 18 | "source_url": "https://splice.com" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/automated-readability-index/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "rabestro" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "automated-readability-index.awk" 8 | ], 9 | "test": [ 10 | "test-automated-readability-index.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Calculate the automated readability index for the text.", 17 | "source": "Automated readability index", 18 | "source_url": "https://en.wikipedia.org/wiki/Automated_readability_index" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/flower-field/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | [Flower Field][history] is a compassionate reimagining of the popular game Minesweeper. 4 | The object of the game is to find all the flowers in the garden using numeric hints that indicate how many flowers are directly adjacent (horizontally, vertically, diagonally) to a square. 5 | "Flower Field" shipped in regional versions of Microsoft Windows in Italy, Germany, South Korea, Japan and Taiwan. 6 | 7 | [history]: https://web.archive.org/web/20020409051321fw_/http://rcm.usr.dsi.unimi.it/rcmweb/fnm/ 8 | -------------------------------------------------------------------------------- /exercises/practice/knapsack/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "knapsack.awk" 8 | ], 9 | "test": [ 10 | "test-knapsack.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Given a knapsack that can only carry a certain weight, determine which items to put in the knapsack in order to maximize their combined value.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Knapsack_problem" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/matrix/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "matrix.awk" 8 | ], 9 | "test": [ 10 | "test-matrix.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Given a string representing a matrix of numbers, return the rows and columns of that matrix.", 17 | "source": "Exercise by the JumpstartLab team for students at The Turing School of Software and Design.", 18 | "source_url": "https://turing.edu" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/phone-number/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "phone-number.awk" 8 | ], 9 | "test": [ 10 | "test-phone-number.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Clean up user-entered phone numbers so that they can be sent SMS messages.", 17 | "source": "Exercise by the JumpstartLab team for students at The Turing School of Software and Design.", 18 | "source_url": "https://turing.edu" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "IsaacG" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "rna-transcription.awk" 8 | ], 9 | "test": [ 10 | "test-rna-transcription.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Given a DNA strand, return its RNA complement.", 17 | "source": "Hyperphysics", 18 | "source_url": "https://web.archive.org/web/20220408112140/http://hyperphysics.phy-astr.gsu.edu/hbase/Organic/transcription.html" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/rotational-cipher/.meta/example.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - distance 3 | 4 | @load "ordchr" 5 | 6 | BEGIN { 7 | FS = "" 8 | OFS = "" 9 | A = ord("A") 10 | a = ord("a") 11 | } 12 | 13 | { 14 | out = "" 15 | for (i = 1; i <= NF; i++) { 16 | if ("A" <= $i && $i <= "Z") 17 | $i = chr((ord($i) - A + distance) % 26 + A) 18 | else if ("a" <= $i && $i <= "z") 19 | $i = chr((ord($i) - a + distance) % 26 + a) 20 | } 21 | print 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/yacht/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Each year, something new is "all the rage" in your high school. 4 | This year it is a dice game: [Yacht][yacht]. 5 | 6 | The game of Yacht is from the same family as Poker Dice, Generala and particularly Yahtzee, of which it is a precursor. 7 | The game consists of twelve rounds. 8 | In each, five dice are rolled and the player chooses one of twelve categories. 9 | The chosen category is then used to score the throw of the dice. 10 | 11 | [yacht]: https://en.wikipedia.org/wiki/Yacht_(dice_game) 12 | -------------------------------------------------------------------------------- /exercises/practice/grep/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "grep.awk" 8 | ], 9 | "test": [ 10 | "test-grep.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Search a file for lines matching a regular expression pattern. Return the line number and contents of each matching line.", 17 | "source": "Conversation with Nate Foster.", 18 | "source_url": "https://www.cs.cornell.edu/Courses/cs3110/2014sp/hw/0/ps0.pdf" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/roman-numerals/.meta/example.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | dec["M"] = 1000; dec["CM"] = 900; dec["D"] = 500; dec["CD"] = 400 3 | dec["C"] = 100 ; dec["XC"] = 90 ; dec["L"] = 50 ; dec["XL"] = 40 4 | dec["X"] = 10 ; dec["IX"] = 9 ; dec["V"] = 5 ; dec["IV"] = 4 5 | dec["I"] = 1 6 | PROCINFO["sorted_in"] = "@val_num_desc" 7 | } 8 | 9 | { 10 | n = $1 11 | roman = "" 12 | for (r in dec) { 13 | while (n >= dec[r]) { 14 | roman = roman r 15 | n -= dec[r] 16 | } 17 | } 18 | print roman 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/secret-handshake/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "secret-handshake.awk" 8 | ], 9 | "test": [ 10 | "test-secret-handshake.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Given a decimal number, convert it to the appropriate sequence of events for a secret handshake.", 17 | "source": "Bert, in Mary Poppins", 18 | "source_url": "https://www.imdb.com/title/tt0058331/quotes/?item=qt0437047" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/difference-of-squares/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "difference-of-squares.awk" 8 | ], 9 | "test": [ 10 | "test-difference-of-squares.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Find the difference between the square of the sum and the sum of the squares of the first N natural numbers.", 17 | "source": "Problem 6 at Project Euler", 18 | "source_url": "https://projecteuler.net/problem=6" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/hamming/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Calculate the Hamming distance between two DNA strands. 4 | 5 | We read DNA using the letters C, A, G and T. 6 | Two strands might look like this: 7 | 8 | GAGCCTACTAACGGGAT 9 | CATCGTAATGACGGCCT 10 | ^ ^ ^ ^ ^ ^^ 11 | 12 | They have 7 differences, and therefore the Hamming distance is 7. 13 | 14 | ## Implementation notes 15 | 16 | The Hamming distance is only defined for sequences of equal length, so an attempt to calculate it between sequences of different lengths should not work. 17 | -------------------------------------------------------------------------------- /exercises/practice/pig-latin/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "pig-latin.awk" 8 | ], 9 | "test": [ 10 | "test-pig-latin.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Implement a program that translates from English to Pig Latin.", 17 | "source": "The Pig Latin exercise at Test First Teaching by Ultrasaurus", 18 | "source_url": "https://github.com/ultrasaurus/test-first-teaching/blob/master/learn_ruby/pig_latin/" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/prime-factors/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "IsaacG" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "prime-factors.awk" 8 | ], 9 | "test": [ 10 | "test-prime-factors.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Compute the prime factors of a given natural number.", 17 | "source": "The Prime Factors Kata by Uncle Bob", 18 | "source_url": "https://web.archive.org/web/20221026171801/http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/sum-of-multiples/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "IsaacG" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "sum-of-multiples.awk" 8 | ], 9 | "test": [ 10 | "test-sum-of-multiples.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Given a number, find the sum of all the multiples of particular numbers up to but not including that number.", 17 | "source": "A variation on Problem 1 at Project Euler", 18 | "source_url": "https://projecteuler.net/problem=1" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/binary-search/.meta/example.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - value 3 | 4 | BEGIN {FS = ","} 5 | 6 | { 7 | left = 1 8 | right = NF 9 | idx = -1 10 | while (left <= right) { 11 | mid = int((left + right) / 2) 12 | if (value == $mid) { 13 | idx = mid 14 | break 15 | } 16 | else if (value < $mid) { 17 | right = mid - 1 18 | } 19 | else { 20 | left = mid + 1 21 | } 22 | } 23 | print idx 24 | } 25 | -------------------------------------------------------------------------------- /exercises/practice/change/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "change.awk" 8 | ], 9 | "test": [ 10 | "test-change.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Correctly determine change to be given using the least number of coins.", 17 | "source": "Software Craftsmanship - Coin Change Kata", 18 | "source_url": "https://web.archive.org/web/20130115115225/http://craftsmanship.sv.cmu.edu:80/exercises/coin-change-kata" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/crypto-square/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "rabestro" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "crypto-square.awk" 8 | ], 9 | "test": [ 10 | "test-crypto-square.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Implement the classic method for composing secret messages called a square code.", 17 | "source": "J Dalbey's Programming Practice problems", 18 | "source_url": "https://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/all-your-base/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You've just been hired as professor of mathematics. 4 | Your first week went well, but something is off in your second week. 5 | The problem is that every answer given by your students is wrong! 6 | Luckily, your math skills have allowed you to identify the problem: the student answers _are_ correct, but they're all in base 2 (binary)! 7 | Amazingly, it turns out that each week, the students use a different base. 8 | To help you quickly verify the student answers, you'll be building a tool to translate between bases. 9 | -------------------------------------------------------------------------------- /exercises/practice/grains/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "grains.awk" 8 | ], 9 | "test": [ 10 | "test-grains.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Calculate the number of grains of wheat on a chessboard given that the number on each square doubles.", 17 | "source": "The CodeRanch Cattle Drive, Assignment 6", 18 | "source_url": "https://web.archive.org/web/20240908084142/https://coderanch.com/wiki/718824/Grains" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/anagram/.meta/example.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - key 3 | 4 | BEGIN { 5 | PROCINFO["sorted_in"] = "@val_str_asc" 6 | lower_key = tolower(key) 7 | comparitor = encode(lower_key) 8 | } 9 | 10 | function encode(word, letters, i, encoded) { 11 | split(word, letters, "") 12 | for (i in letters) 13 | encoded = encoded letters[i] 14 | return encoded 15 | } 16 | 17 | # process the candidate words 18 | {lower_word = tolower($0)} 19 | lower_word != lower_key && encode(lower_word) == comparitor 20 | -------------------------------------------------------------------------------- /exercises/practice/diamond/.meta/example.awk: -------------------------------------------------------------------------------- 1 | @load "ordchr" 2 | @include "join" 3 | 4 | BEGIN { A = ord("A") } 5 | 6 | $1 ~ /^[A-Z]$/ { 7 | num = ord($1) - A + 1 8 | size = 2 * num - 1 9 | 10 | for (i = 1; i <= num; i++) { 11 | for (j = 1; j <= num; j++) { 12 | char = i == j ? chr(A + i - 1) : " " 13 | row[num - j + 1] = row[num + j - 1] = char 14 | } 15 | line = join(row, 1, length(row), SUBSEP) 16 | diamond[size - i + 1] = diamond[i] = line 17 | } 18 | 19 | print join(diamond, 1, length(diamond), ORS) 20 | } 21 | -------------------------------------------------------------------------------- /exercises/practice/eliuds-eggs/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "pop-count.awk" 8 | ], 9 | "test": [ 10 | "test-pop-count.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Help Eliud count the number of eggs in her chicken coop by counting the number of 1 bits in a binary representation.", 17 | "source": "Christian Willner, Eric Willigers", 18 | "source_url": "https://forum.exercism.org/t/new-exercise-suggestion-pop-count/7632/5" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/killer-sudoku-helper/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "rabestro" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "killer-sudoku-helper.awk" 8 | ], 9 | "test": [ 10 | "test-killer-sudoku-helper.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Write a tool that makes it easier to solve Killer Sudokus", 17 | "source": "Created by Sascha Mann, Jeremy Walker, and BethanyG for the Julia track on Exercism.", 18 | "source_url": "https://github.com/exercism/julia/pull/413" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/largest-series-product/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "largest-series-product.awk" 8 | ], 9 | "test": [ 10 | "test-largest-series-product.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Given a string of digits, calculate the largest product for a contiguous substring of digits of length n.", 17 | "source": "A variation on Problem 8 at Project Euler", 18 | "source_url": "https://projecteuler.net/problem=8" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/series/.meta/example.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - len 3 | 4 | BEGIN { 5 | FS = "" 6 | } 7 | 8 | ! NF { 9 | print("series cannot be empty") 10 | exit(1) 11 | } 12 | 13 | len > NF || len < 1 { 14 | print("invalid length") 15 | exit(1) 16 | } 17 | 18 | { 19 | out = "" 20 | for (start = 1; start <= NF - len + 1; start++ ) { 21 | if (start > 1) 22 | out = out " " 23 | for (i = 0; i < len; i++) 24 | out = out $(start + i) 25 | } 26 | print(out) 27 | } 28 | -------------------------------------------------------------------------------- /exercises/practice/space-age/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "IsaacG" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "space-age.awk" 8 | ], 9 | "test": [ 10 | "test-space-age.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Given an age in seconds, calculate how old someone is in terms of a given planet's solar years.", 17 | "source": "Partially inspired by Chapter 1 in Chris Pine's online Learn to Program tutorial.", 18 | "source_url": "https://pine.fm/LearnToProgram/?Chapter=01" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/book-store/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "rabestro" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "book-store.awk" 8 | ], 9 | "test": [ 10 | "test-book-store.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "To try and encourage more sales of different books from a popular 5 book series, a bookshop has decided to offer discounts of multiple-book purchases.", 17 | "source": "Inspired by the harry potter kata from Cyber-Dojo.", 18 | "source_url": "https://cyber-dojo.org" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/allergies/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "allergies.awk" 8 | ], 9 | "test": [ 10 | "test-allergies.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Given a person's allergy score, determine whether or not they're allergic to a given item, and their full list of allergies.", 17 | "source": "Exercise by the JumpstartLab team for students at The Turing School of Software and Design.", 18 | "source_url": "https://turing.edu" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/kindergarten-garden/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "kindergarten-garden.awk" 8 | ], 9 | "test": [ 10 | "test-kindergarten-garden.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Given a diagram, determine which plants each child in the kindergarten class is responsible for.", 17 | "source": "Exercise by the JumpstartLab team for students at The Turing School of Software and Design.", 18 | "source_url": "https://turing.edu" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/concept/basics/.meta/exemplar.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ## task 1 4 | awk ' 5 | BEGIN {FS = ":"} 6 | {print $1} 7 | ' ./passwd 8 | 9 | ## task 2 10 | awk '{print NR}' ./passwd 11 | 12 | ## task 3 13 | awk ' 14 | function startsWith(text, prefix) { 15 | return text ~ "^"prefix 16 | } 17 | !(startsWith($6, "/home") || startsWith($6, "/root"))' FS=':' ./passwd 18 | 19 | ## task 4 20 | awk -F ':' ' 21 | function startsWith(text, prefix) { 22 | return text ~ "^"prefix 23 | } 24 | (startsWith($6, "/home") || startsWith($6, "/root")) && $NF ~ /bash/ 25 | ' ./passwd 26 | -------------------------------------------------------------------------------- /exercises/practice/queen-attack/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "IsaacG" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "queen-attack.awk" 8 | ], 9 | "test": [ 10 | "test-queen-attack.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Given the position of two queens on a chess board, indicate whether or not they are positioned so that they can attack each other.", 17 | "source": "J Dalbey's Programming Practice problems", 18 | "source_url": "https://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/shared/.docs/help.md: -------------------------------------------------------------------------------- 1 | # Help 2 | 3 | Places to look for help for AWK questions: 4 | 5 | * [Stack Overflow `awk` tag][so]. 6 | * check the Resources section of the [Stack Overflow `awk` tag into page][so-info]. 7 | * raise an issue at the [exercism/awk][github] Github repository. 8 | * IRC: `irc://irc.liberachat.net/#awk`, `irc://irc.liberachat.net/#exercism` 9 | * see [Libera.chat][libera] if you're unfamiliar with IRC. 10 | 11 | 12 | [so]: https://stackoverflow.com/tags/awk 13 | [so-info]: https://stackoverflow.com/tags/awk/info 14 | [github]: https://github.com/exercism/awk 15 | [libera]: https://libera.chat 16 | -------------------------------------------------------------------------------- /exercises/practice/isbn-verifier/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "rabestro" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "isbn-verifier.awk" 8 | ], 9 | "test": [ 10 | "test-isbn-verifier.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Check if a given string is a valid ISBN-10 number.", 17 | "source": "Converting a string into a number and some basic processing utilizing a relatable real world example.", 18 | "source_url": "https://en.wikipedia.org/wiki/International_Standard_Book_Number#ISBN-10_check_digit_calculation" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/series/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Given a string of digits, output all the contiguous substrings of length `n` in that string in the order that they appear. 4 | 5 | For example, the string "49142" has the following 3-digit series: 6 | 7 | - "491" 8 | - "914" 9 | - "142" 10 | 11 | And the following 4-digit series: 12 | 13 | - "4914" 14 | - "9142" 15 | 16 | And if you ask for a 6-digit series from a 5-digit string, you deserve whatever you get. 17 | 18 | Note that these series are only required to occupy _adjacent positions_ in the input; 19 | the digits need not be _numerically consecutive_. 20 | -------------------------------------------------------------------------------- /exercises/practice/luhn/.meta/example.awk: -------------------------------------------------------------------------------- 1 | BEGIN { result = "false" } 2 | 3 | function luhn_digit(digit, double, doubled) { 4 | if (!double) return digit 5 | doubled = digit * 2 6 | return doubled - (doubled > 9 ? 9 : 0) 7 | } 8 | 9 | # remove whitespace 10 | { gsub(/[[:blank:]]+/, "") } 11 | 12 | # only valid if 2 or more digits 13 | /^[[:digit:]]{2,}$/ { 14 | double = 0 15 | sum = 0 16 | for (i = length(); i >= 1; i--) { 17 | sum += luhn_digit(substr($0, i, 1), double) 18 | double = !double 19 | } 20 | result = (sum % 10 == 0) ? "true" : "false" 21 | } 22 | 23 | END { print result } 24 | -------------------------------------------------------------------------------- /exercises/practice/pig-latin/.meta/example.awk: -------------------------------------------------------------------------------- 1 | function pigify(word, pig, m) { 2 | if (word ~ /^([aeiou]|xr|yt)/) # apple, xray, ytria 3 | pig = word 4 | else if (match(word, /^(.?qu)(.*)/, m)) # quit, square 5 | pig = m[2] m[1] 6 | else if (match(word, /^([^aeiou]+)(y.*)/, m)) # rhythm, my 7 | pig = m[2] m[1] 8 | else if (match(word, /^([^aeiou]+)(.*)/, m)) # strength, cat 9 | pig = m[2] m[1] 10 | else 11 | pig = word 12 | 13 | return pig "ay" 14 | } 15 | 16 | { 17 | for (i = 1; i <= NF; i++) 18 | $i = pigify($i) 19 | print 20 | } 21 | -------------------------------------------------------------------------------- /exercises/practice/saddle-points/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You plan to build a tree house in the woods near your house so that you can watch the sun rise and set. 4 | 5 | You've obtained data from a local survey company that show the height of every tree in each rectangular section of the map. 6 | You need to analyze each grid on the map to find good trees for your tree house. 7 | 8 | A good tree is both: 9 | 10 | - taller than every tree to the east and west, so that you have the best possible view of the sunrises and sunsets. 11 | - shorter than every tree to the north and south, to minimize the amount of tree climbing. 12 | -------------------------------------------------------------------------------- /exercises/practice/space-age/.meta/example.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | seconds_per_earth_year = 31557600 3 | 4 | earth_ratio["Mercury"] = 0.2408467 5 | earth_ratio["Venus"] = 0.61519726 6 | earth_ratio["Earth"] = 1.0 7 | earth_ratio["Mars"] = 1.8808158 8 | earth_ratio["Jupiter"] = 11.862615 9 | earth_ratio["Saturn"] = 29.447498 10 | earth_ratio["Uranus"] = 84.016846 11 | earth_ratio["Neptune"] = 164.79132 12 | } 13 | 14 | { 15 | if (earth_ratio[$1]) { 16 | printf("%.2f\n", ($2 / seconds_per_earth_year) / earth_ratio[$1]) 17 | } else { 18 | print($1 " is not a planet") 19 | exit(1) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /exercises/practice/spiral-matrix/.meta/example.awk: -------------------------------------------------------------------------------- 1 | @include "join.awk" 2 | 3 | # `size` variable comes from command-line 4 | 5 | BEGIN { 6 | x = y = 1 7 | dx = 0 8 | dy = 1 9 | 10 | for (i = 1; i <= size * size; i++) { 11 | m[x][y] = i 12 | if (x + dx < 1 || x + dx > size || 13 | y + dy < 1 || y + dy > size || 14 | m[x + dx][y + dy] != "") 15 | { 16 | tmp = dx 17 | dx = dy 18 | dy = -tmp 19 | } 20 | x += dx 21 | y += dy 22 | } 23 | 24 | for (x = 1; x <= size; x++) { 25 | print join(m[x], 1, size) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. 2 | # 3 | # Regenerating this file via `configlet sync` will: 4 | # - Recreate every `description` key/value pair 5 | # - Recreate every `reimplements` key/value pair, where they exist in problem-specifications 6 | # - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) 7 | # - Preserve any other key/value pair 8 | # 9 | # As user-added comments (using the # character) will be removed when this file 10 | # is regenerated, comments can be added via a `comment` key. 11 | 12 | [af9ffe10-dc13-42d8-a742-e7bdafac449d] 13 | description = "Say Hi!" 14 | -------------------------------------------------------------------------------- /exercises/practice/spiral-matrix/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "spiral-matrix.awk" 8 | ], 9 | "test": [ 10 | "test-spiral-matrix.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Given the size, return a square matrix of numbers in spiral order.", 17 | "source": "Reddit r/dailyprogrammer challenge #320 [Easy] Spiral Ascension.", 18 | "source_url": "https://web.archive.org/web/20230607064729/https://old.reddit.com/r/dailyprogrammer/comments/6i60lr/20170619_challenge_320_easy_spiral_ascension/" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/nth-prime/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. Regular comments will be removed when this 2 | # file is regenerated. Regenerating will not touch any manually added keys, 3 | # so comments can be added in a "comment" key. 4 | 5 | [75c65189-8aef-471a-81de-0a90c728160c] 6 | description = "first prime" 7 | 8 | [2c38804c-295f-4701-b728-56dea34fd1a0] 9 | description = "second prime" 10 | 11 | [56692534-781e-4e8c-b1f9-3e82c1640259] 12 | description = "sixth prime" 13 | 14 | [fce1e979-0edb-412d-93aa-2c744e8f50ff] 15 | description = "big prime" 16 | 17 | [bd0a9eae-6df7-485b-a144-80e13c7d55b2] 18 | description = "there is no zeroth prime" 19 | -------------------------------------------------------------------------------- /exercises/practice/roman-numerals/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Your task is to convert a number from Arabic numerals to Roman numerals. 4 | 5 | For this exercise, we are only concerned about traditional Roman numerals, in which the largest number is MMMCMXCIX (or 3,999). 6 | 7 | ~~~~exercism/note 8 | There are lots of different ways to convert between Arabic and Roman numerals. 9 | We recommend taking a naive approach first to familiarise yourself with the concept of Roman numerals and then search for more efficient methods. 10 | 11 | Make sure to check out our Deep Dive video at the end to explore the different approaches you can take! 12 | ~~~~ 13 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | # Run all tests for commits to master 2 | 3 | name: AWK / main 4 | 5 | on: 6 | push: 7 | branches: 8 | - main 9 | 10 | jobs: 11 | ci: 12 | runs-on: ubuntu-24.04 13 | 14 | steps: 15 | - name: Checkout 16 | uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 17 | 18 | - name: Install software 19 | run: sudo apt update && sudo apt -y install gawk bats 20 | # bats v1.10.0 -- https://launchpad.net/ubuntu/noble/+source/bats 21 | # gawk v5.2.1 -- https://launchpad.net/ubuntu/noble/+source/gawk 22 | 23 | - name: Run tests for all exercises 24 | run: bash bin/ci 25 | -------------------------------------------------------------------------------- /exercises/practice/clock/.meta/example.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | MinutesInHour = 60 3 | MinutesInDay = MinutesInHour * 24 4 | } 5 | $1 == "create" { 6 | printClock(clock($2, $3)) 7 | } 8 | $1 == "add" { 9 | printClock(clock($2, $3 + $4)) 10 | } 11 | $1 == "subtract" { 12 | printClock(clock($2, $3 - $4)) 13 | } 14 | $1 == "equal" { 15 | print clock($2, $3) == clock($4, $5) ? "true" : "false" 16 | } 17 | function clock(hours, minutes) { 18 | return ((hours * MinutesInHour + minutes) % MinutesInDay + MinutesInDay) % MinutesInDay 19 | } 20 | function printClock(minutes) { 21 | printf "%02d:%02d\n", int(minutes / MinutesInHour), minutes % MinutesInHour 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/book-store/.meta/example.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | for (i = 5; i; --i) 3 | Books[i] = 0 4 | 5 | Price[1] = 8 * 100 6 | Price[2] = 8 * 95 7 | Price[3] = 8 * 90 8 | Price[4] = 8 * 80 9 | Price[5] = 8 * 75 10 | } 11 | { 12 | ++Books[$1] 13 | } 14 | END { 15 | n = asort(Books) 16 | 17 | for (i = 5; i; --i) 18 | Group[i] = Books[6 - i] - Books[5 - i] 19 | 20 | combined = Group[3] < Group[5] ? Group[3] : Group[5] 21 | Group[3] -= combined 22 | Group[5] -= combined 23 | Group[4] += 2 * combined 24 | 25 | for (i = 5; i; --i) 26 | total += Price[i] * Group[i] * i 27 | 28 | print total 29 | } 30 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | The classical introductory exercise. 4 | Just say "Hello, World!". 5 | 6 | ["Hello, World!"][hello-world] is the traditional first program for beginning programming in a new language or environment. 7 | 8 | The objectives are simple: 9 | 10 | - Modify the provided code so that it produces the string "Hello, World!". 11 | - Run the test suite and make sure that it succeeds. 12 | - Submit your solution and check it at the website. 13 | 14 | If everything goes well, you will be ready to fetch your first real exercise. 15 | 16 | [hello-world]: https://en.wikipedia.org/wiki/%22Hello,_world!%22_program 17 | -------------------------------------------------------------------------------- /exercises/practice/leap/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | A leap year (in the Gregorian calendar) occurs: 4 | 5 | - In every year that is evenly divisible by 4. 6 | - Unless the year is evenly divisible by 100, in which case it's only a leap year if the year is also evenly divisible by 400. 7 | 8 | Some examples: 9 | 10 | - 1997 was not a leap year as it's not divisible by 4. 11 | - 1900 was not a leap year as it's not divisible by 400. 12 | - 2000 was a leap year! 13 | 14 | ~~~~exercism/note 15 | For a delightful, four-minute explanation of the whole phenomenon of leap years, check out [this YouTube video](https://www.youtube.com/watch?v=xX96xng7sAE). 16 | ~~~~ 17 | -------------------------------------------------------------------------------- /exercises/practice/queen-attack/.meta/example.awk: -------------------------------------------------------------------------------- 1 | function abs(val) { 2 | return (val > 0) ? val : -val 3 | } 4 | 5 | { 6 | for (i = 1; i <= NF; i++) 7 | if ($i < 0 || $i > 7) { 8 | print "invalid position: row or column is not on the board" 9 | exit 1 10 | } 11 | if ($1 == $3 && $2 == $4) { 12 | print "invalid position: pieces are on the same tile" 13 | exit 1 14 | } 15 | # Same row or same column. 16 | if ($1 == $3 || $2 == $4) 17 | print "true" 18 | # Same diagonal. 19 | else if (abs($3 - $1) == abs($4 - $2)) 20 | print "true" 21 | else 22 | print "false" 23 | } 24 | -------------------------------------------------------------------------------- /exercises/practice/acronym/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Convert a phrase to its acronym. 4 | 5 | Techies love their TLA (Three Letter Acronyms)! 6 | 7 | Help generate some jargon by writing a program that converts a long name like Portable Network Graphics to its acronym (PNG). 8 | 9 | Punctuation is handled as follows: hyphens are word separators (like whitespace); all other punctuation can be removed from the input. 10 | 11 | For example: 12 | 13 | | Input | Output | 14 | | ------------------------- | ------ | 15 | | As Soon As Possible | ASAP | 16 | | Liquid-crystal display | LCD | 17 | | Thank George It's Friday! | TGIF | 18 | -------------------------------------------------------------------------------- /exercises/practice/matching-brackets/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You're given the opportunity to write software for the Bracketeer™, an ancient but powerful mainframe. 4 | The software that runs on it is written in a proprietary language. 5 | Much of its syntax is familiar, but you notice _lots_ of brackets, braces and parentheses. 6 | Despite the Bracketeer™ being powerful, it lacks flexibility. 7 | If the source code has any unbalanced brackets, braces or parentheses, the Bracketeer™ crashes and must be rebooted. 8 | To avoid such a scenario, you start writing code that can verify that brackets, braces, and parentheses are balanced before attempting to run it on the Bracketeer™. 9 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color-trio/.meta/example.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | split("black brown red orange yellow green blue violet grey white", colors) 3 | split("kilo mega giga", units) 4 | } 5 | 6 | function value(color) { 7 | for (i = 1; i <= length(colors); i++) 8 | if (colors[i] == color) 9 | return i - 1 10 | print("invalid color") 11 | exit(1) 12 | } 13 | 14 | { 15 | # Compute the resistance. 16 | ohms = (value($1) * 10 + value($2)) * 10 ** value($3) 17 | # Convert to unit values. 18 | while (ohms && ohms % 1000 == 0) { 19 | shifted++ 20 | ohms /= 1000 21 | } 22 | print(ohms " " units[shifted] "ohms") 23 | } 24 | 25 | -------------------------------------------------------------------------------- /exercises/practice/raindrops/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "raindrops.awk" 8 | ], 9 | "test": [ 10 | "test-raindrops.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ] 15 | }, 16 | "blurb": "Convert a number into its corresponding raindrop sounds - Pling, Plang and Plong.", 17 | "source": "A variation on FizzBuzz, a famous technical interview question that is intended to weed out potential candidates. That question is itself derived from Fizz Buzz, a popular children's game for teaching division.", 18 | "source_url": "https://en.wikipedia.org/wiki/Fizz_buzz" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/armstrong-numbers/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | An [Armstrong number][armstrong-number] is a number that is the sum of its own digits each raised to the power of the number of digits. 4 | 5 | For example: 6 | 7 | - 9 is an Armstrong number, because `9 = 9^1 = 9` 8 | - 10 is _not_ an Armstrong number, because `10 != 1^2 + 0^2 = 1` 9 | - 153 is an Armstrong number, because: `153 = 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153` 10 | - 154 is _not_ an Armstrong number, because: `154 != 1^3 + 5^3 + 4^3 = 1 + 125 + 64 = 190` 11 | 12 | Write some code to determine whether a number is an Armstrong number. 13 | 14 | [armstrong-number]: https://en.wikipedia.org/wiki/Narcissistic_number 15 | -------------------------------------------------------------------------------- /exercises/practice/scrabble-score/.meta/example.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | tile["A"]=1; tile["E"]=1; tile["I"]=1; tile["O"]=1; tile["U"]=1 3 | tile["L"]=1; tile["N"]=1; tile["R"]=1; tile["S"]=1; tile["T"]=1 4 | tile["D"]=2; tile["G"]=2 5 | tile["B"]=3; tile["C"]=3; tile["M"]=3; tile["P"]=3 6 | tile["F"]=4; tile["H"]=4; tile["V"]=4; tile["W"]=4; tile["Y"]=4 7 | tile["K"]=5 8 | tile["J"]=8; tile["X"]=8 9 | tile["Q"]=10; tile["Z"]=10 10 | 11 | # FS cannot contain space 12 | FS = OFS = "," 13 | } 14 | 15 | { 16 | $1 = toupper($1) 17 | split($1, letters, //) 18 | sum = 0 19 | for (i in letters) 20 | sum += tile[letters[i]] 21 | print $1, sum 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/kindergarten-garden/.meta/example.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - name 3 | 4 | BEGIN { 5 | split("Alice Bob Charlie David Eve Fred Ginny Harriet Ileana Joseph Kincaid Larry", names) 6 | 7 | plants["G"] = "grass" 8 | plants["C"] = "clover" 9 | plants["V"] = "violets" 10 | plants["R"] = "radishes" 11 | 12 | FPAT = ".." 13 | } 14 | 15 | { 16 | for (i = 1; i <= NF; i++) 17 | plots[names[i]] = plots[names[i]] $i 18 | } 19 | 20 | END { 21 | n = split(plots[name], p, "") 22 | printf "%s", plants[p[1]] 23 | for (i = 2; i <= n; i++) 24 | printf " %s", plants[p[i]] 25 | printf "\n" 26 | } 27 | -------------------------------------------------------------------------------- /exercises/practice/saddle-points/.meta/example.awk: -------------------------------------------------------------------------------- 1 | NR == 1 { 2 | Cols = NF 3 | for (i = 1; i<= Cols; i++) { 4 | ColsMinimum[i] = $i 5 | } 6 | } 7 | { 8 | row_max = $1 9 | for (i = 2; i <= Cols; i++) { 10 | if ($i > row_max) row_max = $i 11 | } 12 | RowsMaximum[NR] = row_max 13 | 14 | for (i = 1; i <= Cols; i++) { 15 | if ($i < ColsMinimum[i]) { 16 | ColsMinimum[i] = $i 17 | } 18 | } 19 | } 20 | END { 21 | for (row = 1; row <= NR; row++) { 22 | for (col = 1; col <= Cols; col++) { 23 | if (RowsMaximum[row] == ColsMinimum[col]) { 24 | print row, col 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /exercises/practice/gigasecond/.docs/instructions.append.md: -------------------------------------------------------------------------------- 1 | # placeholder 2 | 3 | ## Time functions 4 | 5 | This exercise requires using GNU awk's [Time Functions][time-func]. 6 | 7 | For the datetime parsing and formatting functions, be sure to **set the UTC flag**. 8 | To demonstrate: 9 | 10 | ```sh 11 | export TZ=Asia/Kolkata 12 | gawk 'BEGIN { 13 | time = 1234567890 14 | print strftime("%Y-%m-%d %T", time) # format for local timezone 15 | print strftime("%Y-%m-%d %T", time, 1) # format for UTC 16 | }' 17 | ``` 18 | 19 | outputs: 20 | 21 | ```none 22 | 2009-02-14 05:01:30 23 | 2009-02-13 23:31:30 24 | ``` 25 | 26 | [time-func]: https://www.gnu.org/software/gawk/manual/html_node/Time-Functions.html 27 | -------------------------------------------------------------------------------- /exercises/practice/matrix/.meta/example.awk: -------------------------------------------------------------------------------- 1 | @namespace "matrix" 2 | 3 | function read(filename, mtx, nr, n, i, line, row) { 4 | nr = 0 5 | while ((getline < filename) > 0) { 6 | nr++ 7 | for (i = 1; i <= NF; i++) 8 | mtx[nr][i] = $i 9 | } 10 | close(filename) 11 | } 12 | 13 | function row(mtx, rownum, len, r, i) { 14 | len = length(mtx[rownum]) 15 | r = mtx[rownum][1] 16 | for (i = 2; i <= len; i++) 17 | r = r " " mtx[rownum][i] 18 | return r 19 | } 20 | 21 | function column(mtx, colnum, len, c, i) { 22 | len = length(mtx) 23 | c = mtx[1][colnum] 24 | for (i = 2; i <= len; i++) 25 | c = c " " mtx[i][colnum] 26 | return c 27 | } 28 | -------------------------------------------------------------------------------- /exercises/practice/pangram/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You work for a company that sells fonts through their website. 4 | They'd like to show a different sentence each time someone views a font on their website. 5 | To give a comprehensive sense of the font, the random sentences should use **all** the letters in the English alphabet. 6 | 7 | They're running a competition to get suggestions for sentences that they can use. 8 | You're in charge of checking the submissions to see if they are valid. 9 | 10 | ~~~~exercism/note 11 | Pangram comes from Greek, παν γράμμα, pan gramma, which means "every letter". 12 | 13 | The best known English pangram is: 14 | 15 | > The quick brown fox jumps over the lazy dog. 16 | ~~~~ 17 | -------------------------------------------------------------------------------- /exercises/practice/two-fer/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to determine what you will say as you give away the extra cookie. 4 | 5 | If you know the person's name (e.g. if they're named Do-yun), then you will say: 6 | 7 | ```text 8 | One for Do-yun, one for me. 9 | ``` 10 | 11 | If you don't know the person's name, you will say _you_ instead. 12 | 13 | ```text 14 | One for you, one for me. 15 | ``` 16 | 17 | Here are some examples: 18 | 19 | | Name | Dialogue | 20 | | :----- | :-------------------------- | 21 | | Alice | One for Alice, one for me. | 22 | | Bohdan | One for Bohdan, one for me. | 23 | | | One for you, one for me. | 24 | | Zaphod | One for Zaphod, one for me. | 25 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You work for a bioengineering company that specializes in developing therapeutic solutions. 4 | 5 | Your team has just been given a new project to develop a targeted therapy for a rare type of cancer. 6 | 7 | ~~~~exercism/note 8 | It's all very complicated, but the basic idea is that sometimes people's bodies produce too much of a given protein. 9 | That can cause all sorts of havoc. 10 | 11 | But if you can create a very specific molecule (called a micro-RNA), it can prevent the protein from being produced. 12 | 13 | This technique is called [RNA Interference][rnai]. 14 | 15 | [rnai]: https://admin.acceleratingscience.com/ask-a-scientist/what-is-rnai/ 16 | ~~~~ 17 | -------------------------------------------------------------------------------- /exercises/practice/mazy-mice/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "rabestro" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "mazy-mice.awk" 8 | ], 9 | "test": [ 10 | "test-mazy-mice.bats" 11 | ], 12 | "example": [ 13 | ".meta/example.awk" 14 | ], 15 | "editor": [ 16 | "test-maze.awk" 17 | ] 18 | }, 19 | "blurb": "Meet Mickey and Minerva, two clever mice who love to navigate their way through a maze to find cheese. They enjoy a good challenge, but with only their tiny mouse brains, they prefer if there is only one correct path to the cheese.", 20 | "source": "Inspired by the 'Maze Generator' created by Jan Boström at Alance AB.", 21 | "source_url": "https://mazegenerator.net/" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/spiral-matrix/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | In a small village near an ancient forest, there was a legend of a hidden treasure buried deep within the woods. 4 | Despite numerous attempts, no one had ever succeeded in finding it. 5 | This was about to change, however, thanks to a young explorer named Elara. 6 | She had discovered an old document containing instructions on how to locate the treasure. 7 | Using these instructions, Elara was able to draw a map that revealed the path to the treasure. 8 | 9 | To her surprise, the path followed a peculiar clockwise spiral. 10 | It was no wonder no one had been able to find the treasure before! 11 | With the map in hand, Elara embarks on her journey to uncover the hidden treasure. 12 | -------------------------------------------------------------------------------- /bin/pr: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # invoked by .github/workflows/pr.yml 3 | 4 | # We'll be handed the list of files added/modified in a PR. 5 | # From that, extract the list of exercise directories, and 6 | # test there. 7 | 8 | if ((BASH_VERSINFO[0] < 4)); then 9 | echo "[Failure] This script requires bash version 4+" >&2 10 | exit 4 11 | fi 12 | shopt -s extglob 13 | 14 | declare -A seen=() 15 | declare -a dirs 16 | status=0 17 | 18 | for file; do 19 | if [[ $file =~ ^exercises/(practice|concept)/[^/]+ ]]; then 20 | dir=${BASH_REMATCH[0]} 21 | if [[ -z ${seen[$dir]} ]]; then 22 | bin/validate_one_exercise "$dir" || status=1 23 | seen["$dir"]=yes 24 | fi 25 | fi 26 | done 27 | 28 | exit $status 29 | -------------------------------------------------------------------------------- /.github/workflows/no-important-files-changed.yml: -------------------------------------------------------------------------------- 1 | name: No important files changed 2 | 3 | on: 4 | pull_request_target: 5 | types: [opened] 6 | branches: [main] 7 | paths: 8 | - "exercises/concept/**" 9 | - "exercises/practice/**" 10 | - "!exercises/*/*/.approaches/**" 11 | - "!exercises/*/*/.articles/**" 12 | - "!exercises/*/*/.docs/**" 13 | - "!exercises/*/*/.meta/**" 14 | 15 | permissions: 16 | pull-requests: write 17 | 18 | jobs: 19 | check: 20 | uses: exercism/github-actions/.github/workflows/check-no-important-files-changed.yml@main 21 | with: 22 | repository: ${{ github.event.pull_request.head.repo.owner.login }}/${{ github.event.pull_request.head.repo.name }} 23 | ref: ${{ github.head_ref }} 24 | -------------------------------------------------------------------------------- /exercises/practice/matching-brackets/.meta/example.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | FS = "" 3 | pair["]"] = "[" 4 | pair[")"] = "(" 5 | pair["}"] = "{" 6 | } 7 | 8 | { 9 | for (i = 1; i <= NF; i++) { 10 | if ($i ~ /[({[]/) { 11 | # Add open brackets to the stack. 12 | stack[size++] = $i 13 | } else if ($i ~ /[])}]/) { 14 | if (stack[size - 1] == pair[$i]) { 15 | # Pop brackets from the stack if possible. 16 | del stack[--size] 17 | } else { 18 | # Otherwise, fail. 19 | print "false" 20 | exit 21 | } 22 | 23 | } 24 | } 25 | # Check if the stack is empty. 26 | print (size == 0) ? "true" : "false" 27 | } 28 | -------------------------------------------------------------------------------- /exercises/practice/phone-number/.meta/example.awk: -------------------------------------------------------------------------------- 1 | function die(msg) { 2 | print msg 3 | exit 1 4 | } 5 | 6 | # remove valid non-digits 7 | { gsub(/[[:blank:]()+.-]/, "", $0) } 8 | 9 | length < 10 { die("must not be fewer than 10 digits") } 10 | length > 11 { die("must not be greater than 11 digits") } 11 | length > 10 { if (!sub(/^1/, "")) die("11 digits must start with 1") } 12 | 13 | /[[:alpha:]]/ { die("letters not permitted") } 14 | /[^[:digit:]]/ { die("punctuations not permitted") } 15 | /^0/ { die("area code cannot start with zero") } 16 | /^1/ { die("area code cannot start with one") } 17 | /^...0/ { die("exchange code cannot start with zero") } 18 | /^...1/ { die("exchange code cannot start with one") } 19 | 20 | { print } 21 | -------------------------------------------------------------------------------- /exercises/practice/hamming/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Your body is made up of cells that contain DNA. 4 | Those cells regularly wear out and need replacing, which they achieve by dividing into daughter cells. 5 | In fact, the average human body experiences about 10 quadrillion cell divisions in a lifetime! 6 | 7 | When cells divide, their DNA replicates too. 8 | Sometimes during this process mistakes happen and single pieces of DNA get encoded with the incorrect information. 9 | If we compare two strands of DNA and count the differences between them, we can see how many mistakes occurred. 10 | This is known as the "Hamming distance". 11 | 12 | The Hamming distance is useful in many areas of science, not just biology, so it's a nice phrase to be familiar with :) 13 | -------------------------------------------------------------------------------- /exercises/practice/high-scores/.meta/example.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | # the scores will be in a numerically indexed array to maintain 3 | # the insertion order. 4 | # This controls the sorting for the "personal top 3" action: 5 | PROCINFO["sorted_in"] = "@val_num_desc" 6 | } 7 | 8 | $0 == "list" { 9 | for (i = 1; i <= n; i++) 10 | print scores[i] 11 | next 12 | } 13 | $0 == "latest" { 14 | print scores[n] 15 | next 16 | } 17 | $0 == "personalBest" { 18 | print max 19 | next 20 | } 21 | $0 == "personalTopThree" { 22 | count = 0 23 | for (i in scores) { 24 | print scores[i] 25 | if (++count == 3) break 26 | } 27 | next 28 | } 29 | max == "" || max < $0 { 30 | max = $0 31 | } 32 | { 33 | scores[++n] = $0 34 | } 35 | -------------------------------------------------------------------------------- /exercises/practice/sieve/.meta/example.awk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env gawk -f 2 | 3 | { 4 | limit = $1 5 | marks[0] = 0; delete marks[0] 6 | for (i = 2; i <= limit; i++) { 7 | marks[i] = i 8 | } 9 | 10 | # multiples of 2 11 | for (p = 4; p <= limit; p += 2) { 12 | marks[p] = 0 13 | } 14 | # multiples of odd numbered (potential) primes 15 | for (p = 3; p * p <= limit; p += 2) { 16 | if (marks[p]) { 17 | for (q = p * p; q <= limit; q += 2 * p) { 18 | marks[q] = 0 19 | } 20 | } 21 | } 22 | 23 | primes = "" 24 | for (p = 2; p <= limit; p++) { 25 | if (marks[p]) { 26 | primes = primes "," p 27 | } 28 | } 29 | 30 | print substr(primes, 2) 31 | } 32 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to determine the RNA complement of a given DNA sequence. 4 | 5 | Both DNA and RNA strands are a sequence of nucleotides. 6 | 7 | The four nucleotides found in DNA are adenine (**A**), cytosine (**C**), guanine (**G**), and thymine (**T**). 8 | 9 | The four nucleotides found in RNA are adenine (**A**), cytosine (**C**), guanine (**G**), and uracil (**U**). 10 | 11 | Given a DNA strand, its transcribed RNA strand is formed by replacing each nucleotide with its complement: 12 | 13 | - `G` -> `C` 14 | - `C` -> `G` 15 | - `T` -> `A` 16 | - `A` -> `U` 17 | 18 | ~~~~exercism/note 19 | If you want to look at how the inputs and outputs are structured, take a look at the examples in the test suite. 20 | ~~~~ 21 | -------------------------------------------------------------------------------- /exercises/practice/difference-of-squares/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Find the difference between the square of the sum and the sum of the squares of the first N natural numbers. 4 | 5 | The square of the sum of the first ten natural numbers is 6 | (1 + 2 + ... + 10)² = 55² = 3025. 7 | 8 | The sum of the squares of the first ten natural numbers is 9 | 1² + 2² + ... + 10² = 385. 10 | 11 | Hence the difference between the square of the sum of the first ten natural numbers and the sum of the squares of the first ten natural numbers is 3025 - 385 = 2640. 12 | 13 | You are not expected to discover an efficient solution to this yourself from first principles; research is allowed, indeed, encouraged. 14 | Finding the best algorithm for the problem is a key skill in software engineering. 15 | -------------------------------------------------------------------------------- /exercises/practice/phone-number/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You've joined LinkLine, a leading communications company working to ensure reliable connections for everyone. 4 | The team faces a big challenge: users submit phone numbers in all sorts of formats — dashes, spaces, dots, parentheses, and even prefixes. 5 | Some numbers are valid, while others are impossible to use. 6 | 7 | Your mission is to turn this chaos into order. 8 | You'll clean up valid numbers, formatting them appropriately for use in the system. 9 | At the same time, you'll identify and filter out any invalid entries. 10 | 11 | The success of LinkLine's operations depends on your ability to separate the useful from the unusable. 12 | Are you ready to take on the challenge and keep the connections running smoothly? 13 | -------------------------------------------------------------------------------- /exercises/practice/eliuds-eggs/test-pop-count.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | load bats-extra 3 | 4 | @test "0 eggs" { 5 | #[[ $BATS_RUN_SKIPPED == "true" ]] || skip 6 | run gawk -f pop-count.awk <<< "0" 7 | assert_success 8 | assert_output "0" 9 | } 10 | 11 | @test "1 egg" { 12 | [[ $BATS_RUN_SKIPPED == "true" ]] || skip 13 | run gawk -f pop-count.awk <<< "16" 14 | assert_success 15 | assert_output "1" 16 | } 17 | 18 | @test "4 eggs" { 19 | [[ $BATS_RUN_SKIPPED == "true" ]] || skip 20 | run gawk -f pop-count.awk <<< "89" 21 | assert_success 22 | assert_output "4" 23 | } 24 | 25 | @test "13 eggs" { 26 | [[ $BATS_RUN_SKIPPED == "true" ]] || skip 27 | run gawk -f pop-count.awk <<< "2000000000" 28 | assert_success 29 | assert_output "13" 30 | } 31 | -------------------------------------------------------------------------------- /exercises/practice/largest-series-product/.meta/example.awk: -------------------------------------------------------------------------------- 1 | @include "assert" 2 | 3 | BEGIN { FS = "," } 4 | 5 | $2 == 0 { 6 | print 1 7 | next 8 | } 9 | 10 | { 11 | len = length($1) 12 | span = $2 13 | 14 | assert(span <= len, "span must not exceed string length") 15 | assert($1 ~ /^[[:digit:]]+$/, "input must only contain digits") 16 | assert(span > 0, "span must not be negative") 17 | 18 | mx = 0 19 | for (i = 1; i <= len - span + 1; i++) 20 | mx = max(mx, product(substr($1, i, span))) 21 | print mx 22 | } 23 | 24 | function max(a, b) { return (a > b ? a : b) } 25 | 26 | function product(str, prod, digits, n, i) { 27 | prod = 1 28 | n = split(str, digits, "") 29 | for (i = 1; i <= n; i++) 30 | prod *= digits[i] 31 | return prod 32 | } 33 | -------------------------------------------------------------------------------- /exercises/practice/luhn/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | At the Global Verification Authority, you've just been entrusted with a critical assignment. 4 | Across the city, from online purchases to secure logins, countless operations rely on the accuracy of numerical identifiers like credit card numbers, bank account numbers, transaction codes, and tracking IDs. 5 | The Luhn algorithm is a simple checksum formula used to help identify mistyped numbers. 6 | 7 | A batch of identifiers has just arrived on your desk. 8 | All of them must pass the Luhn test to ensure they're legitimate. 9 | If any fail, they'll be flagged as invalid, preventing mistakes such as incorrect transactions or failed account verifications. 10 | 11 | Can you ensure this is done right? The integrity of many services depends on you. 12 | -------------------------------------------------------------------------------- /exercises/concept/vehicle-purchase/.docs/hints.md: -------------------------------------------------------------------------------- 1 | # Hints 2 | 3 | ## General 4 | 5 | - You can accomplish all of these tasks without using an `if` statement. 6 | 7 | ## 1. Determine if you will need a drivers license 8 | 9 | - Use the [equality operator][cmp] to check whether the first field equals a certain string. 10 | - Use a a regular expression to check if the second field contains the required substrings. 11 | - Use one of the two [boolean operators][bool] to combine the two requirements. 12 | 13 | ## 2.Calculate an estimation for the price of a used vehicle 14 | 15 | - Use the [comparison operators][cmp] to determine which discount to use. 16 | 17 | [cmp]: https://www.gnu.org/software/gawk/manual/html_node/Comparison-Operators.html 18 | [bool]: https://www.gnu.org/software/gawk/manual/html_node/Boolean-Ops.html 19 | -------------------------------------------------------------------------------- /concepts/nums-strs/links.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "Numeric and String Constants", 4 | "url": "https://www.gnu.org/software/gawk/manual/html_node/Scalar-Constants.html" 5 | }, 6 | { 7 | "description": "Numeric Functions", 8 | "url": "https://www.gnu.org/software/gawk/manual/html_node/Numeric-Functions.html" 9 | }, 10 | { 11 | "description": "String-Manipulation Functions", 12 | "url": "https://www.gnu.org/software/gawk/manual/html_node/String-Functions.html" 13 | }, 14 | { 15 | "description": "Getting Type Information", 16 | "url": "https://www.gnu.org/software/gawk/manual/html_node/Type-Functions.html" 17 | }, 18 | { 19 | "description": "Conversion of Strings and Numbers", 20 | "url": "https://www.gnu.org/software/gawk/manual/html_node/Conversion.html" 21 | } 22 | ] 23 | -------------------------------------------------------------------------------- /exercises/practice/minesweeper/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to add the mine counts to empty squares in a completed Minesweeper board. 4 | The board itself is a rectangle composed of squares that are either empty (`' '`) or a mine (`'*'`). 5 | 6 | For each empty square, count the number of mines adjacent to it (horizontally, vertically, diagonally). 7 | If the empty square has no adjacent mines, leave it empty. 8 | Otherwise replace it with the adjacent mines count. 9 | 10 | For example, you may receive a 5 x 4 board like this (empty spaces are represented here with the '·' character for display on screen): 11 | 12 | ```text 13 | ·*·*· 14 | ··*·· 15 | ··*·· 16 | ····· 17 | ``` 18 | 19 | Which your code should transform into this: 20 | 21 | ```text 22 | 1*3*1 23 | 13*31 24 | ·2*2· 25 | ·111· 26 | ``` 27 | -------------------------------------------------------------------------------- /exercises/practice/two-fer/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. 2 | # 3 | # Regenerating this file via `configlet sync` will: 4 | # - Recreate every `description` key/value pair 5 | # - Recreate every `reimplements` key/value pair, where they exist in problem-specifications 6 | # - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) 7 | # - Preserve any other key/value pair 8 | # 9 | # As user-added comments (using the # character) will be removed when this file 10 | # is regenerated, comments can be added via a `comment` key. 11 | 12 | [1cf3e15a-a3d7-4a87-aeb3-ba1b43bc8dce] 13 | description = "no name given" 14 | 15 | [b4c6dbb8-b4fb-42c2-bafd-10785abe7709] 16 | description = "a name given" 17 | 18 | [3549048d-1a6e-4653-9a79-b0bda163e8d5] 19 | description = "another name given" 20 | -------------------------------------------------------------------------------- /exercises/practice/list-ops/array-utils.awk: -------------------------------------------------------------------------------- 1 | @namespace "array" 2 | 3 | # some functions used in the List Operations test file. 4 | 5 | # Initialize a variable as an array type 6 | function init(array, type) { 7 | type = awk::typeof(array) 8 | if (!(type == "array" || type == "untyped")) 9 | print "Error: parameter of type " type " cannot be converted to an array" > "/dev/stderr" 10 | 11 | delete array 12 | array[0] = 0 13 | delete array[0] 14 | } 15 | 16 | # print an array's keys and values 17 | function pprint(a, maxw, i) { 18 | if (awk::typeof(a) == "array" ) { 19 | maxw = -1 20 | for (i in a) 21 | if (length(i) > maxw) 22 | maxw = length(i) 23 | for (i in a) 24 | printf "%-*s = %s\n", maxw + 2, "[" i "]", a[i] 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /exercises/practice/scrabble-score/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to compute a word's Scrabble score by summing the values of its letters. 4 | 5 | The letters are valued as follows: 6 | 7 | | Letter | Value | 8 | | ---------------------------- | ----- | 9 | | A, E, I, O, U, L, N, R, S, T | 1 | 10 | | D, G | 2 | 11 | | B, C, M, P | 3 | 12 | | F, H, V, W, Y | 4 | 13 | | K | 5 | 14 | | J, X | 8 | 15 | | Q, Z | 10 | 16 | 17 | For example, the word "cabbage" is worth 14 points: 18 | 19 | - 3 points for C 20 | - 1 point for A 21 | - 3 points for B 22 | - 3 points for B 23 | - 1 point for A 24 | - 2 points for G 25 | - 1 point for E 26 | -------------------------------------------------------------------------------- /exercises/practice/matrix/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Given a string representing a matrix of numbers, return the rows and columns of that matrix. 4 | 5 | So given a string with embedded newlines like: 6 | 7 | ```text 8 | 9 8 7 9 | 5 3 2 10 | 6 6 7 11 | ``` 12 | 13 | representing this matrix: 14 | 15 | ```text 16 | 1 2 3 17 | |--------- 18 | 1 | 9 8 7 19 | 2 | 5 3 2 20 | 3 | 6 6 7 21 | ``` 22 | 23 | your code should be able to spit out: 24 | 25 | - A list of the rows, reading each row left-to-right while moving top-to-bottom across the rows, 26 | - A list of the columns, reading each column top-to-bottom while moving from left-to-right. 27 | 28 | The rows for our example matrix: 29 | 30 | - 9, 8, 7 31 | - 5, 3, 2 32 | - 6, 6, 7 33 | 34 | And its columns: 35 | 36 | - 9, 5, 6 37 | - 8, 3, 6 38 | - 7, 2, 7 39 | -------------------------------------------------------------------------------- /exercises/practice/flower-field/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to add flower counts to empty squares in a completed Flower Field garden. 4 | The garden itself is a rectangle board composed of squares that are either empty (`' '`) or a flower (`'*'`). 5 | 6 | For each empty square, count the number of flowers adjacent to it (horizontally, vertically, diagonally). 7 | If the empty square has no adjacent flowers, leave it empty. 8 | Otherwise replace it with the count of adjacent flowers. 9 | 10 | For example, you may receive a 5 x 4 board like this (empty spaces are represented here with the '·' character for display on screen): 11 | 12 | ```text 13 | ·*·*· 14 | ··*·· 15 | ··*·· 16 | ····· 17 | ``` 18 | 19 | Which your code should transform into this: 20 | 21 | ```text 22 | 1*3*1 23 | 13*31 24 | ·2*2· 25 | ·111· 26 | ``` 27 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. Regular comments will be removed when this 2 | # file is regenerated. Regenerating will not touch any manually added keys, 3 | # so comments can be added in a "comment" key. 4 | 5 | [b4631f82-c98c-4a2f-90b3-c5c2b6c6f661] 6 | description = "Empty RNA sequence" 7 | 8 | [a9558a3c-318c-4240-9256-5d5ed47005a6] 9 | description = "RNA complement of cytosine is guanine" 10 | 11 | [6eedbb5c-12cb-4c8b-9f51-f8320b4dc2e7] 12 | description = "RNA complement of guanine is cytosine" 13 | 14 | [870bd3ec-8487-471d-8d9a-a25046488d3e] 15 | description = "RNA complement of thymine is adenine" 16 | 17 | [aade8964-02e1-4073-872f-42d3ffd74c5f] 18 | description = "RNA complement of adenine is uracil" 19 | 20 | [79ed2757-f018-4f47-a1d7-34a559392dbf] 21 | description = "RNA complement" 22 | -------------------------------------------------------------------------------- /exercises/practice/bob/.meta/example.awk: -------------------------------------------------------------------------------- 1 | function rtrim(s) { 2 | return gensub(/[[:space:]]+$/, "", 1, s) 3 | } 4 | function is_yelling(s) { 5 | return (s ~ /[[:upper:]]/) && (s !~ /[[:lower:]]/) 6 | } 7 | function is_asking(s) { 8 | return rtrim(s) ~ /\?$/ 9 | } 10 | 11 | BEGIN { 12 | RS = SUBSEP # unlikely record separator character 13 | # slurps the whole file as one record 14 | } 15 | rtrim($0) == "" { 16 | print "Fine. Be that way!" 17 | next 18 | } 19 | is_yelling($0) && is_asking($0) { 20 | print "Calm down, I know what I'm doing!" 21 | next 22 | } 23 | is_yelling($0) { 24 | print "Whoa, chill out!" 25 | next 26 | } 27 | is_asking($0) { 28 | print "Sure." 29 | next 30 | } 31 | { 32 | print "Whatever." 33 | } 34 | END { 35 | if (NR == 0) print "Fine. Be that way!" 36 | } 37 | -------------------------------------------------------------------------------- /exercises/practice/allergies/.meta/example.awk: -------------------------------------------------------------------------------- 1 | @include "join" 2 | 3 | BEGIN { 4 | FS = "," 5 | 6 | n = split("eggs,peanuts,shellfish,strawberries,tomatoes,chocolate,pollen,cats", tmp) 7 | for (i = 1; i <= n; i++) 8 | allergies[tmp[i]] = i - 1 9 | 10 | PROCINFO["sorted_in"] = "@val_num_asc" 11 | } 12 | 13 | $2 == "allergic_to" { 14 | print is_allergic_to($1, $3) ? "true" : "false" 15 | } 16 | 17 | $2 == "list" { 18 | n = list_allergies($1, list) 19 | print join(list, 1, n, FS) 20 | } 21 | 22 | function is_allergic_to(score, allergen) { 23 | return and(rshift(score, allergies[allergen]), 1) == 1 24 | } 25 | 26 | function list_allergies(score, result, i) { 27 | for (allergen in allergies) 28 | if (is_allergic_to(score, allergen)) 29 | result[++i] = allergen 30 | return 0 + i 31 | } 32 | 33 | -------------------------------------------------------------------------------- /exercises/practice/anagram/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | At a garage sale, you find a lovely vintage typewriter at a bargain price! 4 | Excitedly, you rush home, insert a sheet of paper, and start typing away. 5 | However, your excitement wanes when you examine the output: all words are garbled! 6 | For example, it prints "stop" instead of "post" and "least" instead of "stale." 7 | Carefully, you try again, but now it prints "spot" and "slate." 8 | After some experimentation, you find there is a random delay before each letter is printed, which messes up the order. 9 | You now understand why they sold it for so little money! 10 | 11 | You realize this quirk allows you to generate anagrams, which are words formed by rearranging the letters of another word. 12 | Pleased with your finding, you spend the rest of the day generating hundreds of anagrams. 13 | -------------------------------------------------------------------------------- /exercises/practice/atbash-cipher/.meta/example.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # -direction 3 | 4 | BEGIN { 5 | FPAT = "[[:alpha:][:digit:]]" 6 | OFS = "" 7 | split("abcdefghijklmnopqrstuvwxyz", letters, //) 8 | for (i = 1; i <= 26; i++) 9 | translation[letters[i]] = letters[27 - i] 10 | for (i = 0; i <= 9; i++) 11 | translation[i] = i 12 | } 13 | 14 | { 15 | $0 = tolower($0) 16 | for (i = 1; i <= NF; i++) 17 | $i = translation[$i] 18 | 19 | if (direction == "decode") { 20 | print 21 | exit 22 | } 23 | 24 | # For encoding, chunk output into blocks of 5. 25 | for (i = 1; i <= length($0); i += 5) { 26 | if (out) { 27 | out = out " " 28 | } 29 | out = out substr($0, i, 5) 30 | } 31 | print(out) 32 | } 33 | -------------------------------------------------------------------------------- /exercises/practice/rectangles/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Count the rectangles in an ASCII diagram like the one below. 4 | 5 | ```text 6 | +--+ 7 | ++ | 8 | +-++--+ 9 | | | | 10 | +--+--+ 11 | ``` 12 | 13 | The above diagram contains these 6 rectangles: 14 | 15 | ```text 16 | 17 | 18 | +-----+ 19 | | | 20 | +-----+ 21 | ``` 22 | 23 | ```text 24 | +--+ 25 | | | 26 | | | 27 | | | 28 | +--+ 29 | ``` 30 | 31 | ```text 32 | +--+ 33 | | | 34 | +--+ 35 | 36 | 37 | ``` 38 | 39 | ```text 40 | 41 | 42 | +--+ 43 | | | 44 | +--+ 45 | ``` 46 | 47 | ```text 48 | 49 | 50 | +--+ 51 | | | 52 | +--+ 53 | ``` 54 | 55 | ```text 56 | 57 | ++ 58 | ++ 59 | 60 | 61 | ``` 62 | 63 | You may assume that the input is always a proper rectangle (i.e. the length of every line equals the length of the first line). 64 | -------------------------------------------------------------------------------- /exercises/practice/eliuds-eggs/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. 2 | # 3 | # Regenerating this file via `configlet sync` will: 4 | # - Recreate every `description` key/value pair 5 | # - Recreate every `reimplements` key/value pair, where they exist in problem-specifications 6 | # - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) 7 | # - Preserve any other key/value pair 8 | # 9 | # As user-added comments (using the # character) will be removed when this file 10 | # is regenerated, comments can be added via a `comment` key. 11 | 12 | [559e789d-07d1-4422-9004-3b699f83bca3] 13 | description = "0 eggs" 14 | 15 | [97223282-f71e-490c-92f0-b3ec9e275aba] 16 | description = "1 egg" 17 | 18 | [1f8fd18f-26e9-4144-9a0e-57cdfc4f4ff5] 19 | description = "4 eggs" 20 | 21 | [0c18be92-a498-4ef2-bcbb-28ac4b06cb81] 22 | description = "13 eggs" 23 | -------------------------------------------------------------------------------- /exercises/practice/bob/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to determine what Bob will reply to someone when they say something to him or ask him a question. 4 | 5 | Bob only ever answers one of five things: 6 | 7 | - **"Sure."** 8 | This is his response if you ask him a question, such as "How are you?" 9 | The convention used for questions is that it ends with a question mark. 10 | - **"Whoa, chill out!"** 11 | This is his answer if you YELL AT HIM. 12 | The convention used for yelling is ALL CAPITAL LETTERS. 13 | - **"Calm down, I know what I'm doing!"** 14 | This is what he says if you yell a question at him. 15 | - **"Fine. Be that way!"** 16 | This is how he responds to silence. 17 | The convention used for silence is nothing, or various combinations of whitespace characters. 18 | - **"Whatever."** 19 | This is what he answers to anything else. 20 | -------------------------------------------------------------------------------- /exercises/practice/nth-prime/.meta/example.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - n 3 | 4 | BEGIN { 5 | if (n < 1) { 6 | print("invalid input") 7 | exit(1) 8 | } 9 | if (n == 1) { 10 | print(2) 11 | exit(0) 12 | } 13 | 14 | primes[1] = 2 15 | count = 1 16 | candidate = 1 17 | 18 | while (count < n) { 19 | while (1) { 20 | candidate += 2 21 | is_prime = 1 22 | i = 1 23 | while (primes[i] <= sqrt(candidate)) { 24 | if (candidate % primes[i] == 0) { 25 | is_prime = 0 26 | break 27 | } 28 | i++ 29 | } 30 | if (is_prime) break 31 | } 32 | primes[++count] = candidate 33 | } 34 | 35 | print primes[n] 36 | } 37 | 38 | -------------------------------------------------------------------------------- /exercises/practice/triangle/.meta/example.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - type 3 | 4 | { 5 | # A triangle must have non-zero size. 6 | perimeter = $1 + $2 + $3 7 | if (perimeter == 0) { 8 | print("false") 9 | exit(0) 10 | } 11 | 12 | # Any one side cannot be larger than both other sides. 13 | for (i = 1; i <= 3; i++) { 14 | if (2 * $i > perimeter) { 15 | print("false") 16 | exit(0) 17 | } 18 | } 19 | 20 | switch (type) { 21 | case "equilateral": 22 | result = ($1 == $2 && $2 == $3) 23 | break 24 | case "isosceles": 25 | result = ($1 == $2 || $2 == $3 || $1 == $3) 26 | break 27 | case "scalene": 28 | result = ($1 != $2 && $2 != $3 && $1 != $3) 29 | break 30 | } 31 | 32 | print(result ? "true" : "false") 33 | } 34 | -------------------------------------------------------------------------------- /exercises/practice/binary-search/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You have stumbled upon a group of mathematicians who are also singer-songwriters. 4 | They have written a song for each of their favorite numbers, and, as you can imagine, they have a lot of favorite numbers (like [0][zero] or [73][seventy-three] or [6174][kaprekars-constant]). 5 | 6 | You are curious to hear the song for your favorite number, but with so many songs to wade through, finding the right song could take a while. 7 | Fortunately, they have organized their songs in a playlist sorted by the title — which is simply the number that the song is about. 8 | 9 | You realize that you can use a binary search algorithm to quickly find a song given the title. 10 | 11 | [zero]: https://en.wikipedia.org/wiki/0 12 | [seventy-three]: https://en.wikipedia.org/wiki/73_(number) 13 | [kaprekars-constant]: https://en.wikipedia.org/wiki/6174_(number) 14 | -------------------------------------------------------------------------------- /exercises/concept/basics/basics.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # You will implement this exercise with a shell script that contains some awk commands. 4 | # In subsequent exercises, the solution file will contains only awk code. 5 | # 6 | # You have 4 tasks to solve. 7 | # Replace the `{exit}` action with awk code to solve the task. 8 | 9 | ## task 1 10 | awk '{exit}' ./passwd 11 | 12 | ## task 2 13 | awk '{exit}' ./passwd 14 | 15 | ## task 3 16 | awk ' 17 | # returns true if the text starts with the prefix 18 | # 19 | # startsWith("Hello, World!", "He") # => true 20 | # startsWith("Goodbye, Mars!", "He") # => false 21 | # 22 | function startsWith(text, prefix) { 23 | return text ~ "^"prefix 24 | } 25 | 26 | {exit} 27 | ' ./passwd 28 | 29 | ## task 4 30 | awk ' 31 | function startsWith(text, prefix) { 32 | return text ~ "^"prefix 33 | } 34 | 35 | {exit} 36 | ' ./passwd 37 | -------------------------------------------------------------------------------- /exercises/practice/proverb/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | For want of a horseshoe nail, a kingdom was lost, or so the saying goes. 4 | 5 | Given a list of inputs, generate the relevant proverb. 6 | For example, given the list `["nail", "shoe", "horse", "rider", "message", "battle", "kingdom"]`, you will output the full text of this proverbial rhyme: 7 | 8 | ```text 9 | For want of a nail the shoe was lost. 10 | For want of a shoe the horse was lost. 11 | For want of a horse the rider was lost. 12 | For want of a rider the message was lost. 13 | For want of a message the battle was lost. 14 | For want of a battle the kingdom was lost. 15 | And all for the want of a nail. 16 | ``` 17 | 18 | Note that the list of inputs may vary; your solution should be able to handle lists of arbitrary length and content. 19 | No line of the output text should be a static, unchanging string; all should vary according to the input given. 20 | -------------------------------------------------------------------------------- /.appends/.github/labels.yml: -------------------------------------------------------------------------------- 1 | # ----------------------------------------------------------------------------------------- # 2 | # These are the repository-specific labels that augment the Exercise-wide labels defined in # 3 | # https://github.com/exercism/org-wide-files/blob/main/global-files/.github/labels.yml. # 4 | # ----------------------------------------------------------------------------------------- # 5 | 6 | - name: "duplicate" 7 | description: "" 8 | color: "cccccc" 9 | 10 | - name: "enhancement" 11 | description: "" 12 | color: "84b6eb" 13 | 14 | - name: "invalid" 15 | description: "" 16 | color: "e6e6e6" 17 | 18 | - name: "needs maintainer" 19 | description: "" 20 | color: "fc2929" 21 | 22 | - name: "new track" 23 | description: "" 24 | color: "159818" 25 | 26 | - name: "question" 27 | description: "" 28 | color: "cc317c" 29 | 30 | - name: "wontfix" 31 | description: "" 32 | color: "ffffff" 33 | -------------------------------------------------------------------------------- /exercises/practice/bottle-song/.meta/example.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - startBottles 3 | # - takeDown 4 | 5 | BEGIN { 6 | split("One Two Three Four Five Six Seven Eight Nine Ten", Numbers) 7 | 8 | while (takeDown--) { 9 | print_verse(startBottles--) 10 | if (takeDown) print "" 11 | } 12 | } 13 | 14 | function print_verse(bottles) { 15 | print first_line(bottles) 16 | print first_line(bottles) 17 | print "And if one green bottle should accidentally fall," 18 | print last_line(bottles - 1) 19 | } 20 | 21 | function first_line(bottles) { 22 | return Numbers[bottles] hanging(bottles) "," 23 | } 24 | 25 | function last_line(bottles) { 26 | return "There'll be " tolower(bottles == 0 ? "no" : Numbers[bottles]) hanging(bottles) "." 27 | } 28 | 29 | function hanging(bottles) { 30 | return " green bottle" (bottles == 1 ? "" : "s") " hanging on the wall" 31 | } 32 | -------------------------------------------------------------------------------- /exercises/practice/anagram/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Given a target word and one or more candidate words, your task is to find the candidates that are anagrams of the target. 4 | 5 | An anagram is a rearrangement of letters to form a new word: for example `"owns"` is an anagram of `"snow"`. 6 | A word is _not_ its own anagram: for example, `"stop"` is not an anagram of `"stop"`. 7 | 8 | The target word and candidate words are made up of one or more ASCII alphabetic characters (`A`-`Z` and `a`-`z`). 9 | Lowercase and uppercase characters are equivalent: for example, `"PoTS"` is an anagram of `"sTOp"`, but `"StoP"` is not an anagram of `"sTOp"`. 10 | The words you need to find should be taken from the candidate words, using the same letter case. 11 | 12 | Given the target `"stone"` and the candidate words `"stone"`, `"tones"`, `"banana"`, `"tons"`, `"notes"`, and `"Seton"`, the anagram words you need to find are `"tones"`, `"notes"`, and `"Seton"`. 13 | -------------------------------------------------------------------------------- /exercises/practice/robot-simulator/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Write a robot simulator. 4 | 5 | A robot factory's test facility needs a program to verify robot movements. 6 | 7 | The robots have three possible movements: 8 | 9 | - turn right 10 | - turn left 11 | - advance 12 | 13 | Robots are placed on a hypothetical infinite grid, facing a particular direction (north, east, south, or west) at a set of {x,y} coordinates, 14 | e.g., {3,8}, with coordinates increasing to the north and east. 15 | 16 | The robot then receives a number of instructions, at which point the testing facility verifies the robot's new position, and in which direction it is pointing. 17 | 18 | - The letter-string "RAALAL" means: 19 | - Turn right 20 | - Advance twice 21 | - Turn left 22 | - Advance once 23 | - Turn left yet again 24 | - Say a robot starts at {7, 3} facing north. 25 | Then running this stream of instructions should leave it at {9, 4} facing west. 26 | -------------------------------------------------------------------------------- /exercises/practice/knapsack/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to determine which items to take so that the total value of her selection is maximized, taking into account the knapsack's carrying capacity. 4 | 5 | Items will be represented as a list of items. 6 | Each item will have a weight and value. 7 | All values given will be strictly positive. 8 | Lhakpa can take only one of each item. 9 | 10 | For example: 11 | 12 | ```text 13 | Items: [ 14 | { "weight": 5, "value": 10 }, 15 | { "weight": 4, "value": 40 }, 16 | { "weight": 6, "value": 30 }, 17 | { "weight": 4, "value": 50 } 18 | ] 19 | 20 | Knapsack Maximum Weight: 10 21 | ``` 22 | 23 | For the above, the first item has weight 5 and value 10, the second item has weight 4 and value 40, and so on. 24 | In this example, Lhakpa should take the second and fourth item to maximize her value, which, in this case, is 90. 25 | She cannot get more than 90 as her knapsack has a weight limit of 10. 26 | -------------------------------------------------------------------------------- /exercises/practice/etl/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. 2 | # 3 | # Regenerating this file via `configlet sync` will: 4 | # - Recreate every `description` key/value pair 5 | # - Recreate every `reimplements` key/value pair, where they exist in problem-specifications 6 | # - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) 7 | # - Preserve any other key/value pair 8 | # 9 | # As user-added comments (using the # character) will be removed when this file 10 | # is regenerated, comments can be added via a `comment` key. 11 | 12 | [78a7a9f9-4490-4a47-8ee9-5a38bb47d28f] 13 | description = "single letter" 14 | 15 | [60dbd000-451d-44c7-bdbb-97c73ac1f497] 16 | description = "single score with multiple letters" 17 | 18 | [f5c5de0c-301f-4fdd-a0e5-df97d4214f54] 19 | description = "multiple scores with multiple letters" 20 | 21 | [5db8ea89-ecb4-4dcd-902f-2b418cc87b9d] 22 | description = "multiple scores with differing numbers of letters" 23 | -------------------------------------------------------------------------------- /exercises/practice/saddle-points/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to find the potential trees where you could build your tree house. 4 | 5 | The data company provides the data as grids that show the heights of the trees. 6 | The rows of the grid represent the east-west direction, and the columns represent the north-south direction. 7 | 8 | An acceptable tree will be the largest in its row, while being the smallest in its column. 9 | 10 | A grid might not have any good trees at all. 11 | Or it might have one, or even several. 12 | 13 | Here is a grid that has exactly one candidate tree. 14 | 15 | ```text 16 | ↓ 17 | 1 2 3 4 18 | |----------- 19 | 1 | 9 8 7 8 20 | → 2 |[5] 3 2 4 21 | 3 | 6 6 7 1 22 | ``` 23 | 24 | - Row 2 has values 5, 3, 2, and 4. The largest value is 5. 25 | - Column 1 has values 9, 5, and 6. The smallest value is 5. 26 | 27 | So the point at `[2, 1]` (row: 2, column: 1) is a great spot for a tree house. 28 | -------------------------------------------------------------------------------- /exercises/practice/etl/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You work for a company that makes an online multiplayer game called Lexiconia. 4 | 5 | To play the game, each player is given 13 letters, which they must rearrange to create words. 6 | Different letters have different point values, since it's easier to create words with some letters than others. 7 | 8 | The game was originally launched in English, but it is very popular, and now the company wants to expand to other languages as well. 9 | 10 | Different languages need to support different point values for letters. 11 | The point values are determined by how often letters are used, compared to other letters in that language. 12 | 13 | For example, the letter 'C' is quite common in English, and is only worth 3 points. 14 | But in Norwegian it's a very rare letter, and is worth 10 points. 15 | 16 | To make it easier to add new languages, your team needs to change the way letters and their point values are stored in the game. 17 | -------------------------------------------------------------------------------- /exercises/practice/grade-school/.meta/example.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - action 3 | # - grade 4 | 5 | BEGIN { 6 | PROCINFO["sorted_in"] = "roster_sort" 7 | FS = "," 8 | } 9 | 10 | !($1 in directory) { 11 | directory[$1] = $2 12 | } 13 | 14 | END { 15 | switch (action) { 16 | case "roster": 17 | for (name in directory) 18 | out = out "," name 19 | print substr(out, 2) 20 | break 21 | 22 | case "grade": 23 | for (name in directory) 24 | if (directory[name] == grade) 25 | out = out "," name 26 | print substr(out, 2) 27 | break 28 | } 29 | } 30 | 31 | # index is the name, value is the grade 32 | function roster_sort(i1, v1, i2, v2) { 33 | if (v1 != v2) return v1 - v2 # sort first by grade 34 | if (i1 < i2) return -1; else return i1 > i2 # then by name 35 | } 36 | -------------------------------------------------------------------------------- /exercises/practice/run-length-encoding/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Implement run-length encoding and decoding. 4 | 5 | Run-length encoding (RLE) is a simple form of data compression, where runs (consecutive data elements) are replaced by just one data value and count. 6 | 7 | For example we can represent the original 53 characters with only 13. 8 | 9 | ```text 10 | "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB" -> "12WB12W3B24WB" 11 | ``` 12 | 13 | RLE allows the original data to be perfectly reconstructed from the compressed data, which makes it a lossless data compression. 14 | 15 | ```text 16 | "AABCCCDEEEE" -> "2AB3CD4E" -> "AABCCCDEEEE" 17 | ``` 18 | 19 | For simplicity, you can assume that the unencoded string will only contain the letters A through Z (either lower or upper case) and whitespace. 20 | This way data to be encoded will never contain any numbers and numbers inside data to be decoded always represent the count for the following character. 21 | -------------------------------------------------------------------------------- /exercises/practice/all-your-base/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Convert a sequence of digits in one base, representing a number, into a sequence of digits in another base, representing the same number. 4 | 5 | ~~~~exercism/note 6 | Try to implement the conversion yourself. 7 | Do not use something else to perform the conversion for you. 8 | ~~~~ 9 | 10 | ## About [Positional Notation][positional-notation] 11 | 12 | In positional notation, a number in base **b** can be understood as a linear combination of powers of **b**. 13 | 14 | The number 42, _in base 10_, means: 15 | 16 | `(4 × 10¹) + (2 × 10⁰)` 17 | 18 | The number 101010, _in base 2_, means: 19 | 20 | `(1 × 2⁵) + (0 × 2⁴) + (1 × 2³) + (0 × 2²) + (1 × 2¹) + (0 × 2⁰)` 21 | 22 | The number 1120, _in base 3_, means: 23 | 24 | `(1 × 3³) + (1 × 3²) + (2 × 3¹) + (0 × 3⁰)` 25 | 26 | _Yes. Those three numbers above are exactly the same. Congratulations!_ 27 | 28 | [positional-notation]: https://en.wikipedia.org/wiki/Positional_notation 29 | -------------------------------------------------------------------------------- /concepts/TODO.md: -------------------------------------------------------------------------------- 1 | # Potential concept topics 2 | 3 | - fundamentals 4 | - patterns and actions 5 | - records and fields 6 | - expressions 7 | - truthiness 8 | 9 | - loops 10 | 11 | - special-blocks 12 | - BEGIN and END 13 | - BEGINFILE and ENDFILE 14 | 15 | - datatypes 16 | - strings, numbers, arrays 17 | - type functions 18 | 19 | - strings 20 | - string functions 21 | 22 | - numbers 23 | - numeric functions 24 | - bitwise functions 25 | 26 | - arrays 27 | - numerically-indexed 28 | - associative 29 | - multidimensional (SUBSEP) 30 | - arrays of arrays 31 | - array traversal & sorting 32 | 33 | - functions 34 | - parameters & local variables 35 | - calling dynamic functions 36 | 37 | - variables 38 | - global vs function parameters 39 | - builtin vars (NR, FNR, NF, FILENAME, ARGV, ARGC) 40 | - user-settable vars (FS, OFS, RS, ORS, FPAT, FIELDWIDTHS) 41 | 42 | - redirection 43 | 44 | - include 45 | 46 | - namespaces 47 | 48 | -------------------------------------------------------------------------------- /exercises/practice/prime-factors/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Compute the prime factors of a given natural number. 4 | 5 | A prime number is only evenly divisible by itself and 1. 6 | 7 | Note that 1 is not a prime number. 8 | 9 | ## Example 10 | 11 | What are the prime factors of 60? 12 | 13 | - Our first divisor is 2. 14 | 2 goes into 60, leaving 30. 15 | - 2 goes into 30, leaving 15. 16 | - 2 doesn't go cleanly into 15. 17 | So let's move on to our next divisor, 3. 18 | - 3 goes cleanly into 15, leaving 5. 19 | - 3 does not go cleanly into 5. 20 | The next possible factor is 4. 21 | - 4 does not go cleanly into 5. 22 | The next possible factor is 5. 23 | - 5 does go cleanly into 5. 24 | - We're left only with 1, so now, we're done. 25 | 26 | Our successful divisors in that computation represent the list of prime factors of 60: 2, 2, 3, and 5. 27 | 28 | You can check this yourself: 29 | 30 | ```text 31 | 2 * 2 * 3 * 5 32 | = 4 * 15 33 | = 60 34 | ``` 35 | 36 | Success! 37 | -------------------------------------------------------------------------------- /exercises/practice/sieve/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. 2 | # 3 | # Regenerating this file via `configlet sync` will: 4 | # - Recreate every `description` key/value pair 5 | # - Recreate every `reimplements` key/value pair, where they exist in problem-specifications 6 | # - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) 7 | # - Preserve any other key/value pair 8 | # 9 | # As user-added comments (using the # character) will be removed when this file 10 | # is regenerated, comments can be added via a `comment` key. 11 | 12 | [88529125-c4ce-43cc-bb36-1eb4ddd7b44f] 13 | description = "no primes under two" 14 | 15 | [4afe9474-c705-4477-9923-840e1024cc2b] 16 | description = "find first prime" 17 | 18 | [974945d8-8cd9-4f00-9463-7d813c7f17b7] 19 | description = "find primes up to 10" 20 | 21 | [2e2417b7-3f3a-452a-8594-b9af08af6d82] 22 | description = "limit is prime" 23 | 24 | [92102a05-4c7c-47de-9ed0-b7d5fcd00f21] 25 | description = "find primes up to 1000" 26 | -------------------------------------------------------------------------------- /exercises/practice/etl/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to change the data format of letters and their point values in the game. 4 | 5 | Currently, letters are stored in groups based on their score, in a one-to-many mapping. 6 | 7 | - 1 point: "A", "E", "I", "O", "U", "L", "N", "R", "S", "T", 8 | - 2 points: "D", "G", 9 | - 3 points: "B", "C", "M", "P", 10 | - 4 points: "F", "H", "V", "W", "Y", 11 | - 5 points: "K", 12 | - 8 points: "J", "X", 13 | - 10 points: "Q", "Z", 14 | 15 | This needs to be changed to store each individual letter with its score in a one-to-one mapping. 16 | 17 | - "a" is worth 1 point. 18 | - "b" is worth 3 points. 19 | - "c" is worth 3 points. 20 | - "d" is worth 2 points. 21 | - etc. 22 | 23 | As part of this change, the team has also decided to change the letters to be lower-case rather than upper-case. 24 | 25 | ~~~~exercism/note 26 | If you want to look at how the data was previously structured and how it needs to change, take a look at the examples in the test suite. 27 | ~~~~ 28 | -------------------------------------------------------------------------------- /exercises/practice/killer-sudoku-helper/.meta/example.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | MaxDigit = 9 3 | } 4 | { 5 | cageSum = $1 6 | cageSize = $2 7 | for (i = 3; i <= NF; ++i) { 8 | ExcludedDigits[$i] = 1 9 | } 10 | NF = 0 11 | generate_recursive(1, cageSum, cageSize) 12 | } 13 | 14 | function generate_recursive(currentStartDigit, remainingSum, remainingSize, maxPossibleFirstDigit, digit) { 15 | NF++ 16 | if (remainingSize == 1) { 17 | if (currentStartDigit <= remainingSum && remainingSum <= MaxDigit && !(remainingSum in ExcludedDigits)) { 18 | $NF = remainingSum 19 | print 20 | } 21 | } else { 22 | maxPossibleFirstDigit = MaxDigit - remainingSize + 1 23 | for (digit = currentStartDigit; digit <= maxPossibleFirstDigit; ++digit) { 24 | if (digit in ExcludedDigits) 25 | continue 26 | $NF = digit 27 | generate_recursive(digit + 1, remainingSum - digit, remainingSize - 1) 28 | } 29 | } 30 | NF-- 31 | } 32 | -------------------------------------------------------------------------------- /exercises/practice/list-ops/.docs/instructions.append.md: -------------------------------------------------------------------------------- 1 | # placeholder 2 | 3 | ## New AWK concepts 4 | 5 | Refer to the [`matrix` exercise instructions][ex-matrix] to refresh on some interesting GNU awk language features. 6 | 7 | ### Dynamic function invocation 8 | 9 | awk functions are not first-class objects: they can't get passed around like some other languages allow. 10 | However, a variable can hold the _name_ of a function (a string), and the function is invoked using a special `@varname(args)` notation. 11 | An example: 12 | 13 | ```awk 14 | function greet(name) { 15 | print "Hello, " name 16 | } 17 | BEGIN { 18 | greet("John") # => "Hello, John" 19 | 20 | f = "greet" 21 | f("Bill") # => error 22 | @f("Bill") # => "Hello, Bill" 23 | } 24 | ``` 25 | This is described in [Indirect Function Calls][indirect]. 26 | This is a `gawk` extension. 27 | 28 | 29 | [ex-matrix]: https://exercism.org/tracks/awk/exercises/matrix 30 | [indirect]: https://www.gnu.org/software/gawk/manual/html_node/Indirect-Calls.html 31 | -------------------------------------------------------------------------------- /exercises/practice/forth/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Implement an evaluator for a very simple subset of Forth. 4 | 5 | [Forth][forth] 6 | is a stack-based programming language. 7 | Implement a very basic evaluator for a small subset of Forth. 8 | 9 | Your evaluator has to support the following words: 10 | 11 | - `+`, `-`, `*`, `/` (integer arithmetic) 12 | - `DUP`, `DROP`, `SWAP`, `OVER` (stack manipulation) 13 | 14 | Your evaluator also has to support defining new words using the customary syntax: `: word-name definition ;`. 15 | 16 | To keep things simple the only data type you need to support is signed integers of at least 16 bits size. 17 | 18 | You should use the following rules for the syntax: a number is a sequence of one or more (ASCII) digits, a word is a sequence of one or more letters, digits, symbols or punctuation that is not a number. 19 | (Forth probably uses slightly different rules, but this is close enough.) 20 | 21 | Words are case-insensitive. 22 | 23 | [forth]: https://en.wikipedia.org/wiki/Forth_%28programming_language%29 24 | -------------------------------------------------------------------------------- /exercises/practice/grep/.meta/example.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - flags 3 | # - pattern 4 | 5 | BEGIN { 6 | opts["n"] = 0 # include line number 7 | opts["l"] = 0 # only filenames containing matches 8 | opts["v"] = 0 # invert matches 9 | opts["x"] = 0 # whole line matching 10 | opts["i"] = 0 # case insensitive 11 | 12 | n = split(flags, fs) 13 | for (i = 1; i <= n; i++) opts[fs[i]] = 1 14 | if (opts["i"]) IGNORECASE = 1 15 | count = 0 16 | } 17 | 18 | match($0, pattern, m) && opts["x"] && m[0] != $0 { 19 | delete m 20 | } 21 | 22 | # if there was a match, the `m` array will have an index `0` 23 | xor((0 in m), opts["v"]) { 24 | count++ 25 | if (opts["l"]) { 26 | print FILENAME 27 | nextfile 28 | } else { 29 | output = $0 30 | if (opts["n"]) output = FNR ":" output 31 | if (ARGC > 2) output = FILENAME ":" output 32 | print output 33 | } 34 | } 35 | 36 | END { 37 | exit(!count) 38 | } 39 | -------------------------------------------------------------------------------- /exercises/practice/proverb/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. 2 | # 3 | # Regenerating this file via `configlet sync` will: 4 | # - Recreate every `description` key/value pair 5 | # - Recreate every `reimplements` key/value pair, where they exist in problem-specifications 6 | # - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) 7 | # - Preserve any other key/value pair 8 | # 9 | # As user-added comments (using the # character) will be removed when this file 10 | # is regenerated, comments can be added via a `comment` key. 11 | 12 | [e974b73e-7851-484f-8d6d-92e07fe742fc] 13 | description = "zero pieces" 14 | 15 | [2fcd5f5e-8b82-4e74-b51d-df28a5e0faa4] 16 | description = "one piece" 17 | 18 | [d9d0a8a1-d933-46e2-aa94-eecf679f4b0e] 19 | description = "two pieces" 20 | 21 | [c95ef757-5e94-4f0d-a6cb-d2083f5e5a83] 22 | description = "three pieces" 23 | 24 | [433fb91c-35a2-4d41-aeab-4de1e82b2126] 25 | description = "full proverb" 26 | 27 | [c1eefa5a-e8d9-41c7-91d4-99fab6d6b9f7] 28 | description = "four pieces modernized" 29 | -------------------------------------------------------------------------------- /exercises/practice/raindrops/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to convert a number into its corresponding raindrop sounds. 4 | 5 | If a given number: 6 | 7 | - is divisible by 3, add "Pling" to the result. 8 | - is divisible by 5, add "Plang" to the result. 9 | - is divisible by 7, add "Plong" to the result. 10 | - **is not** divisible by 3, 5, or 7, the result should be the number as a string. 11 | 12 | ## Examples 13 | 14 | - 28 is divisible by 7, but not 3 or 5, so the result would be `"Plong"`. 15 | - 30 is divisible by 3 and 5, but not 7, so the result would be `"PlingPlang"`. 16 | - 34 is not divisible by 3, 5, or 7, so the result would be `"34"`. 17 | 18 | ~~~~exercism/note 19 | A common way to test if one number is evenly divisible by another is to compare the [remainder][remainder] or [modulus][modulo] to zero. 20 | Most languages provide operators or functions for one (or both) of these. 21 | 22 | [remainder]: https://exercism.org/docs/programming/operators/remainder 23 | [modulo]: https://en.wikipedia.org/wiki/Modulo_operation 24 | ~~~~ 25 | -------------------------------------------------------------------------------- /exercises/practice/beer-song/.meta/example.awk: -------------------------------------------------------------------------------- 1 | # These variables are initialized on the command line (using '-v'): 2 | # - verse 3 | # - start 4 | # - stop 5 | 6 | BEGIN { 7 | if (typeof(verse) != "untyped") 8 | start = stop = verse 9 | 10 | for (v = start; v >= stop; v--) 11 | do_verse(v) 12 | } 13 | 14 | function do_verse(v, b1, b2) { 15 | b1 = bottles(v) 16 | b2 = bottles(v == 0 ? 99 : v - 1) 17 | 18 | printf "%s of beer on the wall, %s of beer.\n", b1, tolower(b1) 19 | printf "%s, %s of beer on the wall.\n", action(v), tolower(b2) 20 | } 21 | 22 | function bottles(n) { 23 | switch (n) { 24 | case 0: return "No more bottles"; break 25 | case 1: return "1 bottle"; break 26 | default: return n " bottles"; break 27 | } 28 | } 29 | 30 | function action(n) { 31 | switch (n) { 32 | case 0: return "Go to the store and buy some more"; break 33 | case 1: return "Take it down and pass it around"; break 34 | default: return "Take one down and pass it around"; break 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /exercises/concept/simple-report/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | You are helping a friend generate a report from readings he has taken in different corners of his garden. 4 | Unfortunately, your friend has stored the data in a strange format. 5 | Each reading is a set of comma separated fields. 6 | However, he has stored two-digit numbers across two columns. 7 | 8 | | field number | meaning | 9 | | --- | --- | 10 | | 1 | ID number | 11 | | 2 | location | 12 | | 3 | first reading, tens value | 13 | | 4 | first reading, ones value | 14 | | 5 | second reading, tens value | 15 | | 6 | second reading, ones value | 16 | 17 | For an input row like `101,house,4,2,5,4` 18 | - the first reading is `42`, 19 | - the second reading is `54`. 20 | 21 | ## Task 1: Generate the report 22 | 23 | Your task is find the average of the two readings and output the results of each row in the following format 24 | 25 | ```none 26 | #,