type Enumerator<'a> = System.Collections.Generic.IEnumerator<'a> let enumerator (s:seq<'a>) = s.GetEnumerator() let (|Char|End|) (e:Enumerator<'a>) = match e.MoveNext() with | true -> Char (e.Current, e) | false -> End (* pomocí stromu *) type MTree = E | L of char * MTree * MTree let morsetree = L (' ', L ('e', L ('i', L ('s', L ('h', E, E), L ('v', E, E)) , L ('u', L ('f', E, E), E)) , L ('a', L ('r', L ('l', E, E), E) , L ('w', L ('p', E, E), L ('j', E, E)))) , L ('t', L ('n', L ('d', L ('b', E, E), L ('x', E, E)) , L ('k', L ('y', E, E), L ('c', E, E))) , L ('m', L ('o', E , E) , L ('g', L ('z', E, E), L ('q', E, E))))) let demorse (str : string) = let prepend c = function | None -> None | Some cs -> Some (c::cs) let rec decode tree = function | End -> match tree with | E -> None | L (c, _, _) -> Some (if c<>' ' then [c] else []) | Char (x, xs) -> match tree with | E -> None | L (c, _, _) when x='|' -> prepend c (decode morsetree xs) | L (_, l, _) when x='.' -> decode l xs | L (_, _, r) when x='-' -> decode r xs | _ -> decode tree xs decode morsetree (str |> enumerator) (* pomocí pole *) let demorse2 (str : string) = let rec code2num n = function | End -> if n > 1 then [n] else [] | Char (x, xs) -> match x with | '|' -> n :: code2num 1 xs | '.'|'-' -> code2num (2*n + if x=='.' then 0 else 1) xs | _ -> code2num n xs let morsenums = "~ etianmsurwdkgohvf~l~pjbxcyzq".ToCharArray() let decode num = function | Some cs when num < morsenums.Length -> Some (morsenums.[num] :: cs) | _ -> None List.foldBack decode (str |> enumerator |> code2num 1) (Some [])