.
This commit is contained in:
32
2021/10.js
32
2021/10.js
@@ -3,24 +3,22 @@ const closes = [")", "]", "}", ">"]
|
||||
const scores1 = { ")": 3, "]": 57, "}": 1197, ">": 25137 }
|
||||
const scores2 = { ")": 1, "]": 2, "}": 3, ">": 4 }
|
||||
|
||||
function parse(str) {
|
||||
let stack = []
|
||||
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
let char = str[i]
|
||||
|
||||
if (opens.includes(char)) {
|
||||
stack.push(closes[opens.indexOf(char)])
|
||||
} else if (char != stack.pop()) {
|
||||
return scores1[char]
|
||||
}
|
||||
}
|
||||
|
||||
return stack.reverse()
|
||||
}
|
||||
|
||||
function day10(input, part2) {
|
||||
let results = input.split("\n").map(parse)
|
||||
let results = input.split("\n").map((str) => {
|
||||
let stack = []
|
||||
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
let char = str[i]
|
||||
|
||||
if (opens.includes(char)) {
|
||||
stack.push(closes[opens.indexOf(char)])
|
||||
} else if (char != stack.pop()) {
|
||||
return scores1[char]
|
||||
}
|
||||
}
|
||||
|
||||
return stack.reverse()
|
||||
})
|
||||
|
||||
if (!part2) {
|
||||
return results.filter((e) => !Array.isArray(e)).sum()
|
||||
|
||||
@@ -31,7 +31,7 @@ function day14(input, part2) {
|
||||
|
||||
counts = Object.keys(counts).map((key) => [key.split(""), counts[key]])
|
||||
|
||||
let letters = counts.map((e) => e[0]).flat().uniq().map((letter) => (counts.filter((e) => e[0].includes(letter)).map((e) => e[0].count(letter) * e[1]).sum() + (letter == init[0] || letter == init[init.length - 1])) / 2)
|
||||
let letters = counts.flatMap((e) => e[0]).uniq().map((letter) => (counts.filter((e) => e[0].includes(letter)).map((e) => e[0].count(letter) * e[1]).sum() + (letter == init[0] || letter == init[init.length - 1])) / 2)
|
||||
|
||||
return letters.max() - letters.min()
|
||||
}
|
||||
|
||||
140
2021/16.js
Normal file
140
2021/16.js
Normal file
@@ -0,0 +1,140 @@
|
||||
function toInt(bits) {
|
||||
return parseInt(bits.join(""), 2)
|
||||
}
|
||||
|
||||
class Packet {
|
||||
full = []
|
||||
|
||||
version = []
|
||||
type = []
|
||||
groups = [[]]
|
||||
lengthType = []
|
||||
length = []
|
||||
|
||||
children = []
|
||||
done = false
|
||||
|
||||
constructor(bits = []) {
|
||||
for (let bit of bits) {
|
||||
this.pushBit(bit)
|
||||
}
|
||||
}
|
||||
|
||||
pushBit(bit) {
|
||||
if (this.version.length < 3) {
|
||||
this.version.push(bit)
|
||||
return this.full.push(bit)
|
||||
}
|
||||
|
||||
if (this.type.length < 3) {
|
||||
this.type.push(bit)
|
||||
return this.full.push(bit)
|
||||
}
|
||||
|
||||
if (this.isLiteral()) {
|
||||
if (this.groups.last.length < 5) {
|
||||
this.groups.last.push(bit)
|
||||
return this.full.push(bit)
|
||||
}
|
||||
|
||||
if (this.groups.last[0]) {
|
||||
this.groups.push([bit])
|
||||
return this.full.push(bit)
|
||||
}
|
||||
} else {
|
||||
if (this.children.length == 0) {
|
||||
this.children.push(new Packet())
|
||||
}
|
||||
|
||||
if (this.lengthType.length < 1) {
|
||||
this.lengthType.push(bit)
|
||||
return this.full.push(bit)
|
||||
}
|
||||
|
||||
if (!this.lengthType[0]) {
|
||||
if (this.length.length < 15) {
|
||||
this.length.push(bit)
|
||||
return this.full.push(bit)
|
||||
}
|
||||
|
||||
if (this.children.map((e) => e.full.length).sum() < toInt(this.length)) {
|
||||
this.children.last.pushBit(bit)
|
||||
|
||||
if (this.children.last.done) {
|
||||
this.children.push(new Packet([bit]))
|
||||
}
|
||||
|
||||
return this.full.push(bit)
|
||||
}
|
||||
} else {
|
||||
if (this.length.length < 11) {
|
||||
this.length.push(bit)
|
||||
return this.full.push(bit)
|
||||
}
|
||||
|
||||
if (!this.children.last.done) {
|
||||
this.children.last.pushBit(bit)
|
||||
|
||||
if (this.children.last.done) {
|
||||
if (this.children.length < toInt(this.length)) {
|
||||
this.children.push(new Packet([bit]))
|
||||
return this.full.push(bit)
|
||||
}
|
||||
} else {
|
||||
return this.full.push(bit)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.done = true
|
||||
}
|
||||
|
||||
isLiteral() {
|
||||
return toInt(this.type) == 4
|
||||
}
|
||||
|
||||
getLiteralValue() {
|
||||
return toInt(this.groups.flatMap((e) => e.slice(1)))
|
||||
}
|
||||
|
||||
getVersionSum() {
|
||||
return toInt(this.version) + this.children.map((e) => e.getVersionSum()).sum()
|
||||
}
|
||||
|
||||
getValue() {
|
||||
if (this.isLiteral()) {
|
||||
return this.getLiteralValue()
|
||||
} else {
|
||||
let operands = this.children.map((e) => e.getValue())
|
||||
|
||||
switch (toInt(this.type)) {
|
||||
case 0:
|
||||
return operands.sum()
|
||||
|
||||
case 1:
|
||||
return operands.prod()
|
||||
|
||||
case 2:
|
||||
return operands.min()
|
||||
|
||||
case 3:
|
||||
return operands.max()
|
||||
|
||||
case 5:
|
||||
return +(operands[0] > operands[1])
|
||||
|
||||
case 6:
|
||||
return +(operands[0] < operands[1])
|
||||
|
||||
case 7:
|
||||
return +(operands[0] == operands[1])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function day16(input, part2) {
|
||||
let bits = input.split("").flatMap((e) => parseInt(e, 16).toString(2).padStart(4, "0").split("").num())
|
||||
return new Packet(bits)[part2 ? "getValue" : "getVersionSum"]()
|
||||
}
|
||||
38
2021/17.js
Normal file
38
2021/17.js
Normal file
@@ -0,0 +1,38 @@
|
||||
function day17(input, part2) {
|
||||
let [minX, maxX, minY, maxY] = input.match(/([-\d]+)/g).num()
|
||||
|
||||
let xVelRange = utils.signAgnosticInclusiveRange(0, maxX)
|
||||
let yVelRange = utils.signAgnosticInclusiveRange(-minY, minY)
|
||||
|
||||
let vels = xVelRange.cartProduct(yVelRange).map((e) => new Point(...e)).pt.filter((e) => {
|
||||
let pos = new Point(0, 0)
|
||||
let vel = e.copy()
|
||||
|
||||
while (pos.x <= maxX && pos.y >= minY) {
|
||||
if (pos.x >= minX && pos.y <= maxY) {
|
||||
return true
|
||||
}
|
||||
|
||||
pos.addMut(vel)
|
||||
|
||||
if (vel.x > 0) {
|
||||
vel.x--
|
||||
}
|
||||
|
||||
vel.y--
|
||||
|
||||
if (vel.y == 0) {
|
||||
e.maxYPos = pos.y
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
})
|
||||
|
||||
if (!part2) {
|
||||
// i feel like this is probably equivalent to minY * (minY + 1) / 2 but im not 100% sure for all inputs
|
||||
return vels.max((e) => e.y).maxYPos
|
||||
} else {
|
||||
return vels.length
|
||||
}
|
||||
}
|
||||
144
2021/18.js
Normal file
144
2021/18.js
Normal file
@@ -0,0 +1,144 @@
|
||||
class SnailfishNumber {
|
||||
static fromArr(arr, parent = null, isRight) {
|
||||
let num = new SnailfishNumber()
|
||||
return num.initialize(
|
||||
arr[0] instanceof Array ? SnailfishNumber.fromArr(arr[0], num, false) : arr[0],
|
||||
arr[1] instanceof Array ? SnailfishNumber.fromArr(arr[1], num, true) : arr[1],
|
||||
parent, isRight)
|
||||
}
|
||||
|
||||
initialize(left, right, parent, isRight) {
|
||||
this.left = left
|
||||
this.right = right
|
||||
this.parent = parent
|
||||
this.isRight = isRight
|
||||
return this
|
||||
}
|
||||
|
||||
explode(depth = 0) {
|
||||
if (this.left instanceof SnailfishNumber) {
|
||||
if (this.left.explode(depth + 1)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if (this.right instanceof SnailfishNumber) {
|
||||
if (this.right.explode(depth + 1)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if (!(this.left instanceof SnailfishNumber) && !(this.right instanceof SnailfishNumber) && depth >= 4) {
|
||||
let lastNode = this
|
||||
let node = this.parent
|
||||
|
||||
while (node && node.left == lastNode) {
|
||||
lastNode = node
|
||||
node = node.parent
|
||||
}
|
||||
|
||||
if (node) {
|
||||
if (!(node.left instanceof SnailfishNumber)) {
|
||||
node.left += this.left
|
||||
} else {
|
||||
node = node.left
|
||||
|
||||
while (node.right instanceof SnailfishNumber) {
|
||||
node = node.right
|
||||
}
|
||||
|
||||
node.right += this.left
|
||||
}
|
||||
}
|
||||
|
||||
lastNode = this
|
||||
node = this.parent
|
||||
|
||||
while (node && node.right == lastNode) {
|
||||
lastNode = node
|
||||
node = node.parent
|
||||
}
|
||||
|
||||
if (node) {
|
||||
if (!(node.right instanceof SnailfishNumber)) {
|
||||
node.right += this.right
|
||||
} else {
|
||||
node = node.right
|
||||
|
||||
while (node.left instanceof SnailfishNumber) {
|
||||
node = node.left
|
||||
}
|
||||
|
||||
node.left += this.right
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.isRight) {
|
||||
this.parent.left = 0
|
||||
} else {
|
||||
this.parent.right = 0
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
split() {
|
||||
if (this.left instanceof SnailfishNumber) {
|
||||
if (this.left.split()) {
|
||||
return true
|
||||
}
|
||||
} else if (this.left >= 10) {
|
||||
this.left = SnailfishNumber.fromArr([Math.floor(this.left / 2), Math.ceil(this.left / 2)], this, false)
|
||||
return true
|
||||
}
|
||||
|
||||
if (this.right instanceof SnailfishNumber) {
|
||||
if (this.right.split()) {
|
||||
return true
|
||||
}
|
||||
} else if (this.right >= 10) {
|
||||
this.right = SnailfishNumber.fromArr([Math.floor(this.right / 2), Math.ceil(this.right / 2)], this, true)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
reduce() {
|
||||
while (this.explode() || this.split());
|
||||
return this
|
||||
}
|
||||
|
||||
add(that) {
|
||||
let parent = SnailfishNumber.fromArr([this, that])
|
||||
this.parent = parent
|
||||
this.isRight = false
|
||||
that.parent = parent
|
||||
that.isRight = true
|
||||
return parent.reduce()
|
||||
}
|
||||
|
||||
magnitude() {
|
||||
return 3 * (this.left instanceof SnailfishNumber ? this.left.magnitude() : this.left) +
|
||||
2 * (this.right instanceof SnailfishNumber ? this.right.magnitude() : this.right)
|
||||
}
|
||||
|
||||
toString() {
|
||||
return "[" + this.left.toString() + "," + this.right.toString() + "]"
|
||||
}
|
||||
}
|
||||
|
||||
function day18(input, part2) {
|
||||
let lines = input.split("\n")
|
||||
|
||||
if (!part2) {
|
||||
let nums = lines.map((line) => SnailfishNumber.fromArr(JSON.parse(line)))
|
||||
return nums.reduce((a, b) => a.add(b)).magnitude()
|
||||
} else {
|
||||
let pairs = lines.flatMap((e) => lines.filter((f) => e != f).map((f) => [e, f].map((e) => SnailfishNumber.fromArr(JSON.parse(e)))))
|
||||
return pairs.map((e) => e[0].add(e[1]).magnitude()).max()
|
||||
}
|
||||
}
|
||||
13
out.js
13
out.js
@@ -768,6 +768,18 @@ load = function load() {
|
||||
},
|
||||
configurable: true
|
||||
},
|
||||
prod: {
|
||||
value: function(val = 1) {
|
||||
return this.reduce((a, b) => a * b, val)
|
||||
},
|
||||
configurable: true
|
||||
},
|
||||
cartProduct: {
|
||||
value: function(that) {
|
||||
return this.flatMap((e) => that.map((f) => [e, f]))
|
||||
},
|
||||
configurable: true
|
||||
},
|
||||
flatDeep: {
|
||||
value: function() {
|
||||
return this.flat(Infinity)
|
||||
@@ -1029,6 +1041,7 @@ load = function load() {
|
||||
|
||||
load()
|
||||
utils = {
|
||||
log: (e, copy = false) => (console.log(copy ? e.copyDeep() : e), e),
|
||||
fetch: (url) => fetch(url).then(e => e.text()),
|
||||
fetchEval: (url) => utils.fetch(url).then(e => eval(e)),
|
||||
signAgnosticInclusiveRange: (a, b, s = Math.sign(a - b)) => Array((a - b) * s + 1).fill().map((_, i) => a - i * s),
|
||||
|
||||
12
proto.js
12
proto.js
@@ -102,6 +102,18 @@ load = function load() {
|
||||
},
|
||||
configurable: true
|
||||
},
|
||||
prod: {
|
||||
value: function(val = 1) {
|
||||
return this.reduce((a, b) => a * b, val)
|
||||
},
|
||||
configurable: true
|
||||
},
|
||||
cartProduct: {
|
||||
value: function(that) {
|
||||
return this.flatMap((e) => that.map((f) => [e, f]))
|
||||
},
|
||||
configurable: true
|
||||
},
|
||||
flatDeep: {
|
||||
value: function() {
|
||||
return this.flat(Infinity)
|
||||
|
||||
1
utils.js
1
utils.js
@@ -1,4 +1,5 @@
|
||||
utils = {
|
||||
log: (e, copy = false) => (console.log(copy ? e.copyDeep() : e), e),
|
||||
fetch: (url) => fetch(url).then(e => e.text()),
|
||||
fetchEval: (url) => utils.fetch(url).then(e => eval(e)),
|
||||
signAgnosticInclusiveRange: (a, b, s = Math.sign(a - b)) => Array((a - b) * s + 1).fill().map((_, i) => a - i * s),
|
||||
|
||||
Reference in New Issue
Block a user