this post was submitted on 09 Nov 2025
5 points (77.8% liked)

Advent Of Code

1199 readers
2 users here now

An unofficial home for the advent of code community on programming.dev! Other challenges are also welcome!

Advent of Code is an annual Advent calendar of small programming puzzles for a variety of skill sets and skill levels that can be solved in any programming language you like.

Everybody Codes is another collection of programming puzzles with seasonal events.

EC 2025

AoC 2025

Solution Threads

M T W T F S S
1 2 3 4 5 6 7
8 9 10 11 12

Visualisations Megathread

Rules/Guidelines

Relevant Communities

Relevant Links

Credits

Icon base by Lorc under CC BY 3.0 with modifications to add a gradient

console.log('Hello World')

founded 2 years ago
MODERATORS
 

Quest 3: The Deepest Fit

  • Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
  • You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL

Link to participate: https://everybody.codes/

Also, don't wait for me to make these posts, feel free to post yourself :)

you are viewing a single comment's thread
view the rest of the comments

FSharp

I'm a month late, but eh. Compared to everyone else, it looks like my approach of preserving duplicates was unnecessary. I chose to use SortedSets (redundant since I sort the inputs) and cascade to the next best fit. The sorted sets also let me grab the Max/Min values and I thought that it was more in line with the intention than having a list that happens to be sorted.

I also sorted part 1 based on what I thought was the best fit, which was the same solution for part 3.
For part 2 I duplicated part 1's logic but reversed the order to asc instead of desc, but I don't know that that made a difference and excluded it here. The only difference is the "add if count < 20".

type Crate = int  
 // sorted set because only one item can be in at a time. The SortedSet is unnecessary here since the inputs are already sorted  
type CrateSet = SortedSet<Crate>  
let inline newCrateSet crate =  
    let cs = CrateSet()  
    cs.Add(crate) |> ignore  
    cs  
type Extensions() =  
    [<Extension>]  
    static member inline SmallestCrate (crates:CrateSet) : Crate option = match crates.Min with | 0 -> None | x -> Some x  
    [<Extension>]  
    static member inline LargestCrate (crates:CrateSet) : Crate option = match crates.Max with | 0 -> None | x -> Some x  

/// take a sorted input (not verified) and prioritize insertion into the first found list.  
/// This results in cascading to the "next best fit", but this approach relies on sorted inputs.  
let packEfficiently allCrates =  
    allCrates  
    |> Seq.fold (fun sortedCrates next ->  
            // find the first crate set that can hold the next item and put it in there  
            match sortedCrates with  
            | [] -> [newCrateSet next]  
            | items ->  
                match List.tryFind (fun (i:CrateSet) ->  
                    match i.SmallestCrate() with  
                    | Some c when c > next -> true  
                    | _ -> false) items with  
                | None ->  
                    let cs = newCrateSet next  
                    items@[cs] // appending to the end is less efficient for linked lists, but ensures that the first one gets the best goodies  
                | Some crates ->  
                    if not (crates.Add(next)) then failwith "failed to add" // really wrong if this happens  
                    items  

        ) []  

let part1 () =  
    parseInput "Inputs/Quest03/Q03_P01.txt"  
    |> Enumerable.OrderDescending  
    |> packEfficiently  
    |> _.Max(_.Sum())  

let part2() =  
    parseInput "Inputs/Quest03/Q03_P02.txt"  
    |> Enumerable.Order  
    |> part2Impl  
    |> List.filter (fun x -> x.Count = 20)  
    |> _.Min(_.Sum())  
    
let part3() =  
    parseInput "Inputs/Quest03/Q03_P03.txt"  
    |> Enumerable.OrderDescending  
    |> packEfficiently  
    |> _.Count()