Sign in

bbaaiiaannaann.bsky.social

@bbaaiiaannaann.bsky.social
8 followers 6 following 25 posts
PostsRepliesMedia
bbaaiiaannaann.bsky.social @bbaaiiaannaann.bsky.social · 29/05/2025
F#, I've completed "Chronospatial Computer" - Day 17 - Advent of Code 2024 AdventOfCode adventofcode.com/2024/day/17
// d17a.fsx
"short17.txt" |> System.IO.File.ReadAllText |> _.Split("\r\n\r\n")
|> fun arr_r_p ->
    let reg_ABC = (arr_r_p |> Array.head).Split("\r\n") |> Array.map (fun s -> s.Split ':' |> Array.last |> int) |> fun a -> a[0], a[1], a[2]
    let p_Array = (arr_r_p |> Array.last).Split(':', ' ') |> Array.last |> _.Split(',') |> Array.map int |> Array.chunkBySize 2 |> Array.map (fun a -> a[0], a[1])

    let combo (ra,rb,rc) x =
        match x with
        | 0 | 1 | 2 | 3 -> x
        | 4 -> ra | 5 -> rb | 6 -> rc
        | 7 -> failwith "reserved"
        | _ -> failwith "invalid combo-oprand"

    let rec run (rA, rB, rC) pc out_list =
        if pc > p_Array.Length - 1 then printfn "outlist=\n%s" (out_list|>Seq.map string |> Seq.rev|> String.concat ",")
        else
            match p_Array[pc]|>fst with
            | 0 -> run (rA >>> (p_Array[pc]|>snd |> combo (rA, rB, rC)), rB, rC) (pc + 1) out_list
            | 1 -> run (rA, rB ^^^ (p_Array[pc]|>snd), rC) (pc + 1) out_list
            | 2 -> run (rA, p_Array[pc]|>snd |> combo (rA, rB, rC) &&& 0b0111, rC) (pc + 1) out_list
            | 3 -> run (rA, rB, rC) (if rA <> 0 then p_Array[pc]|>snd else pc + 1) out_list
            | 4 -> run (rA, rB ^^^ rC, rC) (pc + 1) out_list
            | 5 -> run (rA, rB, rC) (pc + 1) ((p_Array[pc]|>snd |> combo (rA, rB, rC) &&& 0b0111) :: out_list)
            | 6 -> run (rA, rA >>> (p_Array[pc]|>snd |> combo (rA, rB, rC)), rC) (pc + 1) out_list
            | 7 -> run (rA, rB, rA >>> (p_Array[pc]|>snd |> combo (rA, rB, rC))) (pc + 1) out_list
            | _ -> failwith "not implemented"

    run reg_ABC 0 [] //
// d17b.fsx
//[ (2, 4); (1, 3); (7, 5); (4, 0); (1, 3); (0, 3); (5, 5); (3, 0) ]
let wanted = (List.rev [ 2; 4; 1; 3; 7; 5; 4; 0; 1; 3; 0; 3; 5; 5; 3 ]) |> List.map uint64
let rec loop (rA_xs: uint64 list) =
    let A0 = rA_xs.Head
    match int (System.Math.Log(float A0, 8.0)) with
    | lg_base_8 when (lg_base_8 = wanted.Length) -> A0 //return A0
    | lg_base_8 ->
        let mutable new_xs = rA_xs.Tail
        (for B0 in [ 0..7 ] do
            let A = (A0 <<< 3) + uint64 B0 // 2,4 and 0,3
            let B1 = B0 ^^^ 3 //              1,3
            let C = A >>> B1 //               7,5
            let B2 = C ^^^ uint64 B1 //       4,0
            let B3 = B2 ^^^ 3UL //            1,3
            let out = B3 &&& 7UL
            if out = wanted[lg_base_8] then new_xs <- A :: new_xs)
        loop new_xs //(count - 1)
let AAA = loop [ 3UL ]
printfn "\n%A\n" (AAA, System.Math.Log(float AAA, 8.0) |> int)
010 0
bbaaiiaannaann.bsky.social @bbaaiiaannaann.bsky.social · 12/03/2025
I've completed "Reindeer Maze" - Day 16 - Advent of Code 2024 AdventOfCode adventofcode.com/2024/day/16
//d16a.fsx
"input16.txt"
|> System.IO.File.ReadAllLines
|> fun aa0 ->
    let WW = aa0[0].Length
    let _one_big_str = aa0 |> String.concat ""
    let ss, ee = _one_big_str.IndexOf('S'), _one_big_str.IndexOf('E')
    let one_big_array = _one_big_str.ToCharArray()

    let rec deer_run (pq: System.Collections.Generic.PriorityQueue<int * char * int, int>) =
        let x0, d0, score0 = pq.Dequeue()
        (one_big_array[x0] <- '#') |> ignore //paint the checked cell

        [| x0 - WW; x0 + WW; x0 - 1; x0 + 1 |]
        |> Array.Parallel.filter (fun x -> one_big_array[x] <> '#')
        |> Array.iter (fun x ->
            let direction = match x - x0 with | 1 -> '>' | -1 -> '<' | d when d = WW -> 'v' | d when d = -1 * WW -> '^' | _ -> failwith "impossible"
            let score = if d0 = direction then 1+score0 else 1001+score0
            pq.Enqueue((x, direction, score), score))|>ignore // enqueue

        match pq.Peek() with
        | x, _ch, score when x = ee -> score //return&exit
        | _  -> deer_run pq

    System.Collections.Generic.PriorityQueue(seq { struct ((ss, '>', 0), 0) }) |> deer_run |> printfn "%A"
|> fun a0 ->
    let WW = a0[0].Length
    let _one_big_string = a0 |> String.concat ""
    let ss, ee = _one_big_string.IndexOf('S'), _one_big_string.IndexOf('E')
    let one_big_array = _one_big_string.ToCharArray() |> Array.mapi (fun i c ->
            match c with
            | '#' -> 0
            | _ -> -1 + Array.Parallel.sumBy (fun x -> if _one_big_string[x] <> '#' then 1 else 0) [| i - WW; i + WW; i - 1; i + 1 |])

    let rec dear_run2 (pq: System.Collections.Generic.PriorityQueue<int list * int, int>) =
        let xl, score0 = pq.Dequeue()
        let x0, x00 = xl.Head, xl.Tail.Head

        one_big_array[x0] <- one_big_array[x0] - 1 //paint the checked cell

        [| x0 - WW; x0 + WW; x0 - 1; x0 + 1 |]
        |> Array.Parallel.filter (fun xa -> xa <> x00 && one_big_array[xa] > 0)
        |> Array.iter (fun new_x ->
            let new_score = if abs (new_x - x00) = 2 || abs (new_x - x00) = 2 * WW then score0 + 1 else score0 + 1001
            let cc: System.Collections.Generic.IEqualityComparer<int list * int> =
                { new System.Collections.Generic.IEqualityComparer<int list * int> with
                    member _.Equals((list1, int1), (list2, int2)) = list1.Head = list2.Head && int1 = int2
                    member _.GetHashCode((list, int)) = hash (list.Head, int) }
            let mutable lout: int list * int = ([], 0)
            let mutable sout: int = 0
            match pq.Remove((new_x :: xl, new_score), &lout, &sout, cc) with
            | true -> pq.Enqueue((new_x :: xl.Head :: (xl.Tail |> List.append (fst lout)), new_score), new_score) // enqueue
            | false -> pq.Enqueue((new_x :: xl, new_score), new_score))

        match pq.Peek() with
        | xl1, _ when xl1.Head = ee -> (xl1 |> List.distinct).Length - 1 //  [ ss; ss - 1 ] is used. So, length-1
        | _ -> dear_run2 pq

    System.Collections.Generic.PriorityQueue(seq { struct (([ ss; ss - 1 ], 0), 0) }) //
    |> dear_run2
010 0
bbaaiiaannaann.bsky.social @bbaaiiaannaann.bsky.social · 28/01/2025
I've completed "Warehouse Woes" - Day 15 - Advent of Code 2024 AdventOfCode adventofcode.com/2024/day/15
    let next_not_O direction (x, y) = match direction with
                                        | '^' -> x, [ 0 .. y - 1 ] |> List.findBack (fun i -> m00.[i].[x] <> 'O')
                                        | 'v' -> x, [ y + 1 .. HH ] |> List.find (fun i -> m00.[i].[x] <> 'O')
                                        | '<' -> [ 0 .. x - 1 ] |> List.findBack (fun j -> m00.[y].[j] <> 'O'), y
                                        | '>' -> [ x + 1 .. WW - 1 ] |> List.find (fun j -> m00.[y].[j] <> 'O'), y
                                        | _ -> failwith "invalid direction"
    let pushbox direction (x, y) (endx, endy) = match m00[endy].[endx] with
                                                | '.' ->
                                                    match direction with
                                                    | '^' -> [ endy .. y - 1 ] |> List.iter (fun yy -> m00[yy].[x] <- m00[yy + 1].[x])
                                                    | 'v' -> [ endy .. -1 .. y + 1 ] |> List.iter (fun yy -> m00[yy].[x] <- m00[yy - 1].[x])
                                                    | '<' -> [ endx .. x - 1 ] |> List.iter (fun xx -> m00[y].[xx] <- m00[y].[xx + 1])
                                                    | '>' -> [ endx .. -1 .. x + 1 ] |> List.iter (fun xx -> m00[y].[xx] <- m00[y].[xx - 1])
                                                    | _ -> failwith "invalid direction"
                                                    m00.[y].[x] <- '.'
                                                    next_any_char direction (x, y) //new p0 
                                                | _ -> (x, y) //no movement
    moves
    |> Seq.fold (fun p direction -> pushbox direction p (next_not_O direction p))
                (input[0].Split("\r\n") |> String.concat "" |> _.IndexOf('@') |> (fun n -> (n % WW, n / WW))) //p0
    let next_LR_non_box direction (x, y) = if direction = '<' then [ 0 .. x - 1 ]      |> List.findBack (fun j -> m0[y].[j] = '.' || m0[y].[j] = '#'), y
                                                              else [ x + 1 .. WW - 1 ] |> List.find     (fun j -> m0[y].[j] = '.' || m0[y].[j] = '#'), y
    let pushbox_LR direction (x, y) (endx, endy) = if m0[endy].[endx] = '.' then
                                                         if direction = '<' then [ endx .. x - 1 ]       |> List.iter (fun xx -> m0[y].[xx] <- m0[y].[xx + 1])
                                                                           else [ endx .. -1 .. x + 1 ] |> List.iter (fun xx -> m0[y].[xx] <- m0[y].[xx - 1])
                                                         m0[y].[x] <- '.' 
                                                         (x, y)|> _to direction  //new p0
                                                    else (x, y)                  //no movement
    let rec find_boxes_up_down direction (known_boxes: (int * int) list list) =
        let _is_moveable direction boxes = boxes |> Seq.collect id |> Seq.map (fun p -> p |> _to direction) |> Seq.exists (fun (x, y) -> m0[y].[x] = '#')|>not
        known_boxes.Head |> List.collect (fun p -> //
            match (p |> _to direction) with
            | (nx, ny) when '[' = m0[ny].[nx] -> [ (nx, ny);     (nx + 1, ny) ]
            | (nx, ny) when ']' = m0[ny].[nx] -> [ (nx - 1, ny); (nx, ny) ]
            | _ -> [])
        |> List.distinct
        |> fun next_line -> if List.isEmpty next_line then
                                known_boxes, known_boxes |> _is_moveable direction
                            else
                                find_boxes_up_down direction (next_line :: known_boxes)
000 0
bbaaiiaannaann.bsky.social @bbaaiiaannaann.bsky.social · 24/01/2025
I've completed "Restroom Redoubt" - Day 14 - Advent of Code 2024 AdventOfCode adventofcode.com/2024/day/14
// d14a.fsx
open System.Text.RegularExpressions
let N, XX, YY = 100, 101, 103

"input14.txt"
|> System.IO.File.ReadAllLines
|> Array.map (fun s -> //
    let _r = Regex @"-?\d+"
    let _out = [ for m in _r.Matches(s) -> int m.Value ]
    let px, py, dx, dy = _out[0], _out[1], _out[2], _out[3]
    let newx = ((px + dx * N + XX * N) % XX)
    let newy = ((py + dy * N + YY * N) % YY)
    (newx, newy))
|> Array.filter (fun (x, y) -> x <> XX / 2 && y <> YY / 2)
|> Array.countBy (fun (x, y) -> x < XX / 2, y < YY / 2)
|> Array.fold (fun acc x -> acc * (snd x)) 1
|> printfn "%A"



// d14b.fsx
open System.Text.RegularExpressions
let XX, YY = 101, 103

"input14.txt"
|> System.IO.File.ReadAllLines
|> Array.map (fun s -> [ for m in (Regex @"-?\d+").Matches(s) -> int m.Value ])// array < [px, py, dx, dy]>
|> fun input_array ->
    let fill_matrix a =
        let m = [| for i in [ 1..YY ] -> Array.copy [| for i in [ 1..XX ] -> 0 |] |]
        for (x, y) in a do m[y].[x] <- 1
        m

    let mut n = Array.map (function
            | [ px; py; dx; dy ] -> (px + dx * n + XX * n) % XX, (py + dy * n + YY * n) % YY
            | _ -> failwith "indalid input14.txt")

    let adjecent_pixels_in (matrix: int array array) (x, y) =
        [ (x + 1, y); (x - 1, y); (x, y + 1); (x, y - 1) ]
        |> List.filter (fun (x, y) -> try matrix.[y].[x] = 1 with _ -> false)

    Seq.initInfinite id
    |> Seq.tryPick (fun n -> //
        let pixels = input_array |> mut n
        let matrix = fill_matrix pixels
        pixels |> Array.map (adjecent_pixels_in matrix)
        |> Array.filter (fun l -> l.Length > 1)
        |> fun a ->
            if a.Length > input_array.Length * 50 / 100 then Some n else None)
|> printfn "%A"
100 0
bbaaiiaannaann.bsky.social @bbaaiiaannaann.bsky.social · 22/01/2025
I just completed "Claw Contraption" - Day 13 - Advent of Code 2024 adventofcode.com/2024/day/13
// d13a.fsx
"input13.txt"
|> System.IO.File.ReadAllText
|> _.Split("\r\n\r\n")
|> Array.sumBy (fun s -> //
    let _r = System.Text.RegularExpressions.Regex @"\d+"
    let _int_xs = [ for m in _r.Matches s -> int m.Value ]

    let a, c, b, d, xx, yy =
        _int_xs[0], _int_xs[1], _int_xs[2], _int_xs[3], _int_xs[4], _int_xs[5]

    let y = (c * xx - a * yy) / (b * c - a * d)
    let x = (d * xx - b * yy) / (a * d - c * b)

    if (a * x + b * y) = xx && (c * x + d * y) = yy then
        x * 3 + y
    else
        0)
|> printfn "\n%A"
// a      c    b     d     xx      yy
// "94", "34", "22", "67", "8400", "5400"
// 80*94 + 40*22 = 8400
// x*a   +  y*b = xx
// 80*34 + 40*67 = 5400
// x*c   +  y*d = yy

// acx + bcy = xx*c
// -acx - ady = -yy*a
// y * (bc -ad) = cxx -  ayy

// adx + bdy = xx*d
// -cbx - bdy = -yy*b
//  x*(ad-cb)= dxx -byy


// d13b.fsx
"input13.txt"
|> System.IO.File.ReadAllText
|> _.Split("\r\n\r\n")
|> Array.sumBy (fun s -> //
    let _r = System.Text.RegularExpressions.Regex @"\d+"
    let _int_xs = [ for m in _r.Matches s -> int64 m.Value ]

    let a, c, b, d, xx0, yy0 =
        _int_xs[0], _int_xs[1], _int_xs[2], _int_xs[3], _int_xs[4], _int_xs[5]
    let xx, yy = xx0 + 10000000000000L, yy0 + 10000000000000L

    let y = (c * xx - a * yy) / (b * c - a * d)
    let x = (d * xx - b * yy) / (a * d - c * b)

    if (a * x + b * y) = xx && (c * x + d * y) = yy then
        x * 3L + y
    else
        0L)
|> printfn "\n%A"
// a      c    b     d     xx      yy
// "94", "34", "22", "67", "8400", "5400"
// 80*94 + 40*22 = 8400
// x*a   +  y*b = xx
// 80*34 + 40*67 = 5400
// x*c   +  y*d = yy

// acx + bcy = xx*c
// -acx - ady = -yy*a
// y * (bc -ad) = cxx -  ayy

// adx + bdy = xx*d
// -cbx - bdy = -yy*b
//  x*(ad-cb)= dxx -byy
010 0
bbaaiiaannaann.bsky.social @bbaaiiaannaann.bsky.social · 19/01/2025
I've completed "Garden Groups" - Day 12 - Advent of Code 2024 #AdventOfCode adventofcode.com/2024/day/12
"input12.txt"
|> System.IO.File.ReadAllLines
|> fun a0 ->
    let n_rows, n_cols = a0.Length, a0[0].Length
    let mark2d = Array2D.create n_rows n_cols false

    let adjecent_in_this_region (i0, j0) =
        [ (i0 - 1, j0); (i0 + 1, j0); (i0, j0 - 1); (i0, j0 + 1) ]
        |> List.filter (fun (i, j) -> try a0.[i0].[j0] = a0.[i].[j] with _ -> false)

    let rec find_region (untouch: List<int * int>) (touched: List<int * int>) (border_count: int) =
        match untouch with
        | [] -> touched, border_count
        | (r, c) :: rest ->
            let adjecent_cells = adjecent_in_this_region (r, c)
            let new_cells = adjecent_cells
                            |> List.filter (fun (row, col) -> mark2d.[row, col] = false)
                            |> List.filter (fun x -> not (rest |> List.exists ((=) x)))
            mark2d.[r, c] <- true
            let new_bdr_cnt = border_count + 4 - adjecent_cells.Length
            let new_untouch = rest @ new_cells |> List.distinct
            let new_touched = (r, c) :: touched
            find_region new_untouch new_touched new_bdr_cnt

    [ for row in 1..n_rows do for col in 1..n_cols do yield (row - 1, col - 1) ]
    |> Seq.choose (fun (i, j) ->
        if mark2d[i, j] = false then Some(find_region [ (i, j) ] [] 0) else None)
    |> Seq.sumBy (fun (region, border_count) -> region.Length * border_count)
    |> printfn "%A"


|> fun a00 ->
    let n_rows, n_cols = ...
    let mark2d = Array2D.create n_rows n_cols false
    let adjecent_of_same_region (i0, j0) =
        [ (i0 - 1, j0); (i0 + 1, j0); (i0, j0 - 1); (i0, j0 + 1) ]
        |> List.filter (fun (i, j) -> try a00.[i0].[j0] = a00.[i].[j] with _ -> false)

    let rec find_region (untouch: List<int * int>) (touched: List<int * int>) =
        match untouch with
        | [] -> touched
        | (r0, c0) :: rest ->
            let adjecent_cells = adjecent_of_same_region (r0, c0)
            let new_cells = adjecent_cells
                            |> List.filter (fun (row, col) -> mark2d.[row, col] = false)
                            |> List.filter (fun n -> not (rest |> List.exists ((=) n)))
            mark2d.[r0, c0] <- true
            find_region (rest @ new_cells |> List.distinct) ((r0, c0) :: touched)

    [ for row in 1..n_rows do for col in 1..n_cols do yield (row - 1, col - 1) ]
    |> List.choose (fun (i, j) -> if mark2d[i, j] = false then Some(find_region [ (i, j) ] []) else None)
    |> List.map (fun region ->
        let imax, jmax = region |> List.maxBy fst |> fst, region |> List.maxBy snd |> snd
        let imin, jmin = region |> List.minBy fst |> fst, region |> List.minBy snd |> snd
        let bw00 = [| for i in imin..imax -> Array.copy [| for j in jmin..jmax -> 0 |] |]
        for (i, j) in region do bw00[i - imin].[j - jmin] <- 1
        [ bw00; bw00 |> Array.transpose ]
        |> List.map (fun arr ->
            arr
            |> Array.pairwise //
            |> Array.map (fun (a, b) -> [| for n in 0 .. a.Length - 1 ->  (a[n] - b[n]) |])
            |> fun diff_arr -> Array.concat [ [| arr[0] |]; diff_arr; [| arr |> Array.last |] ]
            |> Array.map ( Array.fold (fun (out, last_x) x -> if (x=last_x) then out,x else x::out, x ) ([], 0) )
            |> Array.map fst
            |> Array.sumBy (List.sumBy abs) )
        |> List.sum
        |> fun n -> n * region.Length )
    |> List.sum
010 0
bbaaiiaannaann.bsky.social @bbaaiiaannaann.bsky.social · 15/01/2025
I've completed "Plutonian Pebbles" - Day 11 - Advent of Code 2024 #AdventOfCode adventofcode.com/2024/day/11
// d11a.fsx
"input11.txt"
|> System.IO.File.ReadLines
|> Seq.head
|> _.Split((null: char[]), System.StringSplitOptions.RemoveEmptyEntries)
|> fun a0 ->
    let blink a _ =
            a
            |> Seq.collect (function //
                | "0" -> seq {"1"}
                | s when (s.Length) % 2 = 0 ->
                    s
                    |> Seq.chunkBySize (s.Length / 2)
                    |> Seq.map System.String.Concat
                    |> Seq.map (fun s -> (int s) |> string)

                | s -> seq {(int64 s) * 2024L |> string })

    [ 1..25 ] //
    |> Seq.fold blink a0
    |> Seq.length
    |> printfn "%A"

    // d11b.fsx
open System.Collections.Generic

"input11.txt"
|> System.IO.File.ReadLines
|> Seq.head
|> _.Split()
|> Array.countBy id
|> fun read_in ->
    [ 1..75 ]
    |> List.fold
        (fun d_in _ ->
            let d_out = Dictionary<string, int64>()

            d_in
            |> Seq.iter (fun (KeyValue(s, cnt)) ->
                match s with
                | "0" -> [ "1" ]
                | s when s.Length % 2 = 0 -> [ s[.. s.Length / 2 - 1]; s[s.Length / 2 ..] |> int64 |> string ]
                | _ -> [ string (2024L * (int64 s)) ]
                |> List.iter (fun k -> d_out[k] <- cnt + d_out.GetValueOrDefault(k, 0L)))

            d_out)
        (Dictionary(read_in |> Array.map (fun (k, v) -> KeyValuePair(k, int64 v))))
|> _.Values
|> Seq.sum
|> printfn "%A"
010 0
bbaaiiaannaann.bsky.social @bbaaiiaannaann.bsky.social · 13/01/2025
I've completed "Hoof It" - Day 10 - Advent of Code 2024 #AdventOfCode adventofcode.com/2024/day/10
//d10a.fsx
type xy_v = { row: int; col: int; v: int }

"input10.txt"
|> System.IO.File.ReadAllLines
|> fun read_in ->
    let n_rows = read_in.Length
    let n_cols = read_in[0].Length

    let cell2d =
        Array2D.initBased 1 1 n_rows n_cols (fun rr cc -> read_in[rr - 1].[cc - 1])
        |> Array2D.mapi (fun rr cc char ->
            { row = rr
              col = cc
              v = int char - int '0' })

    let next_trail_spots c0 =
        [ (1, 0); (-1, 0); (0, 1); (0, -1) ]
        |> List.choose (fun (rr, cc) ->
            try
                Some(cell2d[c0.row + rr, c0.col + cc])
            with _ ->
                None)
        |> List.filter (fun c -> c.v = c0.v + 1)

    let t0_xs =
        [ for rr in [ 1..n_rows ] do
              for cc in [ 1..n_cols ] do
                  yield cell2d[rr, cc] ]
        |> List.choose (fun cel -> if cel.v = 0 then Some [ cel ] else None)

    [ 1..9 ]
    |> List.fold
        (fun (x0_xs: list<xy_v list>) _ ->
            x0_xs
            |> List.collect (fun ll -> next_trail_spots ll.Head |> List.map (fun s -> s :: ll)))
        t0_xs
    |> List.map (fun l -> [ l.Head; l |> List.last ])
    |> List.distinct
    |> _.Length
    |> printfn "%A"

    //d10b.fsx
type xy_v = { row: int; col: int; v: int }

"input10b.txt"
|> System.IO.File.ReadAllLines
|> fun read_in ->
    let n_rows = read_in.Length
    let n_cols = read_in[0].Length

    let cell2d =
        Array2D.initBased 1 1 n_rows n_cols (fun rr cc -> read_in[rr - 1].[cc - 1])
        |> Array2D.mapi (fun rr cc char ->
            { row = rr
              col = cc
              v = int char - int '0' })

    let next_trail_spots c0 =
        [ (1, 0); (-1, 0); (0, 1); (0, -1) ]
        |> List.choose (fun (rr, cc) ->
            try
                Some(cell2d[c0.row + rr, c0.col + cc])
            with _ ->
                None)
        |> List.filter (fun c -> c.v = c0.v + 1)

    let t0_xs =
        [ for rr in [ 1..n_rows ] do
              for cc in [ 1..n_cols ] do
                  yield cell2d[rr, cc] ]
        |> List.choose (fun cel -> if cel.v = 0 then Some [ cel ] else None)

    [ 1..9 ]
    |> List.fold
        (fun (x0_xs: list<xy_v list>) _ ->
            x0_xs
            |> List.collect (fun ll -> next_trail_spots ll.Head |> List.map (fun s -> s :: ll)))
        t0_xs
    // |> List.map (fun l -> [ l.Head; l |> List.last ])
    |> List.distinct
    |> _.Length
    |> printfn "%A"
010 0
bbaaiiaannaann.bsky.social @bbaaiiaannaann.bsky.social · 12/01/2025
I've completed "Disk Fragmenter" - Day 9 , part2 - Advent of Code 2024 #AdventOfCode adventofcode.com/2024/day/9
// d9b.fsx
"input9.txt"
|> System.IO.File.ReadAllBytes
|> Array.map (fun x -> int x - int '0')
|> fun read_in ->
    let a0 =
        Array.append read_in [| 0 |]
        |> Array.chunkBySize 2 // file_len, free_len
        |> Array.mapi (fun i aa -> (string i, aa[0]), [], aa[1])

    [ a0.Length - 1 .. -1 .. 1 ]
    |> List.fold
        (fun (acc: array<(string * int) * list<string * int> * int>) i -> //
            let (ifile_id, ifile_len), ilst, ifree_len = acc[i]

            acc[0 .. i - 1]
            |> Array.tryFindIndex (fun (_, _, jfree_len) -> jfree_len >= ifile_len)
            |> function
                | Some j -> //
                    let (jfile_id, jfile_len), jlst, jfree_len = acc[j]
                    acc[j] <- (jfile_id, jfile_len), jlst @ [ (ifile_id, ifile_len) ], jfree_len - ifile_len
                    acc[i] <- ("0", ifile_len), ilst, ifree_len
                    acc
                | None -> acc)
        a0
|> Seq.collect (fun ((file_id, file_len), lst, free_len) -> //
    ((file_id, file_len) :: lst) @ [ ("0", free_len) ]
    |> Seq.collect (fun (fill, len) -> Seq.replicate len (int64 fill)))
|> Seq.mapi (fun i x -> (int64 i) * x)
|> Seq.sum
|> printfn "\n%A"
010 0
bbaaiiaannaann.bsky.social @bbaaiiaannaann.bsky.social · 10/01/2025
I've completed Part One of "Disk Fragmenter" - Day 9 - part 1, Advent of Code 2024 adventofcode.com/2024/day/9
// d9a.fsx
"input9.txt"
|> System.IO.File.ReadAllBytes
|> Array.map (fun x -> int x - int '0')
|> fun read_in ->
    let a0 =
        Array.append read_in [| 0 |] //
        |> Array.chunkBySize 2 // file_len, free_len
        |> Array.mapi (fun i aa -> i, aa[0], aa[1]) // id, file_len, free_len

    let rec do_compress raw compressed =
        match raw with
        | [||] -> compressed
        | [| (id, file_len, _) |] -> (id, file_len) :: compressed
        | _ ->
            let head_id, head_file_len, head_free_len = raw |> Array.head
            let last_id, last_file_len, _ = raw |> Array.last
            let new_raw, new_compressed =
                match head_free_len, last_file_len with
                | x, y when x = y ->
                    raw[1 .. raw.Length - 2], //
                    (last_id, last_file_len) :: ((head_id, head_file_len) :: compressed)
                | x, y when x < y -> // head_free_len < last_file_len
                    Array.append raw[1 .. raw.Length - 2] [| last_id, last_file_len - head_free_len, 0 |],
                    (last_id, head_free_len) :: ((head_id, head_file_len) :: compressed)
                | _ -> //               head_free_len > last_file_len
                    Array.append [| last_id, last_file_len, head_free_len - last_file_len |] raw[1 .. raw.Length - 2],
                    (head_id, head_file_len) :: compressed
            do_compress new_raw new_compressed

    do_compress a0 []
    |> Seq.rev
    |> Seq.collect (fun (idx, repeat) -> Seq.replicate repeat idx)
    |> Seq.mapi (fun i x -> (int64 x) * (int64 i))
    |> Seq.sum
    |> printf "%A"
000 0
bbaaiiaannaann.bsky.social @bbaaiiaannaann.bsky.social · 06/01/2025
#fsharp, I've completed "Resonant Collinearity" - Day 8 - Advent of Code 2024 #AdventOfCode adventofcode.com/2024/day/8
// d8a.fsx
"input8.txt" |> System.IO.File.ReadAllLines
|> fun a ->
    let comb2 chars = [ for i, i_char in chars |> List.indexed do for j_char in chars[i + 1 ..] do yield (i_char, j_char) ]

    let _one_big_str = a |> String.concat ""
    let attena_char_seq = _one_big_str |> Seq.distinct |> Seq.filter System.Char.IsLetterOrDigit
    
    attena_char_seq
    |> Seq.collect (fun attena_char ->
        let att_postion_list =
            _one_big_str |> Seq.indexed |> Seq.filter (fun (_, ch) -> ch = attena_char)
            |> Seq.map (fun (n, _) -> n % a[0].Length, n / a[0].Length) |> List.ofSeq

        comb2 att_postion_list //
        |> List.collect (fun ((p1x, p1y), (p2x, p2y)) ->
            [ (p1x + p1x - p2x), (p1y + p1y - p2y); (p2x + p2x - p1x), (p2y + p2y - p1y) ])
        |> List.filter (fun (x, y) -> x < a[0].Length && y < a.Length && x >= 0 && y >= 0))
    |> Seq.distinct
    |> Seq.length
    |> printfn "%A"

// d8a.fsx
"input8.txt" |> System.IO.File.ReadAllLines
|> fun a ->
    let comb2 chars = [ for i, i_char in chars |> List.indexed do
                        for j_char in chars[i + 1 ..] do yield (i_char, j_char) ]
    let is_valid x y = x < a[0].Length && y < a.Length && x >= 0 && y >= 0

    let _one_big_str = a |> String.concat ""
    let attena_char_seq = _one_big_str |> Seq.distinct |> Seq.filter System.Char.IsLetterOrDigit
    attena_char_seq
    |> Seq.collect (fun attena_char ->
        let att_postion_list = _one_big_str |> Seq.indexed |> Seq.filter (fun (_, ch) -> ch = attena_char)
                            |> Seq.map (fun (n, _) -> n % a[0].Length, n / a[0].Length) |> List.ofSeq
        comb2 att_postion_list //
        |> List.collect (fun ((p1x, p1y), (p2x, p2y)) ->
            let dx, dy = p2x - p1x, p2y - p1y
            let fwd = (p1x, p1y) |> List.unfold (fun (x, y) ->
                match x + dx, y + dy with
                | xx, yy when is_valid xx yy -> Some((xx, yy), (xx, yy))
                | _ -> None)
            let bkwd = (p2x, p2y) |> List.unfold (fun (x, y) ->
                match x - dx, y - dy with
                | xx, yy when is_valid xx yy -> Some((xx, yy), (xx, yy))
                | _ -> None)
            fwd @ bkwd ))
    |> Seq.distinct |> Seq.length |> printfn "%A"
040 0
bbaaiiaannaann.bsky.social @bbaaiiaannaann.bsky.social · 05/01/2025
#fsharp, I've completed "Bridge Repair" - Day 7 - Advent of Code 2024 #AdventOfCode adventofcode.com/2024/day/7
//d7a.fsx
"input7.txt"
|> System.IO.File.ReadLines
|> Seq.map (fun s ->
    s.Split([| ' '; ':' |], System.StringSplitOptions.RemoveEmptyEntries)
    |> Array.map int64
    |> fun a ->
        let rec gen_op_combinations n last_result =
            match n with
            | 0 -> last_result
            | _ -> gen_op_combinations (n - 1) (last_result |> List.collect (fun l -> [ (+) :: l; (*) :: l ]))

        let rec compute_exp op_list (input_int_array: 'a array) last_operand =
            match op_list with
            | op :: new_op_list -> compute_exp (new_op_list) input_int_array[1..] (op last_operand input_int_array[0] )
            | _ -> last_operand

        let expected, input_ints = a[0], a[1..]

        gen_op_combinations (input_ints.Length - 1) [ [] ]
        |> List.tryPick (fun op_list ->
            match expected = (compute_exp op_list input_ints[1..] input_ints[0]) with
            | true -> Some expected
            | false -> None))
|> Seq.choose id
|> Seq.sum
|> printfn "%A"
//d7b.fsx
"input7.txt"
|> System.IO.File.ReadLines
|> Seq.map (fun s ->
    s.Split([| ' '; ':' |], System.StringSplitOptions.RemoveEmptyEntries)
    |> Array.map int64
    |> fun a ->
        let (!!) = fun x y -> int64 ((string x) + (string y))

        let rec gen_op_combinations n last_result =
            match n with
            | 0 -> last_result
            | _ ->
                gen_op_combinations (n - 1) (last_result |> List.collect (fun l -> [ (+) :: l; (*) :: l; (!!) :: l ]))

        let rec compute_exp op_list (input_int_array: 'a array) left_operand =
            match op_list with
            | op :: tail_op_list -> compute_exp tail_op_list input_int_array[1..] (op left_operand input_int_array[0])
            | _ -> left_operand

        let expected, input_ints = a[0], a[1..]

        gen_op_combinations (input_ints.Length - 1) [ [] ]
        |> List.tryPick (fun op_list ->
            match (=) expected (compute_exp op_list input_ints[1..] input_ints[0]) with
            | true -> Some expected
            | false -> None))
|> Seq.choose id
|> Seq.sum
|> printfn "%A"
030 0
Reposted by @bbaaiiaannaann.bsky.social
jkone27 @jkone27.bsky.social · 23/12/2024
@fsharponline.bsky.social this is sooooo cute! #fsharp thanks @sergeytihon.com 🩵 > sergeytihon.com/2024/12/22/f... - any designer wanting to help the F# community with the official mascotte? would be great to update the official fsharp.org one day with the official illustrated mascot 💕 🦔🔮❄️
161 0
bbaaiiaannaann.bsky.social @bbaaiiaannaann.bsky.social · 27/12/2024
#fsharp , I've completed "Guard Gallivant" - Day 6, part2 - Advent of Code 2024 #AdventOfCode adventofcode.com/2024/day/6
// d6b.fsx
"input6.txt"
|> System.IO.File.ReadAllLines
|> fun a0 ->
    let arrow0 = a0 |> Seq.concat |> Seq.distinct |> Seq.sort |> Seq.last
    if "<>^v" |> Seq.contains arrow0 then

        let rec walk (array: string array) gx gy arrow traces = // -> is_loop, traces
            let new_traces = Array.concat [ [| (gx, gy, arrow) |]; traces ]
            let some_next_char =
                try Some( match arrow with
                        | '^' -> array[gy - 1].[gx]
                        | '>' -> array[gy].[gx + 1]
                        | 'v' -> array[gy + 1].[gx]
                        | '<' -> array[gy].[gx - 1]
                        | c -> c )
                with _ ->
                    None
            let is_loop = traces |> Seq.contains (gx, gy, arrow)
            match is_loop, some_next_char with
            | true, _ -> is_loop, traces
            | _, None -> false, new_traces
            | _, Some next_char ->
                let new_x, new_y, new_direction =
                    match arrow, next_char with
                    | '^', '#' -> gx + 1, gy, '>'
                    | '>', '#' -> gx, gy + 1, 'v'
                    | 'v', '#' -> gx - 1, gy, '<'
                    | '<', '#' -> gx, gy - 1, '^'
                    | '^', _ -> gx, gy - 1, arrow
                    | '>', _ -> gx + 1, gy, arrow
                    | 'v', _ -> gx, gy + 1, arrow
                    | '<', _ -> gx - 1, gy, arrow
                    | _, _ -> gx, gy, arrow
                walk array new_x new_y new_direction new_traces //recur

        let gy0 = a0 |> Seq.findIndex (fun s -> s.Contains(arrow0))
        let gx0 = a0[gy0] |> Seq.findIndex ((=) arrow0)
082 0
bbaaiiaannaann.bsky.social @bbaaiiaannaann.bsky.social · 22/12/2024
#fsharp , I've completed Part One of "Guard Gallivant" - Day 6, part1 - Advent of Code 2024 #AdventOfCode adventofcode.com/2024/day/6
// d6a.fsx
"input6a.txt"
|> System.IO.File.ReadAllLines
|> fun a0 ->
    let arrow0 = a0 |> Seq.concat |> Seq.distinct |> Seq.last // ascii, '#' < '.' < any_arrow_char
    assert ("<>^v" |> Seq.contains arrow0)
    let mutable g_direction = arrow0
    let mutable gy = a0 |> Seq.findIndex (fun s -> s.Contains(arrow0))
    let mutable gx = a0[gy] |> Seq.findIndex ((=) arrow0)
    let mutable traces = []: (int * int) list
    try
        while true do
            traces <- (gx, gy) :: traces
            let next_char = g_direction |> function //let exception do its job here
                    | '^' -> a0[gy - 1].[gx]
                    | '>' -> a0[gy].[gx + 1]
                    | 'v' -> a0[gy + 1].[gx]
                    | '<' -> a0[gy].[gx - 1]
                    | _ -> '#'
            match g_direction, next_char with
            | '^', '#' ->
                gx <- gx + 1; g_direction <- '>'
            | '>', '#' ->
                gy <- gy + 1; g_direction <- 'v'
            | 'v', '#' ->
                gx <- gx - 1; g_direction <- '<'
            | '<', '#' ->
                gy <- gy - 1; g_direction <- '^'
            | '^', _ -> gy <- gy - 1
            | '>', _ -> gx <- gx + 1
            | 'v', _ -> gy <- gy + 1
            | '<', _ -> gx <- gx - 1
            | _, _ -> ()
    with e -> ()
    traces |> Seq.distinct |> Seq.length |> printfn "%A"
281 0
bbaaiiaannaann.bsky.social @bbaaiiaannaann.bsky.social · 19/12/2024
#fsharp , I've completed "Print Queue" - Day 5 part2 - Advent of Code 2024 #AdventOfCode adventofcode.com/2024/day/5
//d5b.fsx
"input5a.txt" |> System.IO.File.ReadAllLines
|> fun a ->
    let i = a |> Array.findIndex (fun s -> s.Length = 0)
    let p_before_those =
        a[.. i - 1]
        |> Array.groupBy (fun s -> s[..1])
        |> Array.map (fun (p, those) -> p, those |> Array.map (fun a -> a[3..]) |> Set.ofArray)
        |> Map.ofArray
    let p_after__those =
        a[.. i - 1]
        |> Array.groupBy (fun s -> s[3..])
        |> Array.map (fun (p, those) -> p, those |> Array.map (fun a -> a[..1]) |> Set.ofArray)
        |> Map.ofArray

    a[i + 1 ..]
    |> Array.map _.Split(',')
    |> Array.filter (fun uuu ->
            seq { for i in 1 .. uuu.Length - 1 -> uuu[0..i] }
            |>  Seq.forall (fun partial ->
                let kp = partial |> Seq.last
                let setA = partial |> Array.rev |> Array.tail |> Set.ofArray
                let setB = p_after__those.TryFind(kp) |> Option.defaultValue (Set.ofList [])
                Set.isSubset setA setB)
            |>not
            ) 
    |> Array.map ( Array.fold
                (fun acc x ->
                    let aa: string array = acc
                    [ for i in 0 .. aa.Length -> aa[.. i - 1], aa[i..] ]
                    |> List.tryPick (fun (a1, a2) ->
                        let setA = a1 |> Set.ofArray
                        let setB = p_after__those.TryFind(x) |> Option.defaultValue (Set.ofList [])
                        let setC = a2 |> Set.ofArray
                        let setD = p_before_those.TryFind(x) |> Option.defaultValue (Set.ofList [])
                        match (Set.isSubset setA setB && Set.isSubset setC setD) with
                        | true -> Some(Array.concat [ a1; [| x |]; a2 ])
                        | _ -> None)
                    |> Option.defaultValue ([||]))
                [||]
        )
|> Array.map (fun a -> int a[(a.Length - 1) / 2])
|> Seq.sum
|> printfn "%A"
071 0
bbaaiiaannaann.bsky.social @bbaaiiaannaann.bsky.social · 17/12/2024
#fsharp, I've completed Part One of "Print Queue" - Day 5 part 1 - Advent of Code 2024 #AdventOfCode adventofcode.com/2024/day/5
//d5a.fsx
"input5a.txt"
|> System.IO.File.ReadAllLines
|> fun a ->
    let i = a |> Array.findIndex (fun s -> s.Length = 0)
    let rule0, updates = a[.. i - 1], a[i + 1 ..]
    let p_after_those =
        rule0
        |> Array.groupBy (fun s -> s[3..])
        |> Array.map (fun (k, aa) -> k, aa |> Array.map (fun a -> a[..1]) |> Set.ofArray)
        |> Map.ofArray

    updates
    |> Array.map _.Split(',')
    |> Array.filter (fun a -> //
        [ for i in 1 .. a.Length - 1 -> a[0..i] ]
        |> Seq.forall (fun a ->
            let kp = a |> Seq.last
            let setA = a |>Set.ofArray |> Set.remove kp
            let setB = p_after_those.TryFind(kp) |> Option.defaultValue (Set.ofList [])
            Set.isSubset setA setB))
    |> Array.map (fun a -> int a[(a.Length - 1) / 2])
    |> Seq.sum

|> printfn "%d"
050 0
bbaaiiaannaann.bsky.social @bbaaiiaannaann.bsky.social · 17/12/2024
#fsharp, I just completed "Ceres Search" - Day 4 , part2 - Advent of Code 2024 #AdventOfCode adventofcode.com/2024/day/4
//d4b.fsx
"input4.txt"
|> System.IO.File.ReadLines
|> Seq.windowed 3
|> Seq.map (fun a -> a |> Seq.transpose |> Seq.map System.String.Concat)
|> Seq.collect (Seq.windowed 3)
|> Seq.filter (fun a ->
    a[1].[1] = 'A'
    && Set.ofList [ a[0].[0]; a[0].[2]; a[2].[0]; a[2].[2] ] = Set.ofList [ 'S'; 'M' ]
    && a[0].[0] <> a[2].[2]
    && a[0].[2] <> a[2].[0])
|> Seq.length
|> printfn "%A"
061 0
bbaaiiaannaann.bsky.social @bbaaiiaannaann.bsky.social · 17/12/2024
#fsharp I've completed Part One of "Ceres Search" - Day 4 , part 1- Advent of Code 2024 #AdventOfCode adventofcode.com/2024/day/4
//d4a.fsx
let re = System.Text.RegularExpressions.Regex(@"XMAS")
let er = System.Text.RegularExpressions.Regex(@"SAMX")

"input4.txt"
|> System.IO.File.ReadLines
|> fun s0 ->
    let s1 = s0 |> Seq.transpose |> Seq.map System.String.Concat

    let s2 =
        s0
        |> Seq.indexed
        |> Seq.map (fun (n, line) -> (String.replicate n "_") + line)
        |> Seq.transpose
        |> Seq.map System.String.Concat

    let s3 =
        s0
        |> Seq.rev
        |> Seq.indexed
        |> Seq.map (fun (n, line) -> (String.replicate n "_") + line)
        |> Seq.transpose
        |> Seq.map System.String.Concat

    Seq.concat [ s0; s1; s2; s3 ]
|> Seq.map (fun l -> re.Matches(l).Count + er.Matches(l).Count)
|> Seq.sum
|> printfn "%d"
1121 0
bbaaiiaannaann.bsky.social @bbaaiiaannaann.bsky.social · 17/12/2024
#fsharp, I just completed "Mull It Over" - Day 3, part2 - Advent of Code 2024 #AdventOfCode adventofcode.com/2024/day/3
//d3b.fsx
open System.IO
open System.Text.RegularExpressions

let re = Regex(@"mul\((\d{1,3}),(\d{1,3})\)|do\(\)|don't\(\)")

"input3.txt"
|> File.ReadLines
|> Seq.collect re.Matches
|> Seq.fold
    (fun (sum, do_or_not) m ->
        match m.Value with
        | v when v.StartsWith "mul" && do_or_not -> //
            (sum + int m.Groups[1].Value * int m.Groups[2].Value, true)
        | "don't()" -> (sum, false)
        | "do()" -> (sum, true)
        | _ -> (sum, do_or_not))
    (0, true)
|> fst
|> printfn "%d"
1111 0