.
This commit is contained in:
@@ -3,7 +3,8 @@ const closes = [")", "]", "}", ">"]
|
|||||||
const scores1 = { ")": 3, "]": 57, "}": 1197, ">": 25137 }
|
const scores1 = { ")": 3, "]": 57, "}": 1197, ">": 25137 }
|
||||||
const scores2 = { ")": 1, "]": 2, "}": 3, ">": 4 }
|
const scores2 = { ")": 1, "]": 2, "}": 3, ">": 4 }
|
||||||
|
|
||||||
function parse(str) {
|
function day10(input, part2) {
|
||||||
|
let results = input.split("\n").map((str) => {
|
||||||
let stack = []
|
let stack = []
|
||||||
|
|
||||||
for (let i = 0; i < str.length; i++) {
|
for (let i = 0; i < str.length; i++) {
|
||||||
@@ -17,10 +18,7 @@ function parse(str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return stack.reverse()
|
return stack.reverse()
|
||||||
}
|
})
|
||||||
|
|
||||||
function day10(input, part2) {
|
|
||||||
let results = input.split("\n").map(parse)
|
|
||||||
|
|
||||||
if (!part2) {
|
if (!part2) {
|
||||||
return results.filter((e) => !Array.isArray(e)).sum()
|
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]])
|
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()
|
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
|
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: {
|
flatDeep: {
|
||||||
value: function() {
|
value: function() {
|
||||||
return this.flat(Infinity)
|
return this.flat(Infinity)
|
||||||
@@ -1029,6 +1041,7 @@ load = function load() {
|
|||||||
|
|
||||||
load()
|
load()
|
||||||
utils = {
|
utils = {
|
||||||
|
log: (e, copy = false) => (console.log(copy ? e.copyDeep() : e), e),
|
||||||
fetch: (url) => fetch(url).then(e => e.text()),
|
fetch: (url) => fetch(url).then(e => e.text()),
|
||||||
fetchEval: (url) => utils.fetch(url).then(e => eval(e)),
|
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),
|
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
|
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: {
|
flatDeep: {
|
||||||
value: function() {
|
value: function() {
|
||||||
return this.flat(Infinity)
|
return this.flat(Infinity)
|
||||||
|
|||||||
1
utils.js
1
utils.js
@@ -1,4 +1,5 @@
|
|||||||
utils = {
|
utils = {
|
||||||
|
log: (e, copy = false) => (console.log(copy ? e.copyDeep() : e), e),
|
||||||
fetch: (url) => fetch(url).then(e => e.text()),
|
fetch: (url) => fetch(url).then(e => e.text()),
|
||||||
fetchEval: (url) => utils.fetch(url).then(e => eval(e)),
|
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),
|
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