1

I have this self-defined IO() Triangle, which has each row of a triangle as an element in a list:

import Data.List ( intersperse )
type Triangle = Char -> Int -> [String]

centeredTriangle :: Triangle
centeredTriangle c n = [replicate (n-i) ' ' ++ intersperse ' ' (replicate i c) | i <- [0 .. n]]

Output:

Ok, one module loaded.
ghci> centeredTriangle '*' 6
["      ","     *","    * *","   * * *","  * * * *"," * * * * *","* * * * * *"]

When I run my main function, I use unlines to print out the triangle like so:

triangles :: Int -> Int -> Int -> IO()
triangles a b c = do 
    putStr $ unlines $ centeredTriangle '*' a
    putStr $ unlines $ centeredTriangle '*' b 
    putStr $ unlines $ centeredTriangle '*' c

Output:

ghci> triangles 1 2 3

*

 *
* *

  *
 * *
* * *

I want to print the triangles on the same line, like so:

ghci> triangles 1 2 3

               *
       *      * *
 *    * *    * * *

I realise it may be a bigger task than I first anticipated, but my first thought was to use centeredTriangle to get the bottom line (last element of the list) of each triangle, and put them toghether in a new string which I then put as the last element in a new list of strings. I thought If I do this for each element (starting from the last) and up to the top I can print the triangles in the same line using my main funtion. How do I achieve this?

Mampenda
  • 661
  • 4
  • 21
  • 2
    What exactly do you mean by "on the same line"? Can you add the exact output you want to your question? – Joseph Sible-Reinstate Monica Oct 10 '21 at 17:56
  • You will need to add the right amount of vertical and horizontal space to make this work. Maybe, you could start by making a function to add a given amount of padding to a `[String]`, assuming it is "rectangular". Then, pad the triangles so that they have the same size X*Y. Finally, concatenate them horizontally. – chi Oct 10 '21 at 18:12
  • 2
    Imagine that we modify `centeredTriangle` so that each line was actually the full length of the triangle's "base". So, the second line for a 3-triangle would be " * " instead of " *". That would make it easier to write a function that put two of those figures (still considered as lists of lines) side-by-side. You would only call `unlines` at the very end, after having put all the figures together. – danidiaz Oct 10 '21 at 18:13

1 Answers1

1

Using type Triangle = [String],

  1. Write a function boundingBox :: Triangle -> (Int,Int).
  2. Write a function maxBoundingBox :: [Triangle] -> (Int,Int).
  3. Write a function putInBox :: Triangle -> (Int,Int) -> Triangle.
  4. Write a function makeSameSize :: [Triangle] -> [Triangle].
  5. Write a function sideToSide :: Triangle -> [String] -> [String].

Use it in foldr to conjoin all the resized Triangles together.

Some of the above functions aren't needed if you are the one creating these triangles in the first place. Then you just know the bounding box of the triangle you would create from the given parameters.

Will Ness
  • 70,110
  • 9
  • 98
  • 181