Skip to content

Instantly share code, notes, and snippets.

@HurricanKai
Created December 4, 2021 05:46
Show Gist options
  • Save HurricanKai/1ed211f997da89ae29f0650f537e8cca to your computer and use it in GitHub Desktop.
Save HurricanKai/1ed211f997da89ae29f0650f537e8cca to your computer and use it in GitHub Desktop.
using System.Diagnostics;
namespace Implementation;
public class Day4
{
public static int Part1(string input)
{
var lines = input.Split('\n').Where(x => x is not null).ToArray();
var drawOrder = lines[0].Split(',').Select(int.Parse).ToArray();
var boards = lines.Skip(1).Select((x, i) => (x, i)).GroupBy(x => x.i / 6).Where(x => x.Count() != 1).Select(g =>
{
Debug.Assert(g.First().x == string.Empty);
Debug.Assert(g.Count() == 6);
return g.Skip(1).Take(5).Select(x => x.x).Select(x => x.Split(' ').Where(x => !string.IsNullOrWhiteSpace(x)).Select(int.Parse).Select(x => new int?(x)).ToArray())
.ToArray();
}).ToArray();
foreach (var drawn in drawOrder)
{
for (int b = 0; b < boards.Length; b++)
{
ref var board = ref boards[b];
for (int i = 0; i < board.Length; i++)
{
ref var row = ref board[i];
for (int j = 0; j < row.Length; j++)
{
if (row[j] == drawn)
{
row[j] = null;
}
}
}
}
var done = boards.Where(x =>
{
// check if a board is done in here
if (x.Any(x2 => x2.All(x3 => !x3.HasValue)))
return true;
if (Enumerable.Range(0, x[0].Length).Any(i => x.Select(x2 => x2[i]).All(x3 => !x3.HasValue)))
return true;
// if (Enumerable.Range(0, x[0].Length).All(i => !x[i][i].HasValue))
// return true;
//
// if (Enumerable.Range(0, x[0].Length).All(i => !x[i][x[i].Length - i - 1].HasValue))
// return true;
return false;
});
bool anyDone = false;
int maxScore = 0;
foreach (var v in done)
{
Console.WriteLine($"Found done board after drawing {drawn}");
anyDone = true;
maxScore = Math.Max(maxScore, v.SelectMany(x => x).Where(x => x.HasValue).Sum(x => x.Value) * drawn);
}
if (anyDone)
return maxScore;
}
throw null;
}
public static int Part2(string input)
{
var lines = input.Split('\n').Where(x => x is not null).ToArray();
var drawOrder = lines[0].Split(',').Select(int.Parse).ToArray();
int finalScore = 0;
var boards = lines.Skip(1).Select((x, i) => (x, i)).GroupBy(x => x.i / 6).Where(x => x.Count() != 1).Select(g =>
{
Debug.Assert(g.First().x == string.Empty);
Debug.Assert(g.Count() == 6);
return g.Skip(1).Take(5).Select(x => x.x).Select(x => x.Split(' ').Where(x => !string.IsNullOrWhiteSpace(x)).Select(int.Parse).Select(x => new int?(x)).ToArray())
.ToArray();
}).ToArray();
foreach (var drawn in drawOrder)
{
for (int b = 0; b < boards.Length; b++)
{
ref var board = ref boards[b];
for (int i = 0; i < board.Length; i++)
{
ref var row = ref board[i];
for (int j = 0; j < row.Length; j++)
{
if (row[j] == drawn)
{
row[j] = null;
}
}
}
}
var done = boards.Where(x =>
{
// check if a board is done in here
if (x.Any(x2 => x2.All(x3 => !x3.HasValue)))
return true;
if (Enumerable.Range(0, x[0].Length).Any(i => x.Select(x2 => x2[i]).All(x3 => !x3.HasValue)))
return true;
// if (Enumerable.Range(0, x[0].Length).All(i => !x[i][i].HasValue))
// return true;
//
// if (Enumerable.Range(0, x[0].Length).All(i => !x[i][x[i].Length - i - 1].HasValue))
// return true;
return false;
}).ToArray();
foreach (var v in done)
{
finalScore = v.SelectMany(x => x).Where(x => x.HasValue).Sum(x => x.Value) * drawn;
}
boards = boards.Where(x => !done.Contains(x)).ToArray();
}
return finalScore;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment