def tally(data, ii) Hash.new(0).tap do |h| data.each { h[_1[ii]] += 1 } end end n = data.first.length # part 1 gamma = (0...n).map do |ii| tally = tally(data, ii) tally['0'] > tally['1'] ? 0 : 1 end gamma = gamma.join.to_i(2) epsilon = gamma ^ ((1 << n) - 1) p gamma * epsilon # part 2 oxy, co2 = data.dup, data.dup (0...n).each do |ii| if oxy.length > 1 tally = tally(oxy, ii) keep = tally['0'] > tally['1'] ? '0' : '1' oxy.select! { _1[ii] == keep } end if co2.length > 1 tally = tally(co2, ii) keep = tally['0'] > tally['1'] ? '1' : '0' co2.select! { _1[ii] == keep } end end oxy, co2 = oxy.first.to_i(2), co2.first.to_i(2) p oxy * co2