AdventOfCode2023/day_1/solution.d

50 lines
1.4 KiB
D
Raw Permalink Normal View History

2023-12-01 14:52:16 +00:00
module day_1.solution;
import std.file;
import std.string : splitLines;
import std.algorithm;
import std.stdio;
import std.uni : isNumber;
2023-12-01 15:21:40 +00:00
import std.functional;
/// Parses the first and last digits, using a function F to determine if and
/// what digit is at a string at a particular index. F should return -1 if no
/// digit exists.
int parseDigits(int delegate(string, size_t) F)(string s) {
int a = -1, b = -1;
for (size_t i = 0; i < s.length; i++) {
int an = F(s, i);
int bn = F(s, s.length-i-1);
if (a == -1 && an != -1) a = an;
if (b == -1 && bn != -1) b = bn;
if (a != -1 && b != -1) break;
}
return a * 10 + b;
}
2023-12-01 14:52:16 +00:00
void part1() {
2023-12-01 15:21:40 +00:00
readText("part_1_input.txt").splitLines()
.map!(line => parseDigits!((s, i) => isNumber(s[i]) ? s[i] - '0' : -1)(line))
.sum().writeln();
2023-12-01 14:52:16 +00:00
}
void part2() {
int findDigit(string s, size_t idx) {
if (isNumber(s[idx])) return s[idx] - '0';
const string[] words = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine"];
static foreach (size_t i, string word; words) {
2023-12-01 15:21:40 +00:00
if (s.length - idx >= word.length && s[idx .. idx + word.length] == word) return cast(int) i + 1;
2023-12-01 14:52:16 +00:00
}
return -1;
}
2023-12-01 15:21:40 +00:00
readText("part_2_input.txt").splitLines()
.map!(line => parseDigits!((s, i) => findDigit(s, i))(line))
.sum().writeln();
2023-12-01 14:52:16 +00:00
}
void main() {
part1();
part2();
}