Coding in browser developer tools.
var line = document.querySelector('pre').innerText.split('\n').filter(s => s)
var arr = document.querySelector('pre').innerText.split('\n\n')
.map(a => a.split('\n').map(s => parseInt(s)).reduce((a, b) => a+b))
.sort((a, b) => b-a)
arr[0]
arr[0] + arr[1] + arr[2]
line.map(s => s.split(' ')).map(([p1, p2]) => {
const p1n = p1.charCodeAt() - 'A'.charCodeAt() + 1
const p2n = p2.charCodeAt() - 'X'.charCodeAt() + 1
const diff = p2n - p1n;
let score = p2n;
const result = diff === 0
? 0
: diff === 1 || diff === -2
? 1
: -1
if (result === 0) score += 3;
else if (result === 1) score += 6;
return score
}).reduce((sum, n) => sum+n, 0)
line.map(s => s.split(' ')).map(([p1, p2]) => {
const p1n = p1.charCodeAt() - 'A'.charCodeAt() + 1
const result = p2.charCodeAt() - 'X'.charCodeAt()
let p2n = result === 0
? ((p1n-1) > 0 ? (p1n-1) : 3)
: result === 1
? p1n
: ((p1n+1) < 4 ? (p1n+1): 1)
let score = p2n;
if (result === 1) score += 3;
else if (result === 2) score += 6;
return score
}).reduce((sum, n) => sum+n, 0)
line.map(s => {
const map = {}
for (let i=0; i<s.length/2; i++) {
const c1 = s.charAt(i)
const c2 = s.charAt(i+s.length/2)
if (map[c1] === -1) return c1
map[c1] = 1
if (map[c2] === 1) return c2
map[c2] = -1
}
}).map(c => {
let code = c.charCodeAt() - 'a'.charCodeAt() + 1
return code < 0 ? code+58 : code
}).reduce((s, n) => s+n)
line.reduce((r, l) => {
let last = r[r.length-1]
if (last.length === 3) {
last = []
r.push(last)
}
last.push(l)
return r
}, [[]]).map(three => {
const map = {}
for (let c of three[0])
map[c] = 1
for (let c of three[1])
if (map[c])
map[c] = 2
for (let c of three[2])
if (map[c] === 2)
return c
}).map(c => {
let code = c.charCodeAt() - 'a'.charCodeAt() + 1
return code < 0 ? code+58 : code
}).reduce((s, n) => s+n)
line.map(l => l.split(',').map(a => a.split('-').map(s => parseInt(s))).sort((a, b) => a[0]-b[0] ? a[0]-b[0] : b[1]-a[1]))
.filter(arr => arr[0][1] >= arr[1][1])
.length
line.map(l => l.split(',').map(a => a.split('-').map(s => parseInt(s))).sort((a, b) => a[0]-b[0]))
.filter(arr => arr[0][1] >= arr[1][0])
.length
var line = document.querySelector('pre').innerText.split('\n\n')
var diagram = line[0].split('\n')
var stacks = [[],[],[],[],[],[],[],[],[]]
for (let i=diagram.length-2; i>=0; i--) {
let pos = 1;
for (let j=0; j<9; j++) {
const char = diagram[i].charAt(pos)
if (char !== ' ') stacks[j].push(char)
pos += 4
}
}
line[1].split('\n').filter(s => s).map(s => s.split(' ')).map(([_, r, __, f, ___, t]) => [parseInt(r), parseInt(f), parseInt(t)])
.forEach(([repeat, from, to]) => {
stacks[to-1] = stacks[to-1].concat(stacks[from-1].slice(-repeat).reverse())
stacks[from-1] = stacks[from-1].slice(0, -repeat)
})
stacks.map(arr => arr[arr.length-1]).reduce((r, x) => r+x)
line[1].split('\n').filter(s => s).map(s => s.split(' ')).map(([_, r, __, f, ___, t]) => [parseInt(r), parseInt(f), parseInt(t)])
.forEach(([repeat, from, to]) => {
stacks[to-1] = stacks[to-1].concat(stacks[from-1].slice(-repeat))
stacks[from-1] = stacks[from-1].slice(0, -repeat)
})
stacks.map(arr => arr[arr.length-1]).reduce((r, x) => r+x)
var chars = line[0].split('')
var map = {}
for (let i=0; i<4; i++) map[chars[i]] = (map[chars[i]] ? map[chars[i]] : 0 ) + 1
for (let i=4; i<chars.length; i++) {
map[chars[i]] = (map[chars[i]] ? map[chars[i]] : 0 ) + 1
map[chars[i-4]]--
if (Object.values(map).every(n => n < 2)) {
console.log(i+1)
break
}
}
same as above but replace 4 with 14
var tree = {}
var dirs = [tree]
line.forEach(s => {
const curDir = dirs[dirs.length-1]
const cmd = s.split(' ')
if (cmd[0] === '$') {
if (cmd[1] === 'cd') {
if (cmd[2] === '..') {
dirs.pop()
} else {
const newDir = {}
curDir[cmd[2]] = newDir
dirs.push(newDir)
}
}
} else if (cmd[0] !== 'dir') {
const fileSize = parseInt(cmd[0])
curDir[cmd[1]] = fileSize
curDir.size = (curDir.size ? curDir.size : 0) + fileSize
}
})
var result = 0
var dfs = dir => {
for (const [key, value] of Object.entries(dir)) {
if (typeof value === 'object') {
dir.size = (dir.size ? dir.size : 0) + dfs(value)
}
}
if (dir.size <= 100000) result+= dir.size
return dir.size
}
dfs(tree['/'])
result
var sizes = []
var dfs = dir => {
for (const [key, value] of Object.entries(dir)) {
if (typeof value === 'object') {
dir.size = (dir.size ? dir.size : 0) + dfs(value)
}
}
if (dir.size <= 100000) result+= dir.size
sizes.push(dir.size)
return dir.size
}
var total = dfs(tree['/'])
sizes.sort((a, b) => a-b).filter(s => s > total-40000000)[0]
var map = line.map(s => s.split('').map(n => parseInt(n)))
var visible = new Set()
for (let i=1; i<map.length-1; i++) {
let tallest = 0
let positions = { [map[i][tallest]]: tallest }
for (let j=1; j<map.length-1; j++) {
if (map[i][j] >= [map[i][tallest]]) {
if (map[i][j] > [map[i][tallest]]) visible.add(`${i},${j}`)
tallest = j
positions = { [map[i][tallest]]: tallest }
} else {
positions[map[i][j]] = j
}
}
positions[map[i][map.length-1]] = map.length-1
let previous = -1
for (let k=map[i][tallest]; k>map[i][map.length-1]; k--) {
if (positions[k]) {
if (previous === -1 || positions[k] > positions[previous]) {
visible.add(`${i},${positions[k]}`)
previous = k
}
}
}
}
for (let i=1; i<map.length-1; i++) {
let tallest = 0
let positions = { [map[tallest][i]]: tallest }
for (let j=1; j<map.length-1; j++) {
if (map[j][i] >= [map[tallest][i]]) {
if (map[j][i] > [map[tallest][i]]) visible.add(`${j},${i}`)
tallest = j
positions = { [map[tallest][i]]: tallest }
} else {
positions[map[j][i]] = j
}
}
positions[map[map.length-1][i]] = map.length-1
let previous = -1
for (let k=map[tallest][i]; k>map[map.length-1][i]; k--) {
if (positions[k]) {
if (previous === -1 || positions[k] > positions[previous]) {
visible.add(`${positions[k]},${i}`)
previous = k
}
}
}
}
visible.size + map.length*4 - 4
var map = line.map(s => s.split('').map(n => parseInt(n)))
var scores = new Array(map.length-2)
for (let i = 0; i < map.length-2; i++) {
scores[i] = new Array(map.length-2)
}
for (let i=1; i<map.length-1; i++) {
let positions = { [map[i][0]]: 0 }
for (let j=1; j<map.length-1; j++) {
let nearMost = 0;
for (let k=map[i][j]; k<10; k++) {
if (positions[k] != null) nearMost = Math.max(nearMost, positions[k])
}
scores[i-1][j-1] = {}
scores[i-1][j-1].left = j - nearMost
positions[map[i][j]] = j
}
positions = { [map[i][map.length-1]]: map.length-1 }
for (let j=map.length-2; j>0; j--) {
let nearMost = 98;
for (let k=map[i][j]; k<10; k++) {
if (positions[k] != null) nearMost = Math.min(nearMost, positions[k])
}
scores[i-1][j-1].right = nearMost - j
positions[map[i][j]] = j
}
}
for (let j=1; j<map.length-1; j++) {
let positions = { [map[0][j]]: 0 }
for (let i=1; i<map.length-1; i++) {
let nearMost = 0;
for (let k=map[i][j]; k<10; k++) {
if (positions[k] != null) nearMost = Math.max(nearMost, positions[k])
}
scores[i-1][j-1].above = i - nearMost
positions[map[i][j]] = i
}
positions = { [map[map.length-1][j]]: map.length-1 }
for (let i=map.length-2; i>0; i--) {
let nearMost = 98;
for (let k=map[i][j]; k<10; k++) {
if (positions[k] != null) nearMost = Math.min(nearMost, positions[k])
}
score = scores[i-1][j-1]
scores[i-1][j-1] = (nearMost - i) * score.above * score.left * score.right
positions[map[i][j]] = i
}
}
scores.reduce((max, arr) => Math.max(max, arr.reduce((max, n) => Math.max(max, n), 0)), 0)
var dirs = { R: [1, 0], L: [-1, 0], U: [0, 1], D: [0, -1] }
var head = [0, 0]
var tail = [0, 0]
var set = new Set()
set.add('0,0')
line.forEach(motion => {
const [dir, n] = motion.split(' ')
const step = parseInt(n)
for (let i in [0, 1])
head[i] += dirs[dir][i] * step
const diffs = head.map((v, i) => v - tail[i])
if (diffs.every(diff => Math.abs(diff) <= 1)) return
else if (diffs[0] === 0 || Math.abs(diffs[0]) === 1) {
tail[0] = head[0]
const diffSign = diffs[1] / Math.abs(diffs[1])
const newTail = tail[1] + diffSign * (Math.abs(diffs[1])-1)
for (let i=tail[1]+diffSign; i != newTail; i+=diffSign) {
set.add(`${tail[0]},${i}`)
}
tail[1] = newTail
set.add(`${tail[0]},${tail[1]}`)
} else if (diffs[1] === 0 || Math.abs(diffs[1]) === 1) {
tail[1] = head[1]
const diffSign = diffs[0] / Math.abs(diffs[0])
const newTail = tail[0] + diffSign * (Math.abs(diffs[0])-1)
for (let i=tail[0]+diffSign; i != newTail; i+=diffSign) {
set.add(`${i},${tail[1]}`)
}
tail[0] = newTail
set.add(`${tail[0]},${tail[1]}`)
}
})
set.size
var dirs = { R: [1, 0], L: [-1, 0], U: [0, 1], D: [0, -1] }
var knots = [[0, 0],[0, 0],[0, 0],[0, 0],[0, 0],[0, 0],[0, 0],[0, 0],[0, 0],[0, 0]]
var set = new Set()
set.add('0,0')
var followKnot = (lead, follow, isLast) => {
const diffs = lead.map((v, i) => v - follow[i])
if (diffs.every(diff => Math.abs(diff) <= 1)) return
else if (diffs[0] === 0 || Math.abs(diffs[0]) < Math.abs(diffs[1])) {
follow[0] = lead[0]
const diffSign = diffs[1] / Math.abs(diffs[1])
const newFollow = follow[1] + diffSign * (Math.abs(diffs[1])-1)
if (isLast) {
for (let i=follow[1]+diffSign; i != newFollow; i+=diffSign) {
set.add(`${follow[0]},${i}`)
}
set.add(`${follow[0]},${newFollow}`)
}
follow[1] = newFollow
} else if (diffs[1] === 0 || Math.abs(diffs[0]) > Math.abs(diffs[1])) {
follow[1] = lead[1]
const diffSign = diffs[0] / Math.abs(diffs[0])
const newFollow = follow[0] + diffSign * (Math.abs(diffs[0])-1)
if (isLast) {
for (let i=follow[0]+diffSign; i != newFollow; i+=diffSign) {
set.add(`${i},${follow[1]}`)
}
set.add(`${newFollow},${follow[1]}`)
}
follow[0] = newFollow
} else {
const diffSigns = [diffs[0] / Math.abs(diffs[0]), diffs[1] / Math.abs(diffs[1])]
for (let i=1; i<Math.abs(diffs[0]); i++) {
for (let j in [0, 1])
follow[j] += diffSigns[j]
if (isLast) set.add(`${follow[0]},${follow[1]}`)
}
}
}
line.forEach(motion => {
const [dir, n] = motion.split(' ')
const step = parseInt(n)
for (let n=0; n<step; n++) {
for (let i in [0, 1])
knots[0][i] += dirs[dir][i]
for (let i=0; i<9; i++) {
followKnot(knots[i], knots[i+1], i === 8)
}
}
})
set.size
var x = 1
var cycle = []
var hist = [1]
line.forEach(cmd => {
cycle.push(0)
const segs = cmd.split(' ')
if (segs.at(1)) {
cycle.push(parseInt(segs[1]))
}
})
cycle.forEach(c => {
x += c
hist.push(x)
})
var res = 0
for(let i=19; i<hist.length; i+=40) {
res += hist[i]*(i+1)
}
res
var crt = []
for (let i=0; i<240; i++) {
const p = (i+1) % 40
crt.push(hist[i] <= p && p <= hist[i]+2 ? '#' : '.')
}
console.log(...crt.slice(0, 40))
console.log(...crt.slice(40, 80))
console.log(...crt.slice(80, 120))
console.log(...crt.slice(120, 160))
console.log(...crt.slice(160, 200))
console.log(...crt.slice(200, 240))
var monkeys = [
{
items: [63, 57],
op: n => Math.floor(n*11/3),
throwTo: n => monkeys[n % 7 === 0 ? 6 : 2].items.push(n),
count: 0,
},
{
items: [82, 66, 87, 78, 77, 92, 83],
op: n => Math.floor((n+1)/3),
throwTo: n => monkeys[n % 11 === 0 ? 5 : 0].items.push(n),
count: 0,
},
{
items: [97, 53, 53, 85, 58, 54],
op: n => Math.floor(n*7/3),
throwTo: n => monkeys[n % 13 === 0 ? 4 : 3].items.push(n),
count: 0,
},
{
items: [50],
op: n => Math.floor((n+3)/3),
throwTo: n => monkeys[n % 3 === 0 ? 1 : 7].items.push(n),
count: 0,
},
{
items: [64, 69, 52, 65, 73],
op: n => Math.floor((n+6)/3),
throwTo: n => monkeys[n % 17 === 0 ? 3 : 7].items.push(n),
count: 0,
},
{
items: [57, 91, 65],
op: n => Math.floor((n+5)/3),
throwTo: n => monkeys[n % 2 === 0 ? 0 : 6].items.push(n),
count: 0,
},
{
items: [67, 91, 84, 78, 60, 69, 99, 83],
op: n => Math.floor(n*n/3),
throwTo: n => monkeys[n % 5 === 0 ? 2 : 4].items.push(n),
count: 0,
},
{
items: [58, 78, 69, 65],
op: n => Math.floor((n+7)/3),
throwTo: n => monkeys[n % 19 === 0 ? 5 : 1].items.push(n),
count: 0,
},
]
for (let r=0; r<20; r++) {
for (let monkey of monkeys) {
const throwTos = monkey.items.map(monkey.op).forEach(monkey.throwTo)
monkey.count += monkey.items.length
monkey.items = []
}
}
var sortedCount = monkeys.map(m => m.count).sort((a, b) => b-a)
sortedCount[0] * sortedCount[1]
Manage worry level by lcm.
var lcm = 7*11*13*3*17*2*5*19
var monkeys = [
{
items: [63, 57],
op: n => n*11 % lcm,
throwTo: n => monkeys[n % 7 === 0 ? 6 : 2].items.push(n),
count: 0,
},
var map = line.map(l => l.split('').map(c => c.charCodeAt() - 'a'.charCodeAt()))
var S, E
for (let i=0; i<map.length; i++) {
for (let j=0; j<map[0].length; j++) {
if (map[i][j] === -14) { // S
S = [i, j]
map[i][j] = -1
}
if (map[i][j] === -28) { // E
E = [i, j]
map[i][j] = 25
}
}
}
var queue = [[...S, 0, 0]]
while (queue.length !== 0) {
const [i, j, current, depth] = queue.shift()
if (i === E[0] && j === E[1]) {
console.log(depth)
break
}
const dirs = [[0, 1], [0, -1], [1, 0], [-1, 0]]
dirs.forEach(dir => {
const targetI = i+dir[0]
const targetJ = j+dir[1]
const target = map[targetI]?.[targetJ]
if (target !== undefined && target != -1 && target <= current+1) {
queue.push([targetI, targetJ, target, depth+1])
map[targetI][targetJ] = -1
}
})
}
var map = line.map(l => l.split('').map(c => c.charCodeAt() - 'a'.charCodeAt()))
var E
for (let i=0; i<map.length; i++) {
for (let j=0; j<map[0].length; j++) {
if (map[i][j] === -14) {
map[i][j] = 0
}
if (map[i][j] === -28) { // E
E = [i, j]
map[i][j] = -1
}
}
}
var queue = [[...E, 25, 0]]
while (queue.length !== 0) {
const [i, j, current, depth] = queue.shift()
if (current === 0) {
console.log(depth)
break
}
const dirs = [[0, 1], [0, -1], [1, 0], [-1, 0]]
dirs.forEach(dir => {
const targetI = i+dir[0]
const targetJ = j+dir[1]
const target = map[targetI]?.[targetJ]
if (target !== undefined && target != -1 && target >= current-1) {
queue.push([targetI, targetJ, target, depth+1])
map[targetI][targetJ] = -1
}
})
}
var line = document.querySelector('pre').innerText.split('\n\n').map(pair => pair.split('\n').filter(s => s).map(JSON.parse))
var compare = (left, right) => {
if (right === undefined) return false
if (typeof left !== 'object') left = [left]
if (typeof right !== 'object') right = [right]
for (let i=0; i<Math.min(left.length, right.length); i++) {
if (typeof left[i] === 'object' || typeof right[i] === 'object') {
const res = compare(left[i], right[i])
if (res !== null) return res
} else if (left[i] > right[i]) return false
else if (left[i] < right[i]) return true
}
if (left.length < right.length) return true
else if (left.length > right.length) return false
return null;
}
line.map(pair => compare(...pair)).reduce((s, b, i) => b ? s+i+1 : s, 0)
var line = document.querySelector('pre').innerText.split('\n').filter(s => s).map(s => JSON.parse(s))
var compare = (left, right) => {
if (right === undefined) return 1
if (typeof left !== 'object') left = [left]
if (typeof right !== 'object') right = [right]
for (let i=0; i<Math.min(left.length, right.length); i++) {
if (typeof left[i] === 'object' || typeof right[i] === 'object') {
const res = compare(left[i], right[i])
if (res !== 0) return res
} else if (left[i] > right[i]) return 1
else if (left[i] < right[i]) return -1
}
if (left.length < right.length) return -1
else if (left.length > right.length) return 1
return 0;
}
var res = 1
line.concat([[[2]], [[6]]]).sort(compare).forEach((a, i) => {
if ((a[0]?.[0] === 2 || a[0]?.[0] === 6) && a.length === 1 && a[0].length === 1) res *= (i+1)
})
res
var line = document.querySelector('pre').innerText.split('\n').filter(s => s).map(s => s.split(' -> ').map(p => p.split(',').map(Number)))
var MAX_HEIGHT = 170
var map = new Array(509)
for (let i=0; i<map.length; i++) map[i] = new Array(MAX_HEIGHT).fill('.')
line.forEach(paths => {
for (let i=0; i<paths.length-1; i++) {
const diff = [paths[i+1][0]-paths[i][0], paths[i+1][1]-paths[i][1]]
const length = Math.max(Math.abs(diff[0]), Math.abs(diff[1]))
const step = diff.map(d => d/length)
for (let j=0; j<length+1; j++) {
map[paths[i][0]+step[0]*j][paths[i][1]+step[1]*j] = '#'
}
}
})
var fall = ([x, y]) => {
while (y<MAX_HEIGHT) {
if (map[x][y+1] !== '#') y++
else if (map[x-1][y+1] !== '#') {
x--
y++
} else if (map[x+1][y+1] !== '#') {
x++
y++
} else break
}
if (y === MAX_HEIGHT) return null
map[x][y] = '#'
return [x, y]
}
var count = 0
while (true) {
if (fall([500, 0]) === null) break
count++
}
count
var line = document.querySelector('pre').innerText.split('\n').filter(s => s).map(s => s.split(' -> ').map(p => p.split(',').map(Number)))
var MAX_HEIGHT = 172
var map = new Array(1000)
for (let i=0; i<map.length; i++) {
map[i] = new Array(MAX_HEIGHT).fill('.')
map[i][MAX_HEIGHT-1] = '#'
}
line.forEach(paths => {
for (let i=0; i<paths.length-1; i++) {
const diff = [paths[i+1][0]-paths[i][0], paths[i+1][1]-paths[i][1]]
const length = Math.max(Math.abs(diff[0]), Math.abs(diff[1]))
const step = diff.map(d => d/length)
for (let j=0; j<length+1; j++) {
map[paths[i][0]+step[0]*j][paths[i][1]+step[1]*j] = '#'
}
}
})
var fall = ([x, y]) => {
while (y<MAX_HEIGHT) {
if (map[x][y+1] !== '#') y++
else if (map[x-1][y+1] !== '#') {
x--
y++
} else if (map[x+1][y+1] !== '#') {
x++
y++
} else break
}
if (x === 500 && y === 0) return null
map[x][y] = '#'
return [x, y]
}
var count = 1
while (true) {
if (fall([500, 0]) === null) break
count++
}
count
var line = document.querySelector('pre').innerText.split('\n').filter(s => s).map(s => {
let [_, sensor, beacon] = s.split('at ')
sensor = sensor.split(':')[0]
const parseCoor = s => s.split(', ').map(each => each.split('=')[1]).map(Number)
return [parseCoor(sensor), parseCoor(beacon)]
})
var Y = 2000000
var yRow = {}
line.forEach(([senosr, beacon]) => {
if (senosr[1] == Y) yRow[senosr[0]] = 'S'
if (beacon[1] == Y) yRow[beacon[0]] = 'B'
const mDist = Math.abs(senosr[0]-beacon[0]) + Math.abs(senosr[1]-beacon[1])
const yDist = Math.abs(Y-senosr[1])
if (yDist <= mDist) {
const xDist = mDist - yDist
for (let i=senosr[0]-xDist; i<=senosr[0]+xDist; i++) {
if (!yRow[i]) yRow[i] = '#'
}
}
})
Object.values(yRow).filter(p => p === '#').length
var line = document.querySelector('pre').innerText.split('\n').filter(s => s).map(s => {
let [_, sensor, beacon] = s.split('at ')
sensor = sensor.split(':')[0]
const parseCoor = s => s.split(', ').map(each => each.split('=')[1]).map(Number)
sensor = parseCoor(sensor)
beacon = parseCoor(beacon)
const mDist = Math.abs(sensor[0]-beacon[0]) + Math.abs(sensor[1]-beacon[1])
return [sensor, mDist]
})
var MAX = 4000000
var X = []
var mergeRange = (r1, r2) => {
if (r1[1]+1 < r2[0] || r1[0] > r2[1]+1) return [r1, r2]
else return [Math.min(r1[0], r2[0]), Math.max(r1[1], r2[1])]
}
line.forEach(([sensor, mDist]) => {
for (let x=Math.max(0, sensor[0]-mDist); x<=Math.min(sensor[0]+mDist, MAX); x++) {
const yDist = mDist - Math.abs(sensor[0]-x)
let yRange = [Math.max(0, sensor[1]-yDist), Math.min(MAX, sensor[1]+yDist)]
let result = []
if (!X[x]) X[x] = []
X[x].forEach(range => {
const merged = mergeRange(range, yRange)
if (typeof merged[0] === 'object') result.push(merged[0])
else yRange = merged
})
result.push(yRange)
X[x] = result
}
})
X.map((x, index) => {
const result = []
const sorted = x.sort((a, b) => a[0] - b[0])
for (let i=0; i<sorted.length-1; i++) {
result.push(`${index},${sorted[i][1]+1}`)
}
return result
}).filter(x => x.length)[0].forEach(p => {
const [x, y] = p.split(',')
console.log(x*4000000 + parseInt(y))
})
var graph = {}
var line = document.querySelector('pre').innerText.split('\n').filter(s => s).forEach(s => {
let bySemi = s.split(';')
graph[bySemi[0].split(' ')[1]] = {
rate: parseInt(bySemi[0].split('=')[1]),
to: bySemi[1].split(', ').map((v, i) => i === 0 ? v.split(' ')[5] : v)
}
})
var bfs = start => {
const walked = new Set()
walked.add(start)
const queue = [[start, 0]]
while (queue.length !== 0) {
const [target, cost] = queue.shift()
const node = graph[target]
if (node.rate !== 0 && start !== target) {
graph[start][target] = cost+1
}
node.to.forEach(t => {
if (!walked.has(t)) {
walked.add(t)
queue.push([t, cost+1])
}
})
}
}
Object.keys(graph).forEach(bfs)
Object.keys(graph).forEach(node => {
if (graph[node].rate === 0 && node !== 'AA') delete graph[node]
})
var walked = new Set()
walked.add('AA')
var dfs = (node, mins) => {
const [rate, to, ...targets] = Object.keys(graph[node])
const release = graph[node].rate * mins
const candidates = targets.filter(t => !walked.has(t)).map(t => {
if (mins < graph[node][t]) return 0
walked.add(t)
const candidate = dfs(t, mins-graph[node][t])
walked.delete(t)
return candidate
})
return release + (candidates.length == 0 ? 0 : Math.max(...candidates))
}
dfs('AA', 30)
var walked = { 'AA': true }
var memo = {}
var dfs = (p, pMins, e, eMins) => {
let pRelease = graph[p].rate * pMins
let eRelease = graph[e].rate * eMins
const comb = `${p},${e},${pMins},${eMins},${Object.entries(walked).filter(([k, v]) => v).map(([k, v]) => k).join(':')}`
if (memo[comb]) return pRelease + eRelease + memo[comb]
let [rate, to, ...pTargets] = Object.keys(graph[p])
let [_rate, _to, ...eTargets] = Object.keys(graph[e])
let max = 0
for (let i=0; i<pTargets.length; i++) {
const pTarget = pTargets[i]
if (walked[pTarget] || pMins <= graph[p][pTarget]) continue
walked[pTarget] = true
for (let j=0; j<eTargets.length; j++) {
const eTarget = eTargets[j]
if (walked[eTarget] || eMins < graph[e][eTarget]) continue
walked[eTarget] = true
const candidate = dfs(pTarget, pMins-graph[p][pTarget], eTarget, eMins-graph[e][eTarget])
if (candidate > max) max = candidate
walked[eTarget] = false
}
walked[pTarget] = false
}
memo[comb] = max
return pRelease + eRelease + max
}
dfs('AA', 26, 'AA', 26)
var jets = document.querySelector('pre').innerText.split('\n').filter(s => s)[0].split('').map(a => a === '>' ? 1 : -1)
var test = `>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>`.split('').map(a => a === '>' ? 1 : -1)
var chamber = []
for (let i=0; i<7; i++) chamber.push({})
var rocks = [
{
units: [[0, 0], [1, 0], [2, 0], [3, 0]],
bottomChecks: [[0, -1], [1, -1], [2, -1], [3, -1]],
leftChecks: [[-1, 0]],
rightChecks: [[4, 0]],
},
{
units: [[0, 1], [1, 1], [2, 1], [1, 0], [1, 2]],
bottomChecks: [[0, 0], [1, -1], [2, 0]],
leftChecks: [[0, 0], [-1, 1], [0, 2]],
rightChecks: [[2, 0], [3, 1], [2, 2]],
},
{
units: [[0, 0], [1, 0], [2, 0], [2, 1], [2, 2]],
bottomChecks: [[0, -1], [1, -1], [2, -1]],
leftChecks: [[-1, 0], [1, 1], [1, 2]],
rightChecks: [[3, 0], [3, 1], [3, 2]],
},
{
units: [[0, 0], [0, 1], [0, 2], [0, 3]],
bottomChecks: [[0, -1]],
leftChecks: [[-1, 0], [-1, 1], [-1, 2], [-1, 3]],
rightChecks: [[1, 0], [1, 1], [1, 2], [1, 3]],
},
{
units: [[0, 0], [1, 0], [0, 1], [1, 1]],
bottomChecks: [[0, -1], [1, -1]],
leftChecks: [[-1, 0], [-1, 1]],
rightChecks: [[2, 0], [2, 1]],
},
]
var jet = 0
var peak = 0
for (let i=0; i<2022; i++) {
const rock = rocks[i%rocks.length]
const pos = [2, peak+4]
while (true) {
const dir = jets[jet++ % jets.length]
if (dir === 1) {
if (rock.rightChecks.every(([x, y]) => x+pos[0] < 7 && !chamber[x+pos[0]]?.[y+pos[1]])) {
pos[0] += dir
}
} else {
if (rock.leftChecks.every(([x, y]) => x+pos[0] >= 0 && !chamber[x+pos[0]]?.[y+pos[1]])) {
pos[0] += dir
}
}
if (rock.bottomChecks.every(([x, y]) => y+pos[1] > 0 && !chamber[x+pos[0]]?.[y+pos[1]])) {
pos[1]--
} else break
}
rock.units.forEach(([x, y]) => {
chamber[x+pos[0]][y+pos[1]] = 1
peak = Math.max(peak, y+pos[1])
})
}
peak
var run = (times, memo) => {
var jet = 0
var peak = 0
var chamber = []
for (let i=0; i<7; i++) chamber.push({})
for (let i=0; i<times; i++) {
const rock = rocks[i%rocks.length]
const pos = [2, peak+4]
while (true) {
const dir = jets[jet++ % jets.length]
if (dir === 1) {
if (rock.rightChecks.every(([x, y]) => x+pos[0] < 7 && !chamber[x+pos[0]]?.[y+pos[1]])) {
pos[0] += dir
}
} else {
if (rock.leftChecks.every(([x, y]) => x+pos[0] >= 0 && !chamber[x+pos[0]]?.[y+pos[1]])) {
pos[0] += dir
}
}
if (rock.bottomChecks.every(([x, y]) => y+pos[1] > 0 && !chamber[x+pos[0]]?.[y+pos[1]])) {
pos[1]--
} else break
}
rock.units.forEach(([x, y]) => {
chamber[x+pos[0]][y+pos[1]] = 1
peak = Math.max(peak, y+pos[1])
})
if (memo) {
const key = `${jet%jets.length}:${i%rocks.length}`
if (memo[key]) {
console.log(jet, i, key, memo[key])
}
memo[key] = i
}
}
return peak
}
run(2022, {}) // found from memo that from 90 it starts to loop until 1780
var firstLoop = run(1780)
var beforeLoop = run(90)
var loop = 1780-90
var loopsHeight = Math.floor(1000000000000/loop) * (firstLoop-beforeLoop)
var afterLoops = run((1000000000000 % loop))
loopsHeight + afterLoops
var map = {}
var LENGTH = 20
for (let x=0; x<LENGTH; x++) {
map[x] = {}
for (let y=0; y<LENGTH; y++) {
map[x][y] = {}
}
}
line.map(s => s.split(',').map(Number)).forEach(([x,y,z]) => map[x][y][z] = 1)
var count = 0
for (let x=0; x<LENGTH; x++) {
for (let y=0; y<LENGTH; y++) {
for (let z=0; z<LENGTH; z++) {
if (map[x][y][z] === 1) {
const dirs = [[1,0,0],[-1,0,0],[0,1,0],[0,-1,0],[0,0,1],[0,0,-1]]
count += dirs.filter(([_x, _y, _z]) => {
const X = x + _x
const Y = y + _y
const Z = z + _z
if (X < 0 || X >=LENGTH || Y < 0 || Y >=LENGTH || Z < 0 || Z >=LENGTH) return true
return !map[X][Y][Z]
}).length
}
}
}
}
count
var map = {}
var LENGTH = 20
for (let x=0; x<LENGTH; x++) {
map[x] = {}
for (let y=0; y<LENGTH; y++) {
map[x][y] = {}
}
}
line.map(s => s.split(',').map(Number)).forEach(([x,y,z]) => map[x][y][z] = 1)
var dirs = [[1,0,0],[-1,0,0],[0,1,0],[0,-1,0],[0,0,1],[0,0,-1]]
var countSurfaces = (x, y, z) => dirs.filter(([_x, _y, _z]) => {
const X = x + _x
const Y = y + _y
const Z = z + _z
if (X < 0 || X >=LENGTH || Y < 0 || Y >=LENGTH || Z < 0 || Z >=LENGTH) return true
return map[X][Y][Z] === 2
}).length
var dfs = (x, y, z, walked) => {
for (let d=0; d<dirs.length; d++) {
const [_x, _y, _z] = dirs[d]
const X = x + _x
const Y = y + _y
const Z = z + _z
if (X < 0 || X >=LENGTH || Y < 0 || Y >=LENGTH || Z < 0 || Z >=LENGTH) {
return 2
}
let type = map[X][Y][Z]
if (!type && !walked[`${X},${Y},${Z}`]) {
walked[`${X},${Y},${Z}`] = true
type = dfs(X, Y, Z, walked)
map[X][Y][Z] = type
}
if (!type || type === 1) continue
return type
}
}
for (let x=0; x<LENGTH; x++) {
for (let y=0; y<LENGTH; y++) {
for (let z=0; z<LENGTH; z++) {
if (!map[x][y][z]) {
map[x][y][z] = dfs(x, y, z, { [`${x},${y},${z}`]: true })
}
}
}
}
var count = 0
for (let x=0; x<LENGTH; x++) {
for (let y=0; y<LENGTH; y++) {
for (let z=0; z<LENGTH; z++) {
if (map[x][y][z] === 1) {
count += countSurfaces(x, y, z)
}
}
}
}
count
var blueprints = line.map(s => {
const parts = s.split('.').map(sentence => sentence.split(' '))
return {
0: [parseInt(parts[0][6]), 0, 0],
1: [parseInt(parts[1][5]), 0, 0],
2: [parseInt(parts[2][5]), parseInt(parts[2][8]), 0],
3: [parseInt(parts[3][5]), 0, parseInt(parts[3][8])],
}
})
var dfs = (inventory, robots, blueprint, mins, walked) => {
if (mins === 0) return inventory[3]
const key = inventory.join(',') + ':' + robots.join(',')
if (walked[key]) {
return walked[key]
}
const newInventory = [...inventory]
robots.forEach((r, i) => newInventory[i] += r)
let option
let maxGeodes = 0
for (let robot=3; robot>=0; robot--) {
const requirements = blueprint[robot]
if (requirements.some((r, i) => inventory[i] < r)) continue
const optionInventory = [...newInventory]
requirements.forEach((r, i) => optionInventory[i] -= r)
const newRobots = [...robots]
newRobots[robot]++
const geodes = dfs(optionInventory, newRobots, blueprint, mins-1, walked)
if (geodes > maxGeodes) {
maxGeodes = geodes
}
option = robot
if (robot !== 1) break
}
let options = Object.entries(blueprint).filter(([_, requirements]) => requirements.every((r, i) => inventory[i] >= r))
if (option != 3) {
const optionsIfPause = Object.entries(blueprint).filter(([_, requirements]) => requirements.every((r, i) => newInventory[i] >= r))
const pause2Inventory = [...newInventory]
robots.forEach((r, i) => pause2Inventory[i] += r)
const optionsIfPause2 = Object.entries(blueprint).filter(([_, requirements]) => requirements.every((r, i) => pause2Inventory[i] >= r))
if (options.length === 0 || optionsIfPause.length > options.length) {
const pause = dfs(newInventory, robots, blueprint, mins-1, walked)
if (pause > maxGeodes) {
maxGeodes = pause
option = 'pause'
}
} else if (optionsIfPause2.length > options.length && mins-2 >= 0) {
const pause2 = dfs(pause2Inventory, robots, blueprint, mins-2, walked)
if (pause2 > maxGeodes) {
maxGeodes = pause2
option = 'pause2'
}
}
}
walked[key] = maxGeodes
return maxGeodes
}
let res = 0
for (let i=0; i<blueprints.length; i++) {
res += dfs([0, 0, 0, 0], [1, 0, 0, 0], blueprints[i], 24, {}) * (i+1)
}
res
let res = 1
for (let i=0; i<3; i++) {
res *= dfs([0, 0, 0, 0], [1, 0, 0, 0], line[i], 32, {})
}
res
var arr = document.querySelector('pre').innerText.split('\n').filter(s => s)
var head
var ZERO
for (let i=0; i<arr.length; i++) {
const n = parseInt(arr[i])
arr[i] = { n }
if (i === 0) {
head = arr[i]
} else if (i === arr.length-1) {
head.prev = arr[i]
arr[i].next = head
arr[i-1].next = arr[i]
arr[i].prev = arr[i-1]
} else {
arr[i-1].next = arr[i]
arr[i].prev = arr[i-1]
}
if (n === 0) ZERO = arr[i]
}
for (let i=0; i<arr.length; i++) {
const n = arr[i].n
const step = n % (arr.length-1)
if (step === 0) continue
let dir = 'next'
let target = arr[i]
if (step < 0) {
dir = 'prev'
target = target.prev
}
for (let j=0; j<Math.abs(step); j++) {
target = target[dir]
}
arr[i].next.prev = arr[i].prev
arr[i].prev.next = arr[i].next
target.next.prev = arr[i]
arr[i].next = target.next
target.next = arr[i]
arr[i].prev = target
}
let res = 0
for (let i=1000; i<=3000; i+=1000) {
const step = i % arr.length
let target = ZERO
for (let j=0; j<step; j++) target = target.next
res += target.n
}
res
// ...
arr[i] = { n*811589153 }
//...
for (let t=0; t<10; t++)
for (let i=0; i<arr.length; i++) {
// ...
eval(line.map(s => {
let [monkey, operation] = s.split(': ')
monkey = `var ${monkey} = () => `
const operationParts = operation.split(' ')
if (operationParts.length !== 1) {
operation = `${operationParts[0]}() ${operationParts[1]} ${operationParts[2]}()`
}
return monkey + operation
}).join('\n') + '\n root()')
var map = line.reduce((res, s) => {
const [monkey, operation] = s.split(': ')
res[monkey] = operation.split(' ')
return res
}, {})
var REPLACE = 'REPLACE'
var reverseOP = {
left: {
['+']: '-',
['*']: '/',
['-']: '+',
['/']: '*',
},
right: {
['+']: '-',
['*']: '/',
['-']: '-',
['/']: '/',
},
}
var dfs = (monkey) => {
let [left, op, right] = map[monkey]
if (monkey === 'humn') return REPLACE
if (op == null) return left
left = dfs(left)
right = dfs(right)
if (left.includes(REPLACE)) {
return left.replace(REPLACE, `(${REPLACE}) ${reverseOP.left[op]} ${right}`)
} else if (right.includes('REPLACE')) {
const newLeft = op === '+' || op === '*' ? `(${REPLACE})` : left
const newRight = op === '+' || op === '*' ? left : `(${REPLACE})`
return right.replace(REPLACE, `${newLeft} ${reverseOP.right[op]} ${newRight}`)
} else return `${eval([left, op, right].join(' '))}`
}
var humn = dfs(map.root[0])
eval(humn.replace(REPLACE, eval(map.root[2] + '()')))
var line = document.querySelector('pre').innerText.split('\n\n')
var map = line[0].split('\n').map(s => s.split(''))
var pos = [0, map[0].indexOf('.')]
var paths = []
var temp = ''
for (let c of line[1].trim()) {
if (['L', 'R'].includes(c)) {
if (temp.length !== 0) {
paths.push(parseInt(temp))
temp = ''
}
paths.push(c)
} else temp += c
}
if (temp.length !== 0) {
paths.push(parseInt(temp))
}
var faces = [[0, 1], [1, 0], [0, -1], [-1, 0]] // R, D, L, U
var face = 0
for (let p=0; p<paths.length; p++) {
const path = paths[p]
if (path === 'L') {
face = (face+faces.length-1) % faces.length
} else if (path === 'R') {
face = (face+1) % faces.length
} else {
let [x, y] = pos
const [dX, dY] = faces[face]
for (let i=0; i<path; i++) {
let newX = x
let newY = y
while (true) {
newX += dX
newY += dY
if (newX >= map.length) newX = 0
else if (newX < 0) newX = map.length-1
else if (newY >= map[0].length) newY = 0
else if (newY < 0) newY = map[newX].length-1
if (map[newX][newY] && map[newX][newY] !== ' ') break
}
if (map[newX][newY] === '#') break
else {
x = newX
y = newY
}
map[newX][newY] = 'X'
}
pos = [x, y]
}
}
(pos[0]+1)*1000 + (pos[1]+1)*4 + face
var line = document.querySelector('pre').innerText.split('\n\n')
var test = ` ...#
.#..
#...
....
...#.......#
........#...
..#....#....
..........#.
...#....
.....#..
.#......
......#.
10R5L5R10L4R5L5`.split('\n\n')
var map = line[0].split('\n').map(s => s.split('').map(n => n === ' ' ? undefined : n))
var mapWidth = map[8].length
var swapMap = []
for (let j=0; j<mapWidth; j++) {
swapMap[j] = []
for (let i=0; i<map.length; i++) {
swapMap[j][i] = map[i][j]
}
}
var pos = [0, map[0].indexOf('.')]
var paths = []
var temp = ''
for (let c of line[1].trim()) {
if (['L', 'R'].includes(c)) {
if (temp.length !== 0) {
paths.push(parseInt(temp))
temp = ''
}
paths.push(c)
} else temp += c
}
if (temp.length !== 0) {
paths.push(parseInt(temp))
}
var faces = [[0, 1], [1, 0], [0, -1], [-1, 0]] // R, D, L, U
var face = 0
for (let p=0; p<paths.length; p++) {
const path = paths[p]
if (path === 'L') {
face = (face+faces.length-1) % faces.length
} else if (path === 'R') {
face = (face+1) % faces.length
} else {
let [x, y] = pos
const [dX, dY] = faces[face]
for (let i=0; i<path; i++) {
let newX = x + dX
let newY = y + dY
if (!map[newX]?.[newY] || map[newX][newY] === ' ') {
if (face === 0) newY = Math.min(map[newX].indexOf('.'), map[newX].indexOf('#'))
else if (face === 1) newX = Math.min(swapMap[newY].indexOf('.'), swapMap[newY].indexOf('#'))
else if (face === 2) newY = Math.max(map[newX].lastIndexOf('.'), map[newX].lastIndexOf('#'), map[newX].lastIndexOf('X'))
else newX = Math.max(swapMap[newY].lastIndexOf('.'), swapMap[newY].lastIndexOf('#'), swapMap[newY].lastIndexOf('X'))
}
if (map[newX][newY] === '#') break
else {
x = newX
y = newY
}
}
pos = [x, y]
}
}
(pos[0]+1)*1000 + (pos[1]+1)*4 + face
var transformR50to99 = x => [49, x+50, 3]
var transformD100to149 = y => [y-50, 99, 2]
var transformL50to99 = x => [100, x-50, 1]
var transformU0to49 = y => [y+50, 50, 0]
var transformR0to49 = x => [149-x, 99, 2]
var transformR100to149 = x => [149-x, 149, 2]
var transformL0to49 = x => [149-x, 0, 0]
var transformL100to149 = x => [149-x, 50, 0]
var transformD50to99 = y => [y+100, 49, 2]
var transformR150to199 = x => [149, x-100, 3]
var transformU50to99 = y => [y+100, 0, 0]
var transformL150to199 = x => [0, x-100, 1]
var transformU100to149 = y => [199, y-100, 3]
var transformD0to49 = y => [0, y+100, 1]
for (let p=0; p<paths.length; p++) {
const path = paths[p]
if (path === 'L') {
face = (face+faces.length-1) % faces.length
} else if (path === 'R') {
face = (face+1) % faces.length
} else {
let [x, y] = pos
for (let i=0; i<path; i++) {
const [dX, dY] = faces[face]
let newX = x
let newY = y
let newFace = face
while (true) {
newX += dX
newY += dY
if (newX >= map.length) {
const transformed = y < 50
? transformD0to49(y)
: y < 100
? transformD50to99(y)
: transformD100to149(y)
newX = transformed[0]
newY = transformed[1]
newFace = transformed[2]
} else if (newX < 0) {
const transformed = y < 50
? transformU0to49(y)
: y < 100
? transformU50to99(y)
: transformU100to149(y)
newX = transformed[0]
newY = transformed[1]
newFace = transformed[2]
} else if (newY >= map[0].length) {
const transformed = x < 50
? transformR0to49(x)
: x < 100
? transformR50to99(x)
: x < 150
? transformR100to149(x)
: transformR150to199(x)
newX = transformed[0]
newY = transformed[1]
newFace = transformed[2]
} else if (newY < 0) {
const transformed = x < 50
? transformL0to49(x)
: x < 100
? transformL50to99(x)
: x < 150
? transformL100to149(x)
: transformL150to199(x)
newX = transformed[0]
newY = transformed[1]
newFace = transformed[2]
}
if (map[newX][newY] && map[newX][newY] !== ' ') break
}
if (map[newX][newY] === '#') break
else {
x = newX
y = newY
face = newFace
}
}
pos = [x, y]
}
}
(pos[0]+1)*1000 + (pos[1]+1)*4 + face
var elves = []
var map = {}
line.forEach((row, i) => {
map[i] = {}
row.split('').forEach((p, j) => {
if (p === '#') {
elves.push([i, j])
map[i][j] = '#'
}
})
return map
})
var DIRS = {
N: [-1, 0],
S: [1, 0],
E: [0, 1],
W: [0, -1],
NE: [-1, 1],
NW: [-1, -1],
SE: [1, 1],
SW: [1, -1],
}
var lookDirs = [
[ DIRS.N, DIRS.NE, DIRS.NW ],
[ DIRS.S, DIRS.SE, DIRS.SW ],
[ DIRS.W, DIRS.NW, DIRS.SW ],
[ DIRS.E, DIRS.NE, DIRS.SE ]
]
var run = () => {
const targets = {}
elves.forEach((elf, i) => {
for (let l=0; l<lookDirs.length; l++) {
if (Object.values(DIRS).every(dir => map[elf[0]+dir[0]]?.[elf[1]+dir[1]] !== '#')) break
if (lookDirs[l].every(dir => map[elf[0]+dir[0]]?.[elf[1]+dir[1]] !== '#')) {
const [dX, dY] = lookDirs[l][0]
const newX = elf[0]+dX
const newY = elf[1]+dY
if (!targets[newX]) targets[newX] = {}
if (!targets[newX][newY]) targets[newX][newY] = []
targets[newX][newY].push(i)
break
}
}
})
Object.entries(targets).forEach(([x, v]) => {
Object.entries(v).forEach(([y, candidates]) => {
if (candidates.length === 1) {
const [originX, originY] = elves[candidates[0]]
delete map[originX][originY]
elves[candidates[0]] = [parseInt(x), parseInt(y)]
if (!map[x]) map[x] = {}
map[x][y] = '#'
}
})
})
lookDirs.push(lookDirs.shift())
}
for (let i=0; i<10; i++) {
run()
}
var sortedX = Object.keys(map).filter(x => Object.keys(map[x]).length).map(Number).sort((a, b) => a-b)
var height = sortedX[sortedX.length-1] - sortedX[0] + 1
var minY = Infinity
var maxY = -Infinity
Object.values(map).filter(row => Object.keys(row).length).forEach(row => {
const sortedY = Object.keys(row).map(Number).sort((a, b) => a-b)
minY = Math.min(minY, sortedY[0])
maxY = Math.max(maxY, sortedY[sortedY.length-1])
width = Math.max(width, sortedY[sortedY.length-1] - sortedY[0] + 1)
})
var width = maxY - minY + 1
height*width - elves.length
var run = () => {
const targets = {}
if (elves.filter((elf, i) => {
for (let l=0; l<lookDirs.length; l++) {
if (Object.values(DIRS).every(dir => map[elf[0]+dir[0]]?.[elf[1]+dir[1]] !== '#')) return false
if (lookDirs[l].every(dir => map[elf[0]+dir[0]]?.[elf[1]+dir[1]] !== '#')) {
const [dX, dY] = lookDirs[l][0]
const newX = elf[0]+dX
const newY = elf[1]+dY
if (!targets[newX]) targets[newX] = {}
if (!targets[newX][newY]) targets[newX][newY] = []
targets[newX][newY].push(i)
break
}
}
return true
}).length === 0) return true
Object.entries(targets).forEach(([x, v]) => {
Object.entries(v).forEach(([y, candidates]) => {
if (candidates.length === 1) {
const [originX, originY] = elves[candidates[0]]
delete map[originX][originY]
elves[candidates[0]] = [parseInt(x), parseInt(y)]
if (!map[x]) map[x] = {}
map[x][y] = '#'
}
})
})
lookDirs.push(lookDirs.shift())
}
for (let i=0;; i++) {
if (run()) {
console.log(i)
break
}
}
line.shift()
line.pop()
var originMap = line.map(s => {
const row = s.split('')
row.shift()
row.pop()
return row
})
var maps = new Array(originMap.length*originMap[0].length)
maps[0] = originMap
for (let i=1; i<maps.length; i++) {
const nextMap = new Array(originMap.length)
for (let x=0; x<originMap.length; x++) {
if (!nextMap[x]) nextMap[x] = []
for (let y=0; y<originMap[0].length; y++) {
if (originMap[x][y] === '>') {
const newY = (y+i) % originMap[0].length
if (!nextMap[x][newY]) nextMap[x][newY] = ''
nextMap[x][newY] += originMap[x][y]
} else if (originMap[x][y] === '<') {
const newY = (y - (i % originMap[0].length) + originMap[0].length) % originMap[0].length
if (!nextMap[x][newY]) nextMap[x][newY] = ''
nextMap[x][newY] += originMap[x][y]
} else if (originMap[x][y] === 'v') {
const newX = (x+i) % originMap.length
if (!nextMap[newX]) nextMap[newX] = []
if (!nextMap[newX][y]) nextMap[newX][y] = ''
nextMap[newX][y] += originMap[x][y]
} else if (originMap[x][y] === '^') {
const newX = (x - (i % originMap.length) + originMap.length) % originMap.length
if (!nextMap[newX]) nextMap[newX] = []
if (!nextMap[newX][y]) nextMap[newX][y] = ''
nextMap[newX][y] += originMap[x][y]
}
}
}
maps[i] = nextMap
}
var DIRS = [[0, 1], [1, 0], [0, -1], [-1, 0], [0, 0]]
// Maximum call stack size exceeded
// var memo = {}
// var dfs = ([x, y], depth) => {
// const nextDepth = depth+1
// let min = Infinity
// for (let d=0; d<DIRS.length; d++) {
// const [dX, dY] = DIRS[d]
// const newX = x + dX
// const newY = y + dY
// if (newX === originMap.length -1 && newY === originMap[0].length-1) return nextDepth+1
// if (d !== 4 && (newX < 0 || newX === originMap.length || newY < 0 || newY === originMap[0].length)) continue
// const next = maps[nextDepth%maps.length][newX]?.[newY]
// if (next && next !== '.') continue
// const key = `${newX},${newY},${nextDepth%maps.length}`
// if (memo[key]) continue
// else memo[key] = true
// min = Math.min(min, dfs([newX, newY], nextDepth))
// }
// return min
// }
// dfs([-1, 0], 0)
var bfs = () => {
var memo = new Set()
const queue = [[-1, 0, 0]]
let min = Infinity
while (queue.length !== 0) {
const [x, y, depth] = queue.shift()
const nextDepth = depth+1
for (let d=0; d<DIRS.length; d++) {
const [dX, dY] = DIRS[d]
const newX = x + dX
const newY = y + dY
if (newX === originMap.length && newY === originMap[0].length-1) {
min = Math.min(min, nextDepth)
break
}
if (d !== 4 && (newX < 0 || newX === originMap.length || newY < 0 || newY === originMap[0].length)) continue
const next = maps[nextDepth%maps.length][newX]?.[newY]
if (next && next !== '.') continue
const key = `${newX},${newY},${nextDepth%maps.length}`
if (memo.has(key)) continue
memo.add(key)
queue.push([newX, newY, nextDepth])
}
}
return min
}
bfs()
var bfs = (start, end, initDepth) => {
var memo = new Set()
const queue = [[...start, initDepth]]
let min = Infinity
while (queue.length !== 0) {
const [x, y, depth] = queue.shift()
const nextDepth = depth+1
for (let d=0; d<DIRS.length; d++) {
const [dX, dY] = DIRS[d]
const newX = x + dX
const newY = y + dY
if (newX === end[0] && newY === end[1]) {
min = Math.min(min, nextDepth)
break
}
if (d !== 4 && (newX < 0 || newX >= originMap.length || newY < 0 || newY >= originMap[0].length)) continue
const next = maps[nextDepth%maps.length][newX]?.[newY]
if (next && next !== '.') continue
const key = `${newX},${newY},${nextDepth%maps.length}`
if (memo.has(key)) continue
memo.add(key)
queue.push([newX, newY, nextDepth])
}
}
return min
}
bfs([-1, 0], [originMap.length, originMap[0].length-1],
bfs([originMap.length, originMap[0].length-1], [-1, 0],
bfs([-1, 0], [originMap.length, originMap[0].length-1], 0)))
var nums = line.map(n => n.split('').map(d => d === '-'
? -1
: d === '='
? -2
: parseInt(d)
).reverse())
var overflow = 0
var res = []
for (let i=0;; i++) {
const digitSum = nums.map(n => n[i]).filter(s => s).reduce((s, d) => s+d, 0) + overflow
if (digitSum === 0) break
overflow = digitSum / 5
overflow = overflow > 0 ? Math.floor(overflow) : Math.ceil(overflow)
let reminder = digitSum % 5
if (reminder > 2) {
overflow++
reminder -= 5
} else if (reminder < -2) {
overflow--
reminder += 5
}
res.push(reminder)
}
res.reverse().reduce((r, d) => r += d === -1
? '-'
: d === -2
? '='
: d, '')
There is no such thing!