Skip to content

Commit

Permalink
day 9 part 1
Browse files Browse the repository at this point in the history
  • Loading branch information
cdelaorden committed Dec 28, 2023
1 parent fc81760 commit b874f1f
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 129 deletions.
65 changes: 6 additions & 59 deletions src/days/9/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,68 +1,15 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`expandWithDifferences handles neg values 1`] = `
exports[`Day 9 Mirage maintenance reduceHistories (recursive) generates prev histories 1`] = `
[
[
-9,
-13,
-17,
-21,
-25,
-29,
-33,
-37,
-41,
-45,
-49,
-53,
-57,
-61,
-65,
-69,
-73,
-77,
-81,
-85,
-89,
3,
3,
3,
3,
3,
],
[
-4,
-4,
-4,
-4,
-4,
-4,
-4,
-4,
-4,
-4,
-4,
-4,
-4,
-4,
-4,
-4,
-4,
-4,
-4,
-4,
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
Expand Down
76 changes: 50 additions & 26 deletions src/days/9/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,56 @@
import { explode } from '@/lib/utils'
import { calculateDifferences, expandWithDifferences } from '.'
import {
calculateDifferences,
calculateNext,
isAllZeros,
makeHistory,
parseInput,
reduceHistories,
} from '.'

describe('calculateDifferences', () => {
it('creates a new Array with differences', () => {
const result = calculateDifferences([0, 3, 6, 9, 12, 15])
expect(result).toEqual([3, 3, 3, 3, 3])
const result2 = calculateDifferences(result)
expect(result2).toEqual([0, 0, 0, 0])
describe('Day 9 Mirage maintenance', () => {
describe('parseInput', () => {
it('generates array of histories', () => {
expect(parseInput('0 3 6 9 12 15\n1 2 3 4')).toEqual([
[0, 3, 6, 9, 12, 15],
[1, 2, 3, 4],
])
})
})
})

describe('expandWithDifferences', () => {
it('creates an Array of dimishing differences from original row', () => {
const result = expandWithDifferences([0, 3, 6, 9, 12, 15])
expect(result).toEqual([
[0, 3, 6, 9, 12, 15],
[3, 3, 3, 3, 3],
[0, 0, 0, 0],
])
describe('isAllZeros', () => {
it('returns true if array is composed of only 0s', () => {
expect(isAllZeros([0])).toBe(true)
expect(isAllZeros([])).toBe(true)
expect(isAllZeros([1, 0])).toBe(false)
})
})
describe('calculateDifferences', () => {
it('creates a new Array with differences', () => {
const result = calculateDifferences([0, 3, 6, 9, 12, 15])
expect(result).toEqual([3, 3, 3, 3, 3])
const result2 = calculateDifferences(result)
expect(result2).toEqual([0, 0, 0, 0])
})
})

it('handles neg values', () => {
const result = expandWithDifferences(
explode(
'-9 -13 -17 -21 -25 -29 -33 -37 -41 -45 -49 -53 -57 -61 -65 -69 -73 -77 -81 -85 -89',
' '
).map(Number)
)
expect(result).toMatchSnapshot()
describe('reduceHistories (recursive)', () => {
it('generates prev histories', () => {
const result = reduceHistories([0, 3, 6, 9, 12, 15])
expect(result).toMatchSnapshot()
})
})
describe('calculateNext', () => {
it('returns the next value in the history', () => {
expect(calculateNext([0, 3, 6, 9, 12, 15])).toBe(18)
expect(calculateNext([1, 3, 6, 10, 15, 21])).toBe(28)
expect(calculateNext([10, 13, 16, 21, 30, 45])).toBe(68)
expect(
calculateNext(
makeHistory('9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11')
)
).toBe(-12)
expect(calculateNext(makeHistory('-9 -13 -17 -21 -25 -29 -33 -37'))).toBe(
-41
)
})
})
})
78 changes: 34 additions & 44 deletions src/days/9/index.ts
Original file line number Diff line number Diff line change
@@ -1,63 +1,53 @@
import { explode, splitLines, sum } from '@/lib/utils'
import assert from 'assert'
import { createPipe, map, pipe, tap } from 'remeda'
import { createPipe, equals, last, map, pipe } from 'remeda'

const parseInput = createPipe(
splitLines,
map((l) => explode(l, ' ').map(Number))
)
export const makeHistory = (line: string) => explode(line, ' ').map(Number)

export const parseInput = createPipe(splitLines, map(makeHistory))

export const isAllZeros = (xs: number[]) =>
xs.length === 0 || xs.every(equals(0))

export const printPyramid = (hs: number[][]) =>
hs.reduce((acc, h, i) => {
acc += ' '.repeat(i) + h.join(' ') + '\n'
return acc
}, '')

export const calculateDifferences = (seq: number[]) =>
seq.reduce((acc, n, index) => {
if (index < seq.length - 1) {
const next = seq[index + 1]
if (next) {
acc.push(next - n)
}
if (index > 0) {
acc.push(n - (seq.at(index - 1) as number))
}
return acc
}, [] as number[])

export const expandWithDifferences = (seq: number[]) => {
return seq.reduce(
(acc, _seq, index) => {
if (acc.at(-1)?.every((x) => x === 0)) return acc
const differences = calculateDifferences(acc[index] as number[])
acc.push(differences)
return acc
},
[seq]
)
/**
* Returns the differences until a [0...0] array is found.
* Does not include the original
* @param from initial history
* @returns
*/
export function reduceHistories(from: number[]): number[][] {
if (isAllZeros(from)) return []
const next = calculateDifferences(from)
return [next].concat(reduceHistories(next))
}

export const extrapolateNextValue = (seqs: number[][]): number => {
const reversed = seqs.reverse()
reversed[0] = Array.from({ length: seqs.at(-1)?.length ?? 0 }).fill(
0
) as number[]
return reversed
.reduce(
(acc, _seq, index) => {
const nextRow = reversed[index + 1]
if (!nextRow) return acc
acc.push((nextRow.at(-1) as number) + (acc.at(-1) as number))
return acc
},
[0]
)
.at(-1) as number
export const calculateNext = (history: number[], debug = false) => {
assert(history.length, 'empty history')
const histories = reduceHistories(history)
if (debug) {
console.log(printPyramid([history].concat(histories)))
}
const next = histories.reduceRight((acc, h) => (last(h) ?? 0) + acc, 0)
return next + (last(history) ?? 0)
}

export function day9PartOne(sample: string, input: string) {
assert(sample && input, 'Bad input data')
const solution = pipe(
input,
parseInput,
map(expandWithDifferences),
tap(console.log),
map(extrapolateNextValue),
sum
)
const solution = pipe(input, parseInput, map(calculateNext), sum)
console.log('Part One', solution)
}

Expand Down

0 comments on commit b874f1f

Please sign in to comment.