├── myprogram ├── .gitignore ├── solutions.txt ├── Makefile ├── problems.txt └── myprogram.ml /myprogram: -------------------------------------------------------------------------------- 1 | myprogram.native -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /_build/ 2 | /myprogram.native 3 | -------------------------------------------------------------------------------- /solutions.txt: -------------------------------------------------------------------------------- 1 | 1000 2 | -1 3 | 9 4 | 62 5 | 59 6 | 50070 7 | 9 8 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all 2 | 3 | all: 4 | ocamlbuild -use-ocamlfind -tag safe_string -pkg tyre -pkg containers myprogram.native 5 | -------------------------------------------------------------------------------- /problems.txt: -------------------------------------------------------------------------------- 1 | 10 10 10 2000 2 | 10 10 10 900 3 | 4 4 8 10 10 1 4 | 5 5 5 61 7 1 5 | 5 5 6 61 4 1 6 | 1000 1000 1000 0 0 0 46501 0 2791 631 127 19 1 7 | 1 1 9 9 1 8 | -------------------------------------------------------------------------------- /myprogram.ml: -------------------------------------------------------------------------------- 1 | type cube = Cube of int 2 | 3 | exception Too_big 4 | 5 | let extract1 (x, y, z) (Cube n) = 6 | if n > x || n > y || n > z then 7 | (* Trying to pull out a Cube of size n of something that is of less than n? *) 8 | raise Too_big 9 | else 10 | (* Calculate the count and sizes of the respective split cuboids *) 11 | match (n = x, n = y, n = z) with 12 | | true, true, true -> None 13 | | true, true, false -> Some [(x, y, z-n)] 14 | | true, false, true -> Some [(x, y-n, z)] 15 | | false, true, true -> Some [(x-n, y, z)] 16 | | false, false, true -> Some [(x-n, y, z); (n, y-n, z)] 17 | | false, true, false -> Some [(n, y, z-n); (x-n, y, z)] 18 | | true, false, false -> Some [(x, n, z-n); (x, y-n, z)] 19 | | false, false, false -> Some [(n, n, z-n); (x-n, n, z); (x, y-n, z)] 20 | 21 | exception Impossibru 22 | 23 | let rec extract geom = function 24 | (* We ran out of cubes to extract from the geometry *) 25 | | [] -> raise Impossibru 26 | (* Try to extract the first cube *) 27 | | cube::cubes -> match extract1 geom cube with 28 | | exception Too_big -> 29 | (* That cube was too big, try again with the next *) 30 | let (matches, cubes) = extract geom cubes in 31 | (matches, cube::cubes) 32 | | None -> (1, cubes) 33 | (* Then we just recurse on the different ways the cuboids could be split *) 34 | | Some geoms -> 35 | let (matches, cubes) = 36 | List.fold_left (fun (matches, cubes) geom -> 37 | let (matches', cubes') = extract geom cubes in 38 | (matches + matches', cubes')) (0, cubes) geoms 39 | in 40 | (matches + 1, cubes) 41 | 42 | let solve ((x, y, z), cubes) = 43 | match extract (x, y, z) cubes with 44 | | (i, _) -> i 45 | | exception Impossibru -> -1 46 | 47 | let tup4 re = Tyre.conv 48 | (fun (((x, y), z), w) -> ((x, y, z), w)) 49 | (fun ((x, y, z), w) -> ((x, y), z), w) 50 | re 51 | 52 | let extract_values = 53 | let open Tyre in 54 | pos_int <&> (str " " *> pos_int) <&> (str " " *> pos_int) <&> (list @@ str " " *> pos_int) 55 | |> tup4 56 | |> compile 57 | |> exec 58 | 59 | let parse line = 60 | let open CCResult.Infix in 61 | extract_values line >|= fun (coords, cubes_per_power) -> 62 | let cubes = cubes_per_power 63 | |> List.mapi (fun i n -> 64 | let rec loop acc = function 65 | | 0 -> acc 66 | | n -> loop (Cube (1 lsl i)::acc) (n-1) 67 | in loop [] n) 68 | |> List.flatten 69 | |> List.rev 70 | in 71 | (coords, cubes) 72 | 73 | let process line = 74 | let open CCResult.Infix in 75 | let r = line 76 | |> parse 77 | >|= solve 78 | >|= string_of_int 79 | in match r with 80 | | Ok v -> print_endline v 81 | | Error _ -> print_endline "-1" 82 | 83 | let rec main () = 84 | match read_line () with 85 | | line -> process line; main () 86 | | exception End_of_file -> () 87 | 88 | let () = 89 | main () 90 | --------------------------------------------------------------------------------