sad_banana_peel
sad_banana_peel

Reputation: 29

Haskell: how can I take each number from a list separately?

I'm trying to duplicate a "-" character for 0 to n number of times, add a '*' and add a duplicate of "-" character again for n to 0 times recursively, e.g.: If n = 5, I'd like the answer to be:

*-----

-*----

--*---

---*--

----*-

-----*




duplicate :: String -> Int -> String -- will be used to duplicate spaces
duplicate string n = 
    concat $ replicate n string

block :: Int -> String
block n =
    duplicate ***from 0 to n*** "-" ++ '*' ++ duplicate ***from n to 0*** "-"

How can I do this?

Upvotes: 0

Views: 84

Answers (2)

Redu
Redu

Reputation: 26161

A simple code to handle this job could be;

\n -> (drop <> take) <$> [n+1,n..1] <*> ['*':replicate n '-']

I had explained about drop <> take :: Int -> [a] -> [a] in a previous answer of mine. fmap (<$>) and applicative op (<*>) should be clear.

Upvotes: 0

Fyodor Soikin
Fyodor Soikin

Reputation: 80714

The simplest way is to create a function that prints one line:

line width idx = duplicate "-" idx ++ "*" ++ duplicate "-" (width - idx - 1) ++ "\n"

And then map it over a list [0..(n-1)], then concatenate results:

block n = concat $ map (line n) [0..(n-1)]

Or, for a more intuitively looking solution, you can do the same thing as a list comprehension:

block n = concat
    [ duplicate "-" i ++ "*" ++ duplicate "-" (n - i - 1) ++ "\n"
    | i <- [0..(n-1)]
    ]

Upvotes: 1

Related Questions