Skip to content

Instantly share code, notes, and snippets.

@Mellen
Last active December 19, 2021 08:41
Show Gist options
  • Save Mellen/d5bc791fe2505de6f72ead1d32dd45b4 to your computer and use it in GitHub Desktop.
Save Mellen/d5bc791fe2505de6f72ead1d32dd45b4 to your computer and use it in GitHub Desktop.
(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