Добрый день, товарищи! Уже совсем скоро наступит Новый год. Чем же можно заняться, готовясь к этому празднику? А может быть, проводя каникулы? Сегодня я покажу вам как программисты рисуют новогодние елочки, ведь все хотят отмечать новый год.
Этот код не займет много места, но его логику все равно нужно будет понять. В конце статьи я выложу полную версию этого кода. С наступающими праздниками!
1. Определимся с целью
Вывод последовательности/массива «ёлочкой», «пирамидой» — пример решения (вложенные циклы)
Выведите его на экран «ёлочкой» последовательности чисел до $N$.
Например для $N=12$ вы должны получить:
1 2 3 4 5 6 7 8 9 10 11 12 .
Эту задачу можно решить используя два подхода:
- Просто перебрать (обойти) массив (а в данном случае просто последовательность) так как мы это делаем для вывода элементов в строчку, но в определённые моменты выводить между элементами знак переноса строки и таким образом получить ёлочку.
- Рассмотреть ёлочку как таблицу из нескольких строк (их может быть и очень много) в которой каждая следующая строка длиннее предыдущей на $1$, а первая по своей длине $=1$.
Решение с циклом одного уровня
В этом подходе мы просто перебираем все числа до $n$ в цикле for, в каждом витке выводя очередное значение + иногда перенося строку:
Python для котят. Пишем пирамидку из символов!
var n, i, j, k:integer; begin writeln(‘vvedite chislo N:’); readln(n); // получаем число, до которого будем выводить ёлочку k:=1; // число символов которые можно вывести не перенося строку j:=0; // сколько мы вывели с последего переноса строки for i:=1 to N do begin write(i, ‘ ‘); // просто выводим в ждом витке j := j + 1; // учтём, что мы вывели ещё один символ (для будущего переноса) if (j>=k) then // не пора ли переносить строку? begin writeln(); // перенос строки j:=0; // в новой строке ёлочки мы ещё ничего не вывели (сбрасываем счетчик) k:=k+1; // следубщий раз выведем на 1 символ больше до переноса строки end; end; readln(); end.
Решение через вложенные циклы
Здесь мы рассмотрим код, иллюстрирующий второй подход:
Рассмотреть ёлочку как таблицу из нескольких строк (их может быть и очень много) в которой каждая следующая строка длиннее предыдущей на $1$, на первая по своей длине $=1$.
Ясно, что в таблице может быть сколько угодно строк (внешний цикл) + нам потребуется выводить каждую строку посимвольно (внутренний цикл).
При этом внешний цикл просто запускает вывод очередной строки и ничего не знает о том как именно эти строки выводятся — его задача состоит просто в том, чтобы контролировать диапазон значений и заново запускать цикл вывода строки.
Очередной внутренний цикл вывода строки начинает свою работу с того значения $i$, на котором он остановился предыдущий раз. Поэтому мы инкрементируем $i$ в единственном месте — а именно сразу после вывода на экран очередного значения.
КАК НАРИСОВАТЬ ТРЕУГОЛЬНИК В КОНСОЛИ C# | C# ДОМАШНИЕ ЗАДАНИЯ | #5
var n, i, j, k:integer; begin writeln(‘vvedite chislo N:’); readln(n); // получаем число, до которого будем выводить ёлочку i:=1; k:=1; while (i<=n) do // просто контролируем диапазон begin for j:=1 to k do // вывод очередной строки begin if (i<=n) then // если мы всё ещё в диапазоне begin write(i, ‘ ‘); // выводим очередное значение (с пробелом) i:=i+1; // готовим следующее end else break; // досрочный выход из цикла end; writeln(); // переносим строку k:=k+1; // следующая строка будет длиннее на 1 символ end; readln(); end.
Массив как источник данных
Безусловно, мы можем использовать в качестве источника данных для ёлочки и одномерный массив (в программе для инициализации его случайными числами используется процедура — решим задачу первым способом без вложенных циклов с одним источником данных):
var n, i, j, k:integer; a: array [1..17] of integer; // процедура заполнит массив случайными числами procedure initRandArray(var a: array of integer); var min, max, i: integer; begin randomize(); // инициал. датчик случайных чисел (вызов стандартной процедуры) min := -5; // левая граница max := 10; // правая граница < обходим переданный массив и инициализируем массив случайными числами>for i:=low(a) to high(a) do a[i] := random(max + abs(min)) + min; end; begin // начало тела программы N := 17; // число элементов массива initRandArray(a); // передаём по ссылке для заполнения случаными числами k:=1; // число символов которые можно вывести не перенося строку j:=0; // сколько мы вывели с последего переноса строки for i:=1 to N do begin write(a[i], ‘ ‘); // выводим очередной элемент массива j := j + 1; // учтём, что мы вывели ещё один символ (для будущего переноса строки) if (j>=k) then // не пора ли переносить строку? begin writeln(); // перенос строки j:=0; // в новой строке ёлочки мы ещё ничего не вывели (сбрасываем счетчик) k:=k+1; // следубщий раз выведем на 1 символ больше до переноса строки end; end; readln(); end.
Key Words for FKN + antitotal forum (CS VSU):
- ёлочка
- вывод поледовательности ёлочкой пирамидой
- вложенные циклы
- примеры решений задач на вложенные циклы
- вложенные циклы ёлочка Паскаль
Источник: fkn.ktu10.com
Ёлочка
Данная задача представляет собой одну из множества задач, задаваемых время от времени начинающим разработчикам на собеседованиях.
Само задание звучит так:
Написать программу, выводящую в консоль для заданного числа n “изображение” ёлочки высотой n
Обычно, ожидается, что ёлка будет выглядеть так:
Данная задача просто решается на императивных ЯП, таких как Python. Здесь же будет приведено “функциональное” решение.
Скелет программы
Скелет программы будет следующим:
module Main where main :: IO () main = putStrLn (pineTree 10) pineTree :: Int -> String pineTree = undefined
Простое решение
Функция формирования “изображения” дерева представлена следующим кодом:
pineTree x = unlines $ map row ranges where row (n, m) = take n spaces ++ take m stars stars = repeat ‘*’ spaces = repeat ‘ ‘ ranges = zip [x — 1, x — 2 .. 0] [1, 3..] main = putStrLn (pineTree 10)
Бесточечный вариант
В качестве разминки для ума можно переписать функцию “рисования” ёлки в бесточечном стиле:
pineTree = unlines . zipWith (flip (++)) (zipWith take [1,3..] (repeat (repeat ‘*’))) . zipWith (flip take) (repeat (repeat ‘ ‘)) . reverse . flip ($) [1,2..] . take main = putStrLn (pineTree 10)
Бесточечный вариант №2
Функция записана бесточечно, но сложновата на вид, хоть и повторяет изначальное решение. Однако можно реализовать эту функцию и короче:
pineTree = unlines . takeWhile ((== ‘ ‘) . head) . iterate ((++ «**») . tail) . (++ «*») . (flip take) (repeat ‘ ‘) main = putStrLn (pineTree 10)
Источник: ruhaskell.org