diff --git a/day04/part1.lua b/day04/part1.lua new file mode 100644 index 0000000..b9e5fe8 --- /dev/null +++ b/day04/part1.lua @@ -0,0 +1,71 @@ +function split(text, sep) + local parts = {} + local start = 0 + local from, to = text:find(sep) + while from ~= nil do + table.insert(parts, text:sub(start, from - 1)) + text = text:sub(to + 1) + from, to = text:find(sep) + end + table.insert(parts, text) + return parts +end + +local f = io.open(arg[3]) +local numbers = split(f:read("*l"), ",") +local line = f:read("*l") +local boards = {} +while line ~= nil do + local board = {} + for r = 1, 5 do + line = f:read("*l") + while line:byte(1) == string.byte(" ", 1) do + line = line:sub(2) + end + board[r] = split(line, " +") + end + table.insert(boards, board) + line = f:read("*l") +end + +local i, complete = 0, nil +while complete == nil and i <= #numbers do + local number = numbers[i] + local tests = {} + for b, board in pairs(boards) do + for r, row in pairs(board) do + for c, col in pairs(row) do + if col == number then + row[c] = nil + table.insert(tests, {b, r, c}) + end + end + end + end + + for t, test in pairs(tests) do + local board, row, col = unpack(test) + local j, rownils, colnils = 1, 0, 0 + while j <= 5 and (rownils == 0 or colnils == 0) do + if boards[board][row][j] ~= nil then rownils = rownils + 1 end + if boards[board][j][col] ~= nil then colnils = colnils + 1 end + j = j + 1 + end + if rownils == 0 or colnils == 0 then + complete = boards[board] + end + end + + i = i + 1 +end + +print(numbers[i - 1]) +local sum = 0 +for r = 1, 5 do + for c = 1, 5 do + io.write((complete[r][c] or "nil") .. " ") + sum = sum + (complete[r][c] or 0) + end + io.write("\n") +end +print(numbers[i - 1] * sum) diff --git a/day04/part2.lua b/day04/part2.lua new file mode 100644 index 0000000..8338b93 --- /dev/null +++ b/day04/part2.lua @@ -0,0 +1,74 @@ +function split(text, sep) + local parts = {} + local start = 0 + local from, to = text:find(sep) + while from ~= nil do + table.insert(parts, text:sub(start, from - 1)) + text = text:sub(to + 1) + from, to = text:find(sep) + end + table.insert(parts, text) + return parts +end + +local f = io.open(arg[3]) +local numbers = split(f:read("*l"), ",") +local line = f:read("*l") +local boards = {} +while line ~= nil do + local board = {} + for r = 1, 5 do + line = f:read("*l") + while line:byte(1) == string.byte(" ", 1) do + line = line:sub(2) + end + board[r] = split(line, " +") + end + table.insert(boards, board) + line = f:read("*l") +end + +function finished(board, row, col) + local j, rowints, colints = 1, 0, 0 + while j <= 5 and (rowints == 0 or colints == 0) do + if board[row][j] ~= nil then rowints = rowints + 1 end + if board[j][col] ~= nil then colints = colints + 1 end + j = j + 1 + end + return rowints == 0 or colints == 0 +end + +local i = 1 +local complete +while #boards > 0 and i <= #numbers do + local number = numbers[i] + local nboards = {} + for b, board in pairs(boards) do + complete = board + local hasfinished = false + for r, row in pairs(board) do + for c, col in pairs(row) do + if col == number then + row[c] = nil + if finished(board, r, c) then + hasfinished = true + end + end + end + end + if not hasfinished then + table.insert(nboards, board) + end + end + boards = nboards + + i = i + 1 +end + +local sum = 0 +for r = 1, 5 do + for c = 1, 5 do + sum = sum + (complete[r][c] or 0) + end +end +print(numbers[i - 1] * sum)