Skip to content

Commit 7723744

Browse files
committed
Day 1 solutions with original utility functions
1 parent ab43e4f commit 7723744

File tree

3 files changed

+58
-47
lines changed

3 files changed

+58
-47
lines changed

bin/day1bin.ml

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
1-
let () = Printf.printf "Solving Day 1!\n"
1+
let file = "day1/input.txt"
22

3-
let line_list = Day1.lines "day1/input.txt"
3+
let () =
4+
Printf.printf "Solution for part 1 of day 1 is: %d\n"
5+
(Day1.part1_calibration_sum file)
46

5-
let x = List.fold_left (+) 0 (List.map Day1.calib_value line_list)
6-
7-
let () = Printf.printf "Part 1: sum of calibration values is: %d\n" x
8-
9-
let line_list = Day1.lines "day1/input.txt"
10-
11-
let y = List.fold_left (+) 0 (List.map Day1.find_vals line_list)
12-
13-
let () = Printf.printf "Part 2: sum of calibration values is: %d\n" y
7+
let () =
8+
Printf.printf "Solution for part 2 of day 1 is: %d\n"
9+
(Day1.part2_calibration_sum file)

day1/day1.ml

Lines changed: 49 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,21 @@
1-
(* Read the lines of the file into a string list*)
2-
let lines name = In_channel.input_lines (open_in name)
3-
let is_digit d = d >= '0' && d <= '9'
1+
(* read_lines reads each line in the file into a string list*)
2+
let read_lines file = In_channel.input_lines (In_channel.open_text file)
3+
let first_digit line = line.[Str.search_forward (Str.regexp "[0-9]") line 0]
4+
5+
let last_digit line =
6+
line.[Str.search_backward (Str.regexp "[0-9]") line (String.length line - 1)]
7+
8+
let is_digit c = Char.code c >= Char.code '0' && Char.code c <= Char.code '9'
49
let to_digit c = Char.code c - Char.code '0'
510

6-
(* First digit and last digit *)
7-
let fst_lst s =
8-
let rec first_digit s i =
9-
if is_digit s.[i] then s.[i] else first_digit s (i + 1)
11+
let part1_calibration_sum file =
12+
let calibration_value line =
13+
(10 * to_digit (first_digit line)) + to_digit (last_digit line)
1014
in
11-
let rec last_digit s i =
12-
if is_digit s.[i] then s.[i] else last_digit s (i - 1)
13-
in
14-
(first_digit s 0, last_digit s (String.length s - 1))
15-
16-
let calib_value s =
17-
let fst, lst = fst_lst s in
18-
(10 * to_digit fst) + to_digit lst
15+
let calibration_list file = List.map calibration_value (read_lines file) in
16+
List.fold_left ( + ) 0 (calibration_list file)
1917

20-
let digit_words =
18+
let word_to_digit =
2119
[
2220
("zero", 0);
2321
("one", 1);
@@ -31,26 +29,42 @@ let digit_words =
3129
("nine", 9);
3230
]
3331

34-
(* iterate through the string character by character and find the possible numbers*)
32+
let rec check_start line word_map i =
33+
match word_map with
34+
| [] -> None
35+
| h :: t ->
36+
if
37+
String.starts_with ~prefix:(fst h)
38+
(String.sub line i (String.length line - i))
39+
then Some (snd h)
40+
else check_start line t i
3541

36-
let substr s i = String.sub s i (String.length s - i)
42+
let rec check_end line word_map i =
43+
match word_map with
44+
| [] -> None
45+
| h :: t ->
46+
if String.ends_with ~suffix:(fst h) (String.sub line 0 (i + 1)) then
47+
Some (snd h)
48+
else check_end line t i
3749

38-
let string_begins_with s i =
39-
List.find_map
40-
(fun (word, value) ->
41-
if String.starts_with ~prefix:word (substr s i) then Some value else None)
42-
digit_words
50+
let rec parse_first_digit line i =
51+
if is_digit line.[i] then to_digit line.[i]
52+
else
53+
match check_start line word_to_digit i with
54+
| None -> parse_first_digit line (i + 1)
55+
| Some a -> a
4356

44-
let match_digit s i =
45-
if is_digit s.[i] then Some (to_digit s.[i]) else string_begins_with s i
57+
let rec parse_last_digit line i =
58+
if is_digit line.[i] then to_digit line.[i]
59+
else
60+
match check_end line word_to_digit i with
61+
| None -> parse_last_digit line (i - 1)
62+
| Some a -> a
4663

47-
let find_vals line =
48-
let rec first i =
49-
match match_digit line i with Some digit -> digit | None -> first (i + 1)
50-
in
51-
let rec last i =
52-
match match_digit line i with Some digit -> digit | None -> last (i - 1)
53-
in
54-
let first_digit = first 0 in
55-
let last_digit = last (String.length line - 1) in
56-
(first_digit * 10) + last_digit
64+
let vals line =
65+
(parse_first_digit line 0, parse_last_digit line (String.length line - 1))
66+
67+
let part2_calibration_sum file =
68+
let calibration_value line = (10 * fst (vals line)) + snd (vals line) in
69+
let calibration_list file = List.map calibration_value (read_lines file) in
70+
List.fold_left ( + ) 0 (calibration_list file)

day1/dune

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
(library
2-
(name day1))
2+
(name day1)
3+
(libraries str))

0 commit comments

Comments
 (0)