From cc503f93eaa440699333ef5a16976329780904f3 Mon Sep 17 00:00:00 2001 From: Acvaxoort Date: Mon, 9 Dec 2024 22:29:06 +0100 Subject: [PATCH] part 9 --- 9/main.ml | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 9/main.ml diff --git a/9/main.ml b/9/main.ml new file mode 100644 index 0000000..5eb948b --- /dev/null +++ b/9/main.ml @@ -0,0 +1,107 @@ +open Printf;; +open String;; + +let rec list_of_lines in_file = + try + let line = input_line in_file in + line :: list_of_lines(in_file) + with End_of_file -> + close_in in_file; + [] + +let parse_filesystem_block index length = + if index mod 2 == 0 then + Array.init length (fun x -> index / 2) + else + Array.init length (fun x -> (-1)) + +let digit_code_to_int c = + int_of_char c - int_of_char '0' + +let rec fix_file_layout_inner front_index back_index file_layout = + if front_index >= back_index then + () + else if file_layout.(front_index) >= 0 then + fix_file_layout_inner (front_index + 1) back_index file_layout + else if file_layout.(back_index) < 0 then + fix_file_layout_inner front_index (back_index - 1) file_layout + else begin + file_layout.(front_index) <- file_layout.(back_index); + file_layout.(back_index) <- (-1); + fix_file_layout_inner (front_index + 1) (back_index - 1) file_layout + end + +let fix_file_layout file_layout = + let array_copy = Array.copy file_layout in + fix_file_layout_inner 0 (Array.length array_copy - 1) array_copy; + array_copy + +let rec get_repeated_count array value index step = + try + if array.(index) != value then + 0 + else + 1 + get_repeated_count array value (index + step) step + with Invalid_argument _ -> 0 + +let rec try_move_file_no_fragment file_id file_index file_length file_layout front_index = + if front_index >= file_index then + () + else if file_layout.(front_index) >= 0 then + try_move_file_no_fragment file_id file_index file_length file_layout (front_index + 1) + else + let free_space_length = get_repeated_count file_layout (-1) front_index 1 in + if free_space_length < file_length then + try_move_file_no_fragment file_id file_index file_length file_layout (front_index + free_space_length) + else begin + Seq.ints 0 + |> Seq.take file_length + |> Seq.iter ( + fun i -> + file_layout.(front_index + i) <- file_id; + file_layout.(file_index + i) <- (-1)); + end + +let rec fix_file_layout_defragment_inner back_index file_layout = + if back_index < 0 then + () + else if file_layout.(back_index) < 0 then + let free_space_length = get_repeated_count file_layout (-1) back_index (-1) in + fix_file_layout_defragment_inner (back_index - free_space_length) file_layout + else + let file_id = file_layout.(back_index) in + let file_length = get_repeated_count file_layout file_id back_index (-1) in + let new_back_index = back_index - file_length in + try_move_file_no_fragment file_id (new_back_index + 1) file_length file_layout 0; + fix_file_layout_defragment_inner new_back_index file_layout + + +let fix_file_layout_defragment file_layout = + let array_copy = Array.copy file_layout in + fix_file_layout_defragment_inner (Array.length file_layout - 1) array_copy; + array_copy + +let get_checksum file_layout = + file_layout + |> Array.to_seq + |> Seq.mapi (fun i x -> i * x) + |> Seq.filter (fun x -> x >= 0) + |> Seq.fold_left Int.add 0 + +let () = + let f = open_in "input.txt" in + let disk_map = f + |> list_of_lines + |> List.hd + |> String.to_seq + |> Seq.map digit_code_to_int + |> List.of_seq in + let file_layout = disk_map + |> List.mapi (fun i x -> parse_filesystem_block i x) + |> Array.concat in + let fixed_layout = fix_file_layout file_layout in + let result = get_checksum fixed_layout in + printf "%d\n%!" result; + let fixed_layout_defragment = fix_file_layout_defragment file_layout in + let result2 = get_checksum fixed_layout_defragment in + printf "%d\n"result2 \ No newline at end of file