package com.javarush.task.pro.task04.task0405;
/*
Незаполненный прямоугольник
*/
public class Solution {
public static void main(String[] args) {
//напишите тут ваш
int c = 20;
while(c>0)
{
System.out.print("Б");
c--;
}
System.out.println();
int b = 8;
while(b>0)
{
int a = 20;
while(a>0)
{
if(a==1 || a==20)
System.out.print("Б");
else
System.out.print(" ");
a--;
}
System.out.println();
b--;
}
int d = 20;
while(d>0)
{
System.out.print("Б");
d--;
}
}
}
Максим
5 уровень
Задача решена. Но есть ли более лаконичное решение?
Обсуждается
Комментарии (18)
- популярные
- новые
- старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
solid
11 декабря 2022, 20:49
Тогда и я влезу со своим кодом, раз пошла такая эпопея.)))
Это универсальный алгоритм для построения прямоугольника из "Б".
Первая строчка - инициализация размера прямоугольника. Принимает любые int значения, но выводит в консоль только начиная с размера больше 0.
Далее идут два стандартных for для двумерного массива. Тут тоже ничего сложного, ибо с двумерным массивом все сталкиваются и прекрасно понимают данную конструкцию. Единственное, что я изменил - это индексацию: она начинается с 1 и заканчивается объявленными размерами прямоугольника включительно, для удобства, т.к. с реальным массивом мы не работаем, а считать, как в жизни, более привычно.
Затем объявлена булева переменная isEdge (это край?). Где логика тоже простая:
если это первая строка или последняя или это первая колонка или последняя, то вернуть true
(выражение взято в скобки для лучшей читабельности, но можно и без них).
Соответственно, во внутреннем цикле выводим символы в строке: если это край, то "Б", иначе " ".
После завершения вывода строки переходим на новую строку.
По сути 5 строк простого кода.
Там большие дядьки ниже концепции высказали. Так вот моё маленькое мнение.
Пока учишься программировать, естественно, если что-то ещё сложно для тебя, ты будешь стараться разбивать на мелкие подзадачи, дабы не запутаться, но сам понимаешь, что таску с решением в несколько строк кода (за исключением некоторых нюансов - это придёт с опытом), не стоит расписывать простынёй из подзадач.
Мой тебе совет: расписывай таску на понятные тебе фрагменты, а потом оптимизируй до красивого лаконичного и читабельного кода - это полезно.)
Можно просто сделать, а можно сделать это хорошо.
0
ГоффMaster
25 декабря 2022, 14:59
Не понимаю, чем его универсальность выше? Мог бы мне объяснить?
0
solid
27 декабря 2022, 14:42
Перечитай первый абзац после кода.
Для полной универсальности нужно бы закинуть в метод с двумя параметрами на размер прямоугольника и символом окантовки, но пока не хочу загружать человека темами, до которых он ещё не дошёл по уровню.
Это праздный вопрос или хочешь предложить свой вариант кода?
0
ГоффMaster
27 декабря 2022, 21:01
Ну вот смотри, я свой уже предложил 11 декабря.
Вот тест на скорость, три варианта, одинаково универсальные. Первый - твой, второй - мой и третий - оригинальный от Максима. Вариант 1 работает примерно в три раза медленнее варианта 2 и примерно в полтора раза медленнее варианта 3.
Вариант 1, безусловно, лаконичнее и даже красивее, но он самый медленный тут. В три раза медленнее варианта 2. Красота субъективна, цифры - объективны ;-)
Код я немного изменил, пишем в массив, а не в консоль и всё сменил на char, потому что они быстрее, чем String. Для чистоты сравнения именно алгоритмов.
Продолжение ниже
0
ГоффMaster
27 декабря 2022, 21:51
0
solid
28 декабря 2022, 18:53
Всё конечно замечательно, но вопрос был по более лаконичному решению, что я и скинул.
В таких тасках скорость выполнения практически мгновенна, так что про оптимизацию скорости даже не думаю, ибо для меня простота кода, его читабельность здесь имеет больший приоритет. Стараюсь не искать себе геморрой там, где можно обойтись без него.
Если честно, то я твой код дольше читал, чем свой писал.)
Круто, конечно, что ты в этом так хорошо разбираешься, но я ещё не дорос для написания прог а-ля Кафки, где нужно максимально минимизировать затраты времени на обработку потоков.
0
ГоффMaster
28 декабря 2022, 23:00
Да всё хорошо, я об общих принципах и подходах, которые можно учить уже на простых примерах ;-) На практике в продакшн будет взят тот код, который работает быстрее, а не тот, который короче или красивее, но учится можно и нужно на всяких примерах. Да и создание всегда проходит в несколько этапов - "Make it work, make it fast, make it clean" (я бы ещё добавил make it safe). Сначала добиться безошибочного выполнения, потом оптимизировать по ресурсам, а потом почистить от образовавшегося балласта. Редко когда сразу удаётся наваять конечный результат.
0
ГоффMaster
11 декабря 2022, 10:23
Ты всё правильно сделал. Вот почему:
Задача простая, но уже наглядная в том смысле, что решать её лучше не целиком, а разбивая на подзадачи. А умение разбивать задачу на более мелкие - одно из главных достоинств прогера. В данном прямоугольнике несложно разглядеть три подзадачи
Подзадача рас: Первая строка
Подзадача два: 8 одинаковых строк
Подзадача 3: последняя строка, такая же как первая.
При этом подзадача два так же разбивается на более мелкие, в ней тоже явны закономерности.
Так и кодим:
Если нет необходимости ветвления алгоритма (ифы/елсы/свитчи), то и не надо его ветвить. Линейное выполнение - самое эффективное и понятное. Поэтому решение с постоянными проверками внутри цикла, как тут предлагают - совсем не оптимальное. Не нужны тут никакие проверки, всё и так заранее известно.
Грубо говоря, используемый тобою т описанный мною алгоритм идёт слева направо сверху вниз и тупо заполняет прямоугольник. В каждый момент времени алгоритм точно знает, где он находится и какой символ нужно поставить.
Алгоритм от Murad3160818 тоже идёт слева направо и сверху вниз, но он при каждом шаге вычисляет, где же он находится и какой символ надо вывести. Это 200 лишних не нужных вычислений. 200 раз происходит "Ой, где я? А, там-то и там-то. Ну тогда это пробел. А если не там-то и там-то, то тогда Б. Следующий шаг. Ой, где я? А, там-то и там-то. Ну тогда это пробел. А если не там-то и там-то, то тогда Б. Следующий шаг. Ой, где я? А, там-то и там-то. Ну тогда это пробел. А если не там-то и там-то, то тогда Б. ... " Ну ты понел в общем ;-)
Вывод: лаконичное - не всегда оптимальное. Чем меньше машине надо будет делать вычислений, тем лучше.
+4
Денис Enterprise Java Developer
11 декабря 2022, 15:14
Как минимум это спорное утверждение сильно зависящее от контекста. Для этой конкретной задачи, вполне возможно, подход с выводом и верный, но зачем тогда мелочиться, почему не собрать две константных строки и выводить их соответствующим образом? Крышка, стенки, и снова крышка в роли дна. Можно вообще одним циклом обойтись.
Крышку и стенки можно даже генерить на лету, что бы они под любые размеры подходили.
0
ГоффMaster
11 декабря 2022, 16:07
Ты прав, в продакшене было бы, безусловно, самым эффективным и правильным решением это всё захардкодить. Без циклов. Один sout. Быстро, эффективно, экономно.
Но тут не продакшн, мы учимся, учим циклы и учим структурировать задачи. Поэтому в этой задаче мы структурируем и используем циклы, а не хардкодим.
Насчёт спорного утверждения - зачем ты так общо говоришь? Какая именно фраза в моём объяснении вызывает у тебя смущение? Какой педагогический эффект твоё замечание несёт? Чему оно должно научить Максима и остальных?
В данном контексте я всё правильно написал. Тот код лучше, при котором машине не нужно вычислять ненужное или заранее известное. Прога, которая 200 раз повторяет совершенно не нужные вычисления - однозначно не оптимальна.
0
Денис Enterprise Java Developer
11 декабря 2022, 19:01
Какая именно фраза в моём объяснении вызывает у тебя смущение?
Тут не фраза, а скорее концепция. Очевидно, что производительный код работает строго по happyPath и не несет в себе лишних действий, но код который я отправляю в прод должен пережить знакомство со среднестатистическим пользователем. Имхо, люди которые учатся программировать должны учиться писать универсальный код и покрывать corner cases даже если этого не требуется. В конце концов, оптимизировать готовое решение можно. А вот premature optimisation это зло.
Но конечно же это не догма, именно по этому я написал что твоё утверждение спорное.
0
ГоффMaster
11 декабря 2022, 19:15
Речь в моём посте идёт аж о двух концепциях - уметь структурировать задачу и видеть эффективность кода, которая далеко не всегда пропорциональна лаконичности. Какая из этих двух тебя смущает? Какая ещё premature optimisation в данном случае, о чём ты, прости?
Предлагаю срочно эту дискуссию свернуть, если хочешь продолжить - пиши в личку, пиши в форум, здесь ей явно не место.
Можешь/хочешь ответить ОП на его вопрос - ответь. Насчёт универсальности - согласен с тобой. Ну так и предложи свой универсальный вариант, разбери его достоинства по сравнению с другими, аргументируй, что бы было новичку понятно, что ты имеешь в ввиду и почему, добавь своё к его знаниям. Вот это было бы правильно.
Не можешь / не хочешь этим заниматься - ну так и не надо. А вот начатая тобой дискуссия со мной в данном месте не конструктивна и никак не является помощью.
0
Денис Enterprise Java Developer
11 декабря 2022, 20:33
Я тебе уже ответил на твой вопрос, если ты этого не понял - не вижу смысла продолжать.
Более-менее универсальный вариант решения предложили анонимус ниже, только счётчики и границы вынести в переменные нужно.
0
Murad3160818
10 декабря 2022, 23:13
+1
ГоффMaster
11 декабря 2022, 10:40
Если интересно, то глянь на мой комментарий, почему это не хорошо
0
Максим
6 декабря 2022, 06:42
Круто! Спасибо)
0
jvatechsBackend Developer в Ищу стажировкуExpert
6 декабря 2022, 00:23
Можно так:
+3
ГоффMaster
11 декабря 2022, 10:40
Если интересно, то глянь на мой комментарий, почему это не хорошо
0