include("utils.jl") function parse_boards(lines) num_boards = div(length(lines),5) boards = Array{Array{Int}}(undef, num_boards) for i in 1:num_boards boards[i] = zeros(5, 5) for li in 1:5 values = map(x->parse(Int, x), split(lines[(i - 1)*5+li])) boards[i][li,:] .= values end end boards end function parse_input(filename) lines = Iterators.Stateful(non_empty_lines(filename)) numbers = map(x->parse(Int, x), split(popfirst!(lines), ",")) boards = parse_boards(collect(lines)) numbers, boards end function apply(number, boards) for board in boards for i in CartesianIndices((1:5, 1:5)) if board[i] == number board[i] = -1 end end end end function check(boards) for board in boards for i in 1:5 if (reduce(+, board[i,:]) == -5) || (reduce(+, board[:,i]) == -5) return true, board end end end false, nothing end function solution4_1() numbers, boards = parse_input("4.data") for number in numbers apply(number, boards) winning, board = check(boards) if winning score = reduce(+, filter(>(0), board)) return (score, number, score * number) end end end function remove_winning_boards(boards) last = nothing filtered = filter(boards) do board for i in 1:5 if (reduce(+, board[i,:]) == -5) || (reduce(+, board[:,i]) == -5) last = board return false end end true end filtered, last end function solution4_2() numbers, boards = parse_input("4.data") for number in numbers apply(number, boards) boards, board = remove_winning_boards(boards) if length(boards) == 0 score = reduce(+, filter(>(0), board)) return (score, number, score * number) end end end solution4_2()