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
    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"