make run locally works fine. Here’s my latest code in atbash.ml:
open Base
let atbash ch = Char.(if is_alpha ch
then of_int (to_int 'z' - to_int ch + to_int 'a')
else if is_digit ch then Some ch else None)
let encode ?(block_size=5) s =
let rec chunk s = if String.length s <= block_size then [s] else
(String.prefix s block_size) :: (chunk (String.drop_prefix s block_size))
in String.lowercase s |> String.filter_map ~f:atbash |> chunk |> String.concat ~sep:" "
let decode s = String.filter_map s ~f:atbash
I was able to submit a solution just now to the ocaml track ‘bowling’ exercise without any trouble, so it’s not impacting all exercises.
I don’t know this language or the test runner. Two things you can try to help a person who does know these is to:
Run this example solution which should work. Let us know if it does
open Base
let substitute = function
| 'a' .. 'z' as c ->
let offset = (Char.to_int c) - (Char.to_int 'a') in
let code = (Char.to_int 'z') - offset in
Char.of_int_exn code
| other -> other
let is_encodable = function
| 'a' .. 'z' | '0' .. '9' -> true
| _ -> false
let explode s =
let rec expl i l =
if i < 0 then
l
else
expl (i - 1) (s.[i] :: l)
in
expl ((String.length s) - 1) []
let implode l =
let character_at i = List.nth_exn l i in
String.init (List.length l) ~f:character_at
let rec group n l =
if (List.length l) <= n then
[l]
else
(List.take l n) :: (group n (List.drop l n))
let encode ?block_size:(block_size = 5) text =
let lowercase_text = String.lowercase text in
let characters = explode lowercase_text in
let filtered_characters = List.filter ~f:is_encodable characters in
let groups = group block_size filtered_characters in
let preprocessed_texts = List.map ~f:implode groups in
let texts = List.map ~f:(String.map ~f:substitute) preprocessed_texts in
String.concat ~sep:" " texts
let decode text =
let lowercase_text = String.lowercase text in
let characters = explode lowercase_text in
let filtered_characters = List.filter ~f:is_encodable characters in
let preprocessed_text = implode filtered_characters in
String.map ~f:substitute preprocessed_text
If it does, let us know what OCaml version you are using locally.
So String.filter_map works on 5.2.1, but not 5.1.1? Is it possible filter_map was only added to the String module after 5.1.1? It seems a little strange to be honest they would add this method at all given you already have List.filter_map available.
I was confused by this too and looked further into this. The Base import for OCaml exercises on Exercism is a standard library replacement by Jane Street. String.filter_map is provided by Base here and is a name the test runner “knows” because switching it to String.filter_maap results in a different error as an unbound name.
Running make locally would run the same tests so I’m not sure what to say here. My gut was saying there might be a bug in the atbash function, but the tests would have presumably failed locally.
CCing @georgyo@kahgoh since they’re the OCaml track maintainers
It was not present in 0.15.1 and became available in 0.16.0.
I can imagine that this is relevant, however I could not find any mention of pin, hold, or opam-lock in the test-runner, which would (hopefully?) have created a lock-like file which we could then check. 0.16.0 came out 2 years ago so I doubt this is the actual issue but .
Hopefully Kah or George can answer why this is happeneing
The version in the test runner is 0.16.3. I ended up pulling down the test runner image from Docker and checking it inside the container:
20582789ad59:~# opam list --installed
[WARNING] Running as root is not recommended
# Packages matching: installed
# Name # Installed # Synopsis
base v0.16.3 Full standard library replacement for OCaml
base-bigarray base
base-domains base
base-nnp base Naked pointers prohibited in the OCaml heap
base-threads base
base-unix base
According to the docs, the latest version is v0.17.3. I’ll do some further testing between these two versions later tonight to see if this was something that changed between the two versions.
Interesting … I’ve just tested. I was able to reproduce @kevinastock’s issue with the test runner image and v0.16.3. However, I wasn’t able to when I tried base v0.17.3 (both times with OCaml 5.1).
I’m guessing something must’ve changed in the library. I had a look at the changes, but I can’t tell which one would have caused this difference.
I’m planning to look at updating the test runner later in the week.
@kevinastock OCaml has been updated to 5.4 and the Base library is now at 0.17.3. Your atbash-cipher solution should now work with the online submission.