diff --git a/day03/part2.lua b/day03/part2.lua index b557746..ab0d607 100644 --- a/day03/part2.lua +++ b/day03/part2.lua @@ -1,33 +1,55 @@ local ZERO = string.byte("0", 1) local ONE = string.byte("1", 1) -local total = 0 -local counts = {} +local lines = {} for line in io.lines(arg[3]) do + local ones = {} for char = 1, #line do - if line:byte(char) == ONE then - counts[char] = (counts[char] or 0) + 1 - end + table.insert(ones, line:byte(char) == ONE) end - total = total + 1 + table.insert(lines, ones) end -local least, most, lmax, mmax = nil, nil, 0, 0 -for line in io.lines(arg[3]) do - local lcur, mcur, lin, min = 0, 0, true, true - for char = 1, #line do - if line:byte(char) == ONE then - if counts[char] >= total / 2 then - if min then mcur = mcur + 1 end - else - min = false - end - else - if counts[char] < total / 2 then - if min then mcur = mcur + 1 end - else - min = false +function reduce(left, keep) + local char = 1 + while #left > 1 and char <= #lines[1] do + local ones = 0 + for k, line in pairs(left) do + if lines[line][char] then + ones = ones + 1 end end + local nleft = {} + for k, line in pairs(left) do + if keep(lines[line][char], ones, #left) then + table.insert(nleft, line) + end + end + left = nleft + char = char + 1 end - print(line, mcur) + return left[1] end + +function bin2dec(t) + local v = 0 + for i = 1, #t do + v = v * 2 + if t[i] then v = v + 1 end + end + return v +end + +local indices = {} +for line = 1, #lines do + table.insert(indices, line) +end + +local oxygen = reduce(indices, function (bit, ones, total) + return (not bit or ones >= total/2) and (bit or ones < total/2) +end) + +local co2 = reduce(indices, function (bit, ones, total) + return (not bit or ones < total/2) and (bit or ones >= total/2) +end) + +print(bin2dec(lines[oxygen]) * bin2dec(lines[co2]))