blob: 5776e490f8c503887c98a2d6a65732db56f72996 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
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
|