trackler 2.2.1.155 → 2.2.1.156

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/.gitmodules +3 -0
  3. data/lib/trackler/version.rb +1 -1
  4. data/problem-specifications/exercises/simple-cipher/canonical-data.json +147 -0
  5. data/tracks/clojure/exercises/hexadecimal/src/hexadecimal.clj +5 -0
  6. data/tracks/clojure/exercises/isogram/src/isogram.clj +5 -0
  7. data/tracks/clojure/exercises/kindergarten-garden/src/kindergarten-garden.clj +5 -0
  8. data/tracks/csharp/exercises/list-ops/Example.cs +14 -9
  9. data/tracks/csharp/exercises/list-ops/ListOps.cs +4 -4
  10. data/tracks/csharp/exercises/list-ops/ListOpsTest.cs +90 -88
  11. data/tracks/csharp/exercises/zipper/Example.cs +51 -43
  12. data/tracks/csharp/exercises/zipper/Zipper.cs +16 -19
  13. data/tracks/csharp/exercises/zipper/ZipperTest.cs +94 -45
  14. data/tracks/csharp/generators/Exercises/ListOps.cs +123 -0
  15. data/tracks/csharp/generators/Exercises/Zipper.cs +107 -0
  16. data/tracks/csharp/generators/Output/ValueFormatter.cs +14 -0
  17. data/tracks/delphi/config.json +10 -1
  18. data/tracks/delphi/config/maintainers.json +11 -11
  19. data/tracks/elisp/config.json +8 -0
  20. data/tracks/elisp/exercises/run-length-encoding/README.md +36 -0
  21. data/tracks/elisp/exercises/run-length-encoding/example.el +62 -0
  22. data/tracks/elisp/exercises/run-length-encoding/run-length-encoding-test.el +61 -0
  23. data/tracks/elisp/exercises/run-length-encoding/run-length-encoding.el +9 -0
  24. data/tracks/fsharp/docs/LEARNING.md +3 -0
  25. data/tracks/java/exercises/armstrong-numbers/.meta/hints.md +2 -0
  26. data/tracks/java/exercises/armstrong-numbers/README.md +6 -0
  27. data/tracks/java/exercises/bracket-push/.meta/version +1 -1
  28. data/tracks/java/exercises/bracket-push/src/test/java/BracketCheckerTest.java +7 -0
  29. data/tracks/java/exercises/isbn-verifier/.meta/version +1 -1
  30. data/tracks/java/exercises/isbn-verifier/src/test/java/IsbnVerifierTest.java +12 -1
  31. data/tracks/java/exercises/kindergarten-garden/.meta/version +1 -1
  32. data/tracks/java/exercises/list-ops/.meta/version +1 -1
  33. data/tracks/java/exercises/list-ops/src/test/java/ListOpsTest.java +32 -1
  34. data/tracks/nim/config.json +13 -2
  35. data/tracks/nim/exercises/bob/bob_test.nim +1 -1
  36. data/tracks/nim/exercises/bob/example.nim +6 -3
  37. data/tracks/nim/exercises/bracket-push/README.md +11 -0
  38. data/tracks/nim/exercises/bracket-push/bracket_push_test.nim +52 -0
  39. data/tracks/nim/exercises/bracket-push/example.nim +22 -0
  40. data/tracks/ocaml/exercises/bracket-push/test.ml +3 -1
  41. data/tracks/ocaml/exercises/luhn/example.ml +8 -5
  42. data/tracks/ocaml/exercises/luhn/test.ml +3 -1
  43. data/tracks/powershell/.gitignore +2 -1
  44. data/tracks/powershell/config.json +46 -13
  45. data/tracks/powershell/exercises/bob/.version +1 -0
  46. data/tracks/powershell/exercises/bob/BobResponse.example.ps1 +28 -0
  47. data/tracks/powershell/exercises/bob/BobResponse.ps1 +8 -0
  48. data/tracks/powershell/exercises/bob/BobResponse.tests.ps1 +109 -0
  49. data/tracks/powershell/exercises/bob/README.md +20 -0
  50. data/tracks/powershell/exercises/nucleotide-count/.version +1 -0
  51. data/tracks/powershell/exercises/nucleotide-count/NucleotideCount.example.ps1 +36 -0
  52. data/tracks/powershell/exercises/nucleotide-count/NucleotideCount.ps1 +8 -0
  53. data/tracks/powershell/exercises/nucleotide-count/NucleotideCount.tests.ps1 +25 -0
  54. data/tracks/powershell/exercises/nucleotide-count/README.md +19 -0
  55. data/tracks/powershell/exercises/raindrops/.version +1 -0
  56. data/tracks/powershell/exercises/raindrops/README.md +24 -0
  57. data/tracks/powershell/exercises/raindrops/Raindrops.example.ps1 +32 -0
  58. data/tracks/powershell/exercises/raindrops/Raindrops.ps1 +8 -0
  59. data/tracks/powershell/exercises/raindrops/Raindrops.tests.ps1 +34 -0
  60. data/tracks/prolog/exercises/complex-numbers/complex_numbers_tests.plt +28 -29
  61. data/tracks/reasonml/.gitignore +4 -0
  62. data/tracks/reasonml/.travis.yml +5 -0
  63. data/tracks/reasonml/LICENSE +21 -0
  64. data/tracks/reasonml/README.md +67 -0
  65. data/tracks/reasonml/bin/fetch-configlet +32 -0
  66. data/tracks/reasonml/config.json +11 -0
  67. data/tracks/reasonml/config/exercise-readme-insert.md +0 -0
  68. data/tracks/reasonml/config/exercise_readme.go.tmpl +16 -0
  69. data/tracks/reasonml/config/maintainers.json +4 -0
  70. data/tracks/reasonml/docs/ABOUT.md +0 -0
  71. data/tracks/reasonml/docs/INSTALLATION.md +0 -0
  72. data/tracks/reasonml/docs/LEARNING.md +0 -0
  73. data/tracks/reasonml/docs/RESOURCES.md +0 -0
  74. data/tracks/reasonml/docs/TESTS.md +0 -0
  75. data/tracks/reasonml/img/.keep +0 -0
  76. data/tracks/scala/config.json +11 -0
  77. data/tracks/scala/exercises/armstrong-numbers/README.md +29 -0
  78. data/tracks/scala/exercises/armstrong-numbers/build.sbt +3 -0
  79. data/tracks/scala/exercises/armstrong-numbers/example.scala +7 -0
  80. data/tracks/scala/exercises/armstrong-numbers/src/main/scala/.keep +0 -0
  81. data/tracks/scala/exercises/armstrong-numbers/src/test/scala/ArmstrongNumbersTest.scala +44 -0
  82. data/tracks/scala/testgen/src/main/scala/ArmstrongNumbersTestGenerator.scala +33 -0
  83. data/tracks/scheme/config.json +8 -0
  84. data/tracks/scheme/exercises/atbash-cipher/README.md +36 -0
  85. data/tracks/scheme/exercises/atbash-cipher/atbash-cipher-test.scm +67 -0
  86. data/tracks/scheme/exercises/atbash-cipher/atbash-cipher.scm +8 -0
  87. data/tracks/scheme/exercises/atbash-cipher/example.scm +40 -0
  88. metadata +57 -3
  89. data/tracks/python/exercises/rna-transcription/.meta/hints.md +0 -1
@@ -0,0 +1,67 @@
1
+ # Exercism ReasonML Track
2
+
3
+ ![build status](https://travis-ci.org/exercism/reasonml.svg?branch=master)
4
+
5
+ Exercism exercises in ReasonML.
6
+
7
+ ## Setup
8
+
9
+ The simplest way to install ReasonML is ...
10
+
11
+ ## Contributing
12
+
13
+ Thank you so much for contributing! :tada:
14
+
15
+ Please read about how to [get involved in a track](https://github.com/exercism/docs/tree/master/contributing-to-language-tracks). Be sure to read the Exercism [Code of Conduct](https://github.com/exercism/exercism.io/blob/master/CODE_OF_CONDUCT.md).
16
+
17
+ We welcome pull requests of all kinds. No contribution is too small.
18
+
19
+ We encourage contributions that provide fixes and improvements to existing exercises. Please note that this track's exercises must conform to the Exercism-wide standards described in the [documentation](https://github.com/exercism/docs/tree/master/language-tracks/exercises). If you're unsure about how to make a change, then go ahead and open a GitHub issue, and we'll discuss it.
20
+
21
+ ## Exercise Tests
22
+
23
+ At the most basic level, Exercism is all about the tests. You can read more about how we think about test suites in [the Exercism documentation](https://github.com/exercism/docs/blob/master/language-tracks/exercises/anatomy/test-suites.md).
24
+
25
+ Test files should use the following format:
26
+
27
+ ```
28
+ # include the body of an example test
29
+ ```
30
+
31
+ ## Opening an Issue
32
+
33
+ If you plan to make significant or breaking changes, please open an issue so we can discuss it first. If this is a discussion that is relevant to more than just the ReasonML track, please open an issue in [exercism/discussions](https://github.com/exercism/discussions/issues).
34
+
35
+ ## Submitting a Pull Request
36
+
37
+ Pull requests should be focused on a single exercise, issue, or conceptually cohesive change. Please refer to Exercism's [pull request guidelines](https://github.com/exercism/docs/blob/master/contributing/pull-request-guidelines.md).
38
+
39
+ Please follow the coding standards for ReasonML. (If there is a formatter for the track's language, add instructions for using it here.)
40
+
41
+ ### Verifying Your Change
42
+
43
+ Before submitting your pull request, you'll want to verify the changes in two ways:
44
+
45
+ * Run all the tests for the ReasonML exercises
46
+ * Run an Exercism-specific linter to verify the track
47
+
48
+ All the tests for ReasonML exercises can be run from the top level of the repo with
49
+
50
+ ```
51
+ # add this command
52
+ ```
53
+
54
+ For the Exercism-specific linting, please see [the documentation](https://github.com/exercism/docs/blob/master/language-tracks/configuration/linting.md).
55
+
56
+ ## Contributing a New Exercise
57
+
58
+ Please see the documentation about [adding new exercises](https://github.com/exercism/docs/blob/master/you-can-help/make-up-new-exercises.md).
59
+
60
+ Note that:
61
+
62
+ - Each exercise must stand on its own. Do not reference files outside the exercise directory. They will not be included when the user fetches the exercise.
63
+ - Exercises should use only the ReasonML core libraries.
64
+ - Exercises must conform to the Exercism-wide standards described in [the documentation](https://github.com/exercism/docs/tree/master/language-tracks/exercises).
65
+ - Each exercise should have a test suite, an example solution, a template file for the real implementation and ... (anything else that needs to go with each exercise for this track). The CI build expects files to be named using the following convention: (describe the ReasonML convention for naming the various files that make up an exercise).
66
+ - Please do not commit any configuration files or directories inside the exercise other than ...
67
+ - Be sure to add it to the appropriate place in the `config.json` file.
@@ -0,0 +1,32 @@
1
+ #!/bin/bash
2
+
3
+ LATEST=https://github.com/exercism/configlet/releases/latest
4
+
5
+ OS=$(
6
+ case $(uname) in
7
+ (Darwin*)
8
+ echo "mac";;
9
+ (Linux*)
10
+ echo "linux";;
11
+ (Windows*)
12
+ echo "windows";;
13
+ (*)
14
+ echo "linux";;
15
+ esac)
16
+
17
+ ARCH=$(
18
+ case $(uname -m) in
19
+ (*64*)
20
+ echo 64bit;;
21
+ (*686*)
22
+ echo 32bit;;
23
+ (*386*)
24
+ echo 32bit;;
25
+ (*)
26
+ echo 64bit;;
27
+ esac)
28
+
29
+ VERSION="$(curl --head --silent $LATEST | awk -v FS=/ '/Location:/{print $NF}' | tr -d '\r')"
30
+ URL=https://github.com/exercism/configlet/releases/download/$VERSION/configlet-$OS-${ARCH}.tgz
31
+
32
+ curl -s --location $URL | tar xz -C bin/
@@ -0,0 +1,11 @@
1
+ {
2
+ "track_id": "reasonml",
3
+ "language": "ReasonML",
4
+ "active": false,
5
+ "ignore_pattern": "[Ee]xample",
6
+ "solution_pattern": "[Ee]xample",
7
+ "test_pattern": "[Tt]est",
8
+ "foregone": [],
9
+ "exercises": null,
10
+ "deprecated": []
11
+ }
@@ -0,0 +1,16 @@
1
+ # {{ .Spec.Name }}
2
+
3
+ {{ .Spec.Description -}}
4
+ {{- with .Hints }}
5
+ {{ . }}
6
+ {{ end }}
7
+ {{- with .TrackInsert }}
8
+ {{ . }}
9
+ {{ end }}
10
+ {{- with .Spec.Credits -}}
11
+ ## Source
12
+
13
+ {{ . }}
14
+ {{ end }}
15
+ ## Submitting Incomplete Solutions
16
+ It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -0,0 +1,4 @@
1
+ {
2
+ "docs_url": "https://github.com/exercism/docs/blob/master/maintaining-a-track/maintainer-configuration.md",
3
+ "maintainers": []
4
+ }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -105,6 +105,17 @@
105
105
  "Mathematics"
106
106
  ]
107
107
  },
108
+ {
109
+ "uuid": "2bd9ab9e-ecc4-4331-984d-8e5f15f775b4",
110
+ "slug": "armstrong-numbers",
111
+ "core": false,
112
+ "unlocked_by": "leap",
113
+ "difficulty": 2,
114
+ "topics": [
115
+ "Integers",
116
+ "Mathematics"
117
+ ]
118
+ },
108
119
  {
109
120
  "uuid": "5a31217f-02fd-4be4-b64f-7a93f36f5140",
110
121
  "slug": "hamming",
@@ -0,0 +1,29 @@
1
+ # Armstrong Numbers
2
+
3
+ An [Armstrong number](https://en.wikipedia.org/wiki/Narcissistic_number) is a number that is the sum of its own digits each raised to the power of the number of digits.
4
+
5
+ For example:
6
+
7
+ - 9 is an Armstrong number, because `9 = 9^1 = 9`
8
+ - 10 is *not* an Armstrong number, because `10 != 1^2 + 0^2 = 1`
9
+ - 153 is an Armstrong number, because: `153 = 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153`
10
+ - 154 is *not* an Armstrong number, because: `154 != 1^3 + 5^3 + 4^3 = 1 + 125 + 64 = 190`
11
+
12
+ Write some code to determine whether a number is an Armstrong number.
13
+
14
+ The Scala exercises assume an SBT project scheme. The exercise solution source
15
+ should be placed within the exercise directory/src/main/scala. The exercise
16
+ unit tests can be found within the exercise directory/src/test/scala.
17
+
18
+ To run the tests simply run the command `sbt test` in the exercise directory.
19
+
20
+ For more detailed info about the Scala track see the [help
21
+ page](http://exercism.io/languages/scala).
22
+
23
+
24
+ ## Source
25
+
26
+ Wikipedia [https://en.wikipedia.org/wiki/Narcissistic_number](https://en.wikipedia.org/wiki/Narcissistic_number)
27
+
28
+ ## Submitting Incomplete Solutions
29
+ It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -0,0 +1,3 @@
1
+ scalaVersion := "2.12.1"
2
+
3
+ libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.1" % "test"
@@ -0,0 +1,7 @@
1
+ object ArmstrongNumbers {
2
+ def isArmstrongNumber(i: Int): Boolean = {
3
+ val s = i.toString
4
+ val power = s.length
5
+ i == s.toStream.foldLeft(0.0)((acc, c) => acc + math.pow(c.asDigit, power))
6
+ }
7
+ }
@@ -0,0 +1,44 @@
1
+ import org.scalatest.{Matchers, FunSuite}
2
+
3
+ /** @version 1.0.0 */
4
+ class ArmstrongNumbersTest extends FunSuite with Matchers {
5
+
6
+ test("Single digit numbers are Armstrong numbers") {
7
+ ArmstrongNumbers.isArmstrongNumber(5) should be (true)
8
+ }
9
+
10
+ test("There are no 2 digit Armstrong numbers") {
11
+ pending
12
+ ArmstrongNumbers.isArmstrongNumber(10) should be (false)
13
+ }
14
+
15
+ test("Three digit number that is an Armstrong number") {
16
+ pending
17
+ ArmstrongNumbers.isArmstrongNumber(153) should be (true)
18
+ }
19
+
20
+ test("Three digit number that is not an Armstrong number") {
21
+ pending
22
+ ArmstrongNumbers.isArmstrongNumber(100) should be (false)
23
+ }
24
+
25
+ test("Four digit number that is an Armstrong number") {
26
+ pending
27
+ ArmstrongNumbers.isArmstrongNumber(9474) should be (true)
28
+ }
29
+
30
+ test("Four digit number that is not an Armstrong number") {
31
+ pending
32
+ ArmstrongNumbers.isArmstrongNumber(9475) should be (false)
33
+ }
34
+
35
+ test("Seven digit number that is an Armstrong number") {
36
+ pending
37
+ ArmstrongNumbers.isArmstrongNumber(9926315) should be (true)
38
+ }
39
+
40
+ test("Seven digit number that is not an Armstrong number") {
41
+ pending
42
+ ArmstrongNumbers.isArmstrongNumber(9926314) should be (false)
43
+ }
44
+ }
@@ -0,0 +1,33 @@
1
+ import java.io.File
2
+
3
+ import testgen.TestSuiteBuilder._
4
+ import testgen._
5
+
6
+ object ArmstrongNumbersTestGenerator {
7
+ def main(args: Array[String]): Unit = {
8
+ val file = new File("src/main/resources/armstrong-numbers.json")
9
+
10
+ def toString(expected: CanonicalDataParser.Expected): String = {
11
+ expected match {
12
+ case Right(b: Boolean) => b.toString
13
+ case _ => throw new IllegalStateException()
14
+ }
15
+ }
16
+
17
+ def fromLabeledTestFromInput(argNames: String*): ToTestCaseData =
18
+ withLabeledTest { sut =>
19
+ labeledTest =>
20
+ val args = sutArgsFromInput(labeledTest.result, argNames: _*)
21
+ val property = labeledTest.property
22
+ val sutCall =
23
+ s"""$sut.$property($args)"""
24
+ val expected = toString(labeledTest.expected)
25
+ TestCaseData(labeledTest.description, sutCall, expected)
26
+ }
27
+
28
+ val code = TestSuiteBuilder.build(file, fromLabeledTestFromInput("number"))
29
+ println(s"-------------")
30
+ println(code)
31
+ println(s"-------------")
32
+ }
33
+ }
@@ -128,6 +128,14 @@
128
128
  "topics": null,
129
129
  "unlocked_by": null,
130
130
  "uuid": "3ecc2d1c-55e0-45c9-ba35-57d7d8cfd51e"
131
+ },
132
+ {
133
+ "core": false,
134
+ "difficulty": 1,
135
+ "slug": "atbash-cipher",
136
+ "topics": null,
137
+ "unlocked_by": null,
138
+ "uuid": "82169e85-3938-48da-ada9-7394adadc57a"
131
139
  }
132
140
  ],
133
141
  "foregone": [],
@@ -0,0 +1,36 @@
1
+ # Atbash Cipher
2
+
3
+ Create an implementation of the atbash cipher, an ancient encryption system created in the Middle East.
4
+
5
+ The Atbash cipher is a simple substitution cipher that relies on
6
+ transposing all the letters in the alphabet such that the resulting
7
+ alphabet is backwards. The first letter is replaced with the last
8
+ letter, the second with the second-last, and so on.
9
+
10
+ An Atbash cipher for the Latin alphabet would be as follows:
11
+
12
+ ```text
13
+ Plain: abcdefghijklmnopqrstuvwxyz
14
+ Cipher: zyxwvutsrqponmlkjihgfedcba
15
+ ```
16
+
17
+ It is a very weak cipher because it only has one possible key, and it is
18
+ a simple monoalphabetic substitution cipher. However, this may not have
19
+ been an issue in the cipher's time.
20
+
21
+ Ciphertext is written out in groups of fixed length, the traditional group size
22
+ being 5 letters, and punctuation is excluded. This is to make it harder to guess
23
+ things based on word boundaries.
24
+
25
+ ## Examples
26
+
27
+ - Encoding `test` gives `gvhg`
28
+ - Decoding `gvhg` gives `test`
29
+ - Decoding `gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt` gives `thequickbrownfoxjumpsoverthelazydog`
30
+
31
+ ## Source
32
+
33
+ Wikipedia [http://en.wikipedia.org/wiki/Atbash](http://en.wikipedia.org/wiki/Atbash)
34
+
35
+ ## Submitting Incomplete Solutions
36
+ It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -0,0 +1,67 @@
1
+ ;; Load SRFI-64 lightweight testing specification
2
+ (use-modules (srfi srfi-64))
3
+
4
+ ;; Suppress log file output. To write logs, comment out the following line:
5
+ (module-define! (resolve-module '(srfi srfi-64)) 'test-log-to-file #f)
6
+
7
+ ;; Require module
8
+ (add-to-load-path (dirname (current-filename)))
9
+ (use-modules (atbash-cipher))
10
+
11
+ (test-begin "atbash-cipher")
12
+
13
+ ;; Tests go here
14
+
15
+ (test-equal "'yes' encoded is 'bvh'."
16
+ "bvh"
17
+ (encode "yes"))
18
+
19
+ (test-equal "'no' encoded is 'ml'."
20
+ "ml"
21
+ (encode "no"))
22
+
23
+ (test-equal "Encoding always returns lower-case letters."
24
+ "lnt"
25
+ (encode "OMG"))
26
+
27
+ (test-equal "Encoding removes spaces from input."
28
+ "lnt"
29
+ (encode "O M G"))
30
+
31
+ (test-equal "Encoded output includes a space every five characters."
32
+ "nrmwy oldrm tob"
33
+ (encode "mindblowingly"))
34
+
35
+ (test-equal "Symbols are ignored, and numbers are passed-through unmodified"
36
+ "gvhgr mt123 gvhgr mt"
37
+ (encode "Testing,1 2 3, Testing."))
38
+
39
+ (test-equal "Deep thoughts can be encoded"
40
+ "gifgs rhurx grlm"
41
+ (encode "Truth is fiction."))
42
+
43
+ (test-equal "Every lowercase less has an encoding"
44
+ "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt"
45
+ (encode "The quick brown fox jumps over the lazy dog."))
46
+
47
+ (test-equal "Unicode-range symbols are ignored"
48
+ "mlmzh xrrrt mlivw"
49
+ (encode "non ascii éignored"))
50
+
51
+ (test-equal "Exercism can be decoded"
52
+ "exercism"
53
+ (decode "vcvix rhn"))
54
+
55
+ (test-equal "Decodes a sentence"
56
+ "anobstacleisoftenasteppingstone"
57
+ (decode "zmlyh gzxov rhlug vmzhg vkkrm thglm v"))
58
+
59
+ (test-equal "Decoding ignores symbols and passes-through numbers just like encoding"
60
+ "testing123testing"
61
+ (decode "gvhgr mt123 gvhgr mt"))
62
+
63
+ (test-equal "Every lowercase letter can be decoded"
64
+ "thequickbrownfoxjumpsoverthelazydog"
65
+ (decode "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt"))
66
+
67
+ (test-end "atbash-cipher")
@@ -0,0 +1,8 @@
1
+ (define-module (atbash-cipher)
2
+ #:export (encode decode))
3
+
4
+ (define (encode phrase)
5
+ "")
6
+
7
+ (define (decode ciphertext)
8
+ "")
@@ -0,0 +1,40 @@
1
+ (define-module (atbash-cipher)
2
+ #:autoload (srfi srfi-26) (cut)
3
+ #:autoload (srfi srfi-1) (iota)
4
+ #:autoload (ice-9 regex) (regexp-substitute/global
5
+ list-matches)
6
+ #:export (encode decode))
7
+
8
+ ;; "zip" a...z and z...a together to create an alist of mappings.
9
+ (define alphamap
10
+ (let* ((alpha (map integer->char (iota 26 (char->integer #\a)))))
11
+ (map cons alpha (reverse alpha))))
12
+
13
+ ;; Look up the given character in the alphamap and return its complement.
14
+ (define (convert-char chr)
15
+ (or (assoc-ref alphamap chr) chr))
16
+
17
+ ;; Encode the given "val" string using the Atbash cipher.
18
+ (define (encode val)
19
+ (format-atbash (string-map convert-char (prepare-input val))))
20
+
21
+ ;; Decode the given Atbash cipher.
22
+ (define (decode val)
23
+ (string-map convert-char (prepare-input val)))
24
+
25
+ ;; Filter any unprocessable characters out of the plain text.
26
+ ;; Only lowercase a-z and 0-9 are allowed.
27
+ (define (prepare-input val)
28
+ (regexp-substitute/global #f "[^a-z0-9]" (string-downcase val) 'pre "" 'post))
29
+
30
+ ;; Format atbash ciphertext for output.
31
+ ;; Add a space every 5 characters
32
+ ;; Currently generates a preceeding space, which must be trimmed :(
33
+ (define (format-atbash val)
34
+ (string-trim
35
+ (string-concatenate
36
+ (map (compose (cut string-append " " <>)
37
+ match:substring)
38
+ (list-matches "[a-z0-9]{1,5}" val)))))
39
+
40
+