Sha256: a374c579426b9263c38f91f3751bd0424b43baa9decfa3eaa85c3e7d8aafb44a

Contents?: true

Size: 1.5 KB

Versions: 151

Compression:

Stored size: 1.5 KB

Contents

(* Based off the Haskell solution by Tarmean at http://exercism.io/submissions/6dc2eef7e7eb469d8657111fc4389fc0 *)

open Core

type dominoe = int * int

(* Functions from Haskell that I can't find in Core! *)

let zip_with (xs: 'a list) (ys: 'b list) ~(f: 'a -> 'b -> 'c) = 
  let rec go xs ys acc = match (xs,ys) with
  | (x::xs,y::ys) -> go xs ys @@ (f x y)::acc
  | _ -> acc
  in
  List.rev @@ go xs ys []

let tails (xs: 'a list): ('a list) list =
  let rec go acc = function
  | [] -> [] :: acc
  | (_::xs) as l -> go (l :: acc) xs
  in
  List.rev @@ go [] xs

let inits (xs: 'a list): ('a list) list =
  List.rev xs |> tails |> List.map ~f:List.rev |> List.rev

let listToOption = function
| [] -> None
| (x :: _) -> Some x

(* The implementation *)

let left (ds: dominoe list): int = ds |> List.hd_exn |> fst
let right (ds: dominoe list): int = ds |> List.last_exn |> snd
let choose_from (ls: 'a list): ('a * 'a list) list =
  List.zip_exn ls @@ zip_with ~f:List.append (inits ls) (List.tl_exn (tails ls))

let rec attach_to path ((a, b), rest) =
  let lp = left path in
  if b = lp then go rest ((a,b)::path)
  else if a = lp then go rest ((b,a)::path)
  else []
and go stones path = match stones with
| [] -> if left path = right path then [path] else []
| _ -> let open List.Monad_infix in choose_from stones >>= attach_to path

let chain_non_empty (first: dominoe) (rest: dominoe list): (dominoe list) option = 
  listToOption @@ go rest [first]

let chain = function
| [] -> Some []
| first::rest -> chain_non_empty first rest

Version data entries

151 entries across 151 versions & 1 rubygems

Version Path
trackler-2.1.0.53 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.1.0.52 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.1.0.51 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.1.0.50 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.1.0.49 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.1.0.48 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.1.0.47 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.1.0.46 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.1.0.45 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.1.0.44 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.1.0.43 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.1.0.42 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.1.0.41 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.1.0.40 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.1.0.39 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.1.0.38 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.1.0.37 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.1.0.36 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.1.0.34 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.1.0.33 tracks/ocaml/exercises/dominoes/example.ml