Repo for my Advent of Code solutions.
open System.IO

let readLines (filePath: string) = seq {
    use sr = new StreamReader (filePath)
    while not sr.EndOfStream do
        yield sr.ReadLine()
}

type Pos = { x: int; y: int }
type Slope = { x: int; y: int }
type Tile =
    | Open
    | Tree
type Map = { tiles: Tile list list }

let createMap (lines: string seq): Map =
    { Map.tiles = [
        for line in lines do
            [ for char in line do
                if char = '#' then
                    Tile.Tree
                else Tile.Open ]
     ] }
let getMaxPos (map: Map): Pos =
    { Pos.x = map.tiles.[0].Length - 1; y = map.tiles.Length - 1 }

let advancePos (pos: Pos) (slope: Slope) (maxPos: Pos): (bool * Pos) =
    if (pos.y + slope.y > maxPos.y) then
        (true, pos)
    else
        if pos.x + slope.x > maxPos.x then
            (false, { Pos.x = ((pos.x + slope.x) % maxPos.x) - 1; y = pos.y + slope.y })
        else
            (false, { Pos.x = pos.x + slope.x; y = pos.y + slope.y })

let rec checkSlope (map: Map) (pos: Pos) (slope: Slope) (maxPos: Pos) (count: int64): int64 =
    match advancePos pos slope maxPos with
        | (true, { Pos.x = x; Pos.y = y }) -> count
        | (false, { Pos.x = x; Pos.y = y }) -> 
            if map.tiles.[y].[x] = Tile.Tree then
                checkSlope map { Pos.x = x; Pos.y = y } slope maxPos (count + 1L)
            else checkSlope map { Pos.x = x; Pos.y = y } slope maxPos (count)

[<EntryPoint>]
let main argv =
    let lines = readLines "input.txt"
    let map = createMap lines
    let maxPos = getMaxPos map

    let count1 = checkSlope map { Pos.x = 0; y = 0 } { Slope.x = 1; y = 1 } maxPos 0L
    let count2 = checkSlope map { Pos.x = 0; y = 0 } { Slope.x = 3; y = 1 } maxPos 0L
    let count3 = checkSlope map { Pos.x = 0; y = 0 } { Slope.x = 5; y = 1 } maxPos 0L
    let count4 = checkSlope map { Pos.x = 0; y = 0 } { Slope.x = 7; y = 1 } maxPos 0L
    let count5 = checkSlope map { Pos.x = 0; y = 0 } { Slope.x = 1; y = 2 } maxPos 0L

    let part1 = count2
    let part2 = count1 * count2 * count3 * count4 * count5

    printf "%d, %d\n" part1 part2
    0