Day Three completed
This commit is contained in:
parent
14a89267fe
commit
a29299ede8
@ -20,4 +20,8 @@ describe('Day Three', () => {
|
|||||||
const engine = Engine.create(schematic);
|
const engine = Engine.create(schematic);
|
||||||
expect(engine.sumPartNumbers()).toEqual(4361);
|
expect(engine.sumPartNumbers()).toEqual(4361);
|
||||||
});
|
});
|
||||||
|
it('should give the sum of the gear ratios', () => {
|
||||||
|
const engine = Engine.create(schematic, true);
|
||||||
|
expect(engine.gearRatioSums()).toEqual(467835);
|
||||||
|
});
|
||||||
});
|
});
|
105
src/day_three.ts
105
src/day_three.ts
@ -1,75 +1,90 @@
|
|||||||
import { takeWhile } from 'lodash';
|
import { takeWhile } from 'lodash';
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import {calculateMinimumCubePowers, calculatePossibleGames, parseGame} from "./day_two";
|
import {matchAllAndThen} from "./utils";
|
||||||
|
|
||||||
export class Engine {
|
export class Engine {
|
||||||
constructor(private readonly partNumbers: number[]) {
|
constructor(private readonly parts: number[][], private readonly schematic: string[][]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static create(input: string): Engine {
|
public static create(input: string, gearsOnly: boolean = false): Engine {
|
||||||
const lines = input.split('\n').filter(Boolean);
|
const lines = input.split('\n').filter(Boolean);
|
||||||
const partRegex = /\d+/g;
|
const partRegex = /\d+/g;
|
||||||
const symbolRegex = /[^a-zA-Z\d\.]/g;
|
const symbolRegex = gearsOnly ? /\*/g : /[^a-zA-Z\d\.]/g;
|
||||||
|
|
||||||
const parts : number[][] = new Array(lines.length).fill(0).map(() => new Array(lines[0].length));
|
const parts : number[][] = new Array(lines.length).fill(0).map(() => new Array(lines[0].length));
|
||||||
const symbols: string[][] = new Array(lines.length).fill(0).map(() => new Array(lines[0].length));
|
const symbols: string[][] = new Array(lines.length).fill(0).map(() => new Array(lines[0].length));
|
||||||
|
|
||||||
lines.forEach((line, lineNumber) => {
|
lines.forEach((line, lineNumber) => {
|
||||||
const matches = [...line.matchAll(partRegex)];
|
matchAllAndThen(line, partRegex, (match, index) => {
|
||||||
matches.map(match => {
|
const parsedNumber = parseInt(match, 10);
|
||||||
if (match && match.index !== undefined) {
|
for (let i = index; i < index + match.length; i++) {
|
||||||
const parsedNumber = parseInt(match[0], 10);
|
parts[lineNumber][i] = parsedNumber;
|
||||||
for (let i = match.index; i < match.index + match[0].length; i++) {
|
|
||||||
parts[lineNumber][i] = parsedNumber;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
lines.forEach((line, lineNumber) => {
|
lines.forEach((line, lineNumber) => {
|
||||||
const matches = [...line.matchAll(symbolRegex)];
|
matchAllAndThen(line, symbolRegex, (match, index) => symbols[lineNumber][index] = match);
|
||||||
|
|
||||||
matches.map(match => {
|
|
||||||
if (match && match.index !== undefined) {
|
|
||||||
symbols[lineNumber][match.index] = match[0];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
console.log(symbols.length, parts.length)
|
|
||||||
|
|
||||||
const partsList = symbols.flatMap((row, rowIndex) =>
|
return new Engine(parts, symbols);
|
||||||
row.map((symbol, index) => {
|
|
||||||
if (!symbol) return symbol;
|
|
||||||
|
|
||||||
const partIndex = [
|
|
||||||
[rowIndex - 1, index - 1],
|
|
||||||
[rowIndex - 1, index],
|
|
||||||
[rowIndex - 1, index + 1],
|
|
||||||
[rowIndex, index - 1],
|
|
||||||
[rowIndex, index + 1],
|
|
||||||
[rowIndex + 1, index - 1],
|
|
||||||
[rowIndex + 1, index],
|
|
||||||
[rowIndex + 1, index + 1]
|
|
||||||
];
|
|
||||||
return Array.from(new Set(partIndex.filter(([rowNum, col]) => rowNum >= 0 && rowNum <= symbols.length && index >= 0 && index <= row.length)
|
|
||||||
.map(([rowNum, column]) => {
|
|
||||||
return parts[rowNum][column]
|
|
||||||
}).filter(Boolean)))
|
|
||||||
.reduce((total, val) => total + val,0);
|
|
||||||
})
|
|
||||||
)
|
|
||||||
|
|
||||||
return new Engine(partsList as number[]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public sumPartNumbers(): number {
|
public sumPartNumbers(): number {
|
||||||
return this.partNumbers.reduce((total, partNumber) => total + partNumber, 0);
|
const partsList = this.schematic.flatMap((row, rowIndex) =>
|
||||||
|
row.map((symbol, index) => {
|
||||||
|
if (!symbol) return symbol;
|
||||||
|
|
||||||
|
const partIndex = [
|
||||||
|
[rowIndex - 1, index - 1],
|
||||||
|
[rowIndex - 1, index],
|
||||||
|
[rowIndex - 1, index + 1],
|
||||||
|
[rowIndex, index - 1],
|
||||||
|
[rowIndex, index + 1],
|
||||||
|
[rowIndex + 1, index - 1],
|
||||||
|
[rowIndex + 1, index],
|
||||||
|
[rowIndex + 1, index + 1]
|
||||||
|
];
|
||||||
|
return Array.from(new Set(partIndex.filter(([rowNum, col]) => rowNum >= 0 && rowNum <= this.schematic.length && index >= 0 && index <= row.length)
|
||||||
|
.map(([rowNum, column]) => {
|
||||||
|
return this.parts[rowNum][column]
|
||||||
|
}).filter(Boolean)))
|
||||||
|
.reduce((total, val) => total + val,0);
|
||||||
|
})
|
||||||
|
) as number[];
|
||||||
|
return partsList.reduce((total, partNumber) => total + partNumber, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public gearRatioSums(): number {
|
||||||
|
return this.schematic.flatMap((row, rowIndex) =>
|
||||||
|
row
|
||||||
|
.map((symbol, index) => {
|
||||||
|
const partIndex = [
|
||||||
|
[rowIndex - 1, index - 1],
|
||||||
|
[rowIndex - 1, index],
|
||||||
|
[rowIndex - 1, index + 1],
|
||||||
|
[rowIndex, index - 1],
|
||||||
|
[rowIndex, index + 1],
|
||||||
|
[rowIndex + 1, index - 1],
|
||||||
|
[rowIndex + 1, index],
|
||||||
|
[rowIndex + 1, index + 1]
|
||||||
|
];
|
||||||
|
return Array.from(new Set(partIndex.filter(([rowNum, col]) => rowNum >= 0 && rowNum <= this.schematic.length && index >= 0 && index <= row.length)
|
||||||
|
.map(([rowNum, column]) => {
|
||||||
|
return this.parts[rowNum][column]
|
||||||
|
}).filter(Boolean)))
|
||||||
|
})
|
||||||
|
).filter(list => list.length === 2)
|
||||||
|
.reduce((total, [a, b]) => {
|
||||||
|
return total + (a * b)
|
||||||
|
}, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const runDayThree = () => {
|
export const runDayThree = () => {
|
||||||
const input = fs.readFileSync('./inputs/day_three_input.txt', 'utf8');
|
const input = fs.readFileSync('./inputs/day_three_input.txt', 'utf8');
|
||||||
const engine = Engine.create(input)
|
|
||||||
|
|
||||||
console.log(engine.sumPartNumbers());
|
console.log(Engine.create(input).sumPartNumbers())
|
||||||
|
console.log(Engine.create(input, true).gearRatioSums())
|
||||||
|
|
||||||
}
|
}
|
7
src/utils.ts
Normal file
7
src/utils.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export const matchAllAndThen = (input: string, pattern: RegExp, callback: (value: string, index: number) => void) => {
|
||||||
|
[...input.matchAll(pattern)].map(match => {
|
||||||
|
if (match && match.index !== undefined) {
|
||||||
|
callback(match[0], match.index);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user