Files
ocaml-aoc/bin/day2409.ml

72 lines
1.9 KiB
OCaml

let load_file fname =
match In_channel.with_open_text fname In_channel.input_line with
| Some x -> x
| None -> failwith "load_file"
(*
let disk_print disk =
let prnt c = if c = -1 then print_char '.' else print_int c in
Array.iter prnt disk;
print_newline();
*)
let disk_size disk_str =
let rec impl acc disk_str =
let len = String.length disk_str in
match len with
| 0 -> acc
| len ->
let h = int_of_string (String.sub disk_str 0 1) in
flush_all ();
let t = String.sub disk_str 1 (len - 1) in
flush_all ();
impl (acc + h) t
in
impl 0 disk_str
let disk_init disk_str =
let size = disk_size disk_str in
let disk = Array.make size (-1) in
let rec add_id offset id = function
| 0 -> offset
| x ->
disk.(offset) <- id;
add_id (offset + 1) id (x - 1)
in
let rec impl offset id disk_str =
match String.length disk_str with
| 0 -> ()
| 1 ->
let _ = add_id offset id (int_of_string (String.sub disk_str 0 1)) in
()
| str_len ->
let len = int_of_string (String.sub disk_str 0 1) in
impl
(add_id offset id len + int_of_string (String.sub disk_str 1 1))
(id + 1)
(String.sub disk_str 2 (str_len - 2))
in
impl 0 0 disk_str;
disk
let disk_defrag disk =
let rec impl front back =
if front >= back then ()
else if disk.(front) <> -1 then impl (front + 1) back
else if disk.(back) = -1 then impl front (back - 1)
else (
disk.(front) <- disk.(back);
disk.(back) <- -1;
impl (front + 1) (back - 1))
in
impl 0 (Array.length disk - 1);
disk
let calc_checksum disk =
let rec impl acc idx =
if disk.(idx) = -1 then acc else impl (acc + (disk.(idx) * idx)) (idx + 1)
in
impl 0 0
let part1 str = disk_init str |> disk_defrag |> calc_checksum
let _ = Aoc.main load_file [ (string_of_int, part1) ]