using System.Collections.Generic;
var response = await new HttpClient().GetStringAsync("https://tompafireadventofcode.free.beeceptor.com/day4");
const string sectionDelimeter = "\n\n";
var sections = response.Split(sectionDelimeter);
var inputSection = sections.First();
var boardSections = sections.Skip(1);
var input = inputSection.Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries).Select(int.Parse);
var boards = GetBoardsFromText(boardSections);
var boardsStep1 = boards.Select(b => b with { }).ToList();
Board boardWithFullLine = null;
foreach (var calledNumber in input)
var matchingValues = boardsStep1.SelectMany(b => b.Rows.SelectMany(r => r.Values)).Where(x => x.Value == calledNumber).ToList();
matchingValues.ForEach(x => x.IsSelected = true);
boardWithFullLine = boardsStep1.FirstOrDefault(b =>
b.Rows.Any(r => r.Values.All(x => x.IsSelected)) ||
b.Columns.Any(c => c.Values.All(x => x.IsSelected)));
if (boardWithFullLine != null)
finalNumber = calledNumber;
if (boardWithFullLine != null)
var sumOfUnmarkedValues = boardWithFullLine.Rows.SelectMany(r => r.Values).Where(x => !x.IsSelected).Sum(x => x.Value);
Console.WriteLine(finalNumber);
Console.WriteLine(sumOfUnmarkedValues);
var result = finalNumber * sumOfUnmarkedValues;
Console.WriteLine(result);
var boardsStep2 = boards.Select(b => b with { }).ToList();
Board lastBoardWithFullLine = null;
var remainingBoards = boardsStep2;
foreach (var calledNumber in input)
var matchingValues = remainingBoards.SelectMany(b => b.Rows.SelectMany(r => r.Values)).Where(x => x.Value == calledNumber).ToList();
matchingValues.ForEach(x => x.IsSelected = true);
var boardsdWithFullLine = remainingBoards.Where(b =>
b.Rows.Any(r => r.Values.All(x => x.IsSelected)) ||
b.Columns.Any(c => c.Values.All(x => x.IsSelected)));
if (boardsdWithFullLine.Any())
finalNumber2 = calledNumber;
lastBoardWithFullLine = boardsdWithFullLine.Last();
remainingBoards = remainingBoards.Except(boardsdWithFullLine).ToList();
if (lastBoardWithFullLine != null)
var sumOfUnmarkedValues = lastBoardWithFullLine.Rows.SelectMany(r => r.Values).Where(x => !x.IsSelected).Sum(x => x.Value);
Console.WriteLine(finalNumber2);
Console.WriteLine(sumOfUnmarkedValues);
var result = finalNumber2 * sumOfUnmarkedValues;
Console.WriteLine(result);
IEnumerable<Board> GetBoardsFromText(IEnumerable<string> sections)
foreach (var section in sections)
var rows = section.Split("\n").Select(line =>
var values = line.Split(' ', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries).Select((val, index) => new CellValue(index, int.Parse(val)))
yield return new Board(rows);
public record Row(List<CellValue> Values);
public record Column(List<CellValue> Values);
public record CellValue(int Index, int Value)
public bool IsSelected { get; set; }
public record Board(IEnumerable<Row> Rows)
public List<Column> Columns => Rows.SelectMany(row => row.Values).GroupBy(x => x.Index).Select(x => new Column(x.ToList())).ToList();