summaryrefslogtreecommitdiff
path: root/2024/OCaml/test/day_04_part_01.ml
diff options
context:
space:
mode:
Diffstat (limited to '2024/OCaml/test/day_04_part_01.ml')
-rw-r--r--2024/OCaml/test/day_04_part_01.ml141
1 files changed, 141 insertions, 0 deletions
diff --git a/2024/OCaml/test/day_04_part_01.ml b/2024/OCaml/test/day_04_part_01.ml
new file mode 100644
index 0000000..9f43df0
--- /dev/null
+++ b/2024/OCaml/test/day_04_part_01.ml
@@ -0,0 +1,141 @@
+open OUnit2
+open AoC_2024.Day_04.Part_01
+
+let example_input =
+ [
+ "MMMSXXMASM";
+ "MSAMXMSMSA";
+ "AMXSXMAAMM";
+ "MSAMASMSMX";
+ "XMASAMXAMM";
+ "XXAMMXXAMA";
+ "SMSMSASXSS";
+ "SAXAMASAAA";
+ "MAMMMXMMMM";
+ "MXMXAXMASX";
+ ]
+
+let is_in_bounds_tests =
+ let test_is_in_bounds expected length index _ =
+ let actual = is_in_bounds length index in
+ assert_equal ~printer:string_of_bool expected actual
+ in
+ [
+ "not in bounds if below 0" >:: test_is_in_bounds false 1 (-1);
+ "in bounds if gte 0 and lt length" >:: test_is_in_bounds true 1 0;
+ "not in bounds if eq length" >:: test_is_in_bounds false 1 1;
+ "not in bounds if gt length" >:: test_is_in_bounds false 1 2;
+ ]
+
+let calculate_num_of_matches_tests =
+ let test_calculate_num_of_matches expected line row_offset character _ =
+ let actual = calculate_num_of_matches line row_offset character in
+ assert_equal ~printer:string_of_int expected actual
+ in
+ [
+ "is 0 when no matches present"
+ >:: test_calculate_num_of_matches 0 "SMMX" 1 { index = 3; character = 'X' };
+ "is 1 when only one match present - top to bottom"
+ >:: (*
+ |.|X|.|
+ |.|M|.|
+ |.|A|.|
+ |.|S|.|
+ *)
+ test_calculate_num_of_matches 1 ".X..M..A..S." 3
+ { index = 1; character = 'X' };
+ "is 1 when only one match present - top to bottom edge"
+ >:: (*
+ |X|.|.|
+ |M|.|.|
+ |A|.|.|
+ |S|.|.|
+ *)
+ test_calculate_num_of_matches 1 "X..M..A..S.." 3
+ { index = 0; character = 'X' };
+ "is 1 when only one match present - bottom to top"
+ >:: (*
+ |.|S|.|
+ |.|A|.|
+ |.|M|.|
+ |.|X|.|
+ *)
+ test_calculate_num_of_matches 1 ".S..A..M..X." 3
+ { index = 10; character = 'X' };
+ "is 1 when only one match present - left to right"
+ >:: (*
+ |X|M|A|S|
+ *)
+ test_calculate_num_of_matches 1 "XMAS" 4 { index = 0; character = 'X' };
+ "is 1 when only one match present - right to left"
+ >:: (*
+ |S|A|M|X|
+ *)
+ test_calculate_num_of_matches 1 "SAMX" 4 { index = 3; character = 'X' };
+ "is 1 when only one match present - bottom right to top left"
+ >:: (*
+ |S|.|.|.|
+ |.|A|.|.|
+ |.|.|M|.|
+ |.|.|.|X|
+ *)
+ test_calculate_num_of_matches 1 "S....A....M....X" 4
+ { index = 15; character = 'X' };
+ "is 1 when only one match present - top left to bottom right"
+ >:: (*
+ |X|.|.|.|
+ |.|M|.|.|
+ |.|.|A|.|
+ |.|.|.|S|
+ *)
+ test_calculate_num_of_matches 1 "X....M....A....S" 4
+ { index = 0; character = 'X' };
+ "is 1 when only one match present - bottom left to top right"
+ >:: (*
+ |.|.|.|S|
+ |.|.|A|.|
+ |.|M|.|.|
+ |X|.|.|.|
+ *)
+ test_calculate_num_of_matches 1 "...S..A..M..X..." 4
+ { index = 12; character = 'X' };
+ "is 1 when only one match present - top right to bottom left"
+ >:: (*
+ |.|.|.|X|
+ |.|.|M|.|
+ |.|A|.|.|
+ |S|.|.|.|
+ *)
+ test_calculate_num_of_matches 1 "...X..M..A..S..." 4
+ { index = 3; character = 'X' };
+ "is 8 when matches present in all possible directions"
+ >:: (*
+ |S|.|.|S|.|.|S|
+ |.|A|.|A|.|A|.|
+ |.|.|M|M|M|.|.|
+ |S|A|M|X|M|A|S|
+ |.|.|M|M|M|.|.|
+ |.|A|.|A|.|A|.|
+ |S|.|.|S|.|.|S|
+ *)
+ test_calculate_num_of_matches 8
+ "S..S..S.A.A.A...MMM..SAMXMAS..MMM...A.A.A.S..S..S" 7
+ { index = 24; character = 'X' };
+ ]
+
+let solve_tests =
+ let test_solve expected lines _ =
+ let actual = solve lines in
+ assert_equal ~printer:string_of_int expected actual
+ in
+ [
+ "example is solved correctly" >:: test_solve 18 example_input;
+ "minimal example is solved correctly"
+ >:: test_solve 4 [ "..X..."; ".SAMX."; ".A..A."; "XMAS.S"; ".X...." ];
+ ]
+
+let tests =
+ "test suite for day 4 part 1"
+ >::: is_in_bounds_tests @ calculate_num_of_matches_tests @ solve_tests
+
+let _ = run_test_tt_main tests