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.2.1.10 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.2.1.9 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.2.1.8 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.2.1.7 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.2.1.6 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.2.1.5 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.2.1.4 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.2.1.3 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.2.1.2 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.2.1.1 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.2.1.0 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.2.0.6 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.2.0.5 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.2.0.4 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.2.0.3 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.2.0.2 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.2.0.1 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.2.0.0 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.1.0.55 tracks/ocaml/exercises/dominoes/example.ml
trackler-2.1.0.54 tracks/ocaml/exercises/dominoes/example.ml