2023 day 18 in F#
Real: 00:00:00.153, CPU: 00:00:00.150, GC gen0: 0, gen1: 0, gen2: 0
This commit is contained in:
parent
446e09a44b
commit
4138b9d0f1
|
@ -0,0 +1,14 @@
|
|||
R 6 (#70c710)
|
||||
D 5 (#0dc571)
|
||||
L 2 (#5713f0)
|
||||
D 2 (#d2c081)
|
||||
R 2 (#59c680)
|
||||
D 2 (#411b91)
|
||||
L 5 (#8ceee2)
|
||||
U 2 (#caa173)
|
||||
L 1 (#1b58a2)
|
||||
U 2 (#caa171)
|
||||
R 2 (#7807d2)
|
||||
U 3 (#a77fa3)
|
||||
L 2 (#015232)
|
||||
U 2 (#7a21e3)
|
|
@ -0,0 +1,105 @@
|
|||
#time
|
||||
|
||||
open System
|
||||
open System.Text.RegularExpressions
|
||||
|
||||
let (|Regex|_|) pattern input =
|
||||
let m = Regex.Match(input, pattern)
|
||||
|
||||
if m.Success then
|
||||
Some(List.tail [ for g in m.Groups -> g.Value ])
|
||||
else
|
||||
None
|
||||
|
||||
type Direction =
|
||||
| L
|
||||
| R
|
||||
| U
|
||||
| D
|
||||
|
||||
type Instruction = Direction * int * string
|
||||
|
||||
let parseDirection =
|
||||
function
|
||||
| "L" -> L
|
||||
| "R" -> R
|
||||
| "U" -> U
|
||||
| "D" -> D
|
||||
| _ -> failwith "Unreachable"
|
||||
|
||||
let parsePart line =
|
||||
match line with
|
||||
| Regex @"([LRUD])\s+(\d+)\s+\(#([^)]+)\)" (dir :: n :: color :: []) -> (parseDirection dir, int n, color)
|
||||
| _ -> failwith "Unreachable"
|
||||
|
||||
let parseInput = Seq.map parsePart
|
||||
|
||||
let pointAdd (x1, y1) (x2, y2) = (x1 + x2, y1 + y2)
|
||||
|
||||
let pointInDirection (x, y) ins =
|
||||
match ins with
|
||||
| (L, n, _) -> (0, -n)
|
||||
| (R, n, _) -> (0, n)
|
||||
| (U, n, _) -> (-n, 0)
|
||||
| (D, n, _) -> (n, 0)
|
||||
|> pointAdd (x, y)
|
||||
|
||||
let walk input =
|
||||
let rec walk' input point points length =
|
||||
match input with
|
||||
| [] -> (points, length)
|
||||
| x :: xs ->
|
||||
let (_, n, _) = x
|
||||
let p = pointInDirection point x
|
||||
walk' xs p (Seq.append points [ p ]) (length + n)
|
||||
|
||||
walk' input (0, 0) [ (0, 0) ] 0
|
||||
|
||||
let shoelaceArea points : int64 =
|
||||
let double =
|
||||
points
|
||||
|> Seq.skip 1
|
||||
|> Seq.zip points
|
||||
|> Seq.sumBy (fun ((x1, y1), (x2, y2)) -> int64 x1 * int64 y2 - int64 x2 * int64 y1)
|
||||
|> abs
|
||||
|
||||
double / 2L
|
||||
|
||||
let part1 input =
|
||||
let (points, length) = walk input
|
||||
let area = shoelaceArea points
|
||||
|
||||
area + (int64 length / 2L) + 1L
|
||||
|
||||
let directionFromHex =
|
||||
function
|
||||
| '0' -> R
|
||||
| '1' -> D
|
||||
| '2' -> L
|
||||
| '3' -> U
|
||||
| _ -> failwith "Unreachable"
|
||||
|
||||
let hexValue c =
|
||||
match c with
|
||||
| _ when System.Char.IsAsciiDigit(c) -> int c - int '0'
|
||||
| _ when System.Char.IsAsciiHexDigit(c) -> int c - int 'a' + 10
|
||||
| _ -> failwith "Unreachable"
|
||||
|
||||
let fromHex = Seq.fold (fun acc cur -> acc * 16 + hexValue cur) 0
|
||||
|
||||
let parseColor ((_, _, s): Instruction) =
|
||||
let n = s |> Seq.take 5 |> fromHex
|
||||
let d = directionFromHex s.[5]
|
||||
(d, n, "")
|
||||
|
||||
let part2 input =
|
||||
input |> Seq.map parseColor |> Seq.toList |> part1
|
||||
|
||||
let main f =
|
||||
let input = f |> IO.File.ReadLines |> Seq.toList |> parseInput |> Seq.toList
|
||||
|
||||
printfn "Part 1: %d" (part1 input)
|
||||
printfn "Part 2: %d" (part2 input)
|
||||
0
|
||||
|
||||
main fsi.CommandLineArgs.[1]
|
Loading…
Reference in New Issue