Skip to content

Instantly share code, notes, and snippets.

@robhol
Last active December 7, 2017 09:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robhol/328c468904ce54126e284bc2662ac950 to your computer and use it in GitHub Desktop.
Save robhol/328c468904ce54126e284bc2662ac950 to your computer and use it in GitHub Desktop.
int Part1() => GetSpiralCells()
.Skip(PuzzleInput - 1)
.Select(t => Math.Abs(t.x) + Math.Abs(t.y))
.First();
int Part2()
{
var values = new Dictionary<(int x, int y), int>();
values[(0, 0)] = 1;
foreach (var t in GetSpiralCells().Skip(1))
{
var v = t.GetNeighbors().Sum(n => values.GetOrDefault(n));
if (v > PuzzleInput)
return v;
values[t] = v;
}
throw new Exception();
}
IEnumerable<(int x, int y)> GetSpiralCells()
{
var pos = (0,0);
foreach(var run in GetSpiralSegments())
{
for(var i = 0; i < run.length; i++)
{
yield return pos;
pos = pos.Apply(run.dir);
}
}
}
IEnumerable<(Direction dir, int length)> GetSpiralSegments()
{
var d = Direction.East;
var i = 2;
while(true)
{
yield return (d, i / 2);
i += 1;
d = d.GetCounterclockwise();
}
}
enum Direction {North, East, South, West}
static class ext
{
public static Direction GetCounterclockwise(this Direction d) => d == Direction.North ? Direction.West : ((Direction)d - 1);
public static (int x, int y) Apply(this (int x, int y) t, Direction dir, int d = 1)
{
switch(dir)
{
case Direction.North: return (t.x, t.y - d);
case Direction.East: return (t.x + d, t.y);
case Direction.South: return (t.x, t.y+d);
case Direction.West: return (t.x-d, t.y);
}
throw new Exception();
}
public static IEnumerable<(int x, int y)> GetNeighbors(this (int x, int y) origin) =>
new[] {-1, 0, 1}
.CartesianProduct()
.Where(t => t.a != 0 || t.b != 0)
.Select(t => (origin.x + t.a, origin.y + t.b));
public static IEnumerable<(T a, T b)> CartesianProduct<T>(this IEnumerable<T> ts)
{
var tsa = ts.ToArray();
foreach (var a in tsa)
foreach (var b in tsa)
yield return (a, b);
}
public static V GetOrDefault<K,V>(this IDictionary<K,V> d, K k, V def = default(V)) => d.TryGetValue(k, out V v) ? v : def;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment