first 4 days
This commit is contained in:
52
1/main.ml
Normal file
52
1/main.ml
Normal file
@@ -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
|
70
2/main.ml
Normal file
70
2/main.ml
Normal file
@@ -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
|
47
3/main.ml
Normal file
47
3/main.ml
Normal file
@@ -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
|
160
4/main.ml
Normal file
160
4/main.ml
Normal file
@@ -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
|
7
ocaml compilation is weird.txt
Normal file
7
ocaml compilation is weird.txt
Normal file
@@ -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"
|
Reference in New Issue
Block a user