summary refs log tree commit diff stats
path: root/solutions/day12.fs
blob: d37d08a18a0d16ea19a18b348686567cc510e5ed (plain) (blame)
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
module Solutions.Day12
open System.IO
open AStar

let input = File.ReadAllLines("inputs/day12.txt") |> Array.map Array.ofSeq

let findPoint ch =
    let row = Array.findIndex (Array.contains ch) input
    let col = Array.findIndex (fun x -> x = ch) input[row]
    (row, col)

let startCoord, endCoord = findPoint 'S', findPoint 'E'
input[fst startCoord][snd startCoord] <- 'a'
input[fst endCoord][snd endCoord] <- 'z'

let height, width = input.Length, input[0].Length

let neighbors (row, col) =
    [|(row-1, col); (row+1, col); (row, col-1); (row, col+1)|]
    |> Seq.filter (fun (nRow, nCol) -> nRow >= 0 && 
                                       nRow < height && 
                                       nCol >= 0 && 
                                       nCol < width &&
                                       input[nRow][nCol] <= input[row][col] + char 1)

let gScore _ _ = 1.0

let fScore (x, y) (dx, dy) =
    sqrt ((float dx - float x) ** 2.0 + (float dy - float y) ** 2.0)

let getPathLength start finish =
    match search start finish {neighbours = neighbors; gCost = gScore; fCost = fScore; maxIterations = None} with
    | Some path -> Seq.length path - 1
    | None -> -1

let part1 () =
    getPathLength startCoord endCoord    

let part2 () = 
    seq {
        for row in 0 .. height - 1 do
        for col in 0 .. width - 1 do
        if input[row][col] = 'a' then 
            getPathLength (row, col) endCoord
    }
    |> Seq.filter (fun x -> x > 0)
    |> Seq.sort
    |> Seq.head