Coding in browser developer tools.
var arr = document.querySelector('pre').innerText.split('\n').filter(s => s)
or
var arr
fetch('https://adventofcode.com/2021/day/XX/input')
.then(response => response.text())
.then(data => { arr = data.split('\n') })
arr.filter((n, i) => i != 0 && n > arr[i-1]).length
arr.filter((n, i) => i >= 3 && n > arr[i-3]).length
var x = y = 0
arr.map(item => item.split(' ')).forEach(([direction, valueString]) => {
const value = parseInt(valueString)
direction === 'forward' && (x += value)
direction === 'down' && (y += value)
direction === 'up' && (y -= value)
})
x*y
var y2 = aim = 0
arr.map(item => item.split(' ')).forEach(([direction, valueString]) => {
const value = parseInt(valueString)
direction === 'forward' && (y2 += value * aim)
direction === 'down' && (aim += value)
direction === 'up' && (aim -= value)
})
x*y2
var a = arr.map(item => item.split('').map(s => parseInt(s)))
.reduce(
(result, item) => result.map((r, i) => r + item[i]),
Array(arr[0].length).fill(0)
)
.map(num => num > arr.length/2 ? 1 : 0)
var b = a.map(x => x ? 0 : 1)
var g = parseInt(a.reduce((result, num) => '' + result + num), 2)
var e = parseInt(b.reduce((result, num) => '' + result + num), 2)
var find = (type, rest=arr, index=0) => {
const count = rest
.map(item => parseInt(item[index]))
.reduce((r, n) => r + n)
const next = rest.filter(item => item[index] == ((count >= rest.length / 2 ? 1 : 0) ^ type))
return next.length === 1 ? parseInt(next[0], 2) : find(type, next, index + 1)
}
find(0) * find(1)
var input = document.querySelector('pre').innerText.split('\n')
var draw = input[0].split(',').map(d => parseInt(d))
var point = 0
var maxCall = draw.length
for (let i=2; i<input.length; i+=6) {
let board = Array.from(Array(10), () => new Array())
let mapToBoard = {}
for (let r=0; r<5; r++) {
var nums = input[i+r].split(' ').filter(s => s !== '').map(s => parseInt(s))
for (let c=0; c<5; c++) {
const num = nums[c]
board[r].push(num)
board[c+5].push(num)
mapToBoard[num] = [board[r], board[c+5]]
}
}
for (let call=0; call < maxCall; call++) {
let isBingo = false
const d = draw[call]
mapToBoard[d]?.forEach(boardEntry => {
const index = boardEntry.indexOf(d);
if (index > -1) {
boardEntry.splice(index, 1);
}
if (boardEntry.length === 0) {
isBingo = true
}
})
if (isBingo) {
const sum = board.slice(0, 5).flat().reduce((sum, r) => sum + r)
const point = sum * d
if (call < maxCall) {
point = sum * d
maxCall = call
console.log('point: ', point)
}
break
}
}
}
var point = 0
var maxCall = 0
for (let i=2; i<input.length; i+=6) {
let board = Array.from(Array(10), () => new Array())
let mapToBoard = {}
for (let r=0; r<5; r++) {
var nums = input[i+r].split(' ').filter(s => s !== '').map(s => parseInt(s))
for (let c=0; c<5; c++) {
const num = nums[c]
board[r].push(num)
board[c+5].push(num)
mapToBoard[num] = [board[r], board[c+5]]
}
}
for (let call=0; call < draw.length; call++) {
let isBingo = false
const d = draw[call]
mapToBoard[d]?.forEach(boardEntry => {
const index = boardEntry.indexOf(d);
if (index > -1) {
boardEntry.splice(index, 1);
}
if (boardEntry.length === 0) {
isBingo = true
}
})
if (isBingo) {
const sum = board.slice(0, 5).flat().reduce((sum, r) => sum + r)
const point = sum * d
if (call > maxCall) {
lastPoint = sum * d
maxCall = call
console.log('point: ', point)
}
break
}
}
}
var map = {}
var count = 0
arr.forEach(l => {
let [a, b] = l.split(' -> ')
.map(s => s.split(',').map(s => parseInt(s)))
.map(([x, y]) => ({x, y}))
if (a.x === b.x) {
const start = a.y < b.y ? a.y : b.y
const end = a.y < b.y ? b.y : a.y
for (let i=start; i<=end; i++) {
if (map[`${a.x},${i}`]++ === 1) {
count++
} else {
map[`${a.x},${i}`] = 1
}
}
} else if (a.y === b.y) {
const start = a.x < b.x ? a.x : b.x
const end = a.x < b.x ? b.x : a.x
for (let i=start; i<=end; i++) {
if (map[`${i},${a.y}`]++ === 1) {
count++
} else {
map[`${i},${a.y}`] = 1
}
}
}
})
arr.forEach(l => {
let [a, b] = l.split(' -> ')
.map(s => s.split(',').map(s => parseInt(s)))
.map(([x, y]) => ({x, y}))
if (a.x === b.x) {
const start = a.y < b.y ? a.y : b.y
const end = a.y < b.y ? b.y : a.y
for (let i=start; i<=end; i++) {
if (!map[`${a.x},${i}`]) {
map[`${a.x},${i}`] = 1
} else if (map[`${a.x},${i}`]++ === 1) {
count++
}
}
} else if (a.y === b.y) {
const start = a.x < b.x ? a.x : b.x
const end = a.x < b.x ? b.x : a.x
for (let i=start; i<=end; i++) {
if (!map[`${i},${a.y}`]) {
map[`${i},${a.y}`] = 1
} else if (map[`${i},${a.y}`]++ === 1) {
count++
}
}
} else {
const xStep = a.x < b.x ? 1 : -1
const yStep = a.y < b.y ? 1 : -1
console.log(a.x, a.y, b.x, b.y, '>>>>')
for (let i=a.x; (a.x < b.x) ? (i<=b.x) : (i>=b.x); i+=xStep) {
const x = a.x + xStep * Math.abs(a.x-i)
const y = a.y + yStep * Math.abs(a.x-i)
if (!map[`${x},${y}`]) {
map[`${x},${y}`] = 1
} else if (map[`${x},${y}`]++ === 1) {
count++
}
}
}
})
var result = arr[0].split(',').map(s => parseInt(s))
for (let i=0; i<80; i++) {
const current = result
result = []
for (let j=0; j<current.length; j++) {
const value = current[j]-1
if (value < 0) {
result.push(6)
result.push(8)
} else {
result.push(value)
}
}
}
Didn't write code, but divded to 128 and conquered.
When starting array is [1]
, with part 1 after 128 days, it becomes a 90763 long array.
Calcualte all single number arrays for 128 days.
After that, check how many 0s, 1s, ..., or 8s in the result arrays and multiply the result length. Finally check how many 0s, 1s, ..., or 8s in the input array and multiploy the 256 result length.
[1] / 128 => 90763 / 256 => 6206821033
[2] / 79321 / 5617089148
[3] / 75638 / 5217223242
[4] / 67616 / 4726100874
[5] / 62475 / 4368232009
[6] / 58016
[7] / 51564
[8] / 49380
[0] / 94508
6206821033 * 191 + 5617089148 * 30 + 5217223242 * 20 + 4726100874 * 35 + 4368232009 * 24
It could be divided and conquered from 1, 2, 4, ... to replace part 1 and become a O(m*logn) algorithm where m is number of possible numbers and n is days.
Most peoople use a O(m*n) that shifts numbers of numbers to number-1 buckets.
var input = arr[0].split(',').map(s => parseInt(s))
input.sort((a, b) => a-b)
var min = Infinity
for (let i=0; i<=input[input.length-1]; i++) {
var fuel = arr.map(n => Math.abs(n-i)).reduce((r, n) => r+n)
if (fuel < min) {
min = fuel
console.log(i, min)
}
}
var accuMap = {0: 0}
var sum = 0
for (let i=1; input[input.length-1]; i++) {
sum += i
accuMap[i] = sum
}
var min = Infinity
for (let i=0; i<=input[input.length-1]; i++) {
var fuel = input
.map(n => Math.abs(n-i))
.map(n => accuMap[n])
.reduce((r, n) => r+n)
if (fuel < min) {
min = fuel
console.log(i, min)
}
}
var input = arr.map(l => l.split(' | ').map(s => s.split(' ').map(s => s.split('').sort().reduce((r, s) => r+s))))
input.map(([signal, match]) =>
match.filter(m => m.length === 2 || m.length === 3 || m.length === 4 || m.length === 7)
.filter(m => signal.indexOf(m) !== -1).length
).reduce((r, n) => r+n)
var fn = signal => {
const map = {
[signal.filter(s => s.length === 2)[0]]: '1',
[signal.filter(s => s.length === 4)[0]]: '4',
[signal.filter(s => s.length === 3)[0]]: '7',
[signal.filter(s => s.length === 7)[0]]: '8',
1: signal.filter(s => s.length === 2)[0],
4: signal.filter(s => s.length === 4)[0],
7: signal.filter(s => s.length === 3)[0],
}
signal.forEach(s => {
if ([2, 3, 4, 7].indexOf(s.length) !== -1) { return }
if (s.length === 5) {
if (map[7].split('').every(a => s.indexOf(a) !== -1)) {
map[s] = '3'
} else if (map[4].split('').filter(a => s.indexOf(a) !== -1).length === 3) {
map[s] = '5'
} else {
map[s] = '2'
}
} else { // 6
if (map[4].split('').every(a => s.indexOf(a) !== -1)) {
map[s] = '9'
} else if (map[1].split('').every(a => s.indexOf(a) !== -1)) {
map[s] = '0'
} else {
map[s] = '6'
}
}
})
return map
}
input.map(([signal, digits]) =>
digits.map(d => fn(signal)[d]).reduce((r, s) => r+s)
).map(s => parseInt(s)).reduce((r, n) => r+n)
var input = arr.map(l => l.split('').map(s => parseInt(s)))
var map = {}
input.forEach((l, i, o) => {
l.forEach((n, j) => {
if ((j === 0 && n < l[j+1])
|| (j === l.length-1 && n < l[j-1])
|| (n < l[j+1] && n < l[j-1])
) {
map[`${i},${j}`] = 1
}
if (i !== 0 && l[j] > o[i-1][j] && map[`${i-1},${j}`] === 1) {
map[`${i-1},${j}`] = 2
}
if (i !== 0 && l[j] >= o[i-1][j] && map[`${i},${j}`] === 1) {
map[`${i},${j}`] = 0
}
if (i === o.length-1 && map[`${i},${j}`] === 1) {
map[`${i},${j}`] = 2
}
})
})
var sum = 0
for (let i in map) {
if (map[i] === 2) {
const [x, y] = i.split(',')
sum += input[x][y] + 1
}
}
for (let i in map) {
if (map[i] === 2) {
map[i] = 0
} else {
delete map[i]
}
}
var findBasin = (input, arr, checked={}) => {
arr.forEach(({x, y}) => {
checked[`${x},${y}`] = 1
const nextArr = []
if (x-1 >= 0 && input[x-1][y] !== 9 && !checked[`${x-1},${y}`]) {
nextArr.push({x: x-1, y})
}
if (x+1 < input.length && input[x+1][y] !== 9 && !checked[`${x+1},${y}`]) {
nextArr.push({x: x+1, y})
}
if (y-1 >= 0 && input[x][y-1] !== 9 && !checked[`${x},${y-1}`]) {
nextArr.push({x, y: y-1})
}
if (y+1 < input[0].length && input[x][y+1] !== 9 && !checked[`${x},${y+1}`]) {
nextArr.push({x, y: y+1})
}
findBasin(input, nextArr, checked)
})
return checked
}
var basinSizes = Object.entries(map).map(([key, value]) => {
const [x, y] = key.split(',').map(s => parseInt(s))
return { x, y }
}).map(i => Object.entries(findBasin(input, [i])).length)
.sort((a, b) => b-a)
basinSizes[0] * basinSizes[1] * basinSizes[2]
var input = arr.map(s => s.split(''))
var map = {
[')']: 0,
[']']: 0,
['}']: 0,
['>']: 0,
}
var fn = line => {
const stack = []
for (let i=0; i<line.length; i++) {
const last = stack.pop()
const x = line[i]
if (x === '(' || x === '[' || x === '{' || x === '<') {
stack.push(last, x)
} else if ((x === ')' && last !== '(')
|| (x === ']' && last !== '[')
|| (x === '}' && last !== '{')
|| (x === '>' && last !== '<')
) {
map[x] += 1
console.log(line, i, x, last)
break
}
}
}
input.forEach(line => fn(line))
map[')']*3 + map[']']*57 + map['}']*1197 + map['>']*25137
var fn = line => {
const stack = []
for (let i=0; i<line.length; i++) {
const last = stack.pop()
const x = line[i]
if (x === '(' || x === '[' || x === '{' || x === '<') {
stack.push(last, x)
} else if ((x === ')' && last !== '(')
|| (x === ']' && last !== '[')
|| (x === '}' && last !== '{')
|| (x === '>' && last !== '<')
) {
return -1
}
}
return stack.filter(s => s).reverse().map(x => x === '('
? 1
: x === '['
? 2
: x === '{'
? 3
: 4
)
}
var scores = input.map(line => fn(line)).filter(x => x !== -1).map(line => line.reduce((r, n) => r*5 + n, 0))
scores.sort((a, b) => a-b)
scores[Math.floor(scores.length/2)]
var input = arr.map(s => s.split('').map(s => parseInt(s)))
var flashes = 0
var add = (input, [x, y]) => {
if (++input[x][y] === 10) {
flash(input, x, y)
}
}
var flash = (input, i, j) => {
flashes++
[
[i-1, j-1],
[i, j-1],
[i+1, j-1],
[i-1, j],
[i+1, j],
[i-1, j+1],
[i, j+1],
[i+1, j+1],
].filter(([x, y]) => input[x]?.[y] != null).forEach(coor => add(input, coor))
}
var step = input => {
for (let i=0; i<input.length; i++) {
for (let j=0; j<input[0].length; j++) {
add(input, [i, j])
}
}
for (let i=0; i<input.length; i++) {
for (let j=0; j<input[0].length; j++) {
input[i][j] = input[i][j] >= 10 ? 0 : input[i][j]
}
}
}
for (let i=0; i<100; i++) { step(input) }
for (let i=1; i<1000; i++) {
step(input)
if (input.every(l => l.every(n => n === 0))) {
console.log(i)
break
}
}
var map = arr.map(s => s.split('-')).reduce((r, [a, b]) => ({
...r,
[a]: r[a] ? r[a].concat(b) : [b],
[b]: r[b] ? r[b].concat(a) : [a],
}), {})
var countPath = (map, start) => {
if (start === 'end') { return 1 }
const { [start]: directions, ...rest } = map
return directions.filter(d => map[d]).reduce((r, d) => r + countPath(start === start.toUpperCase() ? map : rest, d), 0)
}
countPath(map, 'start')
var countPath = (map, start, small={}) => {
if (start === 'end') { return 1 }
const { [start]: directions, ...rest } = map
let nextMap
if (start === start.toUpperCase()) {
nextMap = map
} else if (start !== 'start') {
small[start] = small[start] ? small[start]+1 : 1
if (Object.entries(small).some(([_, value]) => value >= 2)) {
nextMap = { ...rest }
for (const [key] of Object.entries(small)) {
delete nextMap[key]
}
} else {
nextMap = map
}
} else {
nextMap = rest
}
return directions.filter(d => nextMap[d]).reduce((r, d) => r + countPath(nextMap, d, { ...small }), 0)
}
var coors = arr.filter(s => !s.startsWith('fold')).map(s => s.split(',').map(s => parseInt(s)))
var foldX = (coors, x) => {
const remain = coors.filter(coor => coor[0] <= x)
const folded = coors.filter(coor => coor[0] > x)
return remain.concat(folded.map(coor => [x * 2 - coor[0], coor[1]]).filter(coor => remain.findIndex(i => coor[0] === i[0] && coor[1] === i[1]) === -1))
}
var foldY = (coors, y) => {
const remain = coors.filter(coor => coor[1] <= y)
const folded = coors.filter(coor => coor[1] > y)
return remain.concat(folded.map(coor => [coor[0], y * 2 - coor[1]]).filter(coor => remain.findIndex(i => coor[0] === i[0] && coor[1] === i[1]) === -1))
}
var fold = arr.filter(s => s.startsWith('fold')).map(s => s.split('fold along ')[1].split('='))
fold.forEach(f => {
if (f[0] === 'x') {
coors = foldX(coors, parseInt(f[1]))
} else {
coors = foldY(coors, parseInt(f[1]))
}
})
var graph = Array.from(Array(50), () => new Array(15).fill(0))
coors.forEach(c => graph[c[0]][c[1]] = 1)
var template = arr[0]
var map = arr.slice(1).reduce((r, i) => ({ ...r, [i.split(' -> ')[0]]: i.split(' -> ')[1] }), {})
var step = (current, _map=map) => {
let result = current[0]
for (let i=1; i<current.length; i++) {
const insertion = _map[`${current[i-1]}${current[i]}`]
if (insertion) {
result += insertion
}
result += current[i]
}
return result
}
var tenSteps = step(step(step(step(step(step(step(step(step(step(template))))))))))
tenSteps.split('').reduce((r, s) => ({ ...r, [s]: r[s] ? r[s]+1 : 1 }), {})
var countMap = {}
for (let i=1; i<template.length; i++) {
countMap[template[i-1]+template[i]] = 1
}
var nStep = (n, countMap) => {
if (n === 0) { return countMap }
const result = { }
Object.keys(countMap).filter(k => countMap[k]).forEach(s => {
result[s[0]+map[s]] = result[s[0]+map[s]] ? result[s[0]+map[s]] + countMap[s] : countMap[s]
result[map[s]+s[1]] = result[map[s]+s[1]] ? result[map[s]+s[1]] + countMap[s] : countMap[s]
})
return nStep(n-1, result)
}
var countMap40 = nStep(40, countMap)
Object.keys(countMap40).reduce((r, k) => ({ ...r, [k[0]]: r[k[0]] ? r[k[0]] + countMap40[k] : countMap40[k] }), {})
var map = arr.map(r => r.split('').map(s => parseInt(s)))
var allDirections = () => {
const _riskMap = {}
let changed
do {
changed = false
for (let i=0; i<map.length; i++) {
for (let j=0; j<map[0].length; j++) {
if (i === 0 && j === 0) {
_riskMap[`${i},${j}`] = 0
continue
}
var from = [
_riskMap[`${i-1},${j}`] != null ? _riskMap[`${i-1},${j}`] : Infinity,
_riskMap[`${i},${j-1}`] != null ? _riskMap[`${i},${j-1}`] : Infinity,
_riskMap[`${i},${j+1}`] != null ? _riskMap[`${i},${j+1}`] : Infinity,
_riskMap[`${i+1},${j}`] != null ? _riskMap[`${i+1},${j}`] : Infinity,
].map(n => n + map[i][j])
const current = _riskMap[`${i},${j}`] != null ? _riskMap[`${i},${j}`] : Infinity
const updated = Math.min(...from, current)
if (updated !== current) {
_riskMap[`${i},${j}`] = updated
changed = true
}
}
}
} while(changed)
return _riskMap
}
allDirections()['99,99']
var map1 = arr.map(r => r.split('').map(s => parseInt(s)))
var add = n => o => (o+n)%9 === 0 ? 9 : (o+n)%9
var _map = map1.map(a => [
...a,
...a.map(add(1)),
...a.map(add(2)),
...a.map(add(3)),
...a.map(add(4)),
])
var map = _map.concat(
_map.map(a => a.map(add(1))),
_map.map(a => a.map(add(2))),
_map.map(a => a.map(add(3))),
_map.map(a => a.map(add(4))),
)
allDirections()['499,499']
var hex2bin = hex => (parseInt(hex, 16).toString(2)).padStart(4, '0')
const binary = arr[0].split('').map(hex2bin).reduce((r, s) => r+s)
var sum = 0
var parse = binary => {
const version = parseInt(binary.substr(0, 3), 2)
sum += version
const type = parseInt(binary.substr(3, 3), 2)
if (type === 4) {
let valueBinary = ''
let i=6
for (;; i+=5) {
valueBinary += binary.substr(i+1, 4)
if (binary[i] === '0') { break }
}
return {
version,
type,
value: parseInt(valueBinary, 2),
length: i+5,
}
} else if (binary[6] === '0') {
const len = parseInt(binary.substr(7, 15), 2)
let remain = len
while (remain !== 0) {
const p = parse(binary.substr(22+len-remain, remain))
console.log(p)
remain -= p.length
}
return {
version,
type,
I: '0',
length: len+7+15,
}
} else if (binary[6] === '1') {
const nums = parseInt(binary.substr(7, 11), 2)
let index = 7+11
for (let i=0; i<nums; i++) {
const p = parse(binary.substring(index, binary.length))
console.log(p)
index += p.length
}
return {
version,
type,
I: '1',
length: index,
}
}
}
parse(binary)
var parse = binary => {
const type = parseInt(binary.substr(3, 3), 2)
if (type === 4) {
let valueBinary = ''
let i=6
for (;; i+=5) {
valueBinary += binary.substr(i+1, 4)
if (binary[i] === '0') { break }
}
return {
value: parseInt(valueBinary, 2),
length: i+5,
}
} else if (binary[6] === '0') {
const len = parseInt(binary.substr(7, 15), 2)
let remain = len
const packets = []
while (remain !== 0) {
const p = parse(binary.substr(22+len-remain, remain))
packets.push(p)
remain -= p.length
}
return {
value: packets.map(p => p.value).reduce(
type === 0 ? (r, n) => r+n
: type === 1 ? (r, n) => r*n
: type === 2 ? (r, n) => n < r ? n : r
: type === 3 ? (r, n) => n > r ? n : r
: type === 5 ? (r, n) => r > n ? 1 : 0
: type === 6 ? (r, n) => r < n ? 1 : 0
: (r, n) => r === n ? 1 : 0 // 7
),
length: len+7+15,
}
} else if (binary[6] === '1') {
const nums = parseInt(binary.substr(7, 11), 2)
let index = 7+11
const packets = []
for (let i=0; i<nums; i++) {
const p = parse(binary.substring(index, binary.length))
packets.push(p)
index += p.length
}
return {
value: packets.map(p => p.value).reduce(
type === 0 ? (r, n) => r+n
: type === 1 ? (r, n) => r*n
: type === 2 ? (r, n) => n < r ? n : r
: type === 3 ? (r, n) => n > r ? n : r
: type === 5 ? (r, n) => r > n ? 1 : 0
: type === 6 ? (r, n) => r < n ? 1 : 0
: (r, n) => r === n ? 1 : 0 // 7
),
length: index,
}
}
}
parse(binary)
var step = (v, pos={x:0, y:0}, highest=0) => {
const newPos = { x: pos.x + v.x, y: pos.y + v.y }
const newV = {
x: v.x > 0 ? v.x-1 : v.x < 0 ? v.x+1 : 0,
y: v.y-1,
}
if (newPos.x >= 135 && newPos.x <= 155
&& newPos.y >= -102 && newPos.y <= -78) {
return highest
} else if (newPos.x > 155 || newPos.y < -102) {
return false
} else {
highest = newPos.y > highest ? newPos.y : highest
return step(newV, newPos, highest)
}
}
var highest
for (let x=1; x<=155; x++) {
for (let y=1; y<500; y++) {
const candidate = step({x, y})
if (candidate && candidate > highest) {
highest = candidate
}
}
}
var step = (v, pos={x:0, y:0}) => {
const newPos = { x: pos.x + v.x, y: pos.y + v.y }
const newV = {
x: v.x > 0 ? v.x-1 : v.x < 0 ? v.x+1 : 0,
y: v.y-1,
}
if (newPos.x >= 135 && newPos.x <= 155
&& newPos.y >= -102 && newPos.y <= -78) {
return v
} else if (newPos.x > 155 || newPos.y < -102) {
return false
} else {
return step(newV, newPos) ? v : false
}
}
var count = 0
for (let x=1; x<=155; x++) {
for (let y=1000; y>=-102; y--) {
const candidate = step({x, y})
if (candidate) {
count+=1
}
}
}
var addLeftMost = (a, n) => Array.isArray(a) ? [
!Array.isArray(a[0]) ? a[0]+n : addLeftMost(a[0], n),
a[1]
] : a+n
var addRightMost = (a, n) => Array.isArray(a) ? [
a[0],
!Array.isArray(a[1]) ? a[1]+n : addRightMost(a[1], n)
]: a+n
var explode = (a, depth=1) => {
if (!Array.isArray(a)) return { value: a }
if (Array.isArray(a[0]) && depth === 4) {
return {
addToLeft: a[0][0],
exploded: true,
value: [0, addLeftMost(a[1], a[0][1])],
}
} else if (Array.isArray(a[1]) && depth === 4) {
return {
addToRight: a[1][1],
exploded: true,
value: [a[1][0] + a[0], 0],
}
} else {
const left = explode(a[0], depth+1)
if (left.addToLeft) {
return {
addToLeft: left.addToLeft,
exploded: true,
value: [left.value, a[1]],
}
} else if (left.addToRight) {
return {
exploded: true,
value: [left.value, addLeftMost(a[1], left.addToRight)]
}
} else if (left.exploded) {
return {
exploded: true,
value: [left.value, a[1]],
}
}
const right = explode(a[1], depth+1)
if (right.addToRight) {
return {
addToRight: right.addToRight,
exploded: true,
value: [left.value, right.value],
}
} else if (right.addToLeft) {
return {
exploded: true,
value: [addRightMost(left.value, right.addToLeft), right.value]
}
}
return {
exploded: left.exploded || right.exploded,
value: [left.value, right.value]
}
}
}
var splits = a => {
if (!Array.isArray(a)) {
return {
value: a >= 10 ? [Math.floor(a/2), Math.ceil(a/2)] : a,
splited: a >= 10
}
}
let left = splits(a[0])
if (left.splited) {
return {
value: [left.value, a[1]],
splited: true,
}
}
const right = splits(a[1])
return {
value: [a[0], right.value],
splited: right.splited,
}
}
var reduce = a => {
let result = explode(a).value
if (result.toString() !== a.toString()) {
console.log('explode')
console.log(a.toString(), result.toString())
return reduce(result)
}
result = splits(a).value
if (result.toString() !== a.toString()) {
console.log('splits')
console.log(a.toString(), result.toString())
return reduce(result)
}
return a
}
var add = (a, b) => reduce([a, b])
var magnitude = a => {
const [l, r] = a.map(i => Array.isArray(i) ? magnitude(i) : i)
return l*3 + r*2
}
magnitude(arr.map(s => eval(s)).reduce((r, i) => add(r, i)))
var input = arr.map(s => eval(s))
for (let i=0; i<input.length-1; i++) {
for (let j=2; j<input.length; j++) {
const r1 = magnitude(add(input[i], input[j]))
const r2 = magnitude(add(input[j], input[i]))
max = Math.max(r1, r2, max)
}
}
var parse = input => {
const scanners = []
let scannerIndex = -1
input.forEach(s => {
if (s.startsWith('---')) {
scannerIndex++
scanners.push([])
return
}
scanners[scannerIndex].push(s.split(',').map(s => parseInt(s)))
})
return scanners
}
var evenNotExistedOrientations = beacons => {
const byBeacon = beacons.map(b => [
[b[0], b[1], b[2]],
[b[0], b[2], b[1]],
[b[1], b[0], b[2]],
[b[1], b[2], b[0]],
[b[2], b[0], b[1]],
[b[2], b[1], b[0]],
[-b[0], b[1], b[2]],
[-b[0], b[2], b[1]],
[-b[1], b[0], b[2]],
[-b[1], b[2], b[0]],
[-b[2], b[0], b[1]],
[-b[2], b[1], b[0]],
[b[0], -b[1], b[2]],
[b[0], -b[2], b[1]],
[b[1], -b[0], b[2]],
[b[1], -b[2], b[0]],
[b[2], -b[0], b[1]],
[b[2], -b[1], b[0]],
[-b[0], -b[1], b[2]],
[-b[0], -b[2], b[1]],
[-b[1], -b[0], b[2]],
[-b[1], -b[2], b[0]],
[-b[2], -b[0], b[1]],
[-b[2], -b[1], b[0]],
[b[0], b[1], -b[2]],
[b[0], b[2], -b[1]],
[b[1], b[0], -b[2]],
[b[1], b[2], -b[0]],
[b[2], b[0], -b[1]],
[b[2], b[1], -b[0]],
[-b[0], b[1], -b[2]],
[-b[0], b[2], -b[1]],
[-b[1], b[0], -b[2]],
[-b[1], b[2], -b[0]],
[-b[2], b[0], -b[1]],
[-b[2], b[1], -b[0]],
[b[0], -b[1], -b[2]],
[b[0], -b[2], -b[1]],
[b[1], -b[0], -b[2]],
[b[1], -b[2], -b[0]],
[b[2], -b[0], -b[1]],
[b[2], -b[1], -b[0]],
[-b[0], -b[1], -b[2]],
[-b[0], -b[2], -b[1]],
[-b[1], -b[0], -b[2]],
[-b[1], -b[2], -b[0]],
[-b[2], -b[0], -b[1]],
[-b[2], -b[1], -b[0]],
])
const byOrientation = []
for (let i=0; i<byBeacon[0].length; i++) {
const o = []
for (let j=0; j<beacons.length; j++) {
o.push(byBeacon[j][i])
}
byOrientation.push(o)
}
return byOrientation
}
var correlate = (s1, s2, threshold=12) => {
const s2o = evenNotExistedOrientations(s2)
for (let o=0; o<s2o.length; o++) {
const diffMap = {}
for (let i=0; i<s1.length; i++) {
for (let j=0; j<s2o[o].length; j++) {
const diff = s1[i].map((axis, index) => axis - s2o[o][j][index])
const diffKey = diff.join(',')
diffMap[diffKey] = diffMap[diffKey] ? diffMap[diffKey]+1 : 1
if (diffMap[diffKey] >= threshold) {
return {
diff,
orientation: s2o[o],
}
}
}
}
}
}
var fn = (
scanners=parse(arr),
solved=[0],
unsolved=scanners.map((_, i) => i).slice(1, scanners.length),
scannerMap={ 0: [0,0,0] }
) => {
const stillUnsolved = []
const newSolved = []
unsolved.forEach(u => {
for (let i=0; i<solved.length; i++) {
const s = solved[i]
const result = correlate(scanners[s], scanners[u])
if (result) {
scannerMap[u] = result.diff.map((n, axis) => n+scannerMap[s][axis])
newSolved.push(u)
scanners[u] = result.orientation
return
}
}
stillUnsolved.push(u)
})
if (stillUnsolved.length > 0) {
fn(scanners, newSolved, stillUnsolved, scannerMap)
}
return [scanners, scannerMap]
}
var [orientedScanners, scannerMap] = fn()
new Set(orientedScanners.map((s, i) => s.map(b => b.map((n, axis) => n+scannerMap[i][axis]))).flat().map(a => a.toString()))
var max = 0
for (let i=0; i<orientedScanners.length-1; i++) {
for (let j=0; j<orientedScanners.length; j++) {
const distance = scannerMap[i].map((n, axis) => Math.abs(n-scannerMap[j][axis])).reduce((r, n) => r+n)
max = distance > max ? distance : max
}
}
var enhancement = square => arr[0][parseInt(square, 2)] === '#' ? '1' : '0'
var input = arr.slice(1, arr.length).map(s => s.split('').map(s => s === '#' ? '1' : '0'))
var getSquare = (image, i, j) => (image[i-1]?.[j-1] ? image[i-1][j-1] : (image.length-input.length)/2%2 === 0 ? '0' : '1')
+ (image[i-1]?.[j] ? image[i-1][j] : (image.length-input.length)/2%2 === 0 ? '0' : '1')
+ (image[i-1]?.[j+1] ? image[i-1][j+1] : (image.length-input.length)/2%2 === 0 ? '0' : '1')
+ (image[i]?.[j-1] ? image[i][j-1] : (image.length-input.length)/2%2 === 0 ? '0' : '1')
+ (image[i]?.[j] ? image[i]?.[j] : (image.length-input.length)/2%2 === 0 ? '0' : '1')
+ (image[i]?.[j+1] ? image[i][j+1] : (image.length-input.length)/2%2 === 0 ? '0' : '1')
+ (image[i+1]?.[j-1] ? image[i+1][j-1] : (image.length-input.length)/2%2 === 0 ? '0' : '1')
+ (image[i+1]?.[j] ? image[i+1][j] : (image.length-input.length)/2%2 === 0 ? '0' : '1')
+ (image[i+1]?.[j+1] ? image[i+1][j+1] : (image.length-input.length)/2%2 === 0 ? '0' : '1')
var enhance = (times=1, image=input) => {
if (times === 0 ) return image
const output = []
const newFirstRow = []
const newLastRow = []
for (let j=-1; j<image[0].length+1; j++) {
newFirstRow.push(enhancement(getSquare(image, -1, j)))
}
output.push(newFirstRow)
image.forEach((row, i) => {
const newRow = [enhancement(getSquare(image, i, -1))]
row.forEach((pixel, j) => {
newRow.push(enhancement(getSquare(image, i, j)))
})
newRow.push(enhancement(getSquare(image, i, row.length)))
output.push(newRow)
})
for (let j=-1; j<image[0].length+1; j++) {
newLastRow.push(enhancement(getSquare(image, image.length, j)))
}
output.push(newLastRow)
return enhance(times-1, output)
}
enhance(2).flat(2).filter(n => n == 1).length
enhance(50).flat(2).filter(n => n == 1).length
var deterministicNext = 1; var rolls = 0
var deterministic = (count=3) => {
let sum = 0
for (let i=0; i<count; i++) {
sum += deterministicNext++
if (deterministicNext > 100) {
deterministicNext = 1
}
}
rolls+=count
return sum
}
var players = [{p:4, s:0}, {p:8, s:0}]
do {
players = players.map(p => {
const moves = deterministic()
let newPos = (p.p + moves)%10
newPos = newPos === 0 ? 10 : newPos
return {
p: newPos,
s: p.s + newPos
}
})
} while (players.filter(p => p.s >= 1000).length === 0)
rolls * players[0].s
var allPossibleDiceSum = (() => {
const sides = [1, 2, 3]
const sums = [3, 4, 5, 6, 7, 8, 9].reduce((r, n) => ({...r, [n]: 0}), {})
for (let i=0; i<3; i++) {
for (let j=0; j<3; j++) {
for (let k=0; k<3; k++) {
sums[sides[i]+sides[j]+sides[k]] += 1
}
}
}
return sums
})()
var onBoard = n => n%10 === 0 ? 10 : n%10
var split = (universes={ ['5,0;10,0']: 1 }) => {
let nextUniverses = {}
const finishedUniverses = {}
for (const [universe, count] of Object.entries(universes)) {
const [p1Pos, p1Score, p2Pos, p2Score] = universe.split(';').map(p => p.split(',').map(s => parseInt(s))).flat()
for (let i=3; i<=9; i++) {
const newP1Pos = onBoard(p1Pos+i)
const newP1Score = p1Score+newP1Pos
if (newP1Score >= 21) {
const universeName = newP1Pos+','+newP1Score+';'+p2Pos+','+p2Score
finishedUniverses[universeName] = (finishedUniverses[universeName] || 0) + allPossibleDiceSum[i] * count
continue
}
for (let j=3; j<=9; j++) {
const newP2Pos = onBoard(p2Pos+j)
const newP2Score = p2Score+newP2Pos
const universeName = newP1Pos+','+newP1Score+';'+newP2Pos+','+newP2Score
const universesToUpdate = newP2Score >= 21 ? finishedUniverses : nextUniverses
universesToUpdate[universeName] = (universesToUpdate[universeName] || 0 ) + allPossibleDiceSum[i] * allPossibleDiceSum[j] * count
}
}
}
if (Object.keys(nextUniverses).length !== 0) {
nextUniverses = split(nextUniverses)
}
for (const [universe, count] of Object.entries(nextUniverses)) {
finishedUniverses[universe] = (finishedUniverses[universe] || 0) + count
}
return finishedUniverses
}
var finishedUniverses = split()
Object.keys(finishedUniverses).filter(key => parseInt(key.split(';')[0].split(',')[1]) >= 21).reduce((r, key) => r+finishedUniverses[key], 0)
var input = arr.map(line => line.split(' ')).map(line => line.map((s, i) => i === 0 ? s : s.split(',').map(axis => {
const [name, range] = axis.split('=')
return { [name]: range.split('..').map(s => parseInt(s)) }
}).reduce((r, a) => ({...r, ...a}))))
var intersect = (a, b) => {
const result = {
x: [Math.max(a.x[0], b.x[0]), Math.min(a.x[1], b.x[1])],
y: [Math.max(a.y[0], b.y[0]), Math.min(a.y[1], b.y[1])],
z: [Math.max(a.z[0], b.z[0]), Math.min(a.z[1], b.z[1])],
}
return Object.values(result).some(axis => axis[0] > axis[1]) ? null : result
}
input.reduce((cuboids, next) => {
if (cuboids.length === 0) return [next]
const result = []
cuboids.forEach(cuboid => {
result.push(cuboid)
const interCuboid = intersect(cuboid[1], next[1])
if (interCuboid) {
result.push([cuboid[0] === 'on' ? 'off' : 'on', interCuboid])
}
})
if (next[0] === 'on') result.push(next)
return result
}, [])
.map(cuboid => (cuboid[0] === 'on' ? 1 : -1) * Object.values(cuboid[1]).map(axis => axis[1]-axis[0]+1)
.reduce((r, n) => r*n))
.reduce((r, n) => r+n)
Dropped solution: split cuboids
```javascript var add = (a, b) => { if (a.x[0] <= b.x[0] && a.x[1] >= b.x[1] && a.y[0] <= b.y[0] && a.y[1] >= b.y[1] && a.z[0] <= b.z[0] && a.z[1] >= b.z[1] ) { // a contains whole b return [a] } else if (a.x[0] >= b.x[0] && a.x[1] <= b.x[1] && a.y[0] >= b.y[0] && a.y[1] <= b.y[1] && a.z[0] >= b.z[0] && a.z[1] <= b.z[1] ) { // b contains whole a return [b] } else if (a.x[0] <= b.x[0] && a.x[1] < b.x[1] && a.y[0] <= b.y[0] && a.y[1] >= b.y[1] && a.z[0] <= b.z[0] && a.z[1] >= b.z[1] ) { // a x 由 return [a, {x: [a.x[1], b.x[1]], y: b.y, z: b.z}] } else if (a.x[0] > b.x[0] && a.x[1] >= b.x[1] && a.y[0] <= b.y[0] && a.y[1] >= b.y[1] && a.z[0] <= b.z[0] && a.z[1] >= b.z[1] ) { // a x 甲 return [a, {x: [b.x[0], a.x[0]], y: b.y, z: b.z}] } else if (a.x[0] >= b.x[0] && a.x[1] > b.x[1] && a.y[0] >= b.y[0] && a.y[1] <= b.y[1] && a.z[0] >= b.z[0] && a.z[1] <= b.z[1] ) { // b x 由 return [b, {x: [b.x[1], a.x[1]], y: a.y, z: a.z}] } else if (a.x[0] < b.x[0] && a.x[1] <= b.x[1] && a.y[0] >= b.y[0] && a.y[1] <= b.y[1] && a.z[0] >= b.z[0] && a.z[1] <= b.z[1] ) { // b x 甲 return [b, {x: [a.x[0], b.x[0]], y: a.y, z: a.z}] } else if (a.x[0] <= b.x[0] && a.x[1] >= b.x[1] && a.y[0] <= b.y[0] && a.y[1] < b.y[1] && a.z[0] <= b.z[0] && a.z[1] >= b.z[1] ) { // a y 由 return [a, {x: b.x, y: [a.y[1], b.y[1]], z: b.z}] } else if (a.x[0] <= b.x[0] && a.x[1] >= b.x[1] && a.y[0] > b.y[0] && a.y[1] >= b.y[1] && a.z[0] <= b.z[0] && a.z[1] >= b.z[1] ) { // a y 甲 return [a, {x: b.x, y: [a.y[0], b.y[0]], z: b.z}] } else if (a.x[0] >= b.x[0] && a.x[1] <= b.x[1] && a.y[0] >= b.y[0] && a.y[1] > b.y[1] && a.z[0] >= b.z[0] && a.z[1] <= b.z[1] ) { // b y 由 return [b, {x: a.x, y: [b.y[1], a.y[1]], z: a.z}] } else if (a.x[0] >= b.x[0] && a.x[1] <= b.x[1] && a.y[0] < b.y[0] && a.y[1] <= b.y[1] && a.z[0] >= b.z[0] && a.z[1] <= b.z[1] ) { // b y 甲 return [b, {x: a.x, y: [a.y[0], b.y[0]], z: a.z}] } else if (a.x[0] <= b.x[0] && a.x[1] >= b.x[1] && a.y[0] <= b.y[0] && a.y[1] >= b.y[1] && a.z[0] <= b.z[0] && a.z[1] < b.z[1] ) { // a z 由 return [a, {x: b.x, y: b.y, z: [a.z[1], b.z[1]]}] } else if (a.x[0] <= b.x[0] && a.x[1] >= b.x[1] && a.y[0] <= b.y[0] && a.y[1] >= b.y[1] && a.z[0] > b.z[0] && a.z[1] >= b.z[1] ) { // a z 甲 return [a, {x: b.x, y: b.y, z: [b.z[0], a.z[0]]}] } else if (a.x[0] >= b.x[0] && a.x[1] <= b.x[1] && a.y[0] >= b.y[0] && a.y[1] <= b.y[1] && a.z[0] >= b.z[0] && a.z[1] > b.z[1] ) { // b z 由 return [b, {x: a.x, y: a.y, z: [b.z[1], a.z[1]]}] } else if (a.x[0] >= b.x[0] && a.x[1] <= b.x[1] && a.y[0] >= b.y[0] && a.y[1] <= b.y[1] && a.z[0] < b.z[0] && a.z[1] <= b.z[1] ) { // b z 甲 return [b, {x: a.x, y: a.y, z: [a.z[0], b.z[0]]}] } else if (a.x[0] > b.x[0] && a.x[1] < b.x[1] && a.y[0] <= b.y[0] && a.y[1] >= b.y[1] && a.z[0] <= b.z[0] && a.z[1] >= b.z[1] ) { // a x 中 return [ a, {x: [a.x[1], b.x[1]], y: b.y, z: b.z}, {x: [b.x[0], a.x[0]], y: b.y, z: b.z}, ] } else if (a.x[0] < b.x[0] && a.x[1] > b.x[1] && a.y[0] >= b.y[0] && a.y[1] <= b.y[1] && a.z[0] >= b.z[0] && a.z[1] <= b.z[1] ) { // b x 中 return [ b, {x: [b.z[1], a.z[1]], y: a.y, z: a.z}, {x: [a.z[0], b.z[0]], y: a.y, z: a.z}, ] } else if (a.x[0] <= b.x[0] && a.x[1] >= b.x[1] && a.y[0] > b.y[0] && a.y[1] < b.y[1] && a.z[0] <= b.z[0] && a.z[1] >= b.z[1] ) { // a y 中 return [ a, {x: b.x, y: [a.y[1], b.y[1]], z: b.z}, {x: b.x, y: [b.y[0], a.y[0]], z: b.z}, ] } else if (a.x[0] >= b.x[0] && a.x[1] <= b.x[1] && a.y[0] < b.y[0] && a.y[1] > b.y[1] && a.z[0] >= b.z[0] && a.z[1] <= b.z[1] ) { // b y 中 return [ b, {x: a.x, y: [b.y[1], a.y[1]], z: a.z}, {x: a.x, y: [a.y[0], b.y[0]], z: a.z}, ] } else if (a.x[0] <= b.x[0] && a.x[1] >= b.x[1] && a.y[0] <= b.y[0] && a.y[1] >= b.y[1] && a.z[0] > b.z[0] && a.z[1] < b.z[1] ) { // a z 中 return [ a, {x: b.x, y: b.y, z: [a.z[1], b.z[1]]}, {x: b.x, y: b.y, z: [b.z[0], a.z[0]]}, ] } else if (a.x[0] >= b.x[0] && a.x[1] <= b.x[1] && a.y[0] >= b.y[0] && a.y[1] <= b.y[1] && a.z[0] < b.z[0] && a.z[1] > b.z[1] ) { // b z 中 return [ b, {x: a.x, y: a.y, z: [b.z[1], a.z[1]]}, {x: a.x, y: a.y, z: [a.z[0], b.z[0]]}, ] } else if (a.x[0] >= b.x[1] || a.x[1] <= b.x[0] || a.y[0] >= b.y[1] || a.y[1] <= b.y[0] || a.z[0] >= b.z[1] || a.z[1] <= b.z[0] ) { // no overlap return [a, b] } else { console.log('else') } } ```
Same as part 1.
Walk the amphipods by brain.
Walk the amphipods by brain, again.
var n = [12,13,12,-13,11,15,-14,12,-8,14,-9,-11,-6,-5]
var m = [ 1, 9,11, 6, 6,13, 13, 5, 7, 2,10, 14, 7, 1]
var fn = (i, w, lastZ=0) => {
let x = (lastZ % 26 + n[i]) !== w
let z = n[i] < 0 ? Math.floor(lastZ/26) : lastZ
return x ? (26*z+w+m[i]) : z
}
var cache = {}
var monad = s => {
if (s.length === 1) {
const result = fn(0, parseInt(s))
cache[s] = result
return result
}
const s_1 = s.substr(0, s.length-1)
const result = fn(s.length-1, parseInt(s[s.length-1]), cache[s_1] == null ? monad(s_1) : cache[s_1])
cache[s] = result
return result
}
// doesn't work
for (let i=99999999999999; i>=11111111111111; i--) {
const s = i+''
if (s.indexOf('0') !== -1) continue
if (monad(s) === 0) {
console.log(i)
break
}
}
// to prove monad
var alu = {
x:0, y:0, z:0, w:0, i:0,
inp: () => {alu.w=parseInt(model[alu.i++])},
add: (a, b) => {alu[a] += alu[b] != null ? alu[b] : parseInt(b)},
mul: (a, b) => {alu[a] *= alu[b] != null ? alu[b] : parseInt(b)},
div: (a, b) => {alu[a] = Math.floor(alu[a]/(alu[b] != null ? alu[b] : parseInt(b)))},
mod: (a, b) => {alu[a] %= alu[b] != null ? alu[b] : parseInt(b)},
eql: (a, b) => {alu[a] = alu[a] == (alu[b] != null ? alu[b] : parseInt(b)) ? 1 : 0},
}
arr.map(s => s.split(' ')).forEach(ins => {
alu[ins[0]](ins[1], ins[2])
})
var map = arr.map(s => s.split(''))
var fn = (map=map, count=1) => {
const newMap = []
let moved = false
for (let i=0; i<map.length; i++) {
const newRow = []
for (let j=0; j<map[0].length; j++) {
if (map[i][j] === '>' && j+1 < map[0].length && map[i][j+1] === '.') {
newRow.push('.', '>')
j++
moved = true
} else if (map[i][j] === '>' && j+1 === map[0].length && map[i][0] === '.') {
newRow.push('.')
newRow[0] = '>'
} else {
newRow.push(map[i][j])
}
}
newMap.push(newRow)
}
const finalMap = newMap.map(row => row.slice())
for (let i=0; i<finalMap.length; i++) {
const newRow = []
for (let j=0; j<finalMap[0].length; j++) {
if (finalMap[i][j] === 'v' && i+1 < finalMap.length && finalMap[i+1][j] === '.') {
finalMap[i][j] = '.'
finalMap[i+1][j] = '^'
moved = true
} else if (finalMap[i][j] === '^') {
finalMap[i][j] = 'v'
} else if (finalMap[i][j] === 'v' && i+1 === finalMap.length && newMap[0][j] === '.') {
finalMap[i][j] = '.'
finalMap[0][j] = 'v'
moved = true
}
}
}
return moved ? fn(finalMap, count+1) : count
}
fn(map)
There is no such thing!