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
[โ€“] 3 points 1 year ago* (last edited 1 year ago)

I struggled for a long time because I had nearly the correct results. I had to switch div with quot.

This puzzle was fun. If you have a visualization, it's even cooler. (It's a fractal)

Haskell Code

{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE PatternSynonyms #-}
{-# OPTIONS_GHC -Wall #-}
module Main (main) where
import Text.Read (ReadPrec, Read (readPrec))
import Data.Functor ((<&>))
import Data.Text (pattern (:<), Text)
import qualified Data.Text as Text
import qualified Data.Text.IO as TextIO
import Control.Monad ((<$!>))
import Control.Arrow ((<<<))

newtype Complex = Complex (Int, Int)

instance Read Complex where
  readPrec :: ReadPrec Complex
  readPrec = readPrec <&> \case
    [a, b] -> Complex (a, b)
    _ -> undefined

instance Show Complex where
  show :: Complex -> String
  show (Complex (a, b))= show [a, b]

readAEquals :: Text -> Complex
readAEquals ('A' :< '=':< rest) = read $ Text.unpack rest
readAEquals _ = undefined


-- >>> Complex (1, 1) `add` Complex (2, 2)
-- [3,3]

add :: Complex -> Complex -> Complex
(Complex (x1, y1)) `add` (Complex (x2, y2)) = Complex (x1 + x2, y1 + y2)

-- >>> Complex (2, 5) `times` Complex (5, 7)
-- [-25,-11]

times :: Complex -> Complex -> Complex
(Complex (x1, y1)) `times` (Complex (x2, y2)) = Complex (x1 * x2 - y1 * y2, x1 * y2 + x2 * y1)

dividedBy :: Complex -> Complex -> Complex
(Complex (x1, y1)) `dividedBy` (Complex (x2, y2)) = Complex (x1 `quot` x2, y1 `quot` y2)

step :: Complex -> Complex -> Complex
step a r = let
 r1 = r `times` r
 r2 = r1 `dividedBy` Complex (10, 10)
 r3 = r2 `add` a
 in r3

zero :: Complex
zero = Complex (0, 0)

part1 :: Complex -> Complex
part1 a = iterate (step a) (Complex (0, 0)) !! 3

shouldBeEngraved :: Complex -> Bool
shouldBeEngraved complexPoint = let

  cycleStep :: Complex -> Complex -> Complex
  cycleStep point r = let
    r2 = r `times` r
    r3 = r2 `dividedBy` Complex (100000, 100000)
    in point `add` r3

  inRange x = x <= 1000000 && x >= -1000000


  in all (\ (Complex (x, y)) -> inRange x && inRange y)
    <<< take 101
    <<< iterate (cycleStep complexPoint)
    $ zero

-- >>> shouldBeEngraved $ Complex (35630,-64880)
-- True
-- >>> shouldBeEngraved $ Complex (35460, -64910)
-- False
-- >>> shouldBeEngraved $ Complex (35630, -64830)
-- False

part2 :: Complex -> Int
part2 (Complex (xA, yA)) = let

    xB = xA + 1000
    yB = yA + 1000

  in length . filter shouldBeEngraved $ do
    x <- [xA, xA+10.. xB]
    y <- [yA, yA+10.. yB]
    pure $ Complex (x, y)

part3 :: Complex -> Int
part3 (Complex (xA, yA)) = length . filter shouldBeEngraved $ do
  x <- [xA..xA+1000]
  y <- [yA..yA+1000]
  pure $ Complex (x, y)

-- >>> [0, 10..100]
-- [0,10,20,30,40,50,60,70,80,90,100]

main :: IO ()
main = do
  a <- readAEquals <$!> TextIO.getContents
  print $ part1 a
  print $ part2 a
  print $ part3 a

My girlfriend is learning python, we are taking on the challenges together, today I may upload her solution:

python

A=[-3344,68783]
R = [0, 0]
B= [A[0]+1000, A[1]+1000]
pointsengraved = 0
cycleright = 0


for i in range(A[1], B[1]+1):
    for j in range(A[0], B[0]+1):
        for k in range(100):
            R = [int(R[0] * R[0] - R[1] * R[1]), int(R[0] * R[1] + R[1] * R[0])]
            R = [int(R[0] / 100000), int(R[1] / 100000)]
            R = [int(R[0] + j), int(R[1] + i)]
            if -1000000>R[0] or R[0]>1000000 or -1000000>R[1] or R[1]>1000000:
                #print(".", end="")
                break
            cycleright += 1
        if cycleright == 100:
            pointsengraved += 1
            #print("+", end="")
        cycleright = 0
        R = [0, 0]
    #print()

print(pointsengraved)

The commented out print statements produce an ascii map of the set, which can be cool to view at the right font size.

  • source