From 7c9a40aabab9b3676d80d084b09a24bf3a3034e3 Mon Sep 17 00:00:00 2001 From: Acvaxoort Date: Thu, 5 Dec 2024 22:41:23 +0100 Subject: [PATCH] first 4 days --- 1/main.ml | 52 +++++++++++ 2/main.ml | 70 +++++++++++++++ 3/main.ml | 47 ++++++++++ 4/main.ml | 160 +++++++++++++++++++++++++++++++++ ocaml compilation is weird.txt | 7 ++ 5 files changed, 336 insertions(+) create mode 100644 1/main.ml create mode 100644 2/main.ml create mode 100644 3/main.ml create mode 100644 4/main.ml create mode 100644 ocaml compilation is weird.txt diff --git a/1/main.ml b/1/main.ml new file mode 100644 index 0000000..23c5065 --- /dev/null +++ b/1/main.ml @@ -0,0 +1,52 @@ +open Printf;; +open String;; + +let rec build_list in_file = + try + let line = input_line in_file in + line :: build_list(in_file) + with End_of_file -> + close_in in_file; + [] + +let is_not_empty lst = + match lst with + | [] -> false + | _ -> true + +let rec parse_list (l1, l2) str = + let list1 = (List.filter (fun a -> length a != 0) (String.split_on_char ' ' str)) in + let list_of_int = List.map int_of_string list1 in + match list_of_int with + | e1 :: e2 :: _ -> (e1 :: l1, e2 :: l2) + | _ -> failwith "Not enough ints in a line" + +let rec count_and_remove value acc lst = + match lst with + | n :: tail -> + if n < value then + count_and_remove value acc tail + else if n == value then + count_and_remove value (acc + 1) tail + else + (acc, lst) + | _ -> (acc, lst) + +let rec get_list_similarity acc l1 l2 = + match l1 with + | n :: tail1 -> + let (c1, l1_new) = count_and_remove n 1 tail1 in + let (c2, l2_new) = count_and_remove n 0 l2 in + get_list_similarity (acc + n * c1 * c2) l1_new l2_new + | _ -> acc + +let () = + let f = open_in "input.txt" in + let lst = build_list f in + let (l1, l2) = List.fold_left parse_list ([], []) lst in + let l1_sorted = List.sort Int.compare l1 in + let l2_sorted = List.sort Int.compare l2 in + let result = List.fold_left Int.add 0 (List.map2 (fun a b -> Int.abs(a - b)) l1_sorted l2_sorted) in + let result2 = get_list_similarity 0 l1_sorted l2_sorted in + printf "%d\n" result; + printf "%d\n" result2 \ No newline at end of file diff --git a/2/main.ml b/2/main.ml new file mode 100644 index 0000000..ca39e36 --- /dev/null +++ b/2/main.ml @@ -0,0 +1,70 @@ +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 is_not_empty lst = + match lst with + | [] -> false + | _ -> true + +let rec parse_int_list str = + let list1 = (List.filter (fun a -> length a != 0) (String.split_on_char ' ' str)) in + List.map int_of_string list1 + +let rec int_list_diff int_list = + match int_list with + | e1 :: e2 :: tail -> e2 - e1 :: int_list_diff (e2 :: tail) + | _ -> [] + +let list_diffs_safe diff_list = + match diff_list with + | n :: tail -> + if n > 0 then + List.for_all (fun x -> x >= 1 && x <= 3) diff_list + else if n < 0 then + List.for_all (fun x -> x >= -3 && x <= -1) diff_list + else + false + | _ -> true + +let rec list_diff_safe_with_tolerance_inner last condition tol diff_list = + match diff_list with + | x :: tail -> + if condition x then + list_diff_safe_with_tolerance_inner x condition tol tail + else if tol then + match tail with + | x2 :: tail2 -> + list_diff_safe_with_tolerance_inner 0 condition false (x + x2 :: tail2) + || list_diff_safe_with_tolerance_inner 0 condition false (last + x :: tail) + | _ -> true + else + false + | _ -> true + +let list_diff_safe_with_tolerance diff_list = + if list_diff_safe_with_tolerance_inner 0 (fun x -> x >= 1 && x <= 3) true diff_list + || list_diff_safe_with_tolerance_inner 0 (fun x -> x >= -3 && x <= -1) true diff_list then + true + else + match diff_list with + | _ :: tail -> list_diffs_safe tail + | _ -> true + + +let () = + let f = open_in "input.txt" in + let lines = list_of_lines f in + let diffs = List.map (fun a -> int_list_diff @@ parse_int_list a) lines in + (* List.iter (fun a -> List.iter (printf "%d, ") a; printf "\n") diffs *) + let count = List.fold_left (fun acc l -> if list_diffs_safe l then acc + 1 else acc) 0 diffs in + let count2 = List.fold_left (fun acc l -> if list_diff_safe_with_tolerance l then acc + 1 else acc) 0 diffs in + printf "%d\n" count; + printf "%d\n" count2 diff --git a/3/main.ml b/3/main.ml new file mode 100644 index 0000000..f092281 --- /dev/null +++ b/3/main.ml @@ -0,0 +1,47 @@ +open Printf;; +open String;; +open Str;; + +let read_whole_file f = + let s = really_input_string f (in_channel_length f) in + close_in f; + s + +let rec process_all_mul_inner re str pos acc = + try + let new_pos = Str.search_forward re str pos in + let n1 = int_of_string @@ Str.matched_group 1 str in + let n2 = int_of_string @@ Str.matched_group 2 str in + process_all_mul_inner re str (new_pos + 1) (acc + n1 * n2) + with Not_found -> acc +let rec process_all_mul_with_dont_inner re str enabled pos acc = + try + let new_pos = Str.search_forward re str pos in + let command = Str.matched_group 0 str in + if command = "do()" then + process_all_mul_with_dont_inner re str true (new_pos + 1) acc + else if command = "don't()" then + process_all_mul_with_dont_inner re str false (new_pos + 1) acc + else if enabled then + let n1 = int_of_string @@ Str.matched_group 1 str in + let n2 = int_of_string @@ Str.matched_group 2 str in + process_all_mul_with_dont_inner re str enabled (new_pos + 1) (acc + n1 * n2) + else + process_all_mul_with_dont_inner re str enabled (new_pos + 1) acc + with Not_found -> acc + +let process_all_mul str = + let re = Str.regexp "mul(\\([0-9]+\\),\\([0-9]+\\))" in + process_all_mul_inner re str 0 0 + +let process_all_mul_with_dont str = + let re = Str.regexp "mul(\\([0-9]+\\),\\([0-9]+\\))\\|do()\\|don't()" in + process_all_mul_with_dont_inner re str true 0 0 + +let () = + let f = open_in "input.txt" in + let str = read_whole_file f in + let result = process_all_mul str in + let result2 = process_all_mul_with_dont str in + printf "%d\n" result; + printf "%d\n" result2 diff --git a/4/main.ml b/4/main.ml new file mode 100644 index 0000000..bec46ea --- /dev/null +++ b/4/main.ml @@ -0,0 +1,160 @@ +open Printf;; +open Buffer;; +open String;; +open Str;; + +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 + +let rec parse_int_list str = + let list1 = (List.filter (fun a -> length a != 0) (String.split_on_char ' ' str)) in + List.map int_of_string list1 + +let rec int_list_diff int_list = + match int_list with + | e1 :: e2 :: tail -> e2 - e1 :: int_list_diff (e2 :: tail) + | _ -> [] + +let list_diffs_safe diff_list = + match diff_list with + | n :: tail -> + if n > 0 then + List.for_all (fun x -> x >= 1 && x <= 3) diff_list + else if n < 0 then + List.for_all (fun x -> x >= -3 && x <= -1) diff_list + else + false + | _ -> true + +let rec list_diff_safe_with_tolerance_inner last condition tol diff_list = + match diff_list with + | x :: tail -> + if condition x then + list_diff_safe_with_tolerance_inner x condition tol tail + else if tol then + match tail with + | x2 :: tail2 -> + list_diff_safe_with_tolerance_inner 0 condition false (x + x2 :: tail2) + || list_diff_safe_with_tolerance_inner 0 condition false (last + x :: tail) + | _ -> true + else + false + | _ -> true + +let list_diff_safe_with_tolerance diff_list = + if list_diff_safe_with_tolerance_inner 0 (fun x -> x >= 1 && x <= 3) true diff_list + || list_diff_safe_with_tolerance_inner 0 (fun x -> x >= -3 && x <= -1) true diff_list then + true + else + match diff_list with + | _ :: tail -> list_diffs_safe tail + | _ -> true + +let rec count_in_string_inner re str pos acc = + try + let new_pos = Str.search_forward re str pos in + count_in_string_inner re str (new_pos + 1) (acc + 1) + with Not_found -> acc + +let count_in_string str = + let re = Str.regexp "XMAS\\|SAMX" in + count_in_string_inner re str 0 0 + +let prepare_horizontal_str arr = + let buf = Buffer.create 1024 in + Array.iter (fun row -> Array.iter (fun c -> Buffer.add_char buf c) row; Buffer.add_char buf '\n') arr; + Buffer.contents buf + +let prepare_vertical_str arr = + let buf = Buffer.create 1024 in + Seq.iter (fun i -> Array.iter (fun row -> Buffer.add_char buf row.(i)) arr; Buffer.add_char buf '\n') + (Seq.init (Array.length arr.(0)) (fun x -> x)); + Buffer.contents buf + +let rec traverse_diagonal fn arr x y = + try + let () = fn arr.(y).(x) in + traverse_diagonal fn arr (x + 1) (y + 1) + with Invalid_argument _ -> () + +let rec traverse_antidiagonal fn arr x y = + try + let () = fn arr.(y).(x) in + traverse_antidiagonal fn arr (x - 1) (y + 1) + with Invalid_argument _ -> () + +let range start stop = + Seq.init (stop - start) (fun x -> start + x) + +let range_rev start stop = + Seq.init (stop - start) (fun x -> stop - 1 - x) + +let prepare_diagonal_str arr = + let buf = Buffer.create 1024 in + let length_x = Array.length arr.(0) in + let length_y = Array.length arr in + Seq.iter (fun y -> traverse_diagonal (Buffer.add_char buf) arr 0 y; Buffer.add_char buf '\n') + (range_rev 1 (length_y - 1)); + Seq.iter (fun x -> traverse_diagonal (Buffer.add_char buf) arr x 0; Buffer.add_char buf '\n') + (range 0 length_x); + Buffer.contents buf + +let prepare_antidiagonal_str arr = + let buf = Buffer.create 1024 in + let length_x = Array.length arr.(0) in + let length_y = Array.length arr in + Seq.iter (fun x -> traverse_antidiagonal (Buffer.add_char buf) arr x 0; Buffer.add_char buf '\n') + (range 0 length_x); + Seq.iter (fun y -> traverse_antidiagonal (Buffer.add_char buf) arr (length_x - 1) y; Buffer.add_char buf '\n') + (range 1 (length_y - 1)); + Buffer.contents buf + +let is_mas_x arr x y = + if arr.(y).(x) = 'A' then + let nw = arr.(y - 1).(x - 1) in + let se = arr.(y + 1).(x + 1) in + if (nw = 'M' && se = 'S') || (nw = 'S' && se = 'M') then + let ne = arr.(y - 1).(x + 1) in + let sw = arr.(y + 1).(x - 1) in + (ne = 'M' && sw = 'S') || (ne = 'S' && sw = 'M') + else + false + else + false + +let count_mas_x arr = + let length_x = Array.length arr.(0) in + let length_y = Array.length arr in + Seq.fold_left + (fun acc y -> acc + + Seq.fold_left + (fun acc x -> acc + + if is_mas_x arr x y then 1 else 0) + 0 (range 1 (length_x - 1))) + 0 (range 1 (length_y - 1)) + +let () = + let f = open_in "input.txt" in + let arr = file_to_2d_array f in + (* Array.iter (fun x -> Array.iter print_char x; print_newline()) arr;*) + let counter = + (count_in_string @@ prepare_horizontal_str arr) + + (count_in_string @@ prepare_vertical_str arr) + + (count_in_string @@ prepare_diagonal_str arr) + + (count_in_string @@ prepare_antidiagonal_str arr) in + let counter2 = count_mas_x arr in + printf "%d\n" counter; + printf "%d\n" counter2 \ No newline at end of file diff --git a/ocaml compilation is weird.txt b/ocaml compilation is weird.txt new file mode 100644 index 0000000..3f03d70 --- /dev/null +++ b/ocaml compilation is weird.txt @@ -0,0 +1,7 @@ +Simple compilation: +ocamlc main.ml && ./camlprog +cmd /c "(ocamlc main.ml) && camlprog.exe" + +Libraries: +ocamlfind ocamlc -linkpkg -package str main.ml && ./camlprog +cmd /c "(ocamlfind ocamlc -linkpkg -package str main.ml) && camlprog.exe" \ No newline at end of file