Skip to content

Commit dc1d511

Browse files
committed
Add day 2 solution
1 parent c6aedfa commit dc1d511

1 file changed

Lines changed: 91 additions & 0 deletions

File tree

ts/index.ts

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,97 @@ const daySolvers: { [key: string]: DaySolver } = {
9191
console.log(`Part 1: Number of times position 0 was reached: ${zeroCount1}`);
9292
console.log(`Part 2: Number of times position 0 was crossed: ${zeroCount2}`);
9393
},
94+
'02': (input: DayInput) => {
95+
const ranges = input.trim().split(',');
96+
const invalidNumbers: number[] = [];
97+
const part2InvalidNumbers: number[] = [];
98+
99+
function isNumberInvalid(num: number): boolean {
100+
const strNum = num.toString();
101+
102+
// Odd length numbers can't be invalid based on the criteria.
103+
if (strNum.length % 2 === 1) {
104+
return false;
105+
}
106+
107+
const start = strNum.slice(0, strNum.length / 2);
108+
const end = strNum.slice(strNum.length / 2);
109+
110+
return start === end;
111+
}
112+
113+
function isNumberInvalidPart2(num: number): boolean {
114+
const strNum = num.toString();
115+
const strNumLength = strNum.length;
116+
let isInvalid = false;
117+
118+
// The maximum split point is half the length of the number.
119+
const maxSplitPoint = Math.floor(strNumLength / 2);
120+
const splitPoints = new Set<number>(
121+
Array.from(
122+
{length: maxSplitPoint},
123+
(_, i) => i + 1
124+
)
125+
);
126+
127+
// console.log(`Checking number: ${num} with split points: ${Array.from(splitPoints).join(', ')}`);
128+
129+
splitPoints.forEach((splitLength) => {
130+
// If we already found the number to be invalid, skip further checks.
131+
if (isInvalid) {
132+
return;
133+
}
134+
135+
// If the split point doesn't divide the number evenly, skip it.
136+
if (strNumLength % splitLength !== 0) {
137+
return;
138+
}
139+
140+
const numPieces: number = strNumLength / splitLength;
141+
142+
// Split the number into pieces of the current split length.
143+
const pieces: string[] = [];
144+
145+
/*
146+
* We need to slice the string into pieces of 'splitLength' size.
147+
* For example, if strNum is "121212" and splitLength is 2,
148+
* we want to get ["12", "12", "12"].
149+
*/
150+
for (let i = 0; i < numPieces; i++) {
151+
const start = i * splitLength;
152+
const end = start + splitLength;
153+
pieces.push(strNum.slice(start, end));
154+
}
155+
156+
debugLog(`Number ${num} split into pieces of length ${splitLength}: ${pieces.join(', ')}`);
157+
isInvalid = pieces.every((piece) => piece == pieces[0]);
158+
if (isInvalid) {
159+
debugLog(`Number ${num} is invalid with split length ${splitLength} (pieces: ${pieces.join(', ')})`);
160+
return;
161+
}
162+
});
163+
164+
return isInvalid;
165+
}
166+
167+
ranges.forEach((range) => {
168+
const [start, end] = range.split('-').map(Number);
169+
for (let i = start; i <= end; i++) {
170+
if (isNumberInvalid(i)) {
171+
invalidNumbers.push(i);
172+
}
173+
174+
if (isNumberInvalidPart2(i)) {
175+
part2InvalidNumbers.push(i);
176+
}
177+
}
178+
});
179+
180+
debugLog(`Part 2 invalid numbers: ${part2InvalidNumbers.join(', ')}`);
181+
182+
console.log(`Part 1: Sum of invalid numbers: ${invalidNumbers.reduce((a, b) => a + b, 0)}`);
183+
console.log(`Part 2: Sum of invalid numbers (advanced criteria): ${part2InvalidNumbers.reduce((a, b) => a + b, 0)}`);
184+
},
94185
};
95186

96187
// Set up the CLI program.

0 commit comments

Comments
 (0)