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/

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

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