Add 2024 day 24 part 2
For part 2 we only use helper functions most of the calculations are done manually.
This commit is contained in:
@@ -77,19 +77,58 @@ let process_gates wires =
|
||||
impl wires []
|
||||
|
||||
let rec repeat_to_end wires gates =
|
||||
let old_len = List.length gates in
|
||||
let wires, gates = process_gates wires gates in
|
||||
if gates = [] then wires
|
||||
if gates = [] then Some wires
|
||||
else if old_len = List.length gates then begin
|
||||
Printf.printf "Loop detected: %d\n" (List.length gates);
|
||||
None
|
||||
end
|
||||
else begin
|
||||
Printf.printf "Gate size: %d\n" (List.length gates);
|
||||
repeat_to_end wires gates
|
||||
end
|
||||
|
||||
let calc_value = Fun.flip (List.fold_right (fun x acc -> x + (2 * acc))) 0
|
||||
|
||||
let part1 (wires, gates) =
|
||||
let wires = repeat_to_end wires gates in
|
||||
let zmap = StringMap.filter (fun k _ -> k.[0] = 'z') wires in
|
||||
let zlst = StringMap.bindings zmap |> List.map snd in
|
||||
calc_value zlst
|
||||
let k_wires wires x =
|
||||
StringMap.filter (fun k _ -> k.[0] = x) wires
|
||||
|> StringMap.bindings |> List.map snd |> calc_value
|
||||
|
||||
let _ = Aoc.main config_of_file [ (string_of_int, part1) ]
|
||||
let wires_set wires x v' =
|
||||
let set_v k v =
|
||||
if k.[0] = x then
|
||||
let idx = int_of_string (String.sub k 1 (String.length k - 1)) in
|
||||
(v' lsr idx) land 1
|
||||
else v
|
||||
in
|
||||
StringMap.mapi set_v wires
|
||||
|
||||
let part1 (wires, gates) =
|
||||
match repeat_to_end wires gates with
|
||||
| None -> failwith "part1"
|
||||
| Some wires -> k_wires wires 'z'
|
||||
|
||||
let part2 (wires, gates) =
|
||||
let run_test x y =
|
||||
let wires = wires_set wires 'x' x in
|
||||
let wires = wires_set wires 'y' y in
|
||||
Printf.printf "%d + %d = " (k_wires wires 'x') (k_wires wires 'y');
|
||||
match repeat_to_end wires gates with
|
||||
| None -> print_endline "(infinite loop)"
|
||||
| Some wires ->
|
||||
let z = k_wires wires 'z' in
|
||||
print_int z;
|
||||
if z <> x + y then print_string " (wrong answer)";
|
||||
print_newline ()
|
||||
in
|
||||
let tst n =
|
||||
Printf.printf "Test for n = %d\n" n;
|
||||
run_test (1 lsl n) 0;
|
||||
run_test 0 (1 lsl n);
|
||||
run_test (1 lsl n) (1 lsl n)
|
||||
in
|
||||
Seq.ints 0 |> Seq.take 45 |> Seq.iter tst;
|
||||
0
|
||||
|
||||
let _ =
|
||||
Aoc.main config_of_file [ (string_of_int, part1); (string_of_int, part2) ]
|
||||
|
Reference in New Issue
Block a user