-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay05.fsx
68 lines (50 loc) · 1.83 KB
/
Day05.fsx
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
#load "Common.fsx"
open System
open Common
open FParsec
type Crate = char
type Stack = int
type Cargo = List<Crate>[] // map Stack to List<Crate>
type Instr = { Count: int; From: Stack; To: Stack }
type Crane = Cargo * List<Instr> -> Cargo
let spc = pchar ' '
let crate: Parser<Option<Crate>> =
choice [ between (pstring "[") (pstring "]") upper |>> Some; pstring " " >>% None ]
let cargo: Parser<Cargo> =
many1 (sepBy1 crate spc .>> newline)
|>> List.transpose
|>> List.map (List.choose id)
|>> Array.ofList
let labels: Parser<unit> = skipManyTill anyChar newline .>> newline // useless!
let instrs: Parser<List<Instr>> =
let chunk s = pstring s >>. spc >>. puint64 |>> int
let make count from to_ =
{ Count = count; From = from; To = to_ }
let instr =
pipe3
(chunk "move" .>> spc)
// y u start at 1?
(chunk "from" |>> (+) -1 .>> spc)
(chunk "to" |>> (+) -1 .>> newline)
make
many1 instr
let procedure: Parser<Cargo * List<Instr>> = cargo .>> labels .>>. instrs .>> eof
let crane variant procedure =
let oneStep (cargo: Cargo) { Count = c; From = f; To = t } =
Array.mapi
<| function
| i when i = f -> List.skip c
| i when i = t -> List.append (List.take c cargo[f] |> variant)
| _ -> id
<| cargo
procedure ||> List.fold oneStep
let crane9000: Crane = crane List.rev
let crane9001: Crane = crane id
let reduce: Cargo -> string = Array.map List.head >> String.Concat
let input = runParserOnFile' procedure "data/input05.txt"
crane9000 input
|> reduce
|> partOne "After the rearrangement procedure completes, what crate ends up on top of each stack?"
crane9001 input
|> reduce
|> partTwo "After the rearrangement procedure completes, what crate ends up on top of each stack?"