diff options
| author | DJ O'Leary <dijitol@proton.me> | 2025-11-29 20:23:02 +0100 |
|---|---|---|
| committer | DJ O'Leary <dijitol@proton.me> | 2025-11-29 20:23:02 +0100 |
| commit | 4c3a50166bf0f78ce89459c352cc1c6536a8b96d (patch) | |
| tree | 02e4b66a1435680ef1e92bf82576747b27f16447 /2024/ocaml/test | |
| parent | be2f8528b3829f8263507da301812d852297c168 (diff) | |
chore: make language folders snake_case
Diffstat (limited to '2024/ocaml/test')
| -rw-r--r-- | 2024/ocaml/test/day_01_part_01.ml | 27 | ||||
| -rw-r--r-- | 2024/ocaml/test/day_01_part_02.ml | 17 | ||||
| -rw-r--r-- | 2024/ocaml/test/day_02_part_01.ml | 38 | ||||
| -rw-r--r-- | 2024/ocaml/test/day_03_part_01.ml | 29 | ||||
| -rw-r--r-- | 2024/ocaml/test/day_04_part_01.ml | 151 | ||||
| -rw-r--r-- | 2024/ocaml/test/day_05_part_01.ml | 4 | ||||
| -rw-r--r-- | 2024/ocaml/test/dune | 10 | ||||
| -rw-r--r-- | 2024/ocaml/test/grid.ml | 5 |
8 files changed, 281 insertions, 0 deletions
diff --git a/2024/ocaml/test/day_01_part_01.ml b/2024/ocaml/test/day_01_part_01.ml new file mode 100644 index 0000000..824c95b --- /dev/null +++ b/2024/ocaml/test/day_01_part_01.ml @@ -0,0 +1,27 @@ +open OUnit2 +open AoC_2024.Day_01.Part_01 + +let tests = + "test suite for day 01 part 01" + >::: [ + ("empty list is 0" >:: fun _ -> assert_equal 0 (solve [] [])); + ( "distance between 0 and 1 is 1" >:: fun _ -> + assert_equal 1 (solve [ 0 ] [ 1 ]) ); + ( "distance between 1 and 0 is 1" >:: fun _ -> + assert_equal 1 (solve [ 1 ] [ 0 ]) ); + ( "smallest are paired, then next smallest, ..." >:: fun _ -> + assert_equal 0 (solve [ 1; 2; 3 ] [ 3; 2; 1 ]) ); + (* See https://adventofcode.com/2024/day/1 *) + ( "solves example correctly" >:: fun _ -> + assert_equal 11 (solve [ 3; 4; 2; 1; 3; 3 ] [ 4; 3; 5; 3; 9; 3 ]) ); + ( "same number is 0 distance apart" >:: fun _ -> + assert_equal 0 (calculate_distance 0 0) ); + ( "same number is 0 distance apart" >:: fun _ -> + assert_equal 0 (calculate_distance 1 1) ); + ( "distance is equal to abs(x - y)" >:: fun _ -> + assert_equal 1 (calculate_distance 0 1) ); + ( "order of inputs doesn't matter" >:: fun _ -> + assert_equal 1 (calculate_distance 1 0) ); + ] + +let _ = run_test_tt_main tests diff --git a/2024/ocaml/test/day_01_part_02.ml b/2024/ocaml/test/day_01_part_02.ml new file mode 100644 index 0000000..f7340df --- /dev/null +++ b/2024/ocaml/test/day_01_part_02.ml @@ -0,0 +1,17 @@ +open OUnit2 +open AoC_2024.Day_01.Part_02 + +let test_solve = + "test suite for day 01 part 02" + >::: [ + ("empty list is 0" >:: fun _ -> assert_equal 0 (solve [] [])); + ( "ten x zero occurrances of ten" >:: fun _ -> + assert_equal 0 (solve [ 10 ] [ 1; 2; 3 ]) ); + ( "two x three occurrances of two" >:: fun _ -> + assert_equal 6 (solve [ 2 ] [ 2; 2; 2 ]) ); + (* See https://adventofcode.com/2024/day/1#part2 *) + ( "solves example correctly" >:: fun _ -> + assert_equal 31 (solve [ 3; 4; 2; 1; 3; 3 ] [ 4; 3; 5; 3; 9; 3 ]) ); + ] + +let _ = run_test_tt_main test_solve diff --git a/2024/ocaml/test/day_02_part_01.ml b/2024/ocaml/test/day_02_part_01.ml new file mode 100644 index 0000000..36af248 --- /dev/null +++ b/2024/ocaml/test/day_02_part_01.ml @@ -0,0 +1,38 @@ +open OUnit2 +open AoC_2024.Day_02.Part_01 + +let tests = + "test suite for day 2 part 1" + >::: [ + ( "empty list should have no valid reports" >:: fun _ -> + assert_equal 0 (solve []) ); + ( "valid report should count as one" >:: fun _ -> + assert_equal 1 (solve [ [ 7; 6; 4; 2; 1 ] ]) ); + ( "example correct" >:: fun _ -> + assert_equal 2 + (solve + [ + [ 7; 6; 4; 2; 1 ]; + [ 1; 2; 7; 8; 9 ]; + [ 9; 7; 6; 2; 1 ]; + [ 1; 3; 2; 4; 5 ]; + [ 8; 6; 4; 4; 1 ]; + [ 1; 3; 6; 7; 9 ]; + ]) ); + ( "all increasing" >:: fun _ -> + assert_equal true (check_report_safety [ 1; 2; 3 ]) ); + ( "all decreasing" >:: fun _ -> + assert_equal true (check_report_safety [ 3; 2; 1 ]) ); + ( "increasing and decreasing" >:: fun _ -> + assert_equal false (check_report_safety [ 1; 3; 2 ]) ); + ( "change of at least one" >:: fun _ -> + assert_equal true (check_report_safety [ 1; 2; 3 ]) ); + ( "no change" >:: fun _ -> + assert_equal false (check_report_safety [ 1; 1; 2 ]) ); + ( "change of at most three" >:: fun _ -> + assert_equal true (check_report_safety [ 1; 2; 4; 7 ]) ); + ( "change of at more than three" >:: fun _ -> + assert_equal false (check_report_safety [ 1; 5 ]) ); + ] + +let _ = run_test_tt_main tests diff --git a/2024/ocaml/test/day_03_part_01.ml b/2024/ocaml/test/day_03_part_01.ml new file mode 100644 index 0000000..0db039a --- /dev/null +++ b/2024/ocaml/test/day_03_part_01.ml @@ -0,0 +1,29 @@ +open OUnit2 +open AoC_2024.Day_03.Part_01 + +let example_input = + "xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))" + +let test_find_mul _ = + assert_equal + [ "mul(2,4)"; "mul(5,5)"; "mul(11,8)"; "mul(8,5)" ] + (let result = find_mul example_input in + List.map (fun x -> Re2.Match.get_exn x ~sub:(`Index 0)) result) + +let test_extract_pairs _ = + assert_equal + [ (2, 4); (5, 5); (11, 8); (8, 5) ] + (let matches = find_mul example_input in + extract_pairs matches) + +let test_solve _ = assert_equal ~printer:string_of_int 161 (solve example_input) + +let tests = + "test suite for day 3 part 1" + >::: [ + "muls extracted from example correctly" >:: test_find_mul; + "pairs extracted from matches" >:: test_extract_pairs; + "example correctly solved" >:: test_solve; + ] + +let _ = run_test_tt_main tests 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..9550e5b --- /dev/null +++ b/2024/ocaml/test/day_04_part_01.ml @@ -0,0 +1,151 @@ +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 diff --git a/2024/ocaml/test/day_05_part_01.ml b/2024/ocaml/test/day_05_part_01.ml new file mode 100644 index 0000000..0f50476 --- /dev/null +++ b/2024/ocaml/test/day_05_part_01.ml @@ -0,0 +1,4 @@ +open OUnit2 + +let tests = "test suite for day n part 1" >::: [] +let _ = run_test_tt_main tests diff --git a/2024/ocaml/test/dune b/2024/ocaml/test/dune new file mode 100644 index 0000000..e19cbe9 --- /dev/null +++ b/2024/ocaml/test/dune @@ -0,0 +1,10 @@ +(tests + (names + day_01_part_01 + day_01_part_02 + day_02_part_01 + day_03_part_01 + day_04_part_01 + grid) + (modes byte exe) + (libraries AoC_2024 ounit2)) diff --git a/2024/ocaml/test/grid.ml b/2024/ocaml/test/grid.ml new file mode 100644 index 0000000..bd384cd --- /dev/null +++ b/2024/ocaml/test/grid.ml @@ -0,0 +1,5 @@ +open OUnit2 +open AoC_2024.Grid + +let tests = "" >::: [] +let _ = run_test_tt_main tests |
