summaryrefslogtreecommitdiff
path: root/ocaml/test/year2024/day04
diff options
context:
space:
mode:
authorDJ O'Leary <dijitol@proton.me>2026-06-27 04:28:48 +0200
committerDJ O'Leary <dijitol@proton.me>2026-06-27 04:28:48 +0200
commitbc8b9edc0860f4804dfd0ea868ee7beaa564e62a (patch)
treee1123d11627b4829586da3b097015b1dbb3d0285 /ocaml/test/year2024/day04
parent976048a85403fbb0751c34fa42703a3c47f6e918 (diff)
test: fix ocaml tests 2024 {WIP}HEADmain
Diffstat (limited to 'ocaml/test/year2024/day04')
-rw-r--r--ocaml/test/year2024/day04/dune10
-rw-r--r--ocaml/test/year2024/day04/test_part01.ml141
2 files changed, 151 insertions, 0 deletions
diff --git a/ocaml/test/year2024/day04/dune b/ocaml/test/year2024/day04/dune
new file mode 100644
index 0000000..c4a75c4
--- /dev/null
+++ b/ocaml/test/year2024/day04/dune
@@ -0,0 +1,10 @@
+(tests
+ (names
+ test_part01)
+ (libraries
+ year2024
+ alcotest
+ qcheck-core
+ qcheck-alcotest)
+ (action (run %{test} -e))
+ (modes byte exe))
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