Skip to content

Instantly share code, notes, and snippets.

@MinimumViablePerson
Last active December 3, 2018 18:15
Show Gist options
  • Save MinimumViablePerson/fb7168c277eec664909d703967aeb35e to your computer and use it in GitHub Desktop.
Save MinimumViablePerson/fb7168c277eec664909d703967aeb35e to your computer and use it in GitHub Desktop.
/******** ANSWERS ********/
// ⭐: 1
const addThemAllUp = frequencyChanges => frequencyChanges.reduce((a, b) => a + b)
// ⭐: 2
const findFirstRepeatedFrequency = frequencyChanges => {
let index = 0
let currentFrequency = 0
const frequencies = new Set()
while (true) {
frequencies.add(currentFrequency)
currentFrequency += frequencyChanges[index]
if (frequencies.has(currentFrequency)) {
break
} else {
index = index === frequencyChanges.length - 1 ? 0 : index + 1
}
}
return currentFrequency
}
// ⭐: 3
const getBoxIdChecksum = boxIds => {
const counts = {2: 0, 3: 0}
for (const boxId of boxIds) {
if (anyCharAppearsNTimes(boxId, 2)) counts[2]++
if (anyCharAppearsNTimes(boxId, 3)) counts[3]++
}
return counts[2] * counts[3]
}
// ⭐: 4
const findPrototypeFabric = boxIds => {
boxIds = [...boxIds]
let currentBoxId
while (boxIds.length > 0) {
currentBoxId = boxIds.pop()
for (const boxId of boxIds) {
let differenceCount = 0
let differingIndex
for (const index in currentBoxId) {
if (currentBoxId[index] !== boxId[index]) {
differenceCount++
differingIndex = parseInt(index)
}
if (differenceCount > 1) break
}
if (differenceCount === 1) {
return replaceCharAt(differingIndex, currentBoxId, '')
}
}
}
}
// ⭐: 4 (With ES6 destructuring and recursion)
const findPrototypeFabricR = ([currentBoxId, ...otherBoxIds]) => {
if (!currentBoxId) return null
return prototypeFabricFound(currentBoxId, otherBoxIds) || findPrototypeFabricR(otherBoxIds)
}
// ⭐: 5
const countOverlappingClaims = claims => {
const matrix = addAllClaimsToMatrix(claims)
const overlappingCoords = Object.values(matrix).filter(coord => coord.length > 1)
return overlappingCoords.length
}
// ⭐: 6
const findFirstNonOverlappingClaim = claims => {
const matrix = addAllClaimsToMatrix(claims)
for (const claim of claims) {
if (claimDoesntOverlap(claim, matrix)) return claim
}
}
/******** HELPERS ********/
// get day 1 data ready to operate on
const getDay1Data = () =>
fetch('https://adventofcode.com/2018/day/1/input')
.then(resp => resp.text())
.then(text => text.split('\n').slice(0, -1))
.then(arr => arr.map(n => parseInt(n)))
// get day 2 data ready to operate on
const getDay2Data = () =>
fetch('https://adventofcode.com/2018/day/2/input')
.then(resp => resp.text())
.then(text => text.split('\n').slice(0, -1))
// get day 3 data ready to operate on
const getDay3Data = () =>
fetch('https://adventofcode.com/2018/day/3/input')
.then(resp => resp.text())
.then(text => text.split('\n').slice(0, -1))
.then(data => data.map(parseClaim)
// check if any char in a string appears a given number of times
const anyCharAppearsNTimes = (string, times) => {
const charSet = new Set(string)
for (const char of charSet) {
const match = string.match(new RegExp(char, 'g'))
if (match && match.length === times) return true
}
return false
}
// return a copy of a string with a char replaced at a given index
const replaceCharAt = (index, string, replacement) =>
string.slice(0, index) + replacement + string.slice(index + 1)
// check if prototype fabric is found in a single loop
const prototypeFabricFound = (currentBoxId, boxIds) => {
for (const boxId of boxIds) {
let differenceCount = 0
let differingIndex
for (const index in currentBoxId) {
if (currentBoxId[index] !== boxId[index]) {
differenceCount++
differingIndex = parseInt(index)
}
if (differenceCount > 1) break
}
if (differenceCount === 1) {
return replaceCharAt(differingIndex, currentBoxId, '')
}
}
}
// convert a claim string into a claim object
const parseClaim = claim => {
const match = claim.match(/#(\d+)\s@\s(\d+),(\d+):\s(\d+)x(\d+)/)
return {
id: parseInt(match[1]),
x: parseInt(match[2]),
y: parseInt(match[3]),
w: parseInt(match[4]),
h: parseInt(match[5])
}
}
// add all coords for a single claim into an object "matrix"
const addClaimToMatrix = (claim, matrix) => {
for (let i = 0; i < claim.w; i++) {
const x = claim.x + 1 + i
for (let i = 0; i < claim.h; i++) {
const y = claim.y + 1 + i
const tile = `${x},${y}`
matrix[tile] = matrix[tile] ? [...matrix[tile], claim.id] : [claim.id]
}
}
return matrix
}
// take a list of claims and add them all to a new object
const addAllClaimsToMatrix = claims =>
claims.reduce((matrix, claim) => addClaimToMatrix(claim, matrix), {})
// check if a single claim overlaps
const claimDoesntOverlap = (claim, matrix) =>
Object.values(matrix)
.filter(tile => tile.includes(claim.id))
.every(tile => tile.length === 1)
@stephencweiss
Copy link

@MinimumViablePerson - Super cool. I actually didn't know that feature about Sets. I knew they forced uniqueness, but didn't realize it was because they didn't need values. Looking at MDN, they can have values though, right?

@MinimumViablePerson
Copy link
Author

@stephencweiss Yeah, they only have values in a sense. There's no key/value pair to them, and they are unique. They can have a much faster add and look up performance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment