Skip to content

Instantly share code, notes, and snippets.

@Couto
Created January 7, 2017 22:15
Show Gist options
  • Save Couto/7db6b1c2d92e8ac67fe0df4c1ea00322 to your computer and use it in GitHub Desktop.
Save Couto/7db6b1c2d92e8ac67fe0df4c1ea00322 to your computer and use it in GitHub Desktop.
{-
--- Day 1: No Time for a Taxicab ---
Santa's sleigh uses a very high-precision clock to guide its movements, and the
clock's oscillator is regulated by stars. Unfortunately, the stars have been
stolen... by the Easter Bunny. To save Christmas, Santa needs you to retrieve
all fifty stars by December 25th.
Collect stars by solving puzzles. Two puzzles will be made available on each day
in the advent calendar; the second puzzle is unlocked when you complete the
first. Each puzzle grants one star. Good luck!
You're airdropped near Easter Bunny Headquarters in a city somewhere. "Near",
unfortunately, is as close as you can get - the instructions on the Easter
Bunny Recruiting Document the Elves intercepted start here, and nobody had time
to work them out further.
The Document indicates that you should start at the given coordinates (where
you just landed) and face North. Then, follow the provided sequence: either
turn left (L) or right (R) 90 degrees, then walk forward the given number of
blocks, ending at a new intersection.
There's no time to follow such ridiculous instructions on foot, though, so you
take a moment and work out the destination. Given that you can only walk on the
street grid of the city, how far is the shortest path to the destination?
For example:
Following R2, L3 leaves you 2 blocks East and 3 blocks North, or 5 blocks away.
R2, R2, R2 leaves you 2 blocks due South of your starting position, which is 2 blocks away.
R5, L5, R5, R3 leaves you 12 blocks away.
-}
module PartOne exposing (..)
import Html exposing (text)
import String exposing (left, dropLeft, toInt)
import List exposing (map, foldr)
import Result exposing (withDefault)
import Debug exposing (crash)
type Direction
= Right
| Left
type Cardinal
= North
| East
| South
| West
type alias Instruction =
{ direction : Direction
, steps : Int
}
type alias Position =
{ x : Int
, y : Int
, orientation : Cardinal
}
instructions : List Instruction
instructions =
List.map toDirection
[ "R4", "R4", "L1", "R3", "L5", "R2", "R5", "R1", "L4", "R3", "L5", "R2", "L3", "L4", "L3", "R1", "R5", "R1", "L3", "L1", "R3", "L1", "R2", "R2", "L2", "R5", "L3", "L4", "R4", "R4", "R2", "L4", "L1", "R5", "L1", "L4", "R4", "L1", "R1", "L2", "R5", "L2", "L3", "R2", "R1", "L194", "R2", "L4", "R49", "R1", "R3", "L5", "L4", "L1", "R4", "R2", "R1", "L5", "R3", "L5", "L4", "R4", "R4", "L2", "L3", "R78", "L5", "R4", "R191", "R4", "R3", "R1", "L2", "R1", "R3", "L1", "R3", "R4", "R2", "L2", "R1", "R4", "L5", "R2", "L2", "L4", "L2", "R1", "R2", "L3", "R5", "R2", "L3", "L3", "R3", "L1", "L1", "R5", "L4", "L4", "L2", "R5", "R1", "R4", "L3", "L5", "L4", "R5", "L4", "R5", "R4", "L3", "L2", "L5", "R4", "R3", "L3", "R1", "L5", "R5", "R1", "L3", "R2", "L5", "R5", "L3", "R1", "R4", "L5", "R4", "R2", "R3", "L4", "L5", "R3", "R4", "L5", "L5", "R4", "L4", "L4", "R1", "R5", "R3", "L1", "L4", "L3", "L4", "R1", "L5", "L1", "R2", "R2", "R4", "R4", "L5", "R4", "R1", "L1", "L1", "L3", "L5", "L2", "R4", "L3", "L5", "L4", "L1", "R3" ]
{-| Given a direction Right (R) or Left (L) and a Integer of steps, output a
type Direction
-}
toDirection : String -> Instruction
toDirection instruction =
let
direction =
left 1 instruction
steps =
instruction
|> String.dropLeft 1
|> String.toInt
|> Result.withDefault 0
in
case direction of
"R" ->
{ direction = Right
, steps = steps
}
"L" ->
{ direction = Left
, steps = steps
}
_ ->
Debug.crash "TODO"
toDistance : Position -> Int
toDistance current =
(abs current.x) + (abs current.y)
walk : Instruction -> Position -> Position
walk instruction currentPosition =
let
{ direction, steps } =
instruction
{ orientation, x, y } =
currentPosition
in
case ( orientation, direction ) of
( North, Right ) ->
{ currentPosition | x = x + steps, orientation = East }
( North, Left ) ->
{ currentPosition | x = x - steps, orientation = West }
( East, Right ) ->
{ currentPosition | y = y - steps, orientation = South }
( East, Left ) ->
{ currentPosition | y = y + steps, orientation = North }
( South, Right ) ->
{ currentPosition | x = x - steps, orientation = West }
( South, Left ) ->
{ currentPosition | x = x + steps, orientation = East }
( West, Right ) ->
{ currentPosition | y = y + steps, orientation = North }
( West, Left ) ->
{ currentPosition | y = y - steps, orientation = South }
main =
instructions
|> List.foldl walk { x = 0, y = 0, orientation = North }
|> toDistance
|> toString
|> text
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment