diff options
Diffstat (limited to 'ocaml/test/year2024/day04/test_part01.ml')
| -rw-r--r-- | ocaml/test/year2024/day04/test_part01.ml | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/ocaml/test/year2024/day04/test_part01.ml b/ocaml/test/year2024/day04/test_part01.ml new file mode 100644 index 0000000..5776e49 --- /dev/null +++ b/ocaml/test/year2024/day04/test_part01.ml @@ -0,0 +1,141 @@ +open Year2024.Day04.Part01 + +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 have want () = + let actual = solve have in + Alcotest.(check int) "incorrect solution" want actual + in + [ ( "test solution" + , [ Alcotest.test_case "example is solved correctly" `Quick + @@ test_solve example_input 18 + ; Alcotest.test_case "minimal example is solved correctly" `Quick + @@ test_solve ["..X..."; ".SAMX."; ".A..A."; "XMAS.S"; ".X...."] 4 ] ) + ] + +let () = + let open Alcotest in + run "test suite for day 4 part 1" is_in_bounds_tests + @ calculate_num_of_matches_tests @ solve_tests |
