Skip to content

Instantly share code, notes, and snippets.

@Ino4137
Last active April 12, 2018 20:41
Show Gist options
  • Select an option

  • Save Ino4137/dc598e312664c46a4e7f837662c97231 to your computer and use it in GitHub Desktop.

Select an option

Save Ino4137/dc598e312664c46a4e7f837662c97231 to your computer and use it in GitHub Desktop.
Solution Haskell
import Data.List
import Data.Function
import Control.Monad
import Text.Printf
data Tree a =
Leaf | Unary a | Node (Tree a) a (Tree a)
deriving (Eq, Show)
data From = F | B deriving (Eq, Show)
excerciseTree :: Tree Int
excerciseTree = Node (Node (Node Leaf 9 (Unary 4)) 5 Leaf) 2 (Node (Node (Unary 11) 6 (Unary 5)) 7 (Unary 2))
collectLayers :: Int -> Tree Int -> [(Int, Int)]
collectLayers n Leaf = []
collectLayers n (Unary x) = [(n, x)]
collectLayers n (Node l x r) = [(n, x)] : collectLayers (n+1) l ++ collectLayers (n+1) r
prepareToPrint :: [(Int, Int)] -> [[(Int, Int)]]
prepareToPrint = reorder F . groupBy groupingFoo . sortBy sortingFoo
where
sortingFoo = compare `on` fst
groupingFoo = (==) `on` fst
reorder _ [] = []
reorder F (x:xs) = reverse x : reorder B xs
reorder B xs = last xs : reorder F (init xs)
prepSpiral :: [[(Int, Int)]] -> [Int]
prepSpiral = fmap snd . join
printSpiral :: IO ()
printSpiral = mapM_ (printf "%d ") $
prepSpiral . prepareToPrint $ collectLayers 0 excerciseTree
@Antystenes
Copy link

HAI.

  1. I'm not sure about performance, as mapM_ version requires n system IO interrupts, while putStrLn versions require only one, but still may be doing multiple list passes, depending on the inlining and stream fusion in standard library. In spare time I will look if unwords function is inlined and foldr g . map f rule is defined in prelude. It's hard to tell which is more performant but both are linear, so it does not matter as much. However what slipped under this point was this $ operator after mapM_ which I would swap for . (which I did in my substitution propositions) for better separation of data and process. It's only convention suggestion, so it's not important, however I think that separating some . long . and . maybe . complicated . process . from $ data leads to easier refactoring and code analysis, when it is easily seen what part of code is data and what part of code 'does stuff'. However if you want to separate IO from pure functions with dollar that's ok too. Still: just a convention.

tl;dr
dunno wat is fastah, but maibi taht $ aftah mapM_ could bee, liek, dot . , bruh, whatevah

  1. Of course. It's not about generalizing as much as possible, but to see how it could be generalized, for eventual code reusability. You need to see. Connect the dots. They are watching. THEY are seeing this.

Still cool. 21/37 coolness level. Thots like good haskell like this (in my dreams ;_____________________;)

@Ino4137
Copy link
Author

Ino4137 commented Apr 11, 2018

Ohayo!

  1. My guess is that as the number of elements increases, the more in favor of the single-IO-version. About the $ after mapM_... Yeaaaah it
    could be a . but that would feel off... You've noticed, my intent with that was to separate IO from processing visually.

  2. OwO spooked

For it to reach 37/37 it would have to be entirely type-level. (one day I will wield that power.... )

@Antystenes
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment