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

Noice, bruh
But:

  1. collectLayers n (Node l x r) = [(n, x)] : collectLayers (n+1) l ++ collectLayers (n+1) r
    would perform better than
    collectLayers n (Node l x r) = collectLayers (n+1) l ++ [(n, x)] ++ collectLayers (n+1) r
  2. sortingFoo = (\(n1, _) (n2, _) -> compare n1 n2) - why not compare `on` fst?
  3. mapM_ (printf "%d ") $ - why not putStrLn . unwords . map show .
    or to do it in one pass but still with trailing space: putStrLn . foldr ((++).(++" ").show) "".
  4. why not generalize prepSpiral :: [[(Int, Int)]] -> [Int] to prepSpiral :: Functor f => f (f (a, b)) -> f b

Other than that good paste, would read again 42/0

@Ino4137
Copy link
Author

Ino4137 commented Apr 9, 2018

Well hello again.

  1. Yeah. I was trying to do it as fast as I could when I'm working relaxed so a couple of mistakes snuck in.
  2. Whoops. Failed to notice.
  3. I'm assuming that this is more performant. The first version is incompatible since the the exercise requires you to print the numbers with a whitespace separator. But the second one does look good albeit it is more inconvenient.
  4. I thought about doing that when I was coding this. I quickly came to a conclusion that it was a meaningless change since I'm working only on this specific case.

Thank you for reading and for suggestions.
2018-1352

@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