#haskell #recursion #triangle
Вопрос:
У меня есть это определение IO() Triangle
, в котором каждая строка треугольника является элементом в списке:
import Data.List ( intersperse )
type Triangle = Char -> Int -> [String]
centeredTriangle :: Triangle
centeredTriangle c n = [replicate (n-i) ' ' intersperse ' ' (replicate i c) | i <- [0 .. n]]
Выход:
Ok, one module loaded.
ghci> centeredTriangle '*' 6
[" "," *"," * *"," * * *"," * * * *"," * * * * *","* * * * * *"]
Когда я запускаю свою основную функцию, я печатаю unlines
треугольник следующим образом:
triangles :: Int -> Int -> Int -> IO()
triangles a b c = do
putStr $ unlines $ centeredTriangle '*' a
putStr $ unlines $ centeredTriangle '*' b
putStr $ unlines $ centeredTriangle '*' c
Выход:
ghci> triangles 1 2 3
*
*
* *
*
* *
* * *
Я хочу напечатать треугольники на одной линии, вот так:
ghci> triangles 1 2 3
*
* * *
* * * * * *
Я понимаю, что это может оказаться более сложной задачей, чем я ожидал, но моей первой мыслью было использовать centeredTriangle
нижнюю строку (последний элемент списка) каждого треугольника и объединить их в новую строку, которую я затем помещу в качестве последнего элемента в новый список строк. Я подумал, что если я сделаю это для каждого элемента (начиная с последнего) и до самого верха, я смогу напечатать треугольники в одной строке, используя мою основную функцию. Как мне этого добиться?
Комментарии:
1. Что именно вы подразумеваете под «на одной линии»? Можете ли вы добавить точный вывод, который вы хотите, в свой вопрос?
2. Вам нужно будет добавить нужное количество вертикального и горизонтального пространства, чтобы это сработало. Возможно, вы могли бы начать с создания функции для добавления заданного количества отступов в a
[String]
, предполагая, что она «прямоугольная». Затем поместите треугольники так, чтобы они имели одинаковый размер X*Y. Наконец, соединим их горизонтально.3. Представьте, что мы изменим
centeredTriangle
так, чтобы каждая линия была фактически полной длиной «основания»треугольника. Таким образом, вторая строка для 3-треугольника будет » * «вместо» *». Это облегчило бы написание функции, которая помещала бы две из этих фигур (все еще рассматриваемых как списки строк) рядом друг с другом. Вы бы позвонили толькоunlines
в самом конце, после того, как сложите все цифры вместе.
Ответ №1:
С помощью type Triangle = [String]
,
- Напишите функцию
boundingBox :: Triangle -> (Int,Int)
. - Напишите функцию
maxBoundingBox :: [Triangle] -> (Int,Int)
. - Напишите функцию
putInBox :: Triangle -> (Int,Int) -> Triangle
. - Напишите функцию
makeSameSize :: [Triangle] -> [Triangle]
. - Напишите функцию
sideToSide :: Triangle -> [String] -> [String]
.
Используйте его, foldr
чтобы объединить все размеры Triangle
s вместе.
Некоторые из вышеперечисленных функций не нужны, если вы сами создаете эти треугольники в первую очередь. Тогда вы просто знаете ограничивающую рамку треугольника, которую вы создали бы из заданных параметров.