Quest 1: Whispers in the Shell

  • 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/

  • ragingHungryPanda@piefed.keyboardvagabond.com
    link
    fedilink
    English
    arrow-up
    3
    ·
    edit-2
    3 days ago

    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  
    
      • ragingHungryPanda@piefed.keyboardvagabond.com
        link
        fedilink
        English
        arrow-up
        1
        ·
        edit-2
        3 days ago

        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"  
        
    • VegOwOtenks@lemmy.world
      link
      fedilink
      English
      arrow-up
      2
      ·
      4 days ago

      I’m very curious about F# since I’ve never used it or seen it anywhere before but I’m afraid I’m too tired to read it right now. Thank you for posting, I hope I’ll remember to come back tomorrow.