Skip to content

Instantly share code, notes, and snippets.

@thedeemon
Created January 6, 2015 08:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thedeemon/48ab320c3675916f3980 to your computer and use it in GitHub Desktop.
Save thedeemon/48ab320c3675916f3980 to your computer and use it in GitHub Desktop.
Micro interpreter in OCaml, simplified
type exp = IfGt of int * int * block * block
| Swap of int * int
| Copy of int * int
and block = exp list;;
let rec eval a = function
| IfGt(i, j, b1, b2) ->
1 + evalBlock a (if a.(i) > a.(j) then b1 else b2)
| Swap(i, j) ->
let ai = a.(i) and aj = a.(j) in
a.(i) <- aj; a.(j) <- ai; 1
| Copy(i, j) ->
a.(i) <- a.(j); 1
and evalBlock a blk =
let f cnt exp = eval a exp + cnt in
List.fold_left f 0 blk
let numSteps blk ua =
let a = Array.copy ua in
let n = evalBlock a blk in
if a.(1) = 2 && a.(6) = 7 then n else 25000
let rec insert x l = match l with
| [] -> [[x]]
| a::m -> (x::l) :: (List.map (fun y -> a::y) (insert x m))
let rec perms = function
| a::m -> List.flatten (List.map (insert a) (perms m))
| l -> [l]
let inputs =
let zs = Array.make 4 0 in
List.map (fun xs -> Array.append (Array.of_list xs) zs) (perms [1;2;3;4;5;6;7;8])
let calcScore blk = List.fold_left (fun sum a -> sum + numSteps blk a) 0 inputs
let cmp_swap i j = IfGt(i, j, [Swap(i, j)], [])
let mksornet cmp =
[cmp 0 1; cmp 2 3; cmp 4 5; cmp 6 7;
cmp 0 2; cmp 1 3; cmp 4 6; cmp 5 7;
cmp 1 2; cmp 5 6; cmp 0 4; cmp 3 7;
cmp 1 5; cmp 2 6;
cmp 1 4; cmp 3 6]
let sornet = mksornet cmp_swap
let (|>) x f = f x;;
Array.make 40 sornet |> Array.map calcScore |> Array.fold_left min 999999999 |> print_int;;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment