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

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

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

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;
``````

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

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

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

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

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.