DEV Community

Myoungjin Jeon
Myoungjin Jeon

Posted on

Weekly Challenge #088 Task #2 :: {Off The Challenge}

I checked other's code after finishing my solutions, and I found that -- again -- many creative solution are waiting for me.

some solution shows that

  1. read top of the matrix
  2. cut top of the matrix
  3. turning matrix count clock wise
  4. until matrix exists go for another round.

This is simple and elegant solution I believe. and this is best solution in Raku. because Raku generally doesn't like many flow control and variables.

Here is the Code from juliodcs @ PWC

So I follow the step and make another solution for Haskell Task #2

import Data.List (groupBy, transpose, unfoldr)
import Data.Maybe (catMaybes)

{- tested with:
echo "[a b c d][e f g h][i j k l]" | runhaskell ch-2.hs
echo "[1 2 3][4 5 6][7 8 9]" | runhaskell ch-2.hs
echo "[a b][c d][e f]" | runhaskell ch-2.hs
-}

getMatrixFromStdin :: IO [[String]]
getMatrixFromStdin =
  ( map words
    . filter ((0/=).length)             -- 5. (after 3) there is some empty row
    . map (filter (`notElem` "[]"))     -- 4. '[', ']' is not used
    . lines                             -- 3. devide it into rows
    . unlines                           -- 2. make it "]\n"
    . groupBy (\_ b -> b/= ']') )       -- 1. devide row by "]"
  `fmap` getContents

cutTopAndRotateCCW :: [[String]] -> Maybe [[String]]
cutTopAndRotateCCW mat
  | length mat <= 1 = Nothing
  | otherwise = Just $ ( reverse . transpose . drop 1 ) mat

getSpiralAarray :: [[String]] -> [String]
getSpiralAarray mat =
  foldr1 (++)
  ( unfoldr (\m ->
                 case m of
                   Nothing -> Nothing
                   Just m' -> case (cutTopAndRotateCCW m') of
                               Nothing   -> Just (topOf m', Nothing)
                               Just  m'' -> Just (topOf m', Just m''))
      (Just mat) )
  where topOf m = head m

main = do
  getSpiralAarray `fmap` getMatrixFromStdin
  >>= print
Enter fullscreen mode Exit fullscreen mode

This is elegant solution. but I'm just curious how fast in real world? this solution definitely interpreted faster than my previous solution because it is just simpler in length of code.

So I run 100 times for same matrix with each solution.

Firstly, I complied the code

> ghc -O2 ch-2.hs
> ghc -O2 ch-2a.hs
Enter fullscreen mode Exit fullscreen mode

Secondly, I prepare the matrix by using Raku (100x100 matrix)

> my $fh = open "test.txt", :ra; my $a = 1; (^100).map( { $fh.say((^100).map( { $a++ } )) } ); close $fh;
Enter fullscreen mode Exit fullscreen mode

Finally, compare them

original solution

time for i in (seq 1 100); cat haskell/test.txt | ./haskell/ch-2 > /dev/null; end

________________________________________________________
Executed in    2.97 secs   fish           external 
   usr time    2.71 secs   50.90 millis    2.66 secs 
   sys time    0.36 secs   76.69 millis    0.29 secs 
Enter fullscreen mode Exit fullscreen mode

new simple solution

time for i in (seq 1 100); cat haskell/test.txt | ./haskell/ch-2a > /dev/null; end

________________________________________________________
Executed in    6.41 secs   fish           external 
   usr time    6.06 secs   42.69 millis    6.02 secs 
   sys time    0.45 secs   75.69 millis    0.37 secs 
Enter fullscreen mode Exit fullscreen mode

But if the matrix is simpler, less difference expected.

Raku Has Different Story

This Link a solution from feng-chang @ PWC
and the speed is fascinating.

time cat ~/my.github/pwc-by-me/088/haskell/test.txt | raku spiral-test.feng-chang.raku > /dev/null

________________________________________________________
Executed in  620.94 millis    fish           external 
   usr time  845.44 millis    0.00 micros  845.44 millis 
   sys time   47.49 millis  1321.00 micros   46.17 millis 
Enter fullscreen mode Exit fullscreen mode

my solution is much slower than that. πŸ˜‚

time cat ~/my.github/pwc-by-me/088/haskell/test.txt | raku ~/my.github/pwc-by-me/088/raku/ch-2.raku ^/dev/null > /dev/null
time cat 100x100.txt | raku ~/my.github/pwc-by-me/088/raku/ch-2.raku > /dev/null                                                       2116ms ξ‚³ Mon 30 Nov 2020 21:07:20
Input: (Ctrl-D or Ctrl-Z to finish to input.)

________________________________________________________
Executed in    2.04 secs   fish           external 
   usr time    2.58 secs  1042.00 micros    2.58 secs 
   sys time    0.08 secs  129.00 micros    0.08 secs 
Enter fullscreen mode Exit fullscreen mode

But frankly speaking, I'm not very satisfied with the result. Raku is still mystery for me. but it is worth to learn.
If looking at the history of the common-lisp, we can see well-designed language will survive eventually!!!

Thank you!! That's all for today.

Discussion (0)