diff --git a/day13.cr b/day13.cr new file mode 100644 index 0000000..2445c3c --- /dev/null +++ b/day13.cr @@ -0,0 +1,110 @@ +require "advent" +INPUT = input(2022, 13).lines + +class Tree + property value : Int32? + property values : Array(Tree)? + + def initialize(@value, @values) + end + + def to_s(io) + if mine = value + io << "value: " << mine + elsif mine = values + io << "values: " + mine.each do |v| + io << "(" + v.to_s io + io << ")" + end + end + end + + def compare(other : Tree) + if mine = value + if yours = other.value + return (mine - yours).sign + end + end + + if mine = values + if yours = other.values + mine.size.times do |i| + return 1 unless i < yours.size # Shorter list smaller + comp = mine[i].compare yours[i] + return comp if comp != 0 + end + return mine.size == yours.size ? 0 : -1 # Shorter list smaller + end + end + + if mine = value + return Tree.new(nil, [self]).compare(other) + elsif yours = other.value + return compare(Tree.new(nil, [other])) + end + return 0 + end +end + +def tree(i) + Tree.new(i, nil) +end + +def list(is : Array(Int32)) + Tree.new(nil, is.map { |it| tree(it) }) +end + +def list(is : Array(Tree)) + Tree.new(nil, is) +end + +def parse(string) + stack = [[] of Tree] + current = nil + string.as(String).each_char do |c| + if c == '[' + stack << [] of Tree + elsif c.alphanumeric? + if current.nil? + current = c.to_i32 + else + current = current * 10 + c.to_i32 + end + elsif c == ',' + if num = current + stack.last << tree(num) + current = nil + end + elsif c == ']' + if num = current + stack.last << tree(num) + current = nil + end + new_tree = Tree.new(nil, stack.pop) + stack.last << new_tree + end + end + return stack[0][0] +end + +puts parse("[[10,1,2],[],[]]") +total = 0 +INPUT.in_groups_of(3).each_with_index do |group, i| + t1 = parse(group[0]) + t2 = parse(group[1]) + cmp = t1.compare t2 + total += (i+1) if cmp != 1 +end +puts total + +trees = INPUT.reject { |it| it.empty? }.map { |it| parse(it) } +d1 = parse("[[2]]") +d2 = parse("[[6]]") +trees << d1 +trees << d2 +trees.sort! do |l, r| + l.compare r +end +puts (trees.index!(d1)+1)*(trees.index!(d2)+1)