1
0
Fork 0
advent-of-code/2021/day5.cs

56 lines
2 KiB
C#
Raw Permalink Normal View History

2024-02-08 09:55:40 +01:00
// TODO: I've shamelessly copied this off Reddit because i had no idea how to solve it.
// I need to come back to this and actually solve this myself.
/*using var sr = new StreamReader("./day05.txt");
var input = sr.ReadToEnd().Split("\n").Select(x => x.Trim());
foreach (var line in input)
{
var nums = line.Split(", ->".ToArray(), StringSplitOptions.RemoveEmptyEntries).Select(byte.Parse).ToArray();
var start = new Vector2(nums[0], nums[1]);
var end = new Vector2(nums[2], nums[3]);
}*/
using var sr = new StreamReader("../inputs/day05.txt");
var input = sr.ReadToEnd();
Console.WriteLine(GetIntersectionCount(ParseLines(input, skipDiagonals: true)));
Console.WriteLine(GetIntersectionCount(ParseLines(input, skipDiagonals: false)));
private static int GetIntersectionCount(IEnumerable<IEnumerable<Vec2>> lines)
{
// build a grid with iterating over all points, counting intersections:
var grid = new Dictionary<Vec2, int>();
foreach (var pt in lines.SelectMany(pt => pt))
{
grid[pt] = grid.GetValueOrDefault(pt, 0) + 1;
}
return grid.Count(kvp => kvp.Value > 1);
}
private static IEnumerable<IEnumerable<Vec2>> ParseLines(string input, bool skipDiagonals) =>
from line in input.Split("\n")
// parse the numbers first:
let ns = (
from st in line.Split(", ->".ToArray(), StringSplitOptions.RemoveEmptyEntries)
select int.Parse(st)
).ToArray()
// line properties:
let start = new Vec2(ns[0], ns[1])
let end = new Vec2(ns[2], ns[3])
let displacement = new Vec2(end.x - start.x, end.y - start.y)
let length = 1 + Math.Max(Math.Abs(displacement.x), Math.Abs(displacement.y))
let dir = new Vec2(Math.Sign(displacement.x), Math.Sign(displacement.y))
// represent lines with a set of points:
let points =
from i in Enumerable.Range(0, length)
select new Vec2(start.x + i * dir.x, start.y + i * dir.y)
where !skipDiagonals || dir.x == 0 || dir.y == 0 // skip diagonals in part 1
select points;
record Vec2(int x, int y);