86 lines
2.5 KiB
D
86 lines
2.5 KiB
D
|
import std.stdio;
|
||
|
import std.file;
|
||
|
import std.string;
|
||
|
import std.algorithm;
|
||
|
import std.array;
|
||
|
import std.ascii : isDigit;
|
||
|
import std.conv;
|
||
|
|
||
|
struct Point {const int x, y;}
|
||
|
|
||
|
char getChar(ref char[][] array, int x, int y) {
|
||
|
if (y >= 0 && y < array.length && x >= 0 && x < array[y].length) return array[y][x];
|
||
|
return '.';
|
||
|
}
|
||
|
|
||
|
void part1() {
|
||
|
char[][] schematic = File("input.txt").byLineCopy()
|
||
|
.map!(line => cast(char[])line)
|
||
|
.array();
|
||
|
|
||
|
bool hasAdjacentSymbol(int x, int y, int length) {
|
||
|
for (int i = y-1; i < y+2; i++) {
|
||
|
for (int j = x-1; j < x+length+1; j++) {
|
||
|
const char c = getChar(schematic, j, i);
|
||
|
if (c != '.' && !isDigit(c)) return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
int sum = 0;
|
||
|
for (int y = 0; y < schematic.length; y++) {
|
||
|
for (int x = 0; x < schematic[y].length; x++) {
|
||
|
if (isDigit(schematic[y][x])) {
|
||
|
int length = 1;
|
||
|
while (x + length < schematic[y].length && isDigit(schematic[y][x+length])) length++;
|
||
|
if (hasAdjacentSymbol(x, y, length)) {
|
||
|
int n = schematic[y][x..x+length].to!int;
|
||
|
sum += n;
|
||
|
}
|
||
|
x += length;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
writeln(sum);
|
||
|
}
|
||
|
|
||
|
void part2() {
|
||
|
char[][] schematic = File("input.txt").byLineCopy()
|
||
|
.map!(line => cast(char[])line)
|
||
|
.array();
|
||
|
|
||
|
Point[] findGears(int x, int y, int length) {
|
||
|
Point[] gears;
|
||
|
for (int i = y-1; i < y+2; i++) {
|
||
|
for (int j = x-1; j < x+length+1; j++) {
|
||
|
if (getChar(schematic, j, i) == '*') gears ~= Point(j, i);
|
||
|
}
|
||
|
}
|
||
|
return gears;
|
||
|
}
|
||
|
|
||
|
int[][Point] gearNumbers;
|
||
|
for (int y = 0; y < schematic.length; y++) {
|
||
|
for (int x = 0; x < schematic[y].length; x++) {
|
||
|
if (isDigit(schematic[y][x])) {
|
||
|
int length = 1;
|
||
|
while (x + length < schematic[y].length && isDigit(schematic[y][x+length])) length++;
|
||
|
int n = schematic[y][x..x+length].to!int;
|
||
|
Point[] gears = findGears(x, y, length);
|
||
|
foreach (Point gear; gears) {
|
||
|
if (gear !in gearNumbers) gearNumbers[gear] = [];
|
||
|
gearNumbers[gear] ~= n;
|
||
|
}
|
||
|
x += length;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
gearNumbers.values.map!(a => a.length == 2 ? a[0] * a[1] : 0).sum.writeln();
|
||
|
}
|
||
|
|
||
|
void main() {
|
||
|
part1();
|
||
|
part2();
|
||
|
}
|