Quest 2: From Complex to Clarity

  • 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
    ·
    3 days ago

    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