2023 - Day 1
Intro
The puzzle prompt on adventofcode.com
# run solution with test data
zx content/advent-of-code/2023/1/_index.md
# run solution with input file data
zx content/advent-of-code/2023/1/_index.md content/advent-of-code/2023/1/input.txt
Code
const assert = require('assert')
debug(argv)
const [inputFile] = argv._
const sampleData = {
part1: `1abc2
pqr3stu8vwx
a1b2c3d4e5f
treb7uchet`,
part2: `two1nine
eightwothree
abcone2threexyz
xtwone3four
4nineeightseven2
zoneight234
7pqrstsixteen`
}
const sampleSolutions = {
part1: 142,
part2: 281
}
let inputContent
if (inputFile) {
debug(`input file specified, loading data from: ${inputFile}`)
inputContent = await fs.readFile(inputFile, 'utf-8')
} else {
debug(`no input file specified, using part 1 sample data`)
inputContent = sampleData.part1
}
const calibrationSum = inputContent
.split('\n')
.map(value => value.toLowerCase())
.map(value => value.replace(/[a-z]*/g, '').split(''))
.map((coordinates) => {
const first = coordinates[0]
const last = coordinates[coordinates.length - 1]
return parseInt(`${first}${last}`, 10)
})
.reduce((total, item, i, arr) => {
total += item
return total
}, 0)
if (!inputFile) debug(calibrationSum)
console.log(`Part 1: Sum of all calibration values is: ${calibrationSum}`)
if (!inputFile) assert.equal(calibrationSum, sampleSolutions.part1, 'part 1 solution should match expected')
const wordMap = {
eight: '8',
one: '1',
two: '2',
three: '3',
four: '4',
five: '5',
six: '6',
seven: '7',
nine: '9'
}
if (!inputFile) {
debug(`no input file specified, using part 2 sample data`)
inputContent = sampleData.part2
}
const calibrationSumPart2 = inputContent
.split('\n')
.map(value => value.toLowerCase())
.map((value, i) => {
debug(`before: ${value}`)
for (let n = 0; n < value.length; n++) {
let substr = value.slice(n)
Object.keys(wordMap).forEach((numberWord) => {
if (substr.match(new RegExp(`^${numberWord}`))) {
value = value.replace(numberWord, wordMap[numberWord])
}
})
}
return value
})
.map((value, i) => {
debug(`${i}: ${value}`)
const numbersOnly = value.replace(/[a-z]*/g, '').split('')
debug(`${i}: ${numbersOnly}`)
return numbersOnly
})
.map((coordinates) => {
const first = coordinates[0]
const last = coordinates[coordinates.length - 1]
return parseInt(`${first}${last}`, 10)
})
.reduce((total, item, i, arr) => {
total += item
return total
}, 0)
if (!inputFile) debug(calibrationSumPart2)
console.log(`Part 2: Sum of all values with spelled numbers converted is: ${calibrationSumPart2}`)
if (!inputFile) assert.equal(calibrationSumPart2, sampleSolutions.part2, 'part 2 solution should match expected')
function debug (msg) {
if (process.env.DEBUG) console.log(msg)
}