Skip to content

Instantly share code, notes, and snippets.

@mharju
Last active January 1, 2016 10:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mharju/8132827 to your computer and use it in GitHub Desktop.
Save mharju/8132827 to your computer and use it in GitHub Desktop.
Reaktor FastTrack morse code DFA solution
(ns test.core
(:require [clojure.string :as str]))
(def morse
(into []
(sort-by key (comparator (fn [x y] (<= (count x) (count y))))
{".-" "A" "-..." "B" "-.-." "C" "-.." "D" "." "E" "..-." "F" "--." "G" "...." "H" ".." "I" ".---" "J" "-.-" "K" ".-.." "L" "--" "M" "-." "N" "---" "O" ".--." "P" "--.-" "Q" ".-." "R" "..." "S" "-" "T" "..-" "U" "...-" "V" ".--" "W" "-..-" "X" "-.--" "Y" "--.." "Z"})))
(defn build-dfa
([codes] (build-dfa codes []))
([codes current-list]
(letfn [(first-char [c codes] (filter (fn [[code letter]] (= c (first code))) codes))
(drop-first-char [codes] (map (fn [[k v]] [(subs k 1) v]) codes))
(build-sublist [c codes] (-> (first-char c codes) (drop-first-char)))]
(let [[code letter] (first codes)]
(cond (not (empty? (rest codes)))
(let [result-dit (build-dfa (build-sublist \. codes) current-list)
index-dit (if (> (count result-dit) (count current-list)) (dec (count result-dit)) nil)
result-dah (build-dfa (build-sublist \- codes) result-dit)
index-dah (if (> (count result-dah) (count result-dit)) (dec (count result-dah)) nil)]
(concat result-dah [[index-dit index-dah (if (empty? code) letter nil)]]))
(and (not (empty? letter)) (empty? code))
(concat current-list [[nil nil letter]])
:else current-list)))))
(defn dfa->javascript-array [dfa]
(str "[" (str/join
","
(letfn [(print-number [n] (if (number? n) n nil))
(print-char [n] (if (string? n) (format "'%s'" n) nil))]
(map (fn [[dit dah letter]]
(format "[%s]" (str/join "," (remove nil? [(print-number dit) (print-number dah) (print-char letter)])))) dfa)))
"]"))
(let [dfa (build-dfa morse)]
(println
(format (str "var morse_dfa = %s, l = %d, current_step = l, r;\n"
"function morse(s) {\n"
" if(typeof (current_step = morse_dfa[current_step][{'dit':0,'dah':1,'pause':morse_dfa[current_step].length-1}[s]]) !== 'number') {\n"
" r = current_step; current_step = l;\n"
" return r;\n"
" }\n"
"}\n")
(dfa->javascript-array dfa) (dec (count dfa)))))
var morse_dfa = [['H'],['V'],[0,1,'S'],['F'],[3,'U'],[2,4,'I'],['L'],[6,'R'],['P'],['J'],[8,9,'W'],[7,10,'A'],[5,11,'E'],['B'],['X'],[13,14,'D'],['C'],['Y'],[16,17,'K'],[15,18,'N'],['Z'],['Q'],[20,21,'G'],['O'],[22,23,'M'],[19,24,'T'],[12,25]], l = 26, current_step = l, r;
function morse(s) {
if(typeof (current_step = morse_dfa[current_step][{'dit':0,'dah':1,'pause':morse_dfa[current_step].length-1}[s]]) !== 'number') {
r = current_step; current_step = l;
return r;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment