blob: 46f03c66ac20fd6ffbeb6d4f733ae46abf1f6554 (
plain) (
tree)
|
|
module Solutions.Day15
open System.IO
open System.Text.RegularExpressions
open FSharpPlus.Operators
let cave = set {0 .. 4_000_000}
type Sensor(location: int*int, beacon: int*int) =
let manhattan (x1, y1) (x2, y2) = abs (x1 - x2) + abs (y1 - y2)
member _.Location = location
member _.Beacon = beacon
member _.Distance = manhattan location beacon
member s.Range (y: int) =
let scanWidth = s.Distance - abs (snd s.Location - y)
fst s.Location - scanWidth, fst s.Location + scanWidth
override s.ToString() =
$"{s.Location} {s.Beacon}"
let getCoords (line: string) =
let matches = Regex.Matches(line, "x=(-?\d+), y=(-?\d+)")
matches
|> Seq.map ((fun x -> x.Groups) >> Seq.tail >> (Seq.map (fun x -> int x.Value)) >> Array.ofSeq >> (fun x -> x[0], x[1]))
|> (Array.ofSeq >> (fun x -> Sensor(x[0], x[1])))
let sensors = File.ReadAllLines("inputs/day15.txt")
|> Seq.map getCoords
|> List.ofSeq
let rangeSort (ax, ay) (bx, by) =
match ax - bx with
| 0 -> ay - by
| d -> d
let reduceRanges ranges =
let foldMerge (acc: (int * int) list) (newStart, newEnd) =
match acc with
| [] -> [newStart, newEnd]
| (currStart, currEnd)::tail when newStart <= (currEnd + 1) && currEnd < newEnd -> (currStart, newEnd)::tail
| (_, currEnd)::_ when newStart <= currEnd + 1 -> acc
| _ -> (newStart, newEnd)::acc
ranges
|> List.sortWith rangeSort
|> List.fold foldMerge List.empty
let sumRanges acc (rStart, rEnd) = acc + abs (rEnd + 1 - rStart)
let getRanges y =
sensors
|> List.map (fun x -> x.Range y)
|> List.filter (fun x -> fst x < snd x)
|> reduceRanges
let part1 () =
let beaconCount =
sensors
|> List.map (fun x -> x.Beacon)
|> List.filter (fun x -> snd x = 2_000_000)
|> List.distinct
|> List.length
getRanges 2_000_000
|> List.fold sumRanges 0
|> fun x -> x - beaconCount
let part2 () =
let getGap ranges =
List.sortWith rangeSort ranges
|> List.head
|> snd
|> (+) 1
seq {0 .. 4_000_000}
|> Seq.map (fun i -> i, getRanges i)
|> Seq.find (snd >> List.length >> (=) 2)
|> fun (i, ranges) -> int64 (getGap ranges) * 4_000_000L + int64 i
|