aboutsummaryrefslogtreecommitdiff
path: root/day07/part2
blob: 46245ae98c65761dfca2574d08df76545bafa109 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#!/usr/bin/env ruby

class Array
  def to_empty_hash
    h = {}
    self.each do |el|
      h[el] = nil
    end
    return h
  end
end

input = $stdin.readlines.map(&:chomp)

hash = {}

input.each do |line|
  me, them = line.split(" -> ")
  _, name, weight = me.match(/([a-z]+) \((\d+)\)/).to_a
  children = them.nil? ? [] : them.split(", ")

  hash[name.intern] = {
    :weight => weight.to_i,
    :remove => false,
    :children => children.map(&:intern).to_empty_hash
  }
end

hash.each do |key, value|
  value[:children].each do |ckey, cvalue|
    if cvalue.nil? then
      value[:children][ckey] = hash[ckey].dup
      hash[ckey][:remove] = true
    end
  end
end

hash = hash.reject { |key, value|
  value[:remove]
}

here = nil
newhere = hash[hash.keys.first]

def weight(prog)
  return prog[:weight] if prog[:children].empty?
  chilweight = 0
  prog[:children].each do |k, v|
    chilweight += weight(v)
  end
  return prog[:weight] + chilweight
end

def is_balanced?(tower)
  ws = []
  tower[:children].each do |k, v|
    ws << weight(v)
  end
  return ws.uniq.length == 1
end

while here != newhere do
  here = newhere
  here[:children].each do |key, value|
    unless is_balanced?(value) then
      newhere = value
    end
  end
end

ws = []
here[:children].each do |k, v|
  ws << weight(v)
end

goodweight = nil
ws.each do |w|
  goodweight = w if ws.count(w) != 1
end

here[:children].each do |k, v|
  if weight(v) == goodweight then
    next
  else
    diff = weight(v) - goodweight
    puts v[:weight] - diff
    break
  end
end