using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace _2021___Day_04
{
public class Program
{
static void Main()
{
int[][][] boards;
int[] bingoNums;
var lines = File.ReadAllLines("../../../../Input.in");
bingoNums = lines.First().Split(',').Select(n => int.Parse(n)).ToArray();
boards = Enumerable.Range(0, (lines.Length - 1) / 6).Select((b, i) =>
lines.Skip(i * 6 + 2)
.Take(5)
.Select(s =>
s.Split(' ')
.Where(l => !String.IsNullOrWhiteSpace(l))
.Select(n => Int32.Parse(n))
.ToArray()
).ToArray()
).ToArray();
var winningIndexes = new List<int>();
int[] firstSeq, lastSeq = firstSeq = null;
for (int i = 1; i <= bingoNums.Length; i++)
{
var sequence = bingoNums.Take(i).ToArray();
var indexes = boards.Where((b, bi) => !winningIndexes.Contains(bi) && (IsWinner(b, sequence) || IsWinner(VerticalBoard(b), sequence)))
.Select(b => Array.IndexOf(boards, b));
if (indexes.Any())
{
firstSeq ??= sequence;
lastSeq = sequence;
winningIndexes.AddRange(indexes);
}
}
Console.WriteLine("Score of first winning board: " + FinalScore(winningIndexes.First(), firstSeq, boards));
Console.WriteLine("Score of last winning board: " + FinalScore(winningIndexes.Last(), lastSeq, boards));
}
public static int[][] VerticalBoard(int[][] board)
{
return Enumerable.Range(0, 5).Select(r => Enumerable.Range(0, 5).Select(l => board[l][r]).ToArray()).ToArray();
}
public static bool IsWinner(int[][] board, int[] sequence)
{
return board.Any(l => l.All(n => sequence.Contains(n)));
}
public static int SumUnmarked(int[][] board, int[] sequence)
{
return board.Select(l => l.Where(n => !sequence.Contains(n)).Sum()).Sum();
}
public static int FinalScore(int index, int[] sequence, int[][][] boards)
{
return SumUnmarked(boards[index], sequence) * sequence.Last();
}
}
}