-
Notifications
You must be signed in to change notification settings - Fork 0
/
Program.fs
110 lines (95 loc) · 2.4 KB
/
Program.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
open System
open System.IO
type Direction = | North | East | South | West
type Move = | Forward | Left | Right
type Position = {
x: int
y: int
direction: Direction
}
type Journey = {
startP: Position
endP : Position
moves: Move list
}
let parseMoves (ms: string) =
ms.ToCharArray()
|> List.ofArray
|> List.choose (fun m ->
match m with
| 'F' -> Some Forward
| 'R' -> Some Right
| 'L' -> Some Left
| _ -> None)
|> Some
let parseDirection d =
match d with
| 'N' -> Some North
| 'E' -> Some East
| 'S' -> Some South
| 'W' -> Some West
| _ -> None
let tryInt (s: string) =
match Int32.TryParse(s) with
| (true,int) -> Some int
| _ -> None
let parsePosition (x: string) =
let xs = x.ToCharArray()
Option.map3
(fun x y direction -> {x=x;y=y;direction=direction})
(xs.[0] |> string |> tryInt)
(xs.[2] |> string |> tryInt)
(xs.[4] |> parseDirection)
let parseJourney xs =
match xs with
| s::m::e::_ ->
Option.map3
(fun a b c -> {startP= a; endP = b; moves=c})
(parsePosition s)
(parsePosition e)
(parseMoves m)
| _ -> None
let move (p:Position) =
match p.direction with
| North -> {p with y= p.y+1}
| East -> {p with x= p.x+1}
| South -> {p with y= p.y-1}
| West -> {p with x= p.x-1}
let toTheRight d =
match d with
| North -> East
| East -> South
| South -> West
| West -> North
let toTheLeft d =
match d with
| North -> West
| East -> North
| South -> East
| West -> South
let rotate rotateFn (p:Position) = {p with direction = (rotateFn p.direction)}
let executeMove p m =
p |> match m with
| Forward -> move
| Right -> rotate toTheRight
| Left -> rotate toTheLeft
let isJourneyValid j =
match j with
| Some x ->
x.moves
|> List.fold executeMove x.startP
|> (=) x.endP
| None -> false
[<EntryPoint>]
let main argv =
match argv with
| [|f|] -> f
| _ -> "input.txt"
|> fun file -> File.ReadLines(file)
|> Seq.chunkBySize 4
|> Seq.map (
Array.toList
>> parseJourney
>> isJourneyValid)
|> Seq.iter(printfn "%A")
0