Created
December 18, 2021 19:29
-
-
Save sarahzrf/00c5183f506d83db86d0481ca2cd7275 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
require 'json' | |
class Atom | |
attr_accessor :val, :prv, :nxt, :become | |
def initialize(val) | |
@val = val | |
end | |
def leftmost | |
self | |
end | |
def rightmost | |
self | |
end | |
def split | |
return false unless val >= 10 | |
val_l = val / 2 | |
val_r = val - val_l | |
become.(Pair.new(Atom.new(val_l), Atom.new(val_r))) | |
true | |
end | |
def explode(depth=0) | |
false | |
end | |
def to_nomber | |
val | |
end | |
def magnitude | |
val | |
end | |
def inspect | |
"#<Atom: #{to_nomber.inspect}>" | |
end | |
end | |
class Pair | |
attr_reader :left, :right | |
attr_accessor :become | |
def initialize(l, r) | |
l.rightmost.nxt = r.leftmost | |
r.leftmost.prv = l.rightmost | |
l.become = method(:left=) | |
r.become = method(:right=) | |
@left = l | |
@right = r | |
end | |
def leftmost | |
left.leftmost | |
end | |
def rightmost | |
right.rightmost | |
end | |
def left=(l) | |
l.leftmost.prv = leftmost.prv | |
leftmost.prv.nxt = l.leftmost if leftmost.prv | |
l.rightmost.nxt = right.leftmost | |
right.leftmost.prv = l.rightmost | |
l.become = method(:left=) | |
@left = l | |
end | |
def right=(r) | |
r.rightmost.nxt = rightmost.nxt | |
rightmost.nxt.prv = r.rightmost if rightmost.nxt | |
r.leftmost.prv = left.rightmost | |
left.rightmost.nxt = r.leftmost | |
r.become = method(:right=) | |
@right = r | |
end | |
def explode(depth=0) | |
if depth >= 4 | |
left.prv.val += left.val if left.prv | |
right.nxt.val += right.val if right.nxt | |
become.(Atom.new(0)) | |
true | |
else | |
left.explode(depth + 1) or right.explode(depth + 1) | |
end | |
end | |
def split | |
left.split or right.split | |
end | |
def normalize | |
loop do | |
progress = false | |
while explode | |
progress = true | |
end | |
if split | |
progress = true | |
end | |
break if !progress | |
end | |
self | |
end | |
def to_nomber | |
[left.to_nomber, right.to_nomber] | |
end | |
def magnitude | |
3 * left.magnitude + 2 * right.magnitude | |
end | |
def inspect | |
"#<Pair: #{to_nomber.inspect}>" | |
end | |
end | |
def construct(nomber) | |
case nomber | |
when Integer | |
Atom.new(nomber) | |
when Array | |
nl, nr = nomber | |
Pair.new(construct(nl), construct(nr)) | |
else | |
raise "malformed nomber" | |
end | |
end | |
ns = $<.map {|l| JSON.parse(l)} | |
max = ns.product(ns) | |
.map {|n1, n2| Pair.new(construct(n1), construct(n2)).normalize.magnitude} | |
.max | |
puts max | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment