0 Comments

OK, here’s my solution to Advent of Code day 3:

C# part a (using Scan from MoreLinq):

File.ReadAllText("day3.txt")
    .Scan(new { x = 0, y = 0 }, (state, c) =>
    c == '>' ? new { x = state.x + 1, y = state.y } :
    c == '^' ? new { x = state.x, y = state.y + 1 } :
    c == '<' ? new { x = state.x - 1, y = state.y } :
               new { x = state.x, y = state.y - 1 })
    .Select(p => String.Format("{0},{1}", p.x, p.y))
    .GroupBy(p => p)    
    .Count()

C# part b:

void Main()
{
    File.ReadAllText("day3.txt")
        .Batch(2)
        .Scan(new { Santa = new Pos(0, 0), RoboSanta = new Pos(0, 0) }, (state, c) =>
              new { Santa = Move(c.First(), state.Santa),
                  RoboSanta = Move(c.Last(), state.RoboSanta)
              })
        .SelectMany(p => new[] { p.Santa, p.RoboSanta } )
        .Select(p => String.Format("{0},{1}", p.X, p.Y))
        .GroupBy(p => p)
        .Count()
        .Dump();   
}

public class Pos
{
    public Pos(int x, int y)
    {
        X = x; Y = y;
    }
    public int X { get; } 
    public int Y { get; } 
}

Pos Move(char direction, Pos startingPoint)
{
    return 
        direction == '>' ? new Pos(startingPoint.X + 1, startingPoint.Y) :
        direction == '^' ? new Pos(startingPoint.X, startingPoint.Y + 1) :
        direction == '<' ? new Pos(startingPoint.X - 1, startingPoint.Y) :
                           new Pos(startingPoint.X, startingPoint.Y - 1);
}

F# part a:

File.ReadAllText("day3.txt")
    |> Seq.map (fun c -> match c with | '>' -> (1,0) | '^' -> (0,1) | '<' -> (-1,0) | _ -> (0,-1))
    |> Seq.scan (fun (x1,y1) (x2,y2) -> (x1 + x2, y1 + y2)) (0,0)
    |> Seq.distinct
    |> Seq.length

F# part b:

let getVector c = match c with | '>' -> (1,0) | '^' -> (0,1) | '<' -> (-1,0) | _ -> (0,-1)
let addVector (x1,y1) (x2,y2) = (x1 + x2, y1 + y2)
let directions = 
    File.ReadAllText("day3.txt")
let startState = ((0,0),(0,0),0)
let update (santa,roboSanta,index) nextDir =
    if (index % 2) = 0 then
        ((addVector santa nextDir), roboSanta, index+1)
    else
        (santa, (addVector roboSanta nextDir), index+1)
    
directions
    |> Seq.map getVector
    |> Seq.scan update startState
    |> Seq.map (fun (santa,roboSanta,index) -> if index % 2 = 0 then santa else roboSanta)
    |> Seq.distinct
    |> Seq.length
    |> Dump
Want to learn more about LINQ? Be sure to check out my Pluralsight course More Effective LINQ.
Vote on HN
comments powered by Disqus