Created
January 7, 2017 22:15
-
-
Save Couto/7db6b1c2d92e8ac67fe0df4c1ea00322 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{- | |
--- 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