├── .appends └── .github │ └── labels.yml ├── .dockerignore ├── .github ├── CODEOWNERS ├── dependabot.yml ├── labels.yml └── workflows │ ├── configlet.yml │ └── sync-labels.yml ├── .gitignore ├── .travis.yml ├── .travis └── .gnu-apl │ └── preferences ├── CODE_OF_CONDUCT.md ├── Dockerfiles ├── release.dockerfile └── svn.dockerfile ├── LICENSE ├── README.md ├── bin ├── fetch-configlet ├── install-apl └── run-all-tests ├── config.json ├── config └── exercise_readme.go.tmpl ├── docs ├── ABOUT.md ├── INSTALLATION.md ├── LEARNING.md ├── RESOURCES.md ├── TESTS.md └── config.json ├── exercises ├── practice │ ├── beer-song │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── beer-song-example.apl │ │ │ └── config.json │ │ ├── beer-song.apl │ │ └── beer-song.tc │ ├── difference-of-squares │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── difference-of-squares-example.apl │ │ │ └── tests.toml │ │ ├── difference-of-squares.apl │ │ └── difference-of-squares.tc │ ├── hamming │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── hamming-example.apl │ │ │ └── tests.toml │ │ ├── hamming.apl │ │ └── hamming.tc │ ├── hello-world │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── hello-world-example.apl │ │ │ └── tests.toml │ │ ├── hello-world.apl │ │ └── hello-world.tc │ ├── leap │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── leap-example.apl │ │ │ └── tests.toml │ │ ├── leap.apl │ │ └── leap.tc │ ├── pangram │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── pangram-example.apl │ │ │ └── tests.toml │ │ ├── pangram.apl │ │ └── pangram.tc │ ├── raindrops │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── raindrops-example.apl │ │ │ └── tests.toml │ │ ├── raindrops.apl │ │ └── raindrops.tc │ └── rna-transcription │ │ ├── .docs │ │ └── instructions.md │ │ ├── .meta │ │ ├── config.json │ │ ├── rna-transcription-example.apl │ │ └── tests.toml │ │ ├── rna-transcription.apl │ │ └── rna-transcription.tc └── shared │ └── .docs │ ├── help.md │ └── tests.md ├── img └── .keep └── test.apl /.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: "bug" 7 | description: "" 8 | color: "ee0701" 9 | 10 | - name: "duplicate" 11 | description: "" 12 | color: "cccccc" 13 | 14 | - name: "enhancement" 15 | description: "" 16 | color: "84b6eb" 17 | 18 | - name: "help wanted" 19 | description: "" 20 | color: "128A0C" 21 | 22 | - name: "invalid" 23 | description: "" 24 | color: "e6e6e6" 25 | 26 | - name: "question" 27 | description: "" 28 | color: "cc317c" 29 | 30 | - name: "wontfix" 31 | description: "" 32 | color: "ffffff" 33 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | .DS_Store 3 | tmp 4 | .apl.history 5 | *.log -------------------------------------------------------------------------------- /.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 | 7 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | updates: 4 | 5 | # Keep dependencies for GitHub Actions up-to-date 6 | - package-ecosystem: 'github-actions' 7 | directory: '/' 8 | schedule: 9 | interval: 'daily' 10 | -------------------------------------------------------------------------------- /.github/labels.yml: -------------------------------------------------------------------------------- 1 | # --------------------------------------------------------------- # 2 | # This is an auto-generated file - Do not manually edit this file # 3 | # --------------------------------------------------------------- # 4 | 5 | # This file is automatically generated by concatenating two files: 6 | # 7 | # 1. The Exercism-wide labels: defined in https://github.com/exercism/org-wide-files/blob/main/global-files/.github/labels.yml 8 | # 2. The repository-specific labels: defined in the `.appends/.github/labels.yml` file within this repository. 9 | # 10 | # If any of these two files change, a pull request is automatically created containing a re-generated version of this file. 11 | # Consequently, to change repository-specific labels you should update the `.appends/.github/labels.yml` file and _not_ this file. 12 | # 13 | # When the pull request has been merged, the GitHub labels will be automatically updated by the "Sync labels" workflow. 14 | # This typically takes 5-10 minutes. 15 | 16 | # --------------------------------------------------------------------- # 17 | # These are the Exercism-wide labels which are shared across all repos. # 18 | # --------------------------------------------------------------------- # 19 | 20 | # The following Exercism-wide labels are used to show "tasks" on the website, which will point users to things they can contribute to. 21 | 22 | # The `x:action/` labels describe what sort of work the contributor will be engaged in when working on the issue 23 | - name: "x:action/create" 24 | description: "Work on something from scratch" 25 | color: "ffffff" 26 | 27 | - name: "x:action/fix" 28 | description: "Fix an issue" 29 | color: "ffffff" 30 | 31 | - name: "x:action/improve" 32 | description: "Improve existing functionality/content" 33 | color: "ffffff" 34 | 35 | - name: "x:action/proofread" 36 | description: "Proofread text" 37 | color: "ffffff" 38 | 39 | - name: "x:action/sync" 40 | description: "Sync content with its latest version" 41 | color: "ffffff" 42 | 43 | # The `x:knowledge/` labels describe how much Exercism knowledge is required by the contributor 44 | - name: "x:knowledge/none" 45 | description: "No existing Exercism knowledge required" 46 | color: "ffffff" 47 | 48 | - name: "x:knowledge/elementary" 49 | description: "Little Exercism knowledge required" 50 | color: "ffffff" 51 | 52 | - name: "x:knowledge/intermediate" 53 | description: "Quite a bit of Exercism knowledge required" 54 | color: "ffffff" 55 | 56 | - name: "x:knowledge/advanced" 57 | description: "Comprehensive Exercism knowledge required" 58 | color: "ffffff" 59 | 60 | # The `x:module/` labels indicate what part of Exercism the contributor will be working on 61 | - name: "x:module/analyzer" 62 | description: "Work on Analyzers" 63 | color: "ffffff" 64 | 65 | - name: "x:module/concept" 66 | description: "Work on Concepts" 67 | color: "ffffff" 68 | 69 | - name: "x:module/concept-exercise" 70 | description: "Work on Concept Exercises" 71 | color: "ffffff" 72 | 73 | - name: "x:module/generator" 74 | description: "Work on Exercise generators" 75 | color: "ffffff" 76 | 77 | - name: "x:module/practice-exercise" 78 | description: "Work on Practice Exercises" 79 | color: "ffffff" 80 | 81 | - name: "x:module/representer" 82 | description: "Work on Representers" 83 | color: "ffffff" 84 | 85 | - name: "x:module/test-runner" 86 | description: "Work on Test Runners" 87 | color: "ffffff" 88 | 89 | # The `x:rep/` labels describe the amount of reputation to award 90 | # 91 | # For more information on reputation and how these labels should be used, 92 | # check out https://exercism.org/docs/using/product/reputation 93 | - name: "x:rep/tiny" 94 | description: "Tiny amount of reputation" 95 | color: "ffffff" 96 | 97 | - name: "x:rep/small" 98 | description: "Small amount of reputation" 99 | color: "ffffff" 100 | 101 | - name: "x:rep/medium" 102 | description: "Medium amount of reputation" 103 | color: "ffffff" 104 | 105 | - name: "x:rep/large" 106 | description: "Large amount of reputation" 107 | color: "ffffff" 108 | 109 | - name: "x:rep/massive" 110 | description: "Massive amount of reputation" 111 | color: "ffffff" 112 | 113 | # The `x:size/` labels describe the expected amount of work for a contributor 114 | - name: "x:size/tiny" 115 | description: "Tiny amount of work" 116 | color: "ffffff" 117 | 118 | - name: "x:size/small" 119 | description: "Small amount of work" 120 | color: "ffffff" 121 | 122 | - name: "x:size/medium" 123 | description: "Medium amount of work" 124 | color: "ffffff" 125 | 126 | - name: "x:size/large" 127 | description: "Large amount of work" 128 | color: "ffffff" 129 | 130 | - name: "x:size/massive" 131 | description: "Massive amount of work" 132 | color: "ffffff" 133 | 134 | # The `x:status/` label indicates if there is already someone working on the issue 135 | - name: "x:status/claimed" 136 | description: "Someone is working on this issue" 137 | color: "ffffff" 138 | 139 | # The `x:type/` labels describe what type of work the contributor will be engaged in 140 | - name: "x:type/ci" 141 | description: "Work on Continuous Integration (e.g. GitHub Actions workflows)" 142 | color: "ffffff" 143 | 144 | - name: "x:type/coding" 145 | description: "Write code that is not student-facing content (e.g. test-runners, generators, but not exercises)" 146 | color: "ffffff" 147 | 148 | - name: "x:type/content" 149 | description: "Work on content (e.g. exercises, concepts)" 150 | color: "ffffff" 151 | 152 | - name: "x:type/docker" 153 | description: "Work on Dockerfiles" 154 | color: "ffffff" 155 | 156 | - name: "x:type/docs" 157 | description: "Work on Documentation" 158 | color: "ffffff" 159 | 160 | # This Exercism-wide label is added to all automatically created pull requests that help migrate/prepare a track for Exercism v3 161 | - name: "v3-migration 🤖" 162 | description: "Preparing for Exercism v3" 163 | color: "e99695" 164 | 165 | # This Exercism-wide label can be used to bulk-close issues in preparation for pausing community contributions 166 | - name: "paused" 167 | description: "Work paused until further notice" 168 | color: "e4e669" 169 | 170 | # ----------------------------------------------------------------------------------------- # 171 | # These are the repository-specific labels that augment the Exercise-wide labels defined in # 172 | # https://github.com/exercism/org-wide-files/blob/main/global-files/.github/labels.yml. # 173 | # ----------------------------------------------------------------------------------------- # 174 | 175 | - name: "bug" 176 | description: "" 177 | color: "ee0701" 178 | 179 | - name: "duplicate" 180 | description: "" 181 | color: "cccccc" 182 | 183 | - name: "enhancement" 184 | description: "" 185 | color: "84b6eb" 186 | 187 | - name: "help wanted" 188 | description: "" 189 | color: "128A0C" 190 | 191 | - name: "invalid" 192 | description: "" 193 | color: "e6e6e6" 194 | 195 | - name: "question" 196 | description: "" 197 | color: "cc317c" 198 | 199 | - name: "wontfix" 200 | description: "" 201 | color: "ffffff" 202 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | .DS_Store 3 | bin/configlet 4 | bin/configlet.exe 5 | tmp 6 | .apl.history 7 | *.log -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | services: 2 | - docker 3 | 4 | language: bash 5 | 6 | env: 7 | - APL_VERSION=1.6 8 | - APL_VERSION=svn945 # fixes a bug in 1.7 release; see https://lists.gnu.org/archive/html/bug-apl/2017-05/msg00016.html 9 | 10 | before_install: 11 | - bin/install-apl 12 | - bin/fetch-configlet 13 | 14 | script: 15 | - bin/configlet lint 16 | - docker run apl 'bin/run-all-tests' 17 | -------------------------------------------------------------------------------- /.travis/.gnu-apl/preferences: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # this file contains user preferences for GNU APL. 4 | # 5 | # It should live in: 6 | # 7 | # (1) in folder gnu-apl of the system configuration directory. or 8 | # (2) in folder .gnu-apl in the user's home 9 | # 10 | # In both cases the file name should be 'preferences' 11 | # 12 | # The system configuration directory is usually /etc or /etc/local 13 | # It can be overridden by ./configure --sysconfdir=something-else 14 | # 15 | # If both files are present then (1) is read before (2) so that for 16 | # duplicate settings in both files (2) prevails. 17 | # 18 | # Command line options take precedence over settings in any of these files. 19 | # 20 | # The initial content of this files contains all possible settings, but 21 | # commented out. You should not remove lines but rather comment or 22 | # uncomment them. 23 | # 24 | 25 | 26 | ############################################################################### 27 | # 28 | # WELCOME MESSAGE 29 | # 30 | # Print (or don't) a welcome message on start-up 31 | # 32 | # The corresponding command line options is --silent 33 | # 34 | Welcome Yes (default) 35 | # Welcome No 36 | 37 | 38 | ############################################################################### 39 | # 40 | # OUTPUT COLORING 41 | # 42 | # Output coloring can cause problems when, for example: 43 | # 44 | # (a) you run GNU APL as script 45 | # (b) you use a black background 46 | # (c) you run GNU APL from emacs 47 | # (d) you run GNU APL from a different terminal than color xterm 48 | # 49 | # In case (a) you should use the --script command line option and 50 | # leave Color as is. 51 | # 52 | # In cases (b), (c), and (d) you can uncomment the 'Color No' line below. 53 | # This only affects the initial state of output coloring; you can 54 | # re-enable colors later with APL command ]XTERM ON. 55 | # 56 | # The corresponding command line options are --Color and --noColor 57 | # 58 | # If your terminal does not understand the ANSI escape sequences, 59 | # or if you don't like to provide escape sequences, then you can set Color 60 | # to "curses" and set color numbers instead of escape sequences below. This 61 | # requires that certain environment variables (e.g. TERM) are set properly 62 | # and that your terminfo database contains the terminal you use. 63 | # 64 | # Color ANSI (default) 65 | Color CURSES 66 | # Color No 67 | # 68 | # If you want to disable coloring initially, but switch to curses if the 69 | # command ]COLOR (or the equivalent but now obsolete command ]XTERM) 70 | # is given later on, then you can give the color command twice: 71 | # 72 | # Color CURSES 73 | # Color No 74 | # 75 | 76 | 77 | ############################################################################### 78 | # 79 | # OUTPUT COLOR ESCAPE SEQUENCES FOR ANSI TERMINALS 80 | # 81 | # Output coloring is implemented as follows: 82 | # 83 | # There are 4 output channels called CIN, COUT, CERR, and UERR 84 | # 85 | # CIN is the echo of the input typed by the user, 86 | # COUT is the normal output of the APL interpreter, 87 | # CERR is additional error information, in particular logging. 88 | # UERR is output of the APL interpreter containing error messages, 89 | # 90 | # CIN, COUT, and UERR appear on stdout while CERR appears on stderr. 91 | # Normally stdout and stderr are both displayed on the same terminal, 92 | # but output redirection in the shell can make a difference. 93 | # 94 | # When the interpreter changes from one output channel to another, for 95 | # instance from CIN to COUT after the user has entered a line, then an 96 | # escape sequence (actually, any short sequence of characters) is sent 97 | # to the real output channel (i,e. stdout or stderr). The new channel 98 | # determines which sequence is sent: 99 | # 100 | # CIN: CIN-SEQUENCE CLEAR-EOL 101 | # COUT: COUT-SEQUENCE CLEAR-EOL 102 | # CERR: CERR-SEQUENCE CLEAR-EOL 103 | #UCERR: UERR-SEQUENCE CLEAR-EOL 104 | # 105 | # In addition, when the interpreter exists, then a sequence 106 | # 107 | # RESET-SEQUENCE CLEAR-EOL 108 | # 109 | # is sent which should set the colors to their initial state. 110 | # 111 | # The reason for sending CLEAR-EOL (i.e. clear to end of line) is to color 112 | # the entire next line not only the chars printed on the next line. 113 | # 114 | # Unfortunately it is difficult, if not impossible, to read the current 115 | # color setting from the terminal. Therefore the following is assumed: 116 | # 117 | # "GNU APL is started in a color xterm with white background". 118 | # 119 | # Color xterm is a VT100 (or ANSI) compatible terminal emulation. 120 | # If this assumption is correct, then everything should be fine. Otherwise 121 | # you may want to change the escape sequence sent to the terminal below. 122 | # The numbers below are the decimal values of the bytes sent to the terminal; 123 | # 27 is the escape character, for example. In order to change some or all 124 | # sequences, uncomment the corresponding line and change the hex numbers 125 | # (most likely the columns background and foreground). 126 | # Each sequence can be up to 20 characters long. 127 | # 128 | # The default setting (i.e. for a white background) is this: 129 | # 130 | # VT100: foreground background 131 | # color | | color 132 | # V V 133 | # // ESC [ 0 ; 3 fg ; 4 bg m 134 | # CIN-SEQUENCE 1b 5b 30 3b 33 30 3b 34 37 6d // ESC [0;30;47m 135 | # COUT-SEQUENCE 1b 5b 30 3b 33 30 3b 34 38 6d // ESC [0;30;48m 136 | # CERR-SEQUENCE 1b 5b 30 3b 33 35 3b 34 38 6d // ESC [0;35;48m 137 | # UERR-SEQUENCE 1b 5b 30 3b 33 35 3b 34 38 6d // ESC [0;35;48m 138 | # RESET-SEQUENCE 1b 5b 30 3b 33 39 3b 34 39 6d // ESC [0;39;49m 139 | # CLEAR-EOL-SEQUENCE 1b 5b 4B // ESC [K 140 | # CLEAR-EOS-SEQUENCE 1b 5b 4A // ESC [J 141 | # 142 | # On a black background (still assuming VT100 so that the CLEAR-EOL-SEQUENCE 143 | # does not need to be re-defined), the following may be more suitable: 144 | # 145 | # CIN-SEQUENCE 1b 5b 30 3b 33 32 3b 34 30 6d // ESC [0;32;40m 146 | # COUT-SEQUENCE 1b 5b 30 3b 33 37 3b 34 30 6d // ESC [0;37;40m 147 | # CERR-SEQUENCE 1b 5b 30 3b 33 31 3b 34 30 6d // ESC [0;31;40m 148 | # UERR-SEQUENCE 1b 5b 30 3b 33 31 3b 34 30 6d // ESC [0;31;40m 149 | # RESET-SEQUENCE 1b 5b 30 3b 33 37 3b 34 30 6d // ESC [0;37;48m 150 | CIN-SEQUENCE 1b 5b 31 3b 33 32 6d // ESC [1;32m 151 | COUT-SEQUENCE 1b 5b 30 3b 33 37 6d // ESC [0;37m 152 | CERR-SEQUENCE 1b 5b 30 3b 33 31 6d // ESC [0;31m 153 | UERR-SEQUENCE 1b 5b 30 3b 33 31 6d // ESC [0;31m 154 | RESET-SEQUENCE 1b 5b 30 3b 33 37 6d // ESC [0;37;48m 155 | # 156 | # 157 | 158 | 159 | ############################################################################### 160 | # 161 | # OUTPUT COLOR NUMBER FOR CURSES 162 | # 163 | # There is second way of specifying colors that uses the curses library. 164 | # Instead of specifying the escape sequences sent to the terminal you 165 | # only need to specify the colors wanted and curses will provide the escape 166 | # sequences needed. 167 | # 168 | # Numbers for colors seem to be (nota bene: the author is color-blind): 169 | # 170 | # 0: black 171 | # 1: blue 172 | # 2: green 173 | # 3: cyan 174 | # 4: red 175 | # 5: magenta 176 | # 6: yellow 177 | # 7: white 178 | # 179 | # The colors are specified as numbers like this: 180 | # 181 | # CIN-FOREGROUND 0 182 | # CIN-BACKGROUND 7 183 | # COUT-FOREGROUND 2 184 | # COUT-BACKGROUND 7 185 | # CERR-FOREGROUND 5 186 | # CERR-BACKGROUND 8 187 | # UERR-FOREGROUND 5 188 | # UERR-BACKGROUND 8 189 | # 190 | # or, for dark background: 191 | # 192 | # CIN-FOREGROUND 2 193 | # CIN-BACKGROUND 0 194 | # COUT-FOREGROUND 7 195 | # COUT-BACKGROUND 0 196 | # CERR-FOREGROUND 5 197 | # CERR-BACKGROUND 0 198 | # UERR-FOREGROUND 5 199 | # UERR-BACKGROUND 0 200 | # 201 | # Normally the two methods (escape sequences vs. color numbers) shall not 202 | # be mixed. If they are mixed then the last entry in this file determines 203 | # which method will be used. Also, the numbers for colors are different 204 | # in both methods. 205 | # 206 | 207 | ############################################################################### 208 | # 209 | # INPUT ESC SEQUENCES 210 | # 211 | # Below you can configure the ESC (or other) sequence send by the cursor-up, 212 | # cursor-down, cursor-left, cursor-right, Home, End, Ins, and Del keys of 213 | # your keyboard. 214 | # 215 | # The sequences can be set explicitly (in the following) or via CURSES 216 | # The latter (CURSES) may fail work because the sequences reported by 217 | # CURSES may be different from the sequences sent by the keyboard. 218 | # 219 | Keyboard NOCURSES (default) 220 | # Keyboard CURSES 221 | # 222 | # KEY-CURSOR-UP 1b 5b 41 223 | # KEY-CURSOR-DOWN 1b 5b 42 224 | # KEY-CURSOR-RIGHT 1b 5b 43 225 | # KEY-CURSOR-LEFT 1b 5b 44 226 | # KEY-CURSOR-END 1b 5b 46 227 | # KEY-CURSOR-HOME 1b 5b 48 228 | # KEY-INSMODE 1b 5b 32 7e 229 | # KEY-DELETE 1b 5b 33 7e 230 | # 231 | 232 | ############################################################################### 233 | # 234 | # SHARED VARIABLES 235 | # 236 | # shared variables ⎕SVO, ⎕SVR, ... fork a helper process (APserver) to 237 | # communicate with other APL processors. If you do not need these functions 238 | # then you can prevent starting of APserver by setting SharedVars to Disabled. 239 | # If SharedVars are disabled then GNU APL starts a little faster and, of 240 | # course, ⎕SVO and friends won't work. 241 | # 242 | # The corresponding command line options are --SV and --noSV 243 | # 244 | SharedVars Enabled (default) 245 | # SharedVars Disabled 246 | 247 | 248 | ############################################################################### 249 | # 250 | # LOGGING FACILITIES 251 | # 252 | # If dynamic logging is disabled then these settings have no effect. 253 | # 254 | # Otherwise you can specify the Logging facilities (numbered 1-37 or more) 255 | # that shall be turned on when the APL interpreter starts, This option can 256 | # be used several times. 257 | # 258 | # See command ]LOG for available logging facilities 259 | # 260 | # The corresponding command line option is -l 261 | # 262 | # Logging 1 263 | # Logging 2 264 | # ... 265 | # Logging 37 266 | 267 | 268 | ############################################################################### 269 | # 270 | # GNU APL uses library numbers from 0 to 9 in commands )LOAD, )SAVE, and )COPY, 271 | # for example: 272 | # 273 | # )LOAD 1 workspace 274 | # 275 | # Commands )IN and )OUT use library number 0 implicitly; 276 | # )LOAD, )SAVE, and )COPY use library number 0 implicitly when no 277 | # library number is given. 278 | # 279 | # The directories corresponding to the library numbers can be configured below. 280 | # library numbers 3, 4, and 5 are used (and overridden) libraries shipped with 281 | # GNU APL 282 | # 283 | # LIBREF-0 /home/xyz/my-own-libs 284 | # LIBREF-1 /home/xyz/my-group-libs 285 | # LIBREF-2 /group/abc/other-libs 286 | LIBREF-3 /usr/lib/apl/wslib3 287 | LIBREF-4 /usr/lib/apl/wslib4 288 | LIBREF-5 /usr/lib/apl/wslib5 289 | # LIBREF-6 /usr/lib/gnu-apl/lib-6 290 | # LIBREF-7 /usr/lib/gnu-apl/lib-7 291 | # LIBREF-8 /usr/lib/gnu-apl/lib-8 292 | # LIBREF-9 /usr/lib/gnu-apl/lib-9 293 | # 294 | 295 | 296 | ############################################################################### 297 | # 298 | # READLINE HISTORY PARAMETERS 299 | # 300 | # GNU APL provides a history of lines entered by the user in immediate 301 | # execution mode and ∇-edit mode. 302 | # 303 | # Below the number of history lines and the location of the history file 304 | # can be configured. 305 | # 306 | READLINE_HISTORY_LEN 500 307 | READLINE_HISTORY_PATH .apl.history 308 | 309 | # The history can serve two purposes: to recall lines that were previously 310 | # and to list what was done (with command )HISTORY). For the latter purpose 311 | # it is normally convenient to show the new ⎕CR of a function that was edited 312 | # instead of the command that started the editor. The following parameter 313 | # controls whether the editor command (like ∇foo ) or the new ⎕CR of the 314 | # function shall be inserted into the history. 315 | # 316 | # The default (modified) shows the editor command if the function was opened 317 | # but not changed and the new ⎕CR if the function was changed. 318 | # 319 | # NABLA-TO-HISTORY Never 320 | NABLA-TO-HISTORY Modified (default) 321 | # NABLA-TO-HISTORY Always 322 | 323 | 324 | ############################################################################### 325 | # 326 | # CREATE BACKUP BEFORE )SAVE or )DUMP WORKSPACE 327 | # 328 | BACKUP_BEFORE_SAVE yes 329 | 330 | 331 | ############################################################################### 332 | # 333 | # GNU APL assumes a particular layout of your keyboard (and assumes that you 334 | # do your best to obtain that layout). That assumed layout is shown when you 335 | # give the ]KEYB command. 336 | # 337 | # If your keyboard layout differs from the assumed keyboard for some reason, 338 | # then the ]KEYB command will show the wrong layout. You can fix this by 339 | # providing your own keyboard file which (when specified) is shown by the 340 | # ]KEYB command instead of the assumed layout. 341 | # 342 | # You can use one of the files called 'keyboard1.txt' somewhere below the 343 | # directory named 'support-files' as a starting point for your own layout 344 | # and uncomment the following setting: 345 | # 346 | # KEYBOARD_LAYOUT_FILE /etc/gnu-apl.d/keyboard1.txt 347 | # 348 | 349 | ############################################################################### 350 | # 351 | # Normally you exit GNU APL by issuing the command )OFF and hitting 352 | # ^D (aka. end-of-input) has no effect. 353 | # 354 | # You can make GNU APL exit after a number of ^Ds in a row by specifying 355 | # a (small) positive number below. Note thsat the interpreter will always 356 | # exit if a large number of ^Ds (or EOFs) are read within a short while. 357 | # 358 | CONTROL-Ds-TO-EXIT 0 359 | 360 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | ## Introduction 4 | 5 | Exercism is a platform centered around empathetic conversation. 6 | We have a low tolerance for communication that makes anyone feel unwelcome, unsupported, insulted or discriminated against. 7 | 8 | ## Seen or experienced something uncomfortable? 9 | 10 | If you see or experience abuse, harassment, discrimination, or feel unsafe or upset, please email [abuse@exercism.org](mailto:abuse@exercism.org?subject=%5BCoC%5D) and include \[CoC\] in the subject line. 11 | We will follow up with you as a priority. 12 | 13 | ## Enforcement 14 | 15 | We actively monitor for Code of Conduct (CoC) violations and take any reports of violations extremely seriously. 16 | We have banned contributors, mentors and users due to violations. 17 | 18 | After we receive a report of a CoC violation, we view that person's conversation history on Exercism and related communication channels and attempt to understand whether someone has deliberately broken the CoC, or accidentally crossed a line. 19 | We generally reach out to the person who has been reported to discuss any concerns we have and warn them that repeated violations will result in a ban. 20 | Sometimes we decide that no violation has occurred and that no action is required and sometimes we will also ban people on a first offense. 21 | We strive to be fair, but will err on the side of protecting the culture of our community. 22 | 23 | Exercism's leadership reserve the right to take whatever action they feel appropriate with regards to CoC violations. 24 | 25 | ## The simple version 26 | 27 | - Be empathetic 28 | - Be welcoming 29 | - Be kind 30 | - Be honest 31 | - Be supportive 32 | - Be polite 33 | 34 | ## The details 35 | 36 | Exercism should be a safe place for everybody regardless of 37 | 38 | - Gender, gender identity or gender expression 39 | - Sexual orientation 40 | - Disability 41 | - Physical appearance (including but not limited to body size) 42 | - Race 43 | - Age 44 | - Religion 45 | - Anything else you can think of 46 | 47 | As someone who is part of this community, you agree that: 48 | 49 | - We are collectively and individually committed to safety and inclusivity 50 | - We have zero tolerance for abuse, harassment, or discrimination 51 | - We respect people’s boundaries and identities 52 | - We refrain from using language that can be considered offensive or oppressive (systemically or otherwise), eg. sexist, racist, homophobic, transphobic, ableist, classist, etc. 53 | - this includes (but is not limited to) various slurs. 54 | - We avoid using offensive topics as a form of humor 55 | 56 | We actively work towards: 57 | 58 | - Being a safe community 59 | - Cultivating a network of support & encouragement for each other 60 | - Encouraging responsible and varied forms of expression 61 | 62 | We condemn: 63 | 64 | - Stalking, doxxing, or publishing private information 65 | - Violence, threats of violence or violent language 66 | - Anything that compromises people’s safety 67 | - Conduct or speech which might be considered sexist, racist, homophobic, transphobic, ableist or otherwise discriminatory or offensive in nature 68 | - The use of unwelcome, suggestive, derogatory or inappropriate nicknames or terms 69 | - Disrespect towards others (jokes, innuendo, dismissive attitudes) and towards differences of opinion 70 | - Intimidation or harassment (online or in-person). 71 | Please read the [Citizen Code of Conduct](https://github.com/stumpsyn/policies/blob/master/citizen_code_of_conduct.md) for how we interpret harassment 72 | - Inappropriate attention or contact 73 | - Not understanding the differences between constructive criticism and disparagement 74 | 75 | These things are NOT OK. 76 | 77 | Be aware of how your actions affect others. 78 | If it makes someone uncomfortable, stop. 79 | 80 | If you say something that is found offensive, and you are called out on it, try to: 81 | 82 | - Listen without interruption 83 | - Believe what the person is saying & do not attempt to disqualify what they have to say 84 | - Ask for tips / help with avoiding making the offense in the future 85 | - Apologize and ask forgiveness 86 | 87 | ## History 88 | 89 | This policy was initially adopted from the Front-end London Slack community and has been modified since. 90 | A version history can be seen on [GitHub](https://github.com/exercism/website-copy/edit/main/pages/code_of_conduct.md). 91 | 92 | _This policy is a "living" document, and subject to refinement and expansion in the future. 93 | This policy applies to the Exercism website, the Exercism GitHub organization, any other Exercism-related communication channels (e.g. Slack, Twitter, email) and any other Exercism entity or event._ 94 | -------------------------------------------------------------------------------- /Dockerfiles/release.dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:xenial 2 | LABEL maintainer="marnen@marnen.org" 3 | 4 | ARG apl_deb 5 | WORKDIR /gnu-apl 6 | ADD . /gnu-apl 7 | 8 | RUN apt-get update -y 9 | RUN dpkg -i ${apl_deb} 10 | RUN rm ${apl_deb} 11 | 12 | # 1.6 and before 13 | COPY .travis/.gnu-apl /etc/gnu-apl/ 14 | # 1.7 and later 15 | COPY .travis/.gnu-apl /etc/gnu-apl.d/ -------------------------------------------------------------------------------- /Dockerfiles/svn.dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:xenial 2 | LABEL maintainer="marnen@marnen.org" 3 | 4 | RUN apt-get update && apt-get install -y g++ build-essential 5 | 6 | ARG apl_dir 7 | ARG base_dir=/gnu-apl 8 | WORKDIR ${base_dir} 9 | ADD . ${base_dir} 10 | 11 | WORKDIR ${apl_dir} 12 | RUN ./configure --prefix=/usr --sysconfdir=/etc 13 | RUN make 14 | RUN make install 15 | 16 | WORKDIR ${base_dir} 17 | RUN rm -r ${apl_dir} 18 | 19 | # 1.6 and before 20 | COPY .travis/.gnu-apl /etc/gnu-apl/ 21 | # 1.7 and later 22 | COPY .travis/.gnu-apl /etc/gnu-apl.d/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Exercism 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Exercism GNU APL Track 2 | 3 | ## Current Status 4 | 5 | Quite a lot of work has been done to configure this track. 6 | There are 8 exercises. 7 | 8 | If you wish to work on this track, please post in the [Exercism Community Forum](https://forum.exercism.org/c/exercism/building-exercism/125) to discuss it with the team. 9 | -------------------------------------------------------------------------------- /bin/fetch-configlet: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This file is a copy of the 4 | # https://github.com/exercism/configlet/blob/main/scripts/fetch-configlet file. 5 | # Please submit bugfixes/improvements to the above file to ensure that all tracks benefit from the changes. 6 | 7 | set -eo pipefail 8 | 9 | curlopts=( 10 | --silent 11 | --show-error 12 | --fail 13 | --location 14 | --retry 3 15 | ) 16 | 17 | if [[ -n "${GITHUB_TOKEN}" ]]; then 18 | curlopts+=(--header "authorization: Bearer ${GITHUB_TOKEN}") 19 | fi 20 | 21 | get_download_url() { 22 | local os="$1" 23 | local ext="$2" 24 | local latest='https://api.github.com/repos/exercism/configlet/releases/latest' 25 | local arch 26 | case "$(uname -m)" in 27 | x86_64) arch='x86-64' ;; 28 | *686*) arch='i386' ;; 29 | *386*) arch='i386' ;; 30 | *) arch='x86-64' ;; 31 | esac 32 | local suffix="${os}_${arch}.${ext}" 33 | curl "${curlopts[@]}" --header 'Accept: application/vnd.github.v3+json' "${latest}" | 34 | grep "\"browser_download_url\": \".*/download/.*/configlet.*${suffix}\"$" | 35 | cut -d'"' -f4 36 | } 37 | 38 | main() { 39 | local output_dir 40 | if [[ -d ./bin ]]; then 41 | output_dir="./bin" 42 | elif [[ $PWD == */bin ]]; then 43 | output_dir="$PWD" 44 | else 45 | echo "Error: no ./bin directory found. This script should be ran from a repo root." >&2 46 | return 1 47 | fi 48 | 49 | local os 50 | case "$(uname)" in 51 | Darwin*) os='macos' ;; 52 | Linux*) os='linux' ;; 53 | Windows*) os='windows' ;; 54 | MINGW*) os='windows' ;; 55 | MSYS_NT-*) os='windows' ;; 56 | *) os='linux' ;; 57 | esac 58 | 59 | local ext 60 | case "${os}" in 61 | windows*) ext='zip' ;; 62 | *) ext='tar.gz' ;; 63 | esac 64 | 65 | echo "Fetching configlet..." >&2 66 | local download_url 67 | download_url="$(get_download_url "${os}" "${ext}")" 68 | local output_path="${output_dir}/latest-configlet.${ext}" 69 | curl "${curlopts[@]}" --output "${output_path}" "${download_url}" 70 | 71 | case "${ext}" in 72 | *zip) unzip "${output_path}" -d "${output_dir}" ;; 73 | *) tar xzf "${output_path}" -C "${output_dir}" ;; 74 | esac 75 | 76 | rm -f "${output_path}" 77 | 78 | local executable_ext 79 | case "${os}" in 80 | windows*) executable_ext='.exe' ;; 81 | *) executable_ext='' ;; 82 | esac 83 | 84 | local configlet_path="${output_dir}/configlet${executable_ext}" 85 | local configlet_version 86 | configlet_version="$(${configlet_path} --version)" 87 | echo "Downloaded configlet ${configlet_version} to ${configlet_path}" 88 | } 89 | 90 | main 91 | -------------------------------------------------------------------------------- /bin/install-apl: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DOCKERFILE_PATH=Dockerfiles 4 | 5 | prepare_svn_install() { 6 | SVN_REV=${APL_VERSION#svn} 7 | APL_DIR=apl-src 8 | svn co "svn://svn.savannah.gnu.org/apl/trunk@${SVN_REV}" $APL_DIR 9 | BUILD_ARGS="--build-arg apl_dir=${APL_DIR}" 10 | DOCKERFILE=svn.dockerfile 11 | } 12 | 13 | prepare_release_install() { 14 | APL_DEB=apl_${APL_VERSION}-1_amd64.deb 15 | wget ftp://ftp.gnu.org/gnu/apl/${APL_DEB} 16 | BUILD_ARGS="--build-arg apl_deb=${APL_DEB}" 17 | DOCKERFILE=release.dockerfile 18 | } 19 | 20 | if [[ ${APL_VERSION} =~ ^svn ]]; then 21 | prepare_svn_install 22 | else 23 | prepare_release_install 24 | fi 25 | 26 | docker build -f ${DOCKERFILE_PATH}/${DOCKERFILE} -t apl ${BUILD_ARGS} . 27 | -------------------------------------------------------------------------------- /bin/run-all-tests: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | STATUS=0 4 | APL=/usr/bin/apl 5 | APL_OPTS='--silent --Color' 6 | TMP=tmp 7 | 8 | cp --recursive exercises/practice $TMP 9 | 10 | for exercise in ${TMP}/*; do 11 | pushd $exercise 12 | pushd .meta 13 | for example in *-example.apl; do 14 | mv $example ../${example/-example/} 15 | done 16 | popd 17 | if ! ${APL} ${APL_OPTS} -T *.tc; then 18 | STATUS=1 19 | fi 20 | popd 21 | done 22 | 23 | rm -r $TMP 24 | 25 | echo "Exiting with status ${STATUS}." 26 | exit $STATUS 27 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "track_id": "gnu-apl", 3 | "language": "GNU APL", 4 | "slug": "gnu-apl", 5 | "active": false, 6 | "status": { 7 | "concept_exercises": false, 8 | "test_runner": false, 9 | "representer": false, 10 | "analyzer": false 11 | }, 12 | "blurb": "APL is a programming language developed in the 1960s by Kenneth E. Iverson. Its central datatype is the multidimensional array. It uses a large range of special graphic symbols to represent most functions and operators, leading to very concise code. It has been an important influence on the development of concept modeling, spreadsheets, functional programming, and computer math packages.", 13 | "version": 3, 14 | "online_editor": { 15 | "indent_style": "space", 16 | "indent_size": 4, 17 | "highlightjs_language": "text" 18 | }, 19 | "files": { 20 | "solution": [ 21 | "%{kebab_slug}.apl" 22 | ], 23 | "test": [ 24 | "%{kebab_slug}.tc" 25 | ], 26 | "example": [ 27 | ".meta/%{kebab_slug}-example.apl" 28 | ], 29 | "exemplar": [ 30 | ".meta/%{kebab_slug}-exemplar.apl" 31 | ] 32 | }, 33 | "exercises": { 34 | "concept": [], 35 | "practice": [ 36 | { 37 | "slug": "hello-world", 38 | "name": "Hello World", 39 | "uuid": "81121f0c-1218-4d88-bb6c-fd9df3bc0b8d", 40 | "practices": [], 41 | "prerequisites": [], 42 | "difficulty": 1, 43 | "topics": [ 44 | "setup" 45 | ] 46 | }, 47 | { 48 | "slug": "leap", 49 | "name": "Leap", 50 | "uuid": "edf36b1a-3f20-4d63-a919-55a2bd063a2f", 51 | "practices": [], 52 | "prerequisites": [], 53 | "difficulty": 1, 54 | "topics": [ 55 | "conditions", 56 | "dates" 57 | ] 58 | }, 59 | { 60 | "slug": "beer-song", 61 | "name": "Beer Song", 62 | "uuid": "47302bc5-727c-4151-80cd-d86064d5f390", 63 | "practices": [], 64 | "prerequisites": [], 65 | "difficulty": 1, 66 | "topics": [ 67 | "conditions", 68 | "recursion" 69 | ] 70 | }, 71 | { 72 | "slug": "hamming", 73 | "name": "Hamming", 74 | "uuid": "4ddbc20a-46dc-4e00-b472-0e108bab3481", 75 | "practices": [], 76 | "prerequisites": [], 77 | "difficulty": 1, 78 | "topics": [ 79 | "arrays", 80 | "differences", 81 | "strings" 82 | ] 83 | }, 84 | { 85 | "slug": "rna-transcription", 86 | "name": "Rna Transcription", 87 | "uuid": "4fbbeab4-2e54-4549-b78b-4c9ec1fea9c0", 88 | "practices": [], 89 | "prerequisites": [], 90 | "difficulty": 1, 91 | "topics": [ 92 | "arrays", 93 | "error_handling", 94 | "strings", 95 | "substitution" 96 | ] 97 | }, 98 | { 99 | "slug": "raindrops", 100 | "name": "Raindrops", 101 | "uuid": "c5f5231d-dce9-4684-9d66-c8a462fecae9", 102 | "practices": [], 103 | "prerequisites": [], 104 | "difficulty": 1, 105 | "topics": [ 106 | "conditions", 107 | "residue", 108 | "strings" 109 | ] 110 | }, 111 | { 112 | "slug": "difference-of-squares", 113 | "name": "Difference Of Squares", 114 | "uuid": "0a5c1f23-8f3f-479c-8ed5-ce21361daa20", 115 | "practices": [], 116 | "prerequisites": [], 117 | "difficulty": 1, 118 | "topics": [ 119 | "arrays", 120 | "math", 121 | "reduce" 122 | ] 123 | }, 124 | { 125 | "slug": "pangram", 126 | "name": "Pangram", 127 | "uuid": "7d52c43e-d193-4c90-a91b-0e6ee605cccb", 128 | "practices": [], 129 | "prerequisites": [], 130 | "difficulty": 1, 131 | "topics": [ 132 | "characters", 133 | "strings" 134 | ] 135 | } 136 | ] 137 | }, 138 | "concepts": [], 139 | "key_features": [], 140 | "tags": [] 141 | } 142 | -------------------------------------------------------------------------------- /config/exercise_readme.go.tmpl: -------------------------------------------------------------------------------- 1 | # {{ .Spec.Name }} 2 | 3 | {{ .Spec.Description -}} 4 | {{- with .Hints }} 5 | {{ . }} 6 | {{ end }} 7 | {{- with .Spec.Credits -}} 8 | ## Source 9 | 10 | {{ . }} 11 | {{ end }} 12 | ## Submitting Incomplete Solutions 13 | It's possible to submit an incomplete solution so you can see how others have completed the exercise. 14 | -------------------------------------------------------------------------------- /docs/ABOUT.md: -------------------------------------------------------------------------------- 1 | # About 2 | 3 | -------------------------------------------------------------------------------- /docs/INSTALLATION.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | -------------------------------------------------------------------------------- /docs/LEARNING.md: -------------------------------------------------------------------------------- 1 | # Learning 2 | 3 | -------------------------------------------------------------------------------- /docs/RESOURCES.md: -------------------------------------------------------------------------------- 1 | # Resources 2 | 3 | -------------------------------------------------------------------------------- /docs/TESTS.md: -------------------------------------------------------------------------------- 1 | # Tests 2 | 3 | -------------------------------------------------------------------------------- /docs/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "docs": [ 3 | { 4 | "uuid": "53edd374-54a1-40d3-bf42-185e29153e11", 5 | "slug": "installation", 6 | "path": "docs/INSTALLATION.md", 7 | "title": "Installing GNU APL locally", 8 | "blurb": "Learn how to install GNU APL locally to solve Exercism's exercises on your own machine" 9 | }, 10 | { 11 | "uuid": "51b7567c-a533-4ec8-8871-295e2ec956a7", 12 | "slug": "learning", 13 | "path": "docs/LEARNING.md", 14 | "title": "How to learn GNU APL", 15 | "blurb": "An overview of how to get started from scratch with GNU APL" 16 | }, 17 | { 18 | "uuid": "965fd33b-8c64-4357-996e-f5aad5d165cc", 19 | "slug": "tests", 20 | "path": "docs/TESTS.md", 21 | "title": "Testing on the GNU APL track", 22 | "blurb": "Learn how to test your GNU APL exercises on Exercism" 23 | }, 24 | { 25 | "uuid": "6b0a415f-f68e-411e-8f11-777e0e68c1a6", 26 | "slug": "resources", 27 | "path": "docs/RESOURCES.md", 28 | "title": "Useful GNU APL resources", 29 | "blurb": "A collection of useful resources to help you master GNU APL" 30 | } 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /exercises/practice/beer-song/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is write a program that outputs the old road-trip standby, "99 Bottles of Beer on the Wall". 4 | 5 | Recite the lyrics to that beloved classic, that field-trip favorite: 99 Bottles of Beer on the Wall. 6 | 7 | Note that not all verses are identical. 8 | 9 | ## Lyrics 10 | 11 | ```text 12 | 99 bottles of beer on the wall, 99 bottles of beer. 13 | Take one down and pass it around, 98 bottles of beer on the wall. 14 | 15 | 98 bottles of beer on the wall, 98 bottles of beer. 16 | Take one down and pass it around, 97 bottles of beer on the wall. 17 | 18 | 97 bottles of beer on the wall, 97 bottles of beer. 19 | Take one down and pass it around, 96 bottles of beer on the wall. 20 | 21 | 96 bottles of beer on the wall, 96 bottles of beer. 22 | Take one down and pass it around, 95 bottles of beer on the wall. 23 | 24 | ... 25 | ... 26 | 27 | 2 bottles of beer on the wall, 2 bottles of beer. 28 | Take one down and pass it around, 1 bottle of beer on the wall. 29 | 30 | 1 bottle of beer on the wall, 1 bottle of beer. 31 | Take it down and pass it around, no more bottles of beer on the wall. 32 | 33 | No more bottles of beer on the wall, no more bottles of beer. 34 | Go to the store and buy some more, 99 bottles of beer on the wall. 35 | ``` 36 | 37 | How will you print out the original number of bottles at the end 38 | of the song? 39 | 40 | Watch out for 0 bottles or negative amounts of bottles! 41 | 42 | ## For bonus points 43 | 44 | The 'simplest' solution may be recursive. Can you come up with 45 | another solution that uses tail recursion, or is iterative? 46 | -------------------------------------------------------------------------------- /exercises/practice/beer-song/.meta/beer-song-example.apl: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/apl --script 2 | 3 | ⍝ The famous '99 Bottles of Beer' road song in APL 4 | ⍝ 5 | ⍝ This solution uses a straightforward recursive solution. 6 | ⍝ There are iterative and tail-recursive ways to do it, why 7 | ⍝ not try it those ways afterwards? 8 | ⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝ 9 | 10 | ∇s beers n;next 11 | ⍝⍝ This function does the real work; note that it takes 12 | ⍝⍝ two arguments: s is the original count at the start of 13 | ⍝⍝ the song, so that it can be printed at the end. 14 | ⍝⍝⍝⍝ 15 | 16 | next←n-1 17 | →(n=0)/none 18 | →(n=1)/last 19 | ⎕←n,'Bottles of beer on the wall,',n,'bottles of beer.' 20 | ⎕←'Take one down and pass it around,',next,'bottles of beer on the wall.' 21 | s beers next 22 | →0 23 | last: 24 | ⎕←n,'Bottle of beer on the wall,',n,'bottle of beer.' 25 | ⎕←'Take it down and pass it around, no more bottles of beer on the wall.' 26 | s beers next 27 | →0 28 | none: 29 | ⎕←'No more bottles of beer on the wall, no more bottles of beer.' 30 | ⎕←'Go to the store and buy some more,',s,'bottles of beer on the wall.' 31 | →0 32 | ∇ 33 | 34 | ∇beerSong n 35 | ⍝⍝ This is the main entry function. 36 | ⍝⍝ Note we avoid counting down from 0 bottles of beer! 37 | ⍝⍝⍝⍝ 38 | →(n≥0)/viableSong 39 | nonsense: 40 | ⎕←'Negative beer? Madness!' 41 | →0 42 | viableSong: 43 | n beers n 44 | ∇ 45 | -------------------------------------------------------------------------------- /exercises/practice/beer-song/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "Recite the lyrics to that beloved classic, that field-trip favorite: 99 Bottles of Beer on the Wall.", 3 | "authors": [ 4 | "russtopia" 5 | ], 6 | "contributors": [ 7 | ], 8 | "files": { 9 | "solution": [ 10 | "beer-song.apl" 11 | ], 12 | "test": [ 13 | "beer-song.tc" 14 | ], 15 | "example": [ 16 | ".meta/beer-song-example.apl" 17 | ] 18 | }, 19 | "source": "Learn to Program by Chris Pine", 20 | "source_url": "http://pine.fm/LearnToProgram/?Chapter=06" 21 | } 22 | -------------------------------------------------------------------------------- /exercises/practice/beer-song/beer-song.apl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exercism/gnu-apl/4443b7ccd0203d4987f74780b9f0869449f49328/exercises/practice/beer-song/beer-song.apl -------------------------------------------------------------------------------- /exercises/practice/beer-song/beer-song.tc: -------------------------------------------------------------------------------- 1 | log←'./beer-song.tc.log' 2 | ⍎ ')COPY ',(⎕FIO 30),'/../../test.apl' 3 | 4 | test∆copy_relative 'beer-song.apl' 5 | test∆clear_log log 6 | 7 | ⍝ ∇beerSong 8 | ⍝ Given a non-negative number, sing the '99 Bottles of Beer' song. 9 | 10 | ⍝ The song given 2 bottles on the wall ... 11 | beerSong 2 12 | 2 Bottles of beer on the wall, 2 bottles of beer. 13 | Take one down and pass it around, 1 bottles of beer on the wall. 14 | 1 Bottle of beer on the wall, 1 bottle of beer. 15 | Take it down and pass it around, no more bottles of beer on the wall. 16 | No more bottles of beer on the wall, no more bottles of beer. 17 | Go to the store and buy some more, 2 bottles of beer on the wall. 18 | 19 | ⍝ The song given 1 bottle on the wall ... 20 | beerSong 1 21 | 1 Bottle of beer on the wall, 1 bottle of beer. 22 | Take it down and pass it around, no more bottles of beer on the wall. 23 | No more bottles of beer on the wall, no more bottles of beer. 24 | Go to the store and buy some more, 1 bottles of beer on the wall. 25 | 26 | ⍝ The song given no bottles on the wall ... 27 | beerSong 0 28 | No more bottles of beer on the wall, no more bottles of beer. 29 | Go to the store and buy some more, 0 bottles of beer on the wall. 30 | 31 | ⍝ Negative bottles of beer?! 32 | beerSong ¯1 33 | Negative beer? Madness! 34 | 35 | test∆show_log log 36 | -------------------------------------------------------------------------------- /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 12 | ten natural numbers and the sum of the squares of the first ten 13 | natural numbers is 3025 - 385 = 2640. 14 | 15 | You are not expected to discover an efficient solution to this yourself from 16 | first principles; research is allowed, indeed, encouraged. Finding the best 17 | algorithm for the problem is a key skill in software engineering. 18 | -------------------------------------------------------------------------------- /exercises/practice/difference-of-squares/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "Find the difference between the square of the sum and the sum of the squares of the first N natural numbers.", 3 | "authors": [ 4 | "marnen" 5 | ], 6 | "contributors": [ 7 | "iHiD" 8 | ], 9 | "files": { 10 | "solution": [ 11 | "difference-of-squares.apl" 12 | ], 13 | "test": [ 14 | "difference-of-squares.tc" 15 | ], 16 | "example": [ 17 | ".meta/difference-of-squares-example.apl" 18 | ] 19 | }, 20 | "source": "Problem 6 at Project Euler", 21 | "source_url": "http://projecteuler.net/problem=6" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/difference-of-squares/.meta/difference-of-squares-example.apl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env apl --script 2 | 3 | ∇z←square_of_sum integer 4 | z←(+/⍳integer)*2 5 | ∇ 6 | 7 | ∇z←sum_of_squares integer 8 | z←+/(⍳integer)*2 9 | ∇ 10 | 11 | ∇z←difference_of_squares integer 12 | z←(square_of_sum integer)-sum_of_squares integer 13 | ∇ -------------------------------------------------------------------------------- /exercises/practice/difference-of-squares/.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 | [e46c542b-31fc-4506-bcae-6b62b3268537] 13 | description = "Square the sum of the numbers up to the given number -> square of sum 1" 14 | 15 | [9b3f96cb-638d-41ee-99b7-b4f9c0622948] 16 | description = "Square the sum of the numbers up to the given number -> square of sum 5" 17 | 18 | [54ba043f-3c35-4d43-86ff-3a41625d5e86] 19 | description = "Square the sum of the numbers up to the given number -> square of sum 100" 20 | 21 | [01d84507-b03e-4238-9395-dd61d03074b5] 22 | description = "Sum the squares of the numbers up to the given number -> sum of squares 1" 23 | 24 | [c93900cd-8cc2-4ca4-917b-dd3027023499] 25 | description = "Sum the squares of the numbers up to the given number -> sum of squares 5" 26 | 27 | [94807386-73e4-4d9e-8dec-69eb135b19e4] 28 | description = "Sum the squares of the numbers up to the given number -> sum of squares 100" 29 | 30 | [44f72ae6-31a7-437f-858d-2c0837adabb6] 31 | description = "Subtract sum of squares from square of sums -> difference of squares 1" 32 | 33 | [005cb2bf-a0c8-46f3-ae25-924029f8b00b] 34 | description = "Subtract sum of squares from square of sums -> difference of squares 5" 35 | 36 | [b1bf19de-9a16-41c0-a62b-1f02ecc0b036] 37 | description = "Subtract sum of squares from square of sums -> difference of squares 100" 38 | -------------------------------------------------------------------------------- /exercises/practice/difference-of-squares/difference-of-squares.apl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exercism/gnu-apl/4443b7ccd0203d4987f74780b9f0869449f49328/exercises/practice/difference-of-squares/difference-of-squares.apl -------------------------------------------------------------------------------- /exercises/practice/difference-of-squares/difference-of-squares.tc: -------------------------------------------------------------------------------- 1 | log←'./difference-of-squares.tc.log' 2 | ⍎ ')COPY ',(⎕FIO 30),'/../../test.apl' 3 | 4 | test∆copy_relative 'difference-of-squares.apl' 5 | test∆clear_log log 6 | 7 | ⍝ ∇square_of_sum 8 | 9 | ⍝ it returns the square of the sum from 1 to the given number 10 | 1⎕CR square_of_sum 1 11 | 1 12 | 1⎕CR square_of_sum 5 ⍝ (1+2+3+4+5)*2 13 | 225 14 | 1⎕CR square_of_sum 100 15 | 25502500 16 | 17 | ⍝ ∇sum_of_squares 18 | 19 | ⍝ it returns the sum of the squares of the numbers from 1 to the given number 20 | 1⎕CR sum_of_squares 1 21 | 1 22 | 1⎕CR sum_of_squares 5 ⍝ (1*2)+(2*2)+(3*2)+(4*2)+(5*2) 23 | 55 24 | 1⎕CR sum_of_squares 100 25 | 338350 26 | 27 | ⍝ ∇difference_of_squares 28 | 29 | ⍝ it returns square_of_sum minus sum_of_squares 30 | 1⎕CR difference_of_squares 1 31 | 0 32 | 1⎕CR difference_of_squares 5 33 | 170 34 | 1⎕CR difference_of_squares 100 35 | 25164150 36 | 37 | test∆show_log log 38 | 39 | -------------------------------------------------------------------------------- /exercises/practice/hamming/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Calculate the Hamming Distance between two DNA strands. 4 | 5 | Your body is made up of cells that contain DNA. Those cells regularly wear out and need replacing, which they achieve by dividing into daughter cells. In fact, the average human body experiences about 10 quadrillion cell divisions in a lifetime! 6 | 7 | When cells divide, their DNA replicates too. Sometimes during this process mistakes happen and single pieces of DNA get encoded with the incorrect information. If we compare two strands of DNA and count the differences between them we can see how many mistakes occurred. This is known as the "Hamming Distance". 8 | 9 | We read DNA using the letters C,A,G and T. Two strands might look like this: 10 | 11 | GAGCCTACTAACGGGAT 12 | CATCGTAATGACGGCCT 13 | ^ ^ ^ ^ ^ ^^ 14 | 15 | They have 7 differences, and therefore the Hamming Distance is 7. 16 | 17 | The Hamming Distance is useful for lots of things in science, not just biology, so it's a nice phrase to be familiar with :) 18 | 19 | # Implementation notes 20 | 21 | The Hamming distance is only defined for sequences of equal length, so 22 | an attempt to calculate it between sequences of different lengths should 23 | not work. The general handling of this situation (e.g., raising an 24 | exception vs returning a special value) may differ between languages. 25 | -------------------------------------------------------------------------------- /exercises/practice/hamming/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "Calculate the Hamming difference between two DNA strands.", 3 | "authors": [ 4 | "marnen" 5 | ], 6 | "contributors": [ 7 | "iHiD", 8 | "sjwarner" 9 | ], 10 | "files": { 11 | "solution": [ 12 | "hamming.apl" 13 | ], 14 | "test": [ 15 | "hamming.tc" 16 | ], 17 | "example": [ 18 | ".meta/hamming-example.apl" 19 | ] 20 | }, 21 | "source": "The Calculating Point Mutations problem at Rosalind", 22 | "source_url": "http://rosalind.info/problems/hamm/" 23 | } 24 | -------------------------------------------------------------------------------- /exercises/practice/hamming/.meta/hamming-example.apl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env apl --script 2 | 3 | ∇z←x distance y 4 | z←↑∊+/(∊x)≠¨∊y 5 | ∇ 6 | -------------------------------------------------------------------------------- /exercises/practice/hamming/.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 | [f6dcb64f-03b0-4b60-81b1-3c9dbf47e887] 13 | description = "empty strands" 14 | 15 | [54681314-eee2-439a-9db0-b0636c656156] 16 | description = "single letter identical strands" 17 | 18 | [294479a3-a4c8-478f-8d63-6209815a827b] 19 | description = "single letter different strands" 20 | 21 | [9aed5f34-5693-4344-9b31-40c692fb5592] 22 | description = "long identical strands" 23 | 24 | [cd2273a5-c576-46c8-a52b-dee251c3e6e5] 25 | description = "long different strands" 26 | 27 | [919f8ef0-b767-4d1b-8516-6379d07fcb28] 28 | description = "disallow first strand longer" 29 | 30 | [b9228bb1-465f-4141-b40f-1f99812de5a8] 31 | description = "disallow first strand longer" 32 | reimplements = "919f8ef0-b767-4d1b-8516-6379d07fcb28" 33 | 34 | [8a2d4ed0-ead5-4fdd-924d-27c4cf56e60e] 35 | description = "disallow second strand longer" 36 | 37 | [dab38838-26bb-4fff-acbe-3b0a9bfeba2d] 38 | description = "disallow second strand longer" 39 | reimplements = "8a2d4ed0-ead5-4fdd-924d-27c4cf56e60e" 40 | 41 | [5dce058b-28d4-4ca7-aa64-adfe4e17784c] 42 | description = "disallow left empty strand" 43 | 44 | [db92e77e-7c72-499d-8fe6-9354d2bfd504] 45 | description = "disallow left empty strand" 46 | reimplements = "5dce058b-28d4-4ca7-aa64-adfe4e17784c" 47 | 48 | [b764d47c-83ff-4de2-ab10-6cfe4b15c0f3] 49 | description = "disallow empty first strand" 50 | reimplements = "db92e77e-7c72-499d-8fe6-9354d2bfd504" 51 | 52 | [38826d4b-16fb-4639-ac3e-ba027dec8b5f] 53 | description = "disallow right empty strand" 54 | 55 | [920cd6e3-18f4-4143-b6b8-74270bb8f8a3] 56 | description = "disallow right empty strand" 57 | reimplements = "38826d4b-16fb-4639-ac3e-ba027dec8b5f" 58 | 59 | [9ab9262f-3521-4191-81f5-0ed184a5aa89] 60 | description = "disallow empty second strand" 61 | reimplements = "920cd6e3-18f4-4143-b6b8-74270bb8f8a3" 62 | -------------------------------------------------------------------------------- /exercises/practice/hamming/hamming.apl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exercism/gnu-apl/4443b7ccd0203d4987f74780b9f0869449f49328/exercises/practice/hamming/hamming.apl -------------------------------------------------------------------------------- /exercises/practice/hamming/hamming.tc: -------------------------------------------------------------------------------- 1 | log←'./hamming.tc.log' 2 | ⍎ ')COPY ',(⎕FIO 30),'/../../test.apl' 3 | 4 | test∆copy_relative 'hamming.apl' 5 | test∆clear_log log 6 | 7 | ⍝ ∇distance 8 | 9 | ⍝ empty strands 10 | 1⎕CR '' distance '' 11 | 0 12 | 13 | ⍝ identical strands 14 | 1⎕CR 'A' distance 'A' 15 | 0 16 | 17 | ⍝ long identical strands 18 | 1⎕CR 'GGACTGA' distance 'GGACTGA' 19 | 0 20 | 21 | ⍝ complete distance in single-nucleotide strands 22 | 1⎕CR 'A' distance 'G' 23 | 1 24 | 25 | ⍝ complete distance in small strands 26 | 'AG' distance 'CT' 27 | 2 28 | 29 | ⍝ small distance in small strands 30 | 'AT' distance 'CT' 31 | 1 32 | 33 | ⍝ small distance 34 | 'GGACG' distance 'GGTCG' 35 | 1 36 | 37 | ⍝ small distance in long strands 38 | 'ACCAGGG' distance 'ACTATGG' 39 | 2 40 | 41 | ⍝ non-unique character in first strand 42 | 'AGA' distance 'AGG' 43 | 1 44 | 45 | ⍝ non-unique character in second strand 46 | 'AGG' distance 'AGA' 47 | 1 48 | 49 | ⍝ same nucleotides in different positions 50 | 'TAG' distance 'GAT' 51 | 2 52 | 53 | ⍝ large distance 54 | 'GATACA' distance 'GCATAA' 55 | 4 56 | 57 | ⍝ large distance in off-by-one strand 58 | 'GGACGGATTCTG' distance 'AGGACGGATTCT' 59 | 9 60 | 61 | ⍝ disallow first strand longer 62 | 1⎕CR test∆try '''AATG'' distance ''AAA''' 63 | 1 'LENGTH ERROR' 64 | 65 | ⍝ disallow single vs. multiple letters 66 | 1⎕CR test∆try '''AATG'' distance ''A''' 67 | 1 'LENGTH ERROR' 68 | 1⎕CR test∆try '''A'' distance ''AAA''' 69 | 1 'LENGTH ERROR' 70 | 71 | ⍝ disallow second strand longer 72 | 1⎕CR test∆try '''ATA'' distance ''AGTG''' 73 | 1 'LENGTH ERROR' 74 | 75 | test∆show_log log 76 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | The classical introductory exercise. Just say "Hello, World!". 4 | 5 | ["Hello, World!"](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program) is 6 | the traditional first program for beginning programming in a new language 7 | or environment. 8 | 9 | The objectives are simple: 10 | 11 | - Write a function that returns the string "Hello, World!". 12 | - Run the test suite and make sure that it succeeds. 13 | - Submit your solution and check it at the website. 14 | 15 | If everything goes well, you will be ready to fetch your first real exercise. 16 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "The classical introductory exercise. Just say \"Hello, World!\"", 3 | "authors": [ 4 | "marnen" 5 | ], 6 | "contributors": [ 7 | "iHiD" 8 | ], 9 | "files": { 10 | "solution": [ 11 | "hello-world.apl" 12 | ], 13 | "test": [ 14 | "hello-world.tc" 15 | ], 16 | "example": [ 17 | ".meta/hello-world-example.apl" 18 | ] 19 | }, 20 | "source": "This is an exercise to introduce users to using Exercism", 21 | "source_url": "http://en.wikipedia.org/wiki/%22Hello,_world!%22_program" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/.meta/hello-world-example.apl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env apl --script 2 | 3 | ∇z←hello 4 | z←'Hello, World!' 5 | ∇ 6 | 7 | -------------------------------------------------------------------------------- /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/hello-world/hello-world.apl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env apl --script 2 | 3 | ∇z←hello 4 | z←'Goodbye, Mars!' 5 | ∇ 6 | 7 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/hello-world.tc: -------------------------------------------------------------------------------- 1 | log←'./hello-world.tc.log' 2 | ⍎ ')COPY ',(⎕FIO 30),'/../../test.apl' 3 | 4 | test∆copy_relative 'hello-world.apl' 5 | test∆clear_log log 6 | 7 | ⍝ ∇hello 8 | 9 | ⍝ it returns 'Hello, World!' 10 | 1⎕CR hello 11 | 'Hello, World!' 12 | 13 | test∆show_log log 14 | -------------------------------------------------------------------------------- /exercises/practice/leap/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Given a year, report if it is a leap year. 4 | 5 | The tricky thing here is that a leap year in the Gregorian calendar occurs: 6 | 7 | ```text 8 | on every year that is evenly divisible by 4 9 | except every year that is evenly divisible by 100 10 | unless the year is also evenly divisible by 400 11 | ``` 12 | 13 | For example, 1997 is not a leap year, but 1996 is. 1900 is not a leap 14 | year, but 2000 is. 15 | 16 | ## Notes 17 | 18 | Though our exercise adopts some very simple rules, there is more to 19 | learn! 20 | 21 | For a delightful, four minute explanation of the whole leap year 22 | phenomenon, go watch [this youtube video][video]. 23 | 24 | [video]: http://www.youtube.com/watch?v=xX96xng7sAE 25 | -------------------------------------------------------------------------------- /exercises/practice/leap/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "Given a year, report if it is a leap year.", 3 | "authors": [ 4 | "marnen" 5 | ], 6 | "contributors": [ 7 | "iHiD", 8 | "sjwarner" 9 | ], 10 | "files": { 11 | "solution": [ 12 | "leap.apl" 13 | ], 14 | "test": [ 15 | "leap.tc" 16 | ], 17 | "example": [ 18 | ".meta/leap-example.apl" 19 | ] 20 | }, 21 | "source": "JavaRanch Cattle Drive, exercise 3", 22 | "source_url": "http://www.javaranch.com/leap.jsp" 23 | } 24 | -------------------------------------------------------------------------------- /exercises/practice/leap/.meta/leap-example.apl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env apl --script 2 | 3 | ∇z←leap_year year 4 | z←(~×400|year)∨∧/0 1=×4 100|year 5 | ∇ 6 | -------------------------------------------------------------------------------- /exercises/practice/leap/.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 | [6466b30d-519c-438e-935d-388224ab5223] 13 | description = "year not divisible by 4 in common year" 14 | 15 | [ac227e82-ee82-4a09-9eb6-4f84331ffdb0] 16 | description = "year divisible by 2, not divisible by 4 in common year" 17 | 18 | [4fe9b84c-8e65-489e-970b-856d60b8b78e] 19 | description = "year divisible by 4, not divisible by 100 in leap year" 20 | 21 | [7fc6aed7-e63c-48f5-ae05-5fe182f60a5d] 22 | description = "year divisible by 4 and 5 is still a leap year" 23 | 24 | [78a7848f-9667-4192-ae53-87b30c9a02dd] 25 | description = "year divisible by 100, not divisible by 400 in common year" 26 | 27 | [9d70f938-537c-40a6-ba19-f50739ce8bac] 28 | description = "year divisible by 100 but not by 3 is still not a leap year" 29 | 30 | [42ee56ad-d3e6-48f1-8e3f-c84078d916fc] 31 | description = "year divisible by 400 is leap year" 32 | 33 | [57902c77-6fe9-40de-8302-587b5c27121e] 34 | description = "year divisible by 400 but not by 125 is still a leap year" 35 | 36 | [c30331f6-f9f6-4881-ad38-8ca8c12520c1] 37 | description = "year divisible by 200, not divisible by 400 in common year" 38 | -------------------------------------------------------------------------------- /exercises/practice/leap/leap.apl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exercism/gnu-apl/4443b7ccd0203d4987f74780b9f0869449f49328/exercises/practice/leap/leap.apl -------------------------------------------------------------------------------- /exercises/practice/leap/leap.tc: -------------------------------------------------------------------------------- 1 | log←'./leap.tc.log' 2 | ⍎ ')COPY ',(⎕FIO 30),'/../../test.apl' 3 | 4 | test∆copy_relative 'leap.apl' 5 | test∆clear_log log 6 | 7 | ⍝ ∇leap_year 8 | 9 | ⍝ year not divisible by 4: common year 10 | 1⎕CR leap_year 2015 11 | 0 12 | 13 | ⍝ year divisible by 4, not divisible by 100: leap year 14 | 1⎕CR leap_year 2016 15 | 1 16 | 17 | ⍝ year divisible by 100, not divisible by 400: common year 18 | 1⎕CR leap_year 2100 19 | 0 20 | 21 | ⍝ year divisible by 400: leap year 22 | 1⎕CR leap_year 2000 23 | 1 24 | 25 | test∆show_log log 26 | -------------------------------------------------------------------------------- /exercises/practice/pangram/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Determine if a sentence is a pangram. A pangram (Greek: παν γράμμα, pan gramma, 4 | "every letter") is a sentence using every letter of the alphabet at least once. 5 | The best known English pangram is: 6 | > The quick brown fox jumps over the lazy dog. 7 | 8 | The alphabet used consists of ASCII letters `a` to `z`, inclusive, and is case 9 | insensitive. Input will not contain non-ASCII symbols. 10 | -------------------------------------------------------------------------------- /exercises/practice/pangram/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "Determine if a sentence is a pangram.", 3 | "authors": [ 4 | "marnen" 5 | ], 6 | "contributors": [ 7 | "iHiD", 8 | "sjwarner" 9 | ], 10 | "files": { 11 | "solution": [ 12 | "pangram.apl" 13 | ], 14 | "test": [ 15 | "pangram.tc" 16 | ], 17 | "example": [ 18 | ".meta/pangram-example.apl" 19 | ] 20 | }, 21 | "source": "Wikipedia", 22 | "source_url": "https://en.wikipedia.org/wiki/Pangram" 23 | } 24 | -------------------------------------------------------------------------------- /exercises/practice/pangram/.meta/pangram-example.apl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env apl --script 2 | 3 | lowercase←⎕AF (⎕AF 'a')+(⍳26)-1 4 | 5 | ∇z←is_pangram string 6 | z←∧/lowercase∊to_lower string 7 | ∇ 8 | 9 | ∇z←to_lower string;uppercase;to_change 10 | uppercase←⎕AF ((⎕AF lowercase)-⎕AF 'a')+(⎕AF 'A') 11 | to_change←(string⍳uppercase)~1+⍴string 12 | z←string 13 | z[to_change]←lowercase[uppercase⍳string[to_change]] 14 | ∇ -------------------------------------------------------------------------------- /exercises/practice/pangram/.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 | [64f61791-508e-4f5c-83ab-05de042b0149] 13 | description = "empty sentence" 14 | 15 | [74858f80-4a4d-478b-8a5e-c6477e4e4e84] 16 | description = "perfect lower case" 17 | 18 | [61288860-35ca-4abe-ba08-f5df76ecbdcd] 19 | description = "only lower case" 20 | 21 | [6564267d-8ac5-4d29-baf2-e7d2e304a743] 22 | description = "missing the letter 'x'" 23 | 24 | [c79af1be-d715-4cdb-a5f2-b2fa3e7e0de0] 25 | description = "missing the letter 'h'" 26 | 27 | [d835ec38-bc8f-48e4-9e36-eb232427b1df] 28 | description = "with underscores" 29 | 30 | [8cc1e080-a178-4494-b4b3-06982c9be2a8] 31 | description = "with numbers" 32 | 33 | [bed96b1c-ff95-45b8-9731-fdbdcb6ede9a] 34 | description = "missing letters replaced by numbers" 35 | 36 | [938bd5d8-ade5-40e2-a2d9-55a338a01030] 37 | description = "mixed case and punctuation" 38 | 39 | [2577bf54-83c8-402d-a64b-a2c0f7bb213a] 40 | description = "case insensitive" 41 | -------------------------------------------------------------------------------- /exercises/practice/pangram/pangram.apl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exercism/gnu-apl/4443b7ccd0203d4987f74780b9f0869449f49328/exercises/practice/pangram/pangram.apl -------------------------------------------------------------------------------- /exercises/practice/pangram/pangram.tc: -------------------------------------------------------------------------------- 1 | log←'./pangram.tc.log' 2 | ⍎ ')COPY ',(⎕FIO 30),'/../../test.apl' 3 | 4 | test∆copy_relative 'pangram.apl' 5 | test∆clear_log log 6 | 7 | ⍝ ∇is_pangram 8 | 9 | ⍝ it returns false for a null vector 10 | 1⎕CR is_pangram '' 11 | 0 12 | ⍝ it recognizes a perfect lower case pangram 13 | 1⎕CR is_pangram 'abcdefghijklmnopqrstuvwxyz' 14 | 1 15 | ⍝ pangram with only lower case: true 16 | 1⎕CR is_pangram 'the quick brown fox jumps over the lazy dog' 17 | 1 18 | ⍝ missing character 'x': false 19 | is_pangram 'a quick movement of the enemy will jeopardize five gunboats' 20 | 0 21 | ⍝ missing 'h': false 22 | is_pangram 'five boxing wizards jump quickly at it' 23 | 0 24 | 25 | ⍝ pangram with non-alphabetic characters: true 26 | is_pangram 'the_quick_brown_fox_jumps_over_the_lazy_dog' 27 | 1 28 | is_pangram 'the 1 quick brown fox jumps over the 2 lazy dogs' 29 | 1 30 | ⍝ letters missing, replaced by numbers: false 31 | is_pangram '7h3 qu1ck brown fox jumps ov3r 7h3 lazy dog' 32 | 0 33 | ⍝ pangram with mixed case and punctuation: true 34 | is_pangram '"Five quacking Zephyrs jolt my wax bed."' 35 | 1 36 | ⍝ non-pangram with upper- and lowercase versions of same letter: false 37 | is_pangram "the quick brown fox jumps over with lazy FX" 38 | 0 39 | 40 | test∆show_log log 41 | -------------------------------------------------------------------------------- /exercises/practice/raindrops/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to convert a number into a string that contains raindrop sounds corresponding to certain potential factors. A factor is a number that evenly divides into another number, leaving no remainder. The simplest way to test if a one number is a factor of another is to use the [modulo operation](https://en.wikipedia.org/wiki/Modulo_operation). 4 | 5 | The rules of `raindrops` are that if a given number: 6 | 7 | - has 3 as a factor, add 'Pling' to the result. 8 | - has 5 as a factor, add 'Plang' to the result. 9 | - has 7 as a factor, add 'Plong' to the result. 10 | - _does not_ have any of 3, 5, or 7 as a factor, the result should be the digits of the number. 11 | 12 | ## Examples 13 | 14 | - 28 has 7 as a factor, but not 3 or 5, so the result would be "Plong". 15 | - 30 has both 3 and 5 as factors, but not 7, so the result would be "PlingPlang". 16 | - 34 is not factored by 3, 5, or 7, so the result would be "34". 17 | -------------------------------------------------------------------------------- /exercises/practice/raindrops/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "Convert a number to a string, the content of which depends on the number's factors.", 3 | "authors": [ 4 | "marnen" 5 | ], 6 | "contributors": [ 7 | "iHiD" 8 | ], 9 | "files": { 10 | "solution": [ 11 | "raindrops.apl" 12 | ], 13 | "test": [ 14 | "raindrops.tc" 15 | ], 16 | "example": [ 17 | ".meta/raindrops-example.apl" 18 | ] 19 | }, 20 | "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.", 21 | "source_url": "https://en.wikipedia.org/wiki/Fizz_buzz" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/raindrops/.meta/raindrops-example.apl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env apl --script 2 | 3 | ∇drops←convert integer;factors;sounds;multiple_of 4 | factors←3 5 7 5 | sounds←('Pling' 'Plang' 'Plong') 6 | multiple_of←0=factors|integer 7 | drops←∊(multiple_of,∧/0=multiple_of)/sounds,⊂⍕integer 8 | ∇ -------------------------------------------------------------------------------- /exercises/practice/raindrops/.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 | [1575d549-e502-46d4-a8e1-6b7bec6123d8] 13 | description = "the sound for 1 is 1" 14 | 15 | [1f51a9f9-4895-4539-b182-d7b0a5ab2913] 16 | description = "the sound for 3 is Pling" 17 | 18 | [2d9bfae5-2b21-4bcd-9629-c8c0e388f3e0] 19 | description = "the sound for 5 is Plang" 20 | 21 | [d7e60daa-32ef-4c23-b688-2abff46c4806] 22 | description = "the sound for 7 is Plong" 23 | 24 | [6bb4947b-a724-430c-923f-f0dc3d62e56a] 25 | description = "the sound for 6 is Pling as it has a factor 3" 26 | 27 | [ce51e0e8-d9d4-446d-9949-96eac4458c2d] 28 | description = "2 to the power 3 does not make a raindrop sound as 3 is the exponent not the base" 29 | 30 | [0dd66175-e3e2-47fc-8750-d01739856671] 31 | description = "the sound for 9 is Pling as it has a factor 3" 32 | 33 | [022c44d3-2182-4471-95d7-c575af225c96] 34 | description = "the sound for 10 is Plang as it has a factor 5" 35 | 36 | [37ab74db-fed3-40ff-b7b9-04acdfea8edf] 37 | description = "the sound for 14 is Plong as it has a factor of 7" 38 | 39 | [31f92999-6afb-40ee-9aa4-6d15e3334d0f] 40 | description = "the sound for 15 is PlingPlang as it has factors 3 and 5" 41 | 42 | [ff9bb95d-6361-4602-be2c-653fe5239b54] 43 | description = "the sound for 21 is PlingPlong as it has factors 3 and 7" 44 | 45 | [d2e75317-b72e-40ab-8a64-6734a21dece1] 46 | description = "the sound for 25 is Plang as it has a factor 5" 47 | 48 | [a09c4c58-c662-4e32-97fe-f1501ef7125c] 49 | description = "the sound for 27 is Pling as it has a factor 3" 50 | 51 | [bdf061de-8564-4899-a843-14b48b722789] 52 | description = "the sound for 35 is PlangPlong as it has factors 5 and 7" 53 | 54 | [c4680bee-69ba-439d-99b5-70c5fd1a7a83] 55 | description = "the sound for 49 is Plong as it has a factor 7" 56 | 57 | [17f2bc9a-b65a-4d23-8ccd-266e8c271444] 58 | description = "the sound for 52 is 52" 59 | 60 | [e46677ed-ff1a-419f-a740-5c713d2830e4] 61 | description = "the sound for 105 is PlingPlangPlong as it has factors 3, 5 and 7" 62 | 63 | [13c6837a-0fcd-4b86-a0eb-20572f7deb0b] 64 | description = "the sound for 3125 is Plang as it has a factor 5" 65 | -------------------------------------------------------------------------------- /exercises/practice/raindrops/raindrops.apl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exercism/gnu-apl/4443b7ccd0203d4987f74780b9f0869449f49328/exercises/practice/raindrops/raindrops.apl -------------------------------------------------------------------------------- /exercises/practice/raindrops/raindrops.tc: -------------------------------------------------------------------------------- 1 | log←'./raindrops.tc.log' 2 | ⍎ ')COPY ',(⎕FIO 30),'/../../test.apl' 3 | 4 | test∆copy_relative 'raindrops.apl' 5 | test∆clear_log log 6 | 7 | ⍝ ∇convert 8 | ⍝ Given an integer, returns a string representation of that integer's "raindrop sound", based on its prime factors. 9 | 10 | ⍝ the sound for 1 is '1' 11 | 1⎕CR convert 1 12 | '1' 13 | 14 | ⍝ the sound for multiples of 3 is 'Pling' 15 | convert 3 16 | Pling 17 | convert 6 18 | Pling 19 | 20 | ⍝ the sound for multiples of 5 is 'Plang' 21 | convert 5 22 | Plang 23 | convert 10 24 | Plang 25 | 26 | ⍝ the sound for multiples of 7 is 'Plong' 27 | convert 7 28 | Plong 29 | convert 14 30 | Plong 31 | 32 | ⍝ the sound for numbers that aren't multiples of 3, 5, or 7 is the stringified number 33 | 1⎕CR convert 8 34 | '8' 35 | 1⎕CR convert 52 36 | '52' 37 | 38 | ⍝ the sound for numbers that have multiple raindrop factors is the combination of all the sounds 39 | convert 15 ⍝ 3×5 40 | PlingPlang 41 | convert 21 ⍝ 3×7 42 | PlingPlong 43 | convert 35 ⍝ 5×7 44 | PlangPlong 45 | 1⎕CR convert 105 ⍝ 3×5×7 46 | 'PlingPlangPlong' 47 | 48 | ⍝ the sound for powers of a raindrop factor is only the single sound 49 | convert 9 ⍝ 3×3 50 | Pling 51 | convert 25 ⍝ 5×5 52 | Plang 53 | convert 49 ⍝ 7×7 54 | Plong 55 | convert 27 ⍝ 3*3 56 | Pling 57 | convert 3125 ⍝ 5*5 58 | Plang 59 | 60 | test∆show_log log 61 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Given a DNA strand, return its RNA complement (per RNA transcription). 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**), 8 | guanine (**G**) and thymine (**T**). 9 | 10 | The four nucleotides found in RNA are adenine (**A**), cytosine (**C**), 11 | guanine (**G**) and uracil (**U**). 12 | 13 | Given a DNA strand, its transcribed RNA strand is formed by replacing 14 | each nucleotide with its complement: 15 | 16 | * `G` -> `C` 17 | * `C` -> `G` 18 | * `T` -> `A` 19 | * `A` -> `U` 20 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "Given a DNA strand, return its RNA Complement Transcription.", 3 | "authors": [ 4 | "marnen" 5 | ], 6 | "contributors": [ 7 | "iHiD", 8 | "sjwarner" 9 | ], 10 | "files": { 11 | "solution": [ 12 | "rna-transcription.apl" 13 | ], 14 | "test": [ 15 | "rna-transcription.tc" 16 | ], 17 | "example": [ 18 | ".meta/rna-transcription-example.apl" 19 | ] 20 | }, 21 | "source": "Hyperphysics", 22 | "source_url": "http://hyperphysics.phy-astr.gsu.edu/hbase/Organic/transcription.html" 23 | } 24 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/.meta/rna-transcription-example.apl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env apl --script 2 | 3 | ∇rna←to_rna dna;dna_bases;rna_bases 4 | dna_bases←'CGTA' 5 | rna_bases←'GCAU' 6 | '1÷0' ⎕EA 'rna←rna_bases[dna_bases⍳dna]' ⍝ throw a domain error if not found 7 | ∇ -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/.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 | [b4631f82-c98c-4a2f-90b3-c5c2b6c6f661] 13 | description = "Empty RNA sequence" 14 | 15 | [a9558a3c-318c-4240-9256-5d5ed47005a6] 16 | description = "RNA complement of cytosine is guanine" 17 | 18 | [6eedbb5c-12cb-4c8b-9f51-f8320b4dc2e7] 19 | description = "RNA complement of guanine is cytosine" 20 | 21 | [870bd3ec-8487-471d-8d9a-a25046488d3e] 22 | description = "RNA complement of thymine is adenine" 23 | 24 | [aade8964-02e1-4073-872f-42d3ffd74c5f] 25 | description = "RNA complement of adenine is uracil" 26 | 27 | [79ed2757-f018-4f47-a1d7-34a559392dbf] 28 | description = "RNA complement" 29 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/rna-transcription.apl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exercism/gnu-apl/4443b7ccd0203d4987f74780b9f0869449f49328/exercises/practice/rna-transcription/rna-transcription.apl -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/rna-transcription.tc: -------------------------------------------------------------------------------- 1 | log←'./rna-transcription.tc.log' 2 | ⍎ ')COPY ',(⎕FIO 30),'/../../test.apl' 3 | 4 | test∆copy_relative 'rna-transcription.apl' 5 | test∆clear_log log 6 | 7 | ⍝ ∇to_rna 8 | 9 | ⍝ RNA complement of cytosine is guanine 10 | 1⎕CR to_rna 'C' 11 | 'G' 12 | 13 | ⍝ RNA complement of guanine is cytosine 14 | to_rna 'G' 15 | C 16 | 17 | ⍝ RNA complement of thymine is adenine 18 | to_rna 'T' 19 | A 20 | 21 | ⍝ RNA complement of adenine is uracil 22 | to_rna 'A' 23 | U 24 | 25 | ⍝ RNA complement of entire string 26 | 1⎕CR to_rna 'ACGTGGTCTTAA' 27 | 'UGCACCAGAAUU' 28 | 29 | ⍝ invalid input (RNA instead of DNA) throws domain error 30 | 1⎕CR test∆try 'to_rna "U"' 31 | 1 'DOMAIN ERROR' 32 | 33 | ⍝ completely invalid DNA input throws domain error 34 | 1⎕CR test∆try 'to_rna "XXX"' 35 | 1 'DOMAIN ERROR' 36 | 37 | ⍝ partially invalid DNA input throws domain error 38 | 1⎕CR test∆try 'to_rna "ACGTXXXCTTAA"' 39 | 1 'DOMAIN ERROR' 40 | 41 | test∆show_log log 42 | -------------------------------------------------------------------------------- /exercises/shared/.docs/help.md: -------------------------------------------------------------------------------- 1 | # {{ .Spec.Name }} 2 | 3 | {{ .Spec.Description -}} 4 | {{- with .Hints }} 5 | {{ . }} 6 | {{ end }} 7 | {{- with .Spec.Credits -}} 8 | ## Source 9 | 10 | {{ . }} 11 | {{ end }} 12 | ## Submitting Incomplete Solutions 13 | It's possible to submit an incomplete solution so you can see how others have completed the exercise. 14 | -------------------------------------------------------------------------------- /exercises/shared/.docs/tests.md: -------------------------------------------------------------------------------- 1 | # {{ .Spec.Name }} 2 | 3 | {{ .Spec.Description -}} 4 | {{- with .Hints }} 5 | {{ . }} 6 | {{ end }} 7 | {{- with .Spec.Credits -}} 8 | ## Source 9 | 10 | {{ . }} 11 | {{ end }} 12 | ## Submitting Incomplete Solutions 13 | It's possible to submit an incomplete solution so you can see how others have completed the exercise. 14 | -------------------------------------------------------------------------------- /img/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exercism/gnu-apl/4443b7ccd0203d4987f74780b9f0869449f49328/img/.keep -------------------------------------------------------------------------------- /test.apl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env apl --script 2 | )COPY 5 FILE_IO.apl 3 | 4 | ⍝ Clear logfile with given filename. 5 | ∇test∆clear_log filename;handle;_ 6 | handle←'w' FIO∆fopen filename 7 | _←FIO∆fclose handle 8 | ∇ 9 | 10 | ⍝ )COPY file relative to current directory. 11 | ∇test∆copy_relative path;_ 12 | _←⍎ ')COPY ',test¯pwd,'/',path 13 | ∇ 14 | 15 | ⍝ Write logfile with given filename to stderr as UTF-8. 16 | ∇test∆show_log filename;cr 17 | cr←⎕UCS 10 18 | test¯warn cr,'***** TEST LOG *****',cr,cr 19 | test¯warn test¯read_unicode filename 20 | ∇ 21 | 22 | ⍝ Evaluate APL code (as string). 23 | ⍝ Returns 2-element vector: 24 | ⍝ [1] Boolean (1 if error, 0 if not). 25 | ⍝ [2] Error message if error; original result if not. 26 | ∇z←test∆try apl_string;response;is_error;result 27 | response←⎕EC apl_string 28 | is_error←0=1⊃response 29 | result←3⊃response 30 | →(~is_error)/return 31 | result←result[1;] 32 | return: z←is_error result 33 | ∇ 34 | 35 | ⍝ private 36 | 37 | ⍝ Return current directory as a string. 38 | ∇pwd←test¯pwd 39 | pwd←FIO∆getcwd 40 | ∇ 41 | 42 | ⍝ Read a UTF-8 file into a Unicode character vector. 43 | ∇unicode←test¯read_unicode filename 44 | unicode←19⎕CR FIO∆read_file filename 45 | ∇ 46 | 47 | ⍝ Write string to stderr. 48 | ∇test¯warn string;_ 49 | _←FIO∆fprintf_stderr '%s' string 50 | ∇ 51 | --------------------------------------------------------------------------------