44 lines
1.2 KiB
OCaml
44 lines
1.2 KiB
OCaml
module IntMap = Map.Make(Int)
|
|
|
|
let seq_lines ch =
|
|
let rec repeat () =
|
|
match input_line ch with
|
|
| s -> Seq.Cons (s, repeat)
|
|
| exception End_of_file -> Nil
|
|
in repeat
|
|
|
|
(* simply use bijective numeration in base 8 for keys *)
|
|
|
|
let key_of_char = function
|
|
| 'a' .. 'c' -> Some 1
|
|
| 'd' .. 'f' -> Some 2
|
|
| 'g' .. 'i' -> Some 3
|
|
| 'j' .. 'l' -> Some 4
|
|
| 'm' .. 'o' -> Some 5
|
|
| 'p' .. 's' -> Some 6
|
|
| 't' .. 'v' -> Some 7
|
|
| 'w' .. 'z' -> Some 8
|
|
| _ -> None
|
|
|
|
let keys_of_word =
|
|
let next k c =
|
|
Option.bind (key_of_char c) (fun d -> Option.map (fun k -> k lsl 3 + d) k)
|
|
in String.fold_left next (Some 0)
|
|
|
|
let update m k =
|
|
IntMap.update k (function Some n -> Some (succ n) | None -> Some 1) m
|
|
|
|
let map_from ch =
|
|
seq_lines ch |> Seq.filter_map keys_of_word |> Seq.fold_left update IntMap.empty
|
|
|
|
let count _ n (words, keys, txtns) =
|
|
words + n, succ keys, if n > 1 then succ txtns else txtns
|
|
|
|
let show src (words, keys, txtns) = Printf.printf "\
|
|
There are %u words in %s which can be represented by the digit key mapping.\n\
|
|
They require %u digit combinations to represent them.\n\
|
|
%u digit combinations represent Textonyms.\n" words src keys txtns
|
|
|
|
let () =
|
|
show "stdin" (IntMap.fold count (map_from stdin) (0, 0, 0))
|