Advent of Code

My solutions for the Advent of Code puzzles. View on GitHub

Day 3 - [No Matter How You Slice It]

starting with a helper class

public class Square
{
	public Square(params int[] values)
	{
		Id = values[0];
		Left = values[1];
		Top = values[2];
		Bottom = Top + values[4];
		Right = Left + values[3];
	}
	public int Id { get; set; }
	public int Left { get; set; }
	public int Top { get; set; }
	public int Bottom { get; set; }
	public int Right { get; set; }
	public bool Contains(int x, int y) => x > Left && x <= Right && y > Top && y <= Bottom;
	public bool Overlaps(Square other) =>
			(
			(Left >= other.Left && Left <= other.Right) ||
			(other.Left >= Left && other.Left <= Right) ||
			(Right >= other.Left && Right <= other.Right) ||
			(other.Right >= Left && other.Right <= Right)
			) &&
			(
			(Top >= other.Top && Top <= other.Bottom) ||
			(other.Top >= Top && other.Top <= Bottom) ||
			(Bottom >= other.Top && Bottom <= other.Bottom) ||
			(other.Bottom >= Top && other.Bottom <= Bottom)
			);
}
	var re = new Regex(@"(\D+(\d+)){5}");
	var numbers = input.Select(i => re.Match(i).Groups[2].Captures.Cast<Capture>().Select(c => int.Parse(c.Value)).ToArray());
	var squares = numbers.Select(n => new Square(n)).ToArray();

	var part1 = Enumerable.Range(1, 1000).Sum(x => Enumerable.Range(1, 1000).Count(y => squares.Count(s => s.Contains(x, y)) > 1));
	var part2 = squares.Single(s => squares.Count(o => o.Overlaps(s)) == 1).Id;

or, a little more efficiently…

	var part1 = Enumerable.Range(0, 1000).Select(e => new { x = e, sq = squares.Where(s => e > s.Left && e <= s.Right).ToArray() })
		.Sum(e => Enumerable.Range(0, 1000).Count(y => e.sq.Count(s => s.Contains(e.x, y)) > 1)).Dump();

or, even more efficiently…

	int part1 = 0;
	for (int x = 0; x < 1000; x++)
	{
		var sq = squares.Where(o => x > o.Left && x <= o.Right).ToArray();
		for (int y = 0; y < 1000; y++)
		{
			int count = 0;
			foreach (var s in sq)
			{
				if (s.Contains(x, y))
				{
					count++;
					if (count > 1)
					{
						part1++;
						break;
					}

				}
			}
		}
	}	

Day 2 - [Inventory Management System]

var counts = input.Select(i => i.GroupBy(c => c).Select(c => new { character = c, count = c.Count() }).ToList());
var two = counts.Count(count => count.Any(c => c.count == 2));
var three = counts.Count(count => count.Any(c => c.count == 3));
var part1 = two * three;


bool isMatch(string a, string b)
{
	var differnces = 0;
	for (int i = 0; i < a.Length; i++)
	{
		if (a[i] != b[i])
		{
			differnces++;
			if (differnces > 1)
				return false;
		}
	}
	return differnces == 1;
}

var part2 = input.SelectMany(i => input.Select(i2 => new { i, i2 }).Where(o => o.i != o.i2 && isMatch(o.i, o.i2)))
				 .Select(o => o.i.Zip(o.i2, (f,s) => f == s ? f : ' ').Where(c => c != ' ').ToArray())
				 .Select(c => new string(c))
				 .First();

Day 1 - [Inverse Captcha]

var part1 = input.Sum();


var frequencies = new List<int>();
var frequency = 0;
var part2 = 0;
while (part2 == 0){
	foreach (var change in input){
		frequency += change;
		if (frequencies.Contains(frequency)){
			part2 = frequency;
			break;
		}
		frequencies.Add(frequency);
	}
}