From af25d54fc23b85431a0441f89a7f0e479bf86d5a Mon Sep 17 00:00:00 2001 From: AlexAegis Date: Sat, 2 Dec 2023 07:47:17 +0100 Subject: [PATCH] feat: cleaned up the 2023 day 1 task --- solutions/typescript/2023/01/readme.md | 2 +- solutions/typescript/2023/01/src/p1.spec.ts | 4 +- solutions/typescript/2023/01/src/p1.ts | 42 +++++--- solutions/typescript/2023/01/src/p2.spec.ts | 11 ++- solutions/typescript/2023/01/src/p2.ts | 97 ++++++++++--------- .../libs/lib/src/string/string.polyfill.ts | 4 +- solutions/typescript/readme.md | 2 +- 7 files changed, 93 insertions(+), 69 deletions(-) diff --git a/solutions/typescript/2023/01/readme.md b/solutions/typescript/2023/01/readme.md index 90ad43ee0..b77faf8b0 100644 --- a/solutions/typescript/2023/01/readme.md +++ b/solutions/typescript/2023/01/readme.md @@ -1,4 +1,4 @@ -# [Day 1: -](https://adventofcode.com/2023/day/1) +# [Day 1: Trebuchet?!](https://adventofcode.com/2023/day/1) ## [Part One](https://adventofcode.com/2023/day/1#part1) diff --git a/solutions/typescript/2023/01/src/p1.spec.ts b/solutions/typescript/2023/01/src/p1.spec.ts index adaebe3be..f116999b2 100644 --- a/solutions/typescript/2023/01/src/p1.spec.ts +++ b/solutions/typescript/2023/01/src/p1.spec.ts @@ -7,14 +7,14 @@ describe('2023 01 p1', () => { describe('the input', () => { it('should solve the input', async () => { const resources = await loadTaskResources(packageJson.aoc); - expect(p1(resources.input)).toEqual(0); + expect(p1(resources.input)).toEqual(54_644); }); }); describe('example 1', () => { it('should be solved', async () => { const resources = await loadTaskResources(packageJson.aoc, 'example.1.txt'); - expect(p1(resources.input)).toEqual(0); + expect(p1(resources.input)).toEqual(142); }); }); }); diff --git a/solutions/typescript/2023/01/src/p1.ts b/solutions/typescript/2023/01/src/p1.ts index 2e8eafd35..dec93f35e 100644 --- a/solutions/typescript/2023/01/src/p1.ts +++ b/solutions/typescript/2023/01/src/p1.ts @@ -1,23 +1,33 @@ -import { NEWLINE, task } from '@alexaegis/advent-of-code-lib'; +import { task } from '@alexaegis/advent-of-code-lib'; import packageJson from '../package.json'; export const p1 = (input: string): number => { return input - .split(NEWLINE) - .map((group) => { - const f = group - .chars() - .find((l) => /\d/.test(l)) - ?.toInt() - .toString(); - const l = group - .chars() - .reverse() - .find((l) => /\d/.test(l)) - ?.toInt() - .toString(); - return f && l ? (f + l).toInt() : 0; + .lines(false) + .map((line) => { + let firstDigit: string | undefined; + let lastDigit: string | undefined; + for (let i = 0; i < line.length; i++) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const maybeFirstDigit = line[i]!; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const maybeLastDigit = line[line.length - i - 1]!; + + if (firstDigit === undefined && /\d/.test(maybeFirstDigit)) { + firstDigit = maybeFirstDigit; + } + + if (lastDigit === undefined && /\d/.test(maybeLastDigit)) { + lastDigit = maybeLastDigit; + } + + if (firstDigit !== undefined && lastDigit !== undefined) { + break; + } + } + + return ((firstDigit ?? '') + (lastDigit ?? '')).toInt(); }) .sum(); }; -await task(p1, packageJson.aoc); // 54644 ~?ms +await task(p1, packageJson.aoc); // 54644 ~0.19ms diff --git a/solutions/typescript/2023/01/src/p2.spec.ts b/solutions/typescript/2023/01/src/p2.spec.ts index 08ef7e01b..2d98ba72a 100644 --- a/solutions/typescript/2023/01/src/p2.spec.ts +++ b/solutions/typescript/2023/01/src/p2.spec.ts @@ -7,14 +7,21 @@ describe('2023 01 p2', () => { describe('the input', () => { it('should solve the input', async () => { const { input } = await loadTaskResources(packageJson.aoc); - expect(p2(input)).toEqual(0); + expect(p2(input)).toEqual(53_348); }); }); describe('example 1', () => { it('should be solved', async () => { const { input } = await loadTaskResources(packageJson.aoc, 'example.1.txt'); - expect(p2(input)).toEqual(0); + expect(p2(input)).toEqual(142); + }); + }); + + describe('example 2', () => { + it('should be solved', async () => { + const { input } = await loadTaskResources(packageJson.aoc, 'example.2.txt'); + expect(p2(input)).toEqual(281); }); }); }); diff --git a/solutions/typescript/2023/01/src/p2.ts b/solutions/typescript/2023/01/src/p2.ts index 06b578590..b535d16b9 100644 --- a/solutions/typescript/2023/01/src/p2.ts +++ b/solutions/typescript/2023/01/src/p2.ts @@ -1,58 +1,65 @@ -import { NEWLINE, task } from '@alexaegis/advent-of-code-lib'; +import { task } from '@alexaegis/advent-of-code-lib'; import packageJson from '../package.json'; +const numbers = { + one: '1', + '1': '1', + two: '2', + '2': '2', + three: '3', + '3': '3', + four: '4', + '4': '4', + five: '5', + '5': '5', + six: '6', + '6': '6', + seven: '7', + '7': '7', + eight: '8', + '8': '8', + nine: '9', + '9': '9', +} as const; + +const numbersAsKeys = Object.keys(numbers) as (keyof typeof numbers)[]; + export const p2 = (input: string): number => { return input - .split(NEWLINE) + .lines() .map((line) => { - let bufferForFirst = ''; - for (const l of line.chars()) { - bufferForFirst += l; - bufferForFirst = bufferForFirst - .replaceAll('one', '1') - .replaceAll('two', '2') - .replaceAll('three', '3') - .replaceAll('four', '4') - .replaceAll('five', '5') - .replaceAll('six', '6') - .replaceAll('seven', '7') - .replaceAll('eight', '8') + let firstDigit: string | undefined; + let lastDigit: string | undefined; + for (let i = 0; i < line.length; i++) { + if (firstDigit === undefined) { + const maybeFirstDigit = line.slice(i, i + 5); + const firstTextNumber = numbersAsKeys.find((key) => + maybeFirstDigit.startsWith(key), + ); + if (firstTextNumber) { + firstDigit = numbers[firstTextNumber]; + } + } - .replaceAll('nine', '9'); - } + if (lastDigit === undefined) { + const maybeDigit = line.slice( + Math.max(line.length - i - 5, 0), + line.length - i, + ); - let bufferForLast = ''; - for (const l of line.chars().reverse()) { - bufferForLast = l + bufferForLast; - bufferForLast = bufferForLast - .replaceAll('one', '1') - .replaceAll('two', '2') - .replaceAll('three', '3') - .replaceAll('four', '4') - .replaceAll('five', '5') - .replaceAll('six', '6') - .replaceAll('seven', '7') - .replaceAll('eight', '8') + const textNumber = numbersAsKeys.find((key) => maybeDigit.endsWith(key)); + if (textNumber) { + lastDigit = numbers[textNumber]; + } + } - .replaceAll('nine', '9'); + if (firstDigit !== undefined && lastDigit !== undefined) { + break; + } } - - const f = bufferForFirst - .chars() - .find((l) => /\d/.test(l)) - ?.toInt() - .toString(); - - const l = bufferForLast - .chars() - .reverse() - .find((l) => /\d/.test(l)) - ?.toInt() - .toString(); - - return f && l ? (f + l).toInt() : 0; + return ((firstDigit ?? '') + (lastDigit ?? '')).toInt(); }) .sum(); }; -await task(p2, packageJson.aoc); // 53348 ~?ms +await task(p2, packageJson.aoc); // 53348 ~1.4ms diff --git a/solutions/typescript/libs/lib/src/string/string.polyfill.ts b/solutions/typescript/libs/lib/src/string/string.polyfill.ts index f8ee18e21..3bc8fc578 100644 --- a/solutions/typescript/libs/lib/src/string/string.polyfill.ts +++ b/solutions/typescript/libs/lib/src/string/string.polyfill.ts @@ -30,7 +30,7 @@ declare global { */ chars(): string[]; /** - * Equivalent to `s.split(/(\r?\n)+/g).filter(line => !!line)` + * Equivalent to `s.split(/\r?\n/g).filter(line => !!line)` * The filter part can be turned off using the first, keepEmpty argument */ lines(keepEmpty?: boolean): string[]; @@ -107,7 +107,7 @@ String.prototype.chars = function (): string[] { }; String.prototype.lines = function (keepEmpty = false): string[] { - const lines = this.split(/(\r?\n)+/g); + const lines = this.split(/\r?\n/g); return keepEmpty ? lines : lines.filter((line) => !!line); }; diff --git a/solutions/typescript/readme.md b/solutions/typescript/readme.md index 038220a64..7c7f2a451 100644 --- a/solutions/typescript/readme.md +++ b/solutions/typescript/readme.md @@ -8,7 +8,7 @@ | Day | Part One | Part Two | | --------------------------------------- | ------------------------------------------------- | ------------------------------------------------- | -| [Day 1](/solutions/typescript/2023/01/) | [?ms](/solutions/typescript/2023/01/src/p1.ts) | [?ms](/solutions/typescript/2023/01/src/p2.ts) | +| [Day 1](/solutions/typescript/2023/01/) | [0.19ms](/solutions/typescript/2023/01/src/p1.ts) | [1.38ms](/solutions/typescript/2023/01/src/p2.ts) | | [Day 2](/solutions/typescript/2023/02/) | [0.22ms](/solutions/typescript/2023/02/src/p1.ts) | [0.25ms](/solutions/typescript/2023/02/src/p2.ts) | | Day 3 | - | - | | Day 4 | - | - |