-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This might be some of the ugliest code I've ever written, but it gets the job done! Took me ~4 hours and there was a point about halfway through that I started to wish I had just built out the binary tree structure instead of trying to manipulate the strings. Oh well.
- Loading branch information
1 parent
0e2285a
commit fa90b4d
Showing
4 changed files
with
319 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
[[1,[8,[5,8]]],[[4,4],[8,[8,8]]]] | ||
[[[3,[2,3]],[[8,0],2]],[0,[[8,1],[7,0]]]] | ||
[4,[[0,3],[[6,6],[3,8]]]] | ||
[[[7,[6,4]],[[0,6],[2,0]]],[[[5,6],[0,4]],[[8,1],[9,1]]]] | ||
[[[6,3],[[6,9],4]],[[1,[4,2]],[[0,0],1]]] | ||
[[2,0],[3,[0,8]]] | ||
[[0,[5,5]],[[4,2],[3,[6,4]]]] | ||
[[[[9,9],[8,5]],[7,4]],[[6,9],[8,[0,8]]]] | ||
[[[[7,1],[2,9]],[[9,3],0]],[3,[[0,6],[7,6]]]] | ||
[[[[3,7],[7,1]],[[5,8],[0,1]]],3] | ||
[[[[4,6],[6,2]],[[9,1],7]],[[9,1],[8,0]]] | ||
[[[[2,7],0],[[9,4],[2,6]]],[0,[[7,4],[0,3]]]] | ||
[[5,[[0,2],[8,8]]],[[[4,1],9],3]] | ||
[[[7,1],[[3,7],[3,4]]],[[[0,7],[1,6]],1]] | ||
[[[6,5],[[1,8],[8,8]]],[[4,5],[3,7]]] | ||
[[[1,[3,3]],[[3,2],[5,7]]],[[8,[9,3]],[[5,3],4]]] | ||
[[[4,[2,7]],9],[9,[[5,6],4]]] | ||
[[[9,1],3],[[1,2],9]] | ||
[[[[0,0],[2,3]],[[7,8],[1,5]]],[[[8,6],7],[[8,3],9]]] | ||
[6,[[5,[0,8]],1]] | ||
[4,[[[3,0],[2,0]],[[7,2],[1,4]]]] | ||
[[[[4,3],[4,1]],8],[[[9,4],[1,9]],[4,[0,6]]]] | ||
[4,[5,6]] | ||
[[[0,[6,1]],[[6,1],3]],[[0,[7,8]],[1,0]]] | ||
[[5,[[8,7],8]],8] | ||
[[5,[[5,2],0]],[[1,[4,7]],[[0,9],[2,3]]]] | ||
[[7,[2,2]],[[6,3],[5,8]]] | ||
[[[0,9],5],[1,[[5,7],1]]] | ||
[[8,[3,[0,3]]],[[[2,2],2],[[8,8],[8,9]]]] | ||
[[6,[[3,2],[2,6]]],[5,1]] | ||
[[[[9,8],[6,8]],[0,7]],7] | ||
[[[7,2],[[6,3],4]],2] | ||
[[[5,2],[[1,6],[8,3]]],[6,5]] | ||
[[5,2],[0,5]] | ||
[[[[4,5],5],[[4,6],[1,2]]],[[[3,6],[4,9]],[1,9]]] | ||
[[1,[4,1]],[[9,[5,5]],[[9,0],[5,7]]]] | ||
[[[[8,9],[7,7]],2],[8,1]] | ||
[[[8,1],[8,[9,5]]],3] | ||
[[[2,[3,9]],[[5,4],[7,9]]],[9,8]] | ||
[8,[[2,[0,9]],[[5,0],4]]] | ||
[[[6,[4,8]],[0,6]],[[8,[1,8]],1]] | ||
[[6,[[1,0],[6,2]]],[[9,[3,7]],[5,[4,0]]]] | ||
[[8,[0,[9,1]]],8] | ||
[7,[4,[7,2]]] | ||
[[1,[[5,7],[5,4]]],[[5,[8,0]],[1,6]]] | ||
[[[[0,6],[6,2]],3],[[[9,3],7],[7,[1,2]]]] | ||
[[[6,[4,9]],8],[6,5]] | ||
[[[0,[1,9]],[[1,9],[3,9]]],[[[3,4],[7,5]],3]] | ||
[[[[9,3],5],[[0,5],[2,7]]],9] | ||
[[[6,[7,5]],5],[1,[[7,0],[3,4]]]] | ||
[[[2,1],[[1,3],[1,5]]],[4,[9,[7,9]]]] | ||
[[[[7,9],4],[[8,8],7]],[[[3,5],2],[[4,4],[6,5]]]] | ||
[[1,1],[1,1]] | ||
[[8,[0,2]],8] | ||
[[[2,[2,1]],[[1,7],[1,2]]],[[1,6],5]] | ||
[6,[0,[[1,0],[0,9]]]] | ||
[6,[[2,[8,0]],[8,[8,8]]]] | ||
[4,[[3,[0,3]],4]] | ||
[[[5,3],3],[[0,[7,6]],[2,[5,8]]]] | ||
[[[[8,1],[4,1]],[[5,8],[4,8]]],[[[1,7],[7,2]],[0,[2,7]]]] | ||
[[[2,[3,5]],3],5] | ||
[[7,[[9,5],[8,2]]],[[[1,8],8],5]] | ||
[[3,5],[[4,[9,3]],5]] | ||
[[[[4,6],2],[2,2]],[0,[0,4]]] | ||
[[[[5,8],[6,6]],[2,0]],[[[2,3],9],[[4,5],2]]] | ||
[[[[1,9],3],[[3,4],6]],[[3,6],[6,[0,7]]]] | ||
[[[0,[5,5]],[2,6]],[[[7,4],4],2]] | ||
[0,[[8,[6,2]],[5,[1,5]]]] | ||
[[[[5,5],[9,6]],[[5,2],2]],[[4,7],[[5,5],[1,6]]]] | ||
[[4,7],[[[1,8],[9,6]],[2,3]]] | ||
[5,[5,4]] | ||
[[[[2,1],[7,0]],[5,[7,8]]],[6,[3,1]]] | ||
[[[3,1],[[2,4],6]],[[[1,8],[2,1]],[[1,7],4]]] | ||
[[[5,[3,3]],6],[[[0,0],9],[1,[7,4]]]] | ||
[[[6,5],[[7,3],4]],[[9,[0,3]],[3,[6,0]]]] | ||
[[[3,4],7],[8,[[1,7],[9,9]]]] | ||
[[[[2,1],6],[2,6]],[[[8,1],[6,2]],[9,0]]] | ||
[[8,4],[5,2]] | ||
[[4,[[4,5],9]],[[3,[5,2]],[4,2]]] | ||
[[[8,8],[[8,0],[5,3]]],4] | ||
[[1,8],[0,2]] | ||
[[[[7,2],[9,0]],[[9,2],[1,2]]],[[[4,0],3],0]] | ||
[[[[1,2],[1,8]],[[4,3],[8,6]]],[[[5,1],8],[8,1]]] | ||
[[[[5,3],[7,2]],7],[[6,[7,9]],[[3,8],[9,4]]]] | ||
[[[[3,1],[2,5]],6],[[[3,2],[8,8]],[4,6]]] | ||
[9,[[3,[2,3]],6]] | ||
[[[[4,0],[5,6]],[5,4]],[[[9,0],[1,8]],[5,[3,6]]]] | ||
[[[[9,5],[9,4]],[[5,7],5]],[[[1,4],7],[6,1]]] | ||
[[2,[6,[8,2]]],[7,[1,[3,3]]]] | ||
[[[9,1],[0,[6,3]]],[[5,[1,5]],[7,[1,0]]]] | ||
[1,6] | ||
[[0,[2,[8,9]]],[[[4,5],[5,4]],1]] | ||
[[[1,[4,1]],8],[[2,[7,0]],[7,[9,9]]]] | ||
[[[[5,7],[3,5]],[[6,6],2]],[2,[8,[9,0]]]] | ||
[6,[[[3,9],8],[[4,3],[6,1]]]] | ||
[[[[6,7],[7,6]],[2,8]],[[9,[4,1]],6]] | ||
[[[[4,5],[4,5]],[[0,6],5]],[[[6,5],[7,0]],1]] | ||
[[[[6,7],9],[[5,5],[6,6]]],[[7,1],[[8,2],[3,1]]]] | ||
[[[9,6],7],[[[1,8],8],[1,7]]] | ||
[[5,2],[[1,9],[2,2]]] |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
require_relative "snailfish" | ||
|
||
input = File.readlines("input.txt") | ||
fish = input.map{Snailfish.new(_1.chomp)} | ||
|
||
puts "Magnitude: #{fish.reduce(:+).magnitude}" | ||
|
||
magnitudes = fish.permutation(2).map{ _1.reduce(:+).magnitude } | ||
puts "Largest of any two: #{magnitudes.max}" |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
require "json" | ||
|
||
class Snailfish | ||
attr_reader :number | ||
|
||
# Convenience constructor to help make tests easier to read. | ||
def self.[](number) | ||
self.new(number) | ||
end | ||
|
||
def initialize(number) | ||
@number = number | ||
end | ||
|
||
def +(other) | ||
Snailfish["[#{number},#{other.number}]"].reduce! | ||
end | ||
|
||
def ==(other) | ||
number == other.number | ||
end | ||
|
||
def inspect | ||
number | ||
end | ||
|
||
def magnitude | ||
a, b = JSON.parse(number) | ||
|
||
a = a.is_a?(Array) ? Snailfish[a.to_json].magnitude : a | ||
b = b.is_a?(Array) ? Snailfish[b.to_json].magnitude : b | ||
|
||
3*a + 2*b | ||
end | ||
|
||
def reduce! | ||
true while explode! || split! | ||
self | ||
end | ||
|
||
def explode! | ||
return false if max_depth <= 4 | ||
|
||
head, pair, tail = find_exploding_pair(JSON.parse(number)) | ||
|
||
if (left = head.scan(/\d{1,}/).last) | ||
idx = head.rindex(left) | ||
head[idx...(idx+left.length)] = (left.to_i + pair[0]).to_s | ||
end | ||
|
||
if (right = tail.scan(/\d{1,}/).first) | ||
idx = tail.index(right) | ||
tail[idx...(idx+right.length)] = (right.to_i + pair[1]).to_s | ||
end | ||
|
||
@number = [head,0,tail].join | ||
end | ||
|
||
def split! | ||
number.match(/\d{2,}/) do |split| | ||
head, tail = number.split(split[0], 2) | ||
m = split[0].to_i / 2.0 | ||
@number = [head, [m.floor, m.ceil].to_json, tail].join | ||
end | ||
end | ||
|
||
private | ||
|
||
def max_depth | ||
array = JSON.parse(number) | ||
depth = 1 | ||
|
||
until array == array.flatten | ||
depth +=1 | ||
array = array.flatten(1) | ||
end | ||
|
||
depth | ||
end | ||
|
||
def find_exploding_pair(pair, depth = 1, head = "", tail = "") | ||
a, b = pair | ||
|
||
if depth == 4 | ||
return ["#{head}[", a, ",#{b.to_json}]#{tail}"] if a.is_a?(Array) | ||
return ["#{head}[#{a.to_json},", b, "]#{tail}"] if b.is_a?(Array) | ||
return false | ||
end | ||
|
||
find_exploding_pair(a, depth + 1, "#{head}[", ",#{b.to_json}]#{tail}") || | ||
find_exploding_pair(b, depth + 1, "#{head}[#{a.to_json},", "]#{tail}") | ||
end | ||
end |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
require "minitest/autorun" | ||
require_relative "snailfish" | ||
|
||
class SnailfishTest < Minitest::Test | ||
def test_addition | ||
assert_equal Snailfish["[[1,2],[[3,4],5]]"], [ | ||
Snailfish["[1,2]"], | ||
Snailfish["[[3,4],5]"] | ||
].reduce(:+) | ||
|
||
assert_equal Snailfish["[[[[1,1],[2,2]],[3,3]],[4,4]]"], [ | ||
Snailfish["[1,1]"], | ||
Snailfish["[2,2]"], | ||
Snailfish["[3,3]"], | ||
Snailfish["[4,4]"] | ||
].reduce(:+) | ||
|
||
assert_equal Snailfish["[[[[3,0],[5,3]],[4,4]],[5,5]]"], [ | ||
Snailfish["[1,1]"], | ||
Snailfish["[2,2]"], | ||
Snailfish["[3,3]"], | ||
Snailfish["[4,4]"], | ||
Snailfish["[5,5]"] | ||
].reduce(:+) | ||
|
||
assert_equal Snailfish["[[[[5,0],[7,4]],[5,5]],[6,6]]"], [ | ||
Snailfish["[1,1]"], | ||
Snailfish["[2,2]"], | ||
Snailfish["[3,3]"], | ||
Snailfish["[4,4]"], | ||
Snailfish["[5,5]"], | ||
Snailfish["[6,6]"] | ||
].reduce(:+) | ||
end | ||
|
||
def test_complex_addition | ||
assert_equal Snailfish["[[[[4,0],[5,4]],[[7,7],[6,0]]],[[8,[7,7]],[[7,9],[5,0]]]]"], | ||
Snailfish["[[[0,[4,5]],[0,0]],[[[4,5],[2,6]],[9,5]]]"] + | ||
Snailfish["[7,[[[3,7],[4,3]],[[6,3],[8,8]]]]"] | ||
|
||
assert_equal Snailfish["[[[[6,7],[6,7]],[[7,7],[0,7]]],[[[8,7],[7,7]],[[8,8],[8,0]]]]"], | ||
Snailfish["[[[[4,0],[5,4]],[[7,7],[6,0]]],[[8,[7,7]],[[7,9],[5,0]]]]"] + | ||
Snailfish["[[2,[[0,8],[3,4]]],[[[6,7],1],[7,[1,6]]]]"] | ||
|
||
assert_equal Snailfish["[[[[7,0],[7,7]],[[7,7],[7,8]]],[[[7,7],[8,8]],[[7,7],[8,7]]]]"], | ||
Snailfish["[[[[6,7],[6,7]],[[7,7],[0,7]]],[[[8,7],[7,7]],[[8,8],[8,0]]]]"] + | ||
Snailfish["[[[[2,4],7],[6,[0,5]]],[[[6,8],[2,8]],[[2,1],[4,5]]]]"] | ||
|
||
assert_equal Snailfish["[[[[7,7],[7,8]],[[9,5],[8,7]]],[[[6,8],[0,8]],[[9,9],[9,0]]]]"], | ||
Snailfish["[[[[7,0],[7,7]],[[7,7],[7,8]]],[[[7,7],[8,8]],[[7,7],[8,7]]]]"] + | ||
Snailfish["[7,[5,[[3,8],[1,4]]]]"] | ||
|
||
assert_equal Snailfish["[[[[6,6],[6,6]],[[6,0],[6,7]]],[[[7,7],[8,9]],[8,[8,1]]]]"], | ||
Snailfish["[[[[7,7],[7,8]],[[9,5],[8,7]]],[[[6,8],[0,8]],[[9,9],[9,0]]]]"] + | ||
Snailfish["[[2,[2,2]],[8,[8,1]]]"] | ||
|
||
assert_equal Snailfish["[[[[6,6],[7,7]],[[0,7],[7,7]]],[[[5,5],[5,6]],9]]"], | ||
Snailfish["[[[[6,6],[6,6]],[[6,0],[6,7]]],[[[7,7],[8,9]],[8,[8,1]]]]"] + | ||
Snailfish["[2,9]"] | ||
|
||
assert_equal Snailfish["[[[[7,8],[6,7]],[[6,8],[0,8]]],[[[7,7],[5,0]],[[5,5],[5,6]]]]"], | ||
Snailfish["[[[[6,6],[7,7]],[[0,7],[7,7]]],[[[5,5],[5,6]],9]]"] + | ||
Snailfish["[1,[[[9,3],9],[[9,0],[0,7]]]]"] | ||
|
||
assert_equal Snailfish["[[[[7,7],[7,7]],[[8,7],[8,7]]],[[[7,0],[7,7]],9]]"], | ||
Snailfish["[[[[7,8],[6,7]],[[6,8],[0,8]]],[[[7,7],[5,0]],[[5,5],[5,6]]]]"] + | ||
Snailfish["[[[5,[7,4]],7],1]"] | ||
|
||
assert_equal Snailfish["[[[[8,7],[7,7]],[[8,6],[7,7]]],[[[0,7],[6,6]],[8,7]]]"], | ||
Snailfish["[[[[7,7],[7,7]],[[8,7],[8,7]]],[[[7,0],[7,7]],9]]"] + | ||
Snailfish["[[[[4,2],2],6],[8,7]]"] | ||
end | ||
|
||
def test_magnitude | ||
assert_equal 143, Snailfish["[[1,2],[[3,4],5]]"].magnitude | ||
assert_equal 1384, Snailfish["[[[[0,7],4],[[7,8],[6,0]]],[8,1]]"].magnitude | ||
assert_equal 445, Snailfish["[[[[1,1],[2,2]],[3,3]],[4,4]]"].magnitude | ||
assert_equal 791, Snailfish["[[[[3,0],[5,3]],[4,4]],[5,5]]"].magnitude | ||
assert_equal 1137, Snailfish["[[[[5,0],[7,4]],[5,5]],[6,6]]"].magnitude | ||
assert_equal 3488, Snailfish["[[[[8,7],[7,7]],[[8,6],[7,7]]],[[[0,7],[6,6]],[8,7]]]"].magnitude | ||
end | ||
|
||
def test_split | ||
assert_equal "[[5,5],0]", Snailfish["[10,0]"].split! | ||
assert_equal "[0,[5,6]]", Snailfish["[0,11]"].split! | ||
|
||
assert_equal "[0,[[6,6],0]]", Snailfish["[0,[12,0]]"].split! | ||
assert_equal "[0,[[6,7],[0,14]]]", Snailfish["[0,[13,[0,14]]]"].split! | ||
|
||
assert_equal "[[[[0,7],4],[[7,8],[0,13]]],[1,1]]", | ||
Snailfish["[[[[0,7],4],[15,[0,13]]],[1,1]]"].split! | ||
|
||
refute Snailfish["[0,[1,[3,[[4,5],6]]]]"].split! | ||
end | ||
|
||
def test_explode | ||
assert_equal "[[[[0,9],2],3],4]", Snailfish["[[[[[9,8],1],2],3],4]"].explode! | ||
assert_equal "[7,[6,[5,[7,0]]]]", Snailfish["[7,[6,[5,[4,[3,2]]]]]"].explode! | ||
assert_equal "[[6,[5,[7,0]]],3]", Snailfish["[[6,[5,[4,[3,2]]]],1]"].explode! | ||
|
||
assert_equal "[[3,[2,[8,0]]],[9,[5,[4,[3,2]]]]]", | ||
Snailfish["[[3,[2,[1,[7,3]]]],[6,[5,[4,[3,2]]]]]"].explode! | ||
assert_equal "[[3,[2,[8,0]]],[9,[5,[7,0]]]]", | ||
|
||
Snailfish["[[3,[2,[8,0]]],[9,[5,[4,[3,2]]]]]"].explode! | ||
|
||
assert_equal "[[[[6,7],[0,7]],[[13,0],[7,21]]],[[2,[11,10]],[[0,8],[8,0]]]]", | ||
Snailfish["[[[[6,7],[0,7]],[[7,[6,7]],[0,21]]],[[2,[11,10]],[[0,8],[8,0]]]]"].explode! | ||
|
||
refute Snailfish["[[[[0,7],4],[[7,8],[6,0]]],[8,1]]"].explode! | ||
end | ||
|
||
def test_reduce | ||
assert_equal Snailfish["[[[[0,7],4],[[7,8],[6,0]]],[8,1]]"], | ||
Snailfish["[[[[[4,3],4],4],[7,[[8,4],9]]],[1,1]]"].reduce! | ||
end | ||
end |