day 7 and 8
This commit is contained in:
62
7/main.ml
Normal file
62
7/main.ml
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
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 clean_string str =
|
||||||
|
str |> String.split_on_char ':' |> List.hd
|
||||||
|
|
||||||
|
let rec parse_int_list sep str =
|
||||||
|
let list1 = (List.filter (fun a -> length a != 0) (String.split_on_char sep str)) in
|
||||||
|
List.map (fun x -> int_of_string @@ clean_string x) list1
|
||||||
|
|
||||||
|
let rec is_possible_inner goal operand_list =
|
||||||
|
match operand_list with
|
||||||
|
| e1 :: tail1 -> begin
|
||||||
|
match tail1 with
|
||||||
|
| e2 :: tail2 ->
|
||||||
|
is_possible_inner goal (e1 + e2 :: tail2)
|
||||||
|
|| is_possible_inner goal (e1 * e2 :: tail2)
|
||||||
|
| _ -> goal == e1
|
||||||
|
end
|
||||||
|
| _ -> false
|
||||||
|
|
||||||
|
let is_possible input_lst =
|
||||||
|
match input_lst with
|
||||||
|
| head :: tail -> is_possible_inner head tail
|
||||||
|
| _ -> false
|
||||||
|
|
||||||
|
let rec int_concat a b =
|
||||||
|
int_of_string (String.cat (string_of_int a) (string_of_int b))
|
||||||
|
|
||||||
|
let rec is_possible_extended_inner goal operand_list =
|
||||||
|
match operand_list with
|
||||||
|
| e1 :: tail1 -> begin
|
||||||
|
match tail1 with
|
||||||
|
| e2 :: tail2 ->
|
||||||
|
is_possible_extended_inner goal (e1 + e2 :: tail2)
|
||||||
|
|| is_possible_extended_inner goal (e1 * e2 :: tail2)
|
||||||
|
|| is_possible_extended_inner goal (int_concat e1 e2 :: tail2)
|
||||||
|
| _ -> goal == e1
|
||||||
|
end
|
||||||
|
| _ -> false
|
||||||
|
|
||||||
|
let is_possible_extended input_lst =
|
||||||
|
match input_lst with
|
||||||
|
| head :: tail -> is_possible_extended_inner head tail
|
||||||
|
| _ -> false
|
||||||
|
|
||||||
|
let () =
|
||||||
|
let f = open_in "input.txt" in
|
||||||
|
let lines = List.map (fun a -> parse_int_list ' ' a) (list_of_lines f) in
|
||||||
|
let valid_lines = List.filter is_possible lines in
|
||||||
|
let valid_lines2 = List.filter is_possible_extended lines in
|
||||||
|
let result = List.fold_left (fun acc lst -> acc + List.hd lst) 0 valid_lines in
|
||||||
|
let result2 = List.fold_left (fun acc lst -> acc + List.hd lst) 0 valid_lines2 in
|
||||||
|
printf "%d\n%d\n" result result2
|
99
8/main.ml
Normal file
99
8/main.ml
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
open Printf;;
|
||||||
|
open String;;
|
||||||
|
open Map;;
|
||||||
|
|
||||||
|
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 file_to_2d_array in_file =
|
||||||
|
let lines = list_of_lines in_file in
|
||||||
|
let size_x = length @@ List.hd lines in
|
||||||
|
let size_y = List.length lines in
|
||||||
|
let arr = Array.make_matrix size_x size_y '?' in
|
||||||
|
List.iteri (fun j line -> String.iteri (fun i c -> arr.(j).(i) <- c) line) lines;
|
||||||
|
arr
|
||||||
|
|
||||||
|
module CharMap = Map.Make(Char)
|
||||||
|
module IntPairs =
|
||||||
|
struct
|
||||||
|
type t = int * int
|
||||||
|
let compare (x0,y0) (x1,y1) =
|
||||||
|
match Stdlib.compare x0 x1 with
|
||||||
|
0 -> Stdlib.compare y0 y1
|
||||||
|
| c -> c
|
||||||
|
end
|
||||||
|
module IntPairsSet = Set.Make(IntPairs)
|
||||||
|
|
||||||
|
let all_objects_in_row arr =
|
||||||
|
arr |> Array.to_seq
|
||||||
|
|> Seq.mapi (fun i x -> (i, x))
|
||||||
|
|> Seq.filter (fun (i, x) -> x <> '.')
|
||||||
|
|
||||||
|
let update_fun elem prev =
|
||||||
|
match prev with
|
||||||
|
| Some lst -> Some (elem :: lst)
|
||||||
|
| None -> Some [elem]
|
||||||
|
|
||||||
|
let group_coords_by_elem arr =
|
||||||
|
arr |> Array.to_seq
|
||||||
|
|> Seq.mapi (fun j row -> Seq.map (fun (i, c) -> ((i, j), c)) (all_objects_in_row row))
|
||||||
|
|> Seq.concat
|
||||||
|
|> Seq.fold_left (fun acc (pos, c) -> CharMap.update c (update_fun pos) acc) CharMap.empty
|
||||||
|
|
||||||
|
let in_bounds (upper_x, upper_y) (x, y) =
|
||||||
|
0 <= x && x < upper_x && 0 <= y && y < upper_y
|
||||||
|
|
||||||
|
let get_antinodes_for_pair (x1, y1) (x2, y2) =
|
||||||
|
let diff_x = x2 - x1 in
|
||||||
|
let diff_y = y2 - y1 in
|
||||||
|
[(x1 - diff_x, y1 - diff_y); (x2 + diff_x, y2 + diff_y)]
|
||||||
|
|
||||||
|
let rec get_antinodes_pairwise antinode_generator antennae_list =
|
||||||
|
match antennae_list with
|
||||||
|
| head :: tail ->
|
||||||
|
(List.fold_left (fun acc x -> List.append acc (antinode_generator head x)) [] tail)
|
||||||
|
|> List.append (get_antinodes_pairwise antinode_generator tail)
|
||||||
|
| _ -> []
|
||||||
|
|
||||||
|
let rec extend_series upper_bounds diff start =
|
||||||
|
if not @@ in_bounds upper_bounds start then
|
||||||
|
[]
|
||||||
|
else
|
||||||
|
start :: extend_series upper_bounds diff (fst start + fst diff, snd start + snd diff)
|
||||||
|
|
||||||
|
let get_harmonic_antinodes_for_pair upper_bounds (x1, y1) (x2, y2) =
|
||||||
|
let diff_x = x2 - x1 in
|
||||||
|
let diff_y = y2 - y1 in
|
||||||
|
List.append
|
||||||
|
(extend_series upper_bounds (-diff_x, -diff_y) (x1, y1))
|
||||||
|
(extend_series upper_bounds (diff_x, diff_y) (x2, y2))
|
||||||
|
|
||||||
|
|
||||||
|
let () =
|
||||||
|
let f = open_in "input.txt" in
|
||||||
|
let arr = file_to_2d_array f in
|
||||||
|
let antennae_grouped = group_coords_by_elem arr in
|
||||||
|
let upper_bounds = (Array.length arr.(0), Array.length arr) in
|
||||||
|
let antinode_set = antennae_grouped
|
||||||
|
|> CharMap.to_seq
|
||||||
|
|> List.of_seq
|
||||||
|
|> List.map snd
|
||||||
|
|> List.map (get_antinodes_pairwise (fun a b -> get_antinodes_for_pair a b
|
||||||
|
|> List.filter (in_bounds upper_bounds)) )
|
||||||
|
|> List.concat
|
||||||
|
|> IntPairsSet.of_list in
|
||||||
|
let harmonic_antinode_set = antennae_grouped
|
||||||
|
|> CharMap.to_seq
|
||||||
|
|> List.of_seq
|
||||||
|
|> List.map snd
|
||||||
|
|> List.map (get_antinodes_pairwise (fun a b -> get_harmonic_antinodes_for_pair upper_bounds a b))
|
||||||
|
|> List.concat
|
||||||
|
|> IntPairsSet.of_list in
|
||||||
|
let result = IntPairsSet.cardinal antinode_set in
|
||||||
|
let result2 = IntPairsSet.cardinal harmonic_antinode_set in
|
||||||
|
printf "%d\n%d\n" result result2
|
Reference in New Issue
Block a user