-
-
Save Mellen/d5bc791fe2505de6f72ead1d32dd45b4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function(inp) | |
{ | |
const maxDepth = 4; | |
const maxValue = 9 | |
function SnailFishNumber(value, depth, parent, direction) | |
{ | |
this.depth = depth; | |
this.parent = parent; | |
this.isArray = Array.isArray(value); | |
this.direction = direction; | |
if(this.isArray) | |
{ | |
let [left, right] = value; | |
this.left = new SnailFishNumber(left, depth+1, this, 'left'); | |
this.right = new SnailFishNumber(right, depth+1, this, 'right'); | |
} | |
else | |
{ | |
this.value = value; | |
} | |
} | |
SnailFishNumber.prototype.getValue = function() | |
{ | |
let result; | |
if(this.isArray) | |
{ | |
result = [this.left.getValue(), this.right.getValue()] | |
} | |
else | |
{ | |
result = this.value; | |
} | |
return result; | |
} | |
SnailFishNumber.prototype.add = function(rhs) | |
{ | |
let newVal = [this.getValue(), rhs.getValue()]; | |
return new SnailFishNumber(newVal, 0, null, ''); | |
} | |
SnailFishNumber.prototype.maxDepth = function() | |
{ | |
let md = this.depth; | |
if(this.isArray) | |
{ | |
let mdl = this.left.maxDepth(); | |
let mdr = this.right.maxDepth(); | |
md = Math.max(mdl, mdr); | |
} | |
return md; | |
} | |
SnailFishNumber.prototype.maxValue = function() | |
{ | |
let mv = 0; | |
if(this.isArray) | |
{ | |
let mvl = this.left.maxValue(); | |
let mvr = this.right.maxValue(); | |
mv = Math.max(mvl, mvr); | |
} | |
else | |
{ | |
mv = this.value; | |
} | |
return mv; | |
} | |
SnailFishNumber.prototype.updateLeft = function(value) | |
{ | |
if(this.parent != null) | |
{ | |
if(this.parent.left != this) | |
{ | |
if(this.parent.left.isArray) | |
{ | |
let right = this.parent.left.right; | |
while(right.isArray) | |
{ | |
right = right.right; | |
} | |
right.value += value; | |
} | |
else | |
{ | |
this.parent.left.value += value; | |
} | |
} | |
else | |
{ | |
this.parent.updateLeft(value); | |
} | |
} | |
} | |
SnailFishNumber.prototype.updateRight = function(value) | |
{ | |
if(this.parent != null) | |
{ | |
if(this.parent.right != this) | |
{ | |
if(this.parent.right.isArray) | |
{ | |
let left = this.parent.right.left; | |
while(left.isArray) | |
{ | |
left = left.left; | |
} | |
left.value += value; | |
} | |
else | |
{ | |
this.parent.right.value += value; | |
} | |
} | |
else | |
{ | |
this.parent.updateRight(value); | |
} | |
} | |
} | |
SnailFishNumber.prototype.explode = function() | |
{ | |
let hasExploded = false; | |
if(this.isArray && this.depth >= maxDepth) | |
{ | |
if(this.left.isArray) | |
{ | |
hasExploded = this.left.explode(); | |
} | |
else if(this.right.isArray && !hasExploded) | |
{ | |
hasExploded = this.right.explode(); | |
} | |
else if(!this.left.isArray && !this.right.isArray) | |
{ | |
let [left, right] = this.getValue(); | |
this.isArray = false; | |
this.left = null; | |
this.right = null; | |
this.value = 0; | |
this.updateLeft(left); | |
this.updateRight(right); | |
hasExploded = true; | |
} | |
} | |
else if(this.isArray) | |
{ | |
if(this.left.isArray) | |
{ | |
hasExploded = this.left.explode(); | |
} | |
if(this.right.isArray && !hasExploded) | |
{ | |
hasExploded = this.right.explode(); | |
} | |
} | |
return hasExploded; | |
} | |
SnailFishNumber.prototype.checkForSplit = function() | |
{ | |
let hasSplit = false; | |
if(!this.isArray) | |
{ | |
if(this.value > maxValue) | |
{ | |
this.isArray = true; | |
let left = Math.floor(this.value/2); | |
let right = Math.ceil(this.value/2); | |
delete this.value; | |
this.left = new SnailFishNumber(left, this.depth+1, this, 'left'); | |
this.right = new SnailFishNumber(right, this.depth+1, this, 'right'); | |
hasSplit = true; | |
} | |
} | |
else | |
{ | |
if(this.left.maxValue() > maxValue) | |
{ | |
hasSplit = this.left.checkForSplit(); | |
} | |
else if(this.right.maxValue() > maxValue) | |
{ | |
hasSplit = this.right.checkForSplit(); | |
} | |
} | |
return hasSplit; | |
} | |
SnailFishNumber.prototype.reduce = function() | |
{ | |
while(this.maxDepth() > maxDepth || this.maxValue() > maxValue) | |
{ | |
let doneAction = false; | |
if(this.left.maxDepth() > maxDepth) | |
{ | |
doneAction = this.left.explode(); | |
} | |
if(this.right.maxDepth() > maxDepth && !doneAction) | |
{ | |
doneAction = this.right.explode(); | |
} | |
if(this.left.maxValue() > maxValue && !doneAction) | |
{ | |
doneAction = this.left.checkForSplit(); | |
} | |
if(this.right.maxValue() > maxValue && !doneAction) | |
{ | |
doneAction = this.right.checkForSplit(); | |
} | |
} | |
} | |
SnailFishNumber.prototype.getMagnitude = function() | |
{ | |
let magnitude = 0; | |
if(this.isArray) | |
{ | |
magnitude += 3*this.left.getMagnitude(); | |
magnitude += 2*this.right.getMagnitude(); | |
} | |
else | |
{ | |
magnitude = this.value; | |
} | |
return magnitude; | |
} | |
let homework = inp.trim().split('\n').map(line => JSON.parse(line)).map(arr => new SnailFishNumber(arr, 0, null, '')); | |
let lastnumber = homework[0]; | |
for(let hi = 1; hi < homework.length; hi++) | |
{ | |
let curnumber = homework[hi]; | |
lastnumber = lastnumber.add(curnumber); | |
lastnumber.reduce(); | |
} | |
return lastnumber.getMagnitude(); | |
})(document.querySelector('pre').textContent); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment