ragingHungryPanda

joined 3 months ago
[โ€“] ragingHungryPanda@piefed.keyboardvagabond.com 1 points 2 weeks ago* (last edited 2 weeks ago)

Then I forgot which of div and quot I should use, and kept getting nearly the right answer

That sounds amazingly infuriating! and hard to debug. I totally feel you there.

FSharp
(my first submission failed, so I may not be as detailed here)

I laugh at how long this took me. At first I got stuck due to checked arithmetic. In FSharp you open the Checked module and you get the overloaded operators for primitives, whereas CSharp is checked {a + b}. I also mistakenly used distinct on part 3 when I didn't need it.

I did appreciate the choose functions of functional programming, which returns all of the Some values of a sequence of options. The PSeq library let me use 70% of the cpu on the calculations :)

module EveryBodyCodes2025.Quest02  

open System.IO  
open System.Text.RegularExpressions  
open FSharp.Collections.ParallelSeq  
open Checked  

[<Struct>]  
type ComplexNumber = 
    {X: int64; Y: int64}  
    static member (+) (a: ComplexNumber, b: ComplexNumber) = {X = a.X + b.X; Y = a.Y + b.Y }  
    static member (*) (a: ComplexNumber, b: ComplexNumber) = { X = ( a.X * b.X ) - (a.Y * b.Y); Y = (a.X * b.Y) + (a.Y * b.X) }  
    static member (/) (a: ComplexNumber, b: ComplexNumber) = { X = a.X / b.X; Y = a.Y / b.Y }  
    override this.ToString() = $"[{this.X},{this.Y}]"  
    
let parseInput file =  
    File.ReadAllLines file  
    |> fun lines ->  
        let reg = Regex(@"A=\[(-?\d+),(-?\d+)\]")  
        let res = reg.Match(lines[0])  
        match res.Success with  
        | true ->  
            let x = int64 res.Groups[1].Value  
            let y = int64 res.Groups[2].Value  
            {X = x; Y = y}  
        | false -> failwith "failed to parse"  
        
    
let part1 () =  
    parseInput "Inputs/Quest02/Q02_P01.txt"  
    |> fun a ->  
        [1..3]  
        |> List.fold (fun acc _ -> (acc * acc) / { X = 10; Y = 10 } + a ) {X = 0; Y = 0}  

let cycle p =  
    let rec iterate current iteration =  
        if iteration = 100 then Some current  
        else  
            let next = (current * current) / {X = 100_000; Y = 100_000 } + p  
            if abs(next.X) > 1_000_000 || abs(next.Y) > 1_000_000 then  
                None  
            else iterate next (iteration + 1)  
    iterate { X = 0; Y = 0 } 0  

let part2 () =  
    parseInput "Inputs/Quest02/Q02_P02.txt"  
    |> fun a ->  
        seq {  
            for y in 0..100 do  
            for x in 0..100 do  
                yield {X = a.X + (int64 x * 10L); Y = a.Y + (int64 y * 10L)}  
        }  
        |> PSeq.choose cycle  
        |> PSeq.distinct  
        |> PSeq.length  

let part3 () =  
    parseInput "Inputs/Quest02/Q02_P03.txt"  
    |> fun a ->  
        seq {  
            for y in 0..1000 do  
            for x in 0..1000 do  
                yield {X = a.X + (int64 x); Y = a.Y + (int64 y)}  
        }  
        |> PSeq.choose cycle  
        |> PSeq.length  

What do the .s mean in addWith f = (f .) . (+)?

[โ€“] ragingHungryPanda@piefed.keyboardvagabond.com 2 points 2 weeks ago* (last edited 2 weeks ago) (2 children)

Here's the right challenge. This was a lot simpler than the tracking of cycles.

type Direction = Left | Right  
type Instruction = { Direction: Direction; Distance: int }  
let parseInstruction (segment:string) =  
    let direction = if segment[0] = 'L' then Left else Right  
    let distance = Int32.Parse(segment.AsSpan().Slice(1)) 
    { Direction = direction; Distance = distance }  
    
let inline normalize (array: 'a array) idx =  
    if idx >= 0 then idx % array.Length else array.Length - (-idx % array.Length)  
    
let inline nextIndex instruction idx =  
    match instruction.Direction with  
    | Left -> idx - instruction.Distance  
    | Right -> idx + instruction.Distance  
    
let readFile file =  
    File.ReadAllLines(file)  
    |> fun lines ->  
        let names = lines.[0] |> _.Split(",", StringSplitOptions.RemoveEmptyEntries ||| StringSplitOptions.TrimEntries)  
        let instructions =  
            lines[2]  
            |> _.Split(",", StringSplitOptions.RemoveEmptyEntries ||| StringSplitOptions.TrimEntries)  
            |> Array.map parseInstruction  
        (names, instructions)  

let part1File file : string =  
        readFile file  
        |> fun (names, instructions) ->  
                instructions  
                |> Seq.fold (fun (idx, _) instruction  ->  
                        let next = nextIndex instruction idx |> fun v -> Math.Clamp(v, 0, names.Length - 1)  

                        match Array.tryItem next names with  
                        | Some n -> next, n  
                        | None -> failwith "off array"  
                    ) (0, "")  
        |> snd  
        
let part1 () = part1File "Inputs/Quest01/Q01_P01.txt"  

let part2File file =  
    readFile file  
    |> fun (names, instructions) ->  
        instructions  
        |> Seq.fold (fun (idx, _) instruction ->  
             let next =  nextIndex instruction idx |> normalize names  
             match Array.tryItem next names with  
                        | Some n -> next, n  
                        | None -> failwith "off array"  
                    ) (0, "")  
        |> snd  

let part2() = part2File "Inputs/Quest01/Q01_P02.txt"  

let part3File file =  
    readFile file  
    |> fun (names, instructions) ->  
        // need to preserve a reference to an array that can be mutated  
        let mutable nameArray = names  
        instructions  
        |> Seq.fold (fun _ instruction ->  
            // for this challenge the index doesn't matter  
            let next = match instruction.Direction with  
                        | Left -> names.Length - instruction.Distance  
                        | Right -> instruction.Distance  
                        |> normalize names  
            match Array.tryItem next nameArray with  
                        | Some n ->  
                            nameArray <- arraySwap 0 next names  
                            0, n  
                        | None -> failwith "off array"  
            ) (0, "")  
        |> snd  

let part3() = part3File  "Inputs/Quest01/Q01_P03.txt"  

Hmmm, I am certain I did the wrong one? I did quest 1, I'm pretty sure

I know a few guys and even a dating coach who did that when it came around. The common thing that they said was that they didn't like how they felt doing it. They also noticed that at the end of the techniques, there was just you, and you would get found out.

Now the common trend is for authenticity and openness/vulnerability. In addition to approaching and that sort of stuff, it's less about learning a technique and more about the other positive things.

I could imagine there being people who would prefer to not have unnecessary alterations, sort of like there's a risk with laser surgery on the eyes, it could be a thing of "the safest thing is to just wear glasses and if it gets worse, come back and we'll look at other options."

I love that correction. I didn't even consider it until I saw it ๐Ÿ˜‚

[โ€“] ragingHungryPanda@piefed.keyboardvagabond.com 3 points 2 weeks ago* (last edited 2 weeks ago) (5 children)

edit: I did the wrong quest

I wasn't very happy with myself on this one. Part 1 wound up being simple enough, but part 2 took me for a loop. My disappointment was that I asked an AI for a hint, but instead it coded up a solution revolved around checking cycle dependency.

I tried to at least redo it in a functional way, since I'm writing this in FSharp, but I ran into a bunch of hiccups around indexes and index tracking. That always costs me so much time. This took me forever and I'm near the bottom of the rankings haha.

Overall, I wasn't terribly happy with how I did on this one. Oh, I wound up switching all of the types to BigInteger because I was lost as to what was happening. It turned out to be indexes and orderings, but I thought that maybe something was getting truncated.

    /// Map from (prev, curr) pair to position  
    type PositionMap = Map<BigInteger * BigInteger, BigInteger * BigInteger>  
    let rec findCycle (pairToNextPair: PositionMap) startPair currentPair acc =  
        if currentPair = startPair && List.length acc > 0 then  
            Some (List.rev acc)  
        else  
            match Map.tryFind currentPair pairToNextPair with  
            | None -> None  
            | Some nextPair -> 
                findCycle pairToNextPair startPair nextPair (snd currentPair :: acc)  

    let rec eni2' score (n:BigInteger) (exp:BigInteger) (m:BigInteger) (pairMap: PositionMap) (scores:BigInteger list) iter =  
        if iter > exp then scores |> List.rev |> List.skip (max 0 (List.length scores - 5)) |> toBigInt  
        else  
            let newScore = (score * n) % m  
            let key = (score, newScore)  
            
            match Map.tryFind key pairMap with  
            | Some _ -> 
                match findCycle pairMap key key [] with  
                | Some cycle ->  
                    let remaining = int64 (exp - iter)  
                    let cycleValues = cycle  
                    let cycleLength = List.length cycleValues |> int64  
                    let scoresLength = List.length scores |> int64  
                    let totalLength = scoresLength + 1L + remaining // scores + newScore + remaining  
                    
                    let needCount = min 5L totalLength  
                    let startPos = max 0L (totalLength - needCount)  
                    
                    let scoresReversed = List.rev scores  
                    
                    let final5 = 
                        [startPos..totalLength - 1L]  
                        |> List.map (fun pos ->  
                            if pos < scoresLength then  
                                // Position is in scores (scores is reversed, so oldest is at end)  
                                scoresReversed.[int pos]  
                            elif pos = scoresLength then  
                                // Position is newScore  
                                newScore  
                            else  
                                let cycleOffset = pos - scoresLength  
                                let cyclePos = cycleOffset % cycleLength  
                                cycleValues.[int cyclePos]  
                        )  
                    
                    // final 5 comes out in reverse order  
                    final5 |> List.rev |> toBigInt  
                | None -> 
                    eni2' newScore n exp m (Map.add key ((newScore, (newScore * n) % m)) pairMap) (newScore::scores) (iter + BigInteger 1)  
            | None ->  
                let nextPair = (newScore, (newScore * n) % m)  
                eni2' newScore n exp m (Map.add key nextPair pairMap) (newScore::scores) (iter +  BigInteger 1)  

    let eni2 (n) (exp) (m) = eni2' (BigInteger 1) n exp m Map.empty [] (BigInteger 1)  

    let part2 (input: IDictionary<string, BigInteger> array)=  
        input  
        |> Array.map (fun line ->  
            //printfn $"""running line {line.AsEnumerable() |> Seq.map(fun kv -> kv.Key + "=" + kv.Value.ToString()) |> fun x -> String.Join(", ", x)}"""  
            let a = eni2 line["A"] line["X"] line["M"]  
            let b = eni2 line["B"] line["Y"] line["M"]  
            let c = eni2 line["C"] line["Z"] line["M"]  
            let ret = a + b + c  
            //printfn $"found {ret}"  
            ret  
        ) |> Seq.max  

    let part2Answer = 
        File.ReadAllLines "Inputs/Q01_P02.txt"  
        |> part1Lines  
        |> part2  

that is a very pleasantly surprising thing to hear!

thanks for the reply, I suspected that the way to play is with the pretty turned up. I'll keep that in the mental backlog haha

[โ€“] ragingHungryPanda@piefed.keyboardvagabond.com 2 points 2 weeks ago* (last edited 2 weeks ago) (5 children)

I have a question for ya, I only means of playing any time soon is on a steam deck. is it the kind of game that I should play on lowish settings, or should I wait until some day when I have a PC

view more: โ€น prev next โ€บ