FizzBuzz на 1С. Чем короче, тем веселее. Варианты принимаются…

Мне было скучно, я не мог себя заставить написать ничего полезного. И читал статью на Хабре. Потом я читал комментарии, а потом… нет я не ушел смотреть котиков на ютюбе. Я решил сделать несколько решений задачки FizzBuzz на 1С, с целью «чем короче, тем лучше».
Прошу сильно не пинать, это просто развлечение для вечера.

Пояснение

Кто не знает, не помнит, вот содержание задачи.

Напишите программу, которая выводит на экран числа от 1 до 100. При этом вместо чисел, кратных трем, программа должна выводить слово «Fizz», а вместо чисел, кратных пяти — слово «Buzz». Если число кратно и 3, и 5, то программа должна выводить слово «FizzBuzz».

И так я сделал для себя 4 варианта.

Вариант 1 — в лоб

&НаКлиенте
Процедура Вариант1(Команда)
Для Индекс = 1 По 100 Цикл
Если Индекс % 15 = 0 Тогда
Т = "FizzBuzz";
ИначеЕсли Индекс % 3 = 0 Тогда
Т = "Fizz";
ИначеЕсли Индекс % 5 = 0 Тогда
Т = "Buzz";
Иначе
Т = Формат(Индекс, "ЧГ=");
КонецЕсли;

Сообщить(Т);
КонецЦикла;
КонецПроцедуры

Выглядит нормально, пишется за несколько секунд на бумажке ручкой, но занимает много строчек. Скучный вариант.

Вариант 2 — сократим ИначеЕсли

&НаКлиенте
Процедура Вариант2(Команда)
Для Индекс = 1 По 100 Цикл
Т = "";
Если Индекс%3 = 0 Тогда
Т = Т + "Fizz";
КонецЕсли;
Если Индекс%5 = 0 Тогда
Т = Т + "Buzz";
КонецЕсли;
Если ПустаяСтрока(Т) Тогда
Т = Формат(Индекс, "ЧГ=");
КонецЕсли;

Сообщить(Т);
КонецЦикла;
КонецПроцедуры

И тут я подумал, ведь FizzBuzz = Fizz + Buzz. А условие для FizzBuzz это %3*5. Ну значит берем и прибавляем к строке результат проверки условия на %3 и на %5. Если ничего нет — значит это число.

Вариант 3 — заменим Если на ?

&НаКлиенте
Процедура Вариант3(Команда)
Для Индекс = 1 По 100 Цикл
Т = ?(Индекс%3 = 0, "Fizz", "") + ?(Индекс%5 = 0, "Buzz", "");
Т = ?(ПустаяСтрока(Т), Формат(Индекс, "ЧГ="), Т);

ВывестиВЛог(Т);
КонецЦикла;
КонецПроцедуры

Ну это было как бы логичное продолжение. Убираем Если … КонецЕсли, меняем на тернарный оператор ? становится короче и лучше.

Вариант 4 — короче, не значит лучше

&НаКлиенте
Процедура Вариант4(Команда)
Для Индекс = 1 По 100 Цикл
Т = ?(Индекс%15 = 0, "FizzBuzz",
?(Индекс%3 = 0, "Fizz",
?(Индекс%5 = 0, "Buzz",
Формат(Индекс, "ЧГ="))));

Сообщить(Т);
КонецЦикла;
КонецПроцедуры

Ну тут мы вообще все свели к одной строке используя только тернарный оператор ?. Однако читаемость этой строки уменьшилась, понимание (имхо) тоже стало хуже. А подсчет закрывающих скобок может заставить нажать пару раз выполнение синтаксис-контроля.

Конец

Поскольку дальше мне стало скучно, отведенное время для развлечений закончилось и пора было идти спать, я решил что продолжать не буду. Мне хватит. Написал тест ко всем 4-м вариантам, прогнал и закрыл этот вопрос. Ну, а поскольку на Инфостарт не нашел упоминания про FizzBuzz решил восполнить пробел.

Прошу ногами не пинать, помидорами не закидывать. Хотите свою интерпретацию — в комментарии. Будет интересно почитать.

16 Comments

  1. VmvLer

    после обеда, да в жару не рационально пинать ногами, а так бы я с большим удовольствием это сделал)

    Reply
  2. chipazawra

    Вот так еще минус 1.

    Сообщить(?(Индекс%15 = 0, «FizzBuzz»,

    ?(Индекс%3 = 0, «Fizz»,

    ?(Индекс%5 = 0, «Buzz»,

    Формат(Индекс, «ЧГ=»)))));

    Reply
  3. chipazawra

    Один оператор )

    Кто меньше ?.

    Сообщить(«1

    |2

    |Fizz

    |4

    |Buzz

    |Fizz

    |7

    |8

    |Fizz

    |Buzz

    |11

    |Fizz

    |13

    |14

    |FizzBuzz

    |16

    |17

    |Fizz

    |19

    |Buzz

    |Fizz

    |22

    |23

    |Fizz

    |Buzz

    |26

    |Fizz

    |28

    |29

    |FizzBuzz

    |31

    |32

    |Fizz

    |34

    |Buzz

    |Fizz

    |37

    |38

    |Fizz

    |Buzz

    |41

    |Fizz

    |43

    |44

    |FizzBuzz

    |46

    |47

    |Fizz

    |49

    |Buzz

    |Fizz

    |52

    |53

    |Fizz

    |Buzz

    |56

    |Fizz

    |58

    |59

    |FizzBuzz

    |61

    |62

    |Fizz

    |64

    |Buzz

    |Fizz

    |67

    |68

    |Fizz

    |Buzz

    |71

    |Fizz

    |73

    |74

    |FizzBuzz

    |76

    |77

    |Fizz

    |79

    |Buzz

    |Fizz

    |82

    |83

    |Fizz

    |Buzz

    |86

    |Fizz

    |88

    |89

    |FizzBuzz

    |91

    |92

    |Fizz

    |94

    |Buzz

    |Fizz

    |97

    |98

    |Fizz

    |Buzz»);

    Reply
  4. Fox-trot

    (0)

    Процедура ПриНачалеРаботыСистемы()
    СписокШиндлера = Делители();
    Для Индекс = 1 По 100 Цикл
    Вывод = Формат(Индекс, «ЧГ=0»);
    Для Каждого Шаг Из СписокШиндлера Цикл
    Если Индекс % Шаг.Значение = 0 Тогда
    Вывод = Шаг.Представление;
    Прервать;
    КонецЕсли;
    КонецЦикла;
    Сообщить(Вывод);
    КонецЦикла;
    КонецПроцедуры
    
    Функция Делители()
    СписокШиндлера = Новый СписокЗначений;
    СписокШиндлера.Добавить(15, «FizzBuzz»);
    СписокШиндлера.Добавить(3, «Fizz»);
    СписокШиндлера.Добавить(5, «Buzz»);
    Возврат СписокШиндлера;
    КонецФункции
    

    Показать

    Reply
  5. Serj1C

    Оооо! Из отпуска вернусь, обязательно напишу вариант)

    Reply
  6. Fox-trot

    (4) создано по феншую 🙂 проще для сопровождения, к примеру ежели внезапно надо добавить еще и 7

    Reply
  7. Неопределено
    Для Счетчик = 1 по 100 Цикл
    fizz = (Счетчик % 3 = 0);
    buzz = (Счетчик % 5 = 0);
    Если (fizz или buzz) Тогда
    Сообщить(?(fizz, «Fizz», «») +?(buzz , «Buzz «, «»));
    Иначе
    Сообщить(Счетчик);
    КонецЕсли;
    КонецЦикла;
    

    Показать

    Reply
  8. Stref75
        т=1;
    п=1;
    Для й=1 По 100 Цикл
    Сообщить(?(т=3 и п=5, «ФуззБузз», ?(т=3, «Фузз», ?(п=5, «Буз», й))));
    т=?(т=3, 1, т+1);
    п=?(п=5, 1, п+1);
    КонецЦикла;
    
    Reply
  9. muskul

    Через запрос же надо )

    Reply
  10. targetis_ru
    // Массив из 15 значений для остатка от деления на 15.
    // Так как остаток от деления 15,30,45… на 15 равун нулю то первым элементом ставим FizzBuzz.
    Мас15 = СтрРазделить(«FIzzBuzz,,,Fizz,,Buzz,Fizz,,,Fizz,Buzz,,Fizz,,»,»,»,Ложь);
    
    Для Н = 1 По 100 Цикл
    Врем = Мас15[Н % 15];
    Сообщить(?(ЗначениеЗаполнено(Врем),Врем,Н));
    КонецЦикла;
    
    

    Показать

    Reply
  11. acanta

    Замеры на каждом варианте?

    Reply
  12. ildarovich

    Вот еще вариант

    Для ё = 1 По 100 Цикл
    Сообщить(Сред(«FizzBuzz» + ё, ?(ё % 3, ?(ё % 5, 9, 5), 1), ?(ё % 15, 4, 8)))
    КонецЦикла

    Но Вариант 4, записанный в таком стиле, еще короче

    Для ё = 1 По 100 Цикл
    Сообщить(?(ё % 15, «FizzBuzz», ?(ё % 5, «Fizz», ?(ё % 3, «Buzz», ё)))
    КонецЦикла

    Так что пока вывод, что короче, чем Вариант 4 решить эту задачу нельзя(((

    Reply
  13. pm74

    (12)

    Сообщить(?(ё % 15, «FizzBuzz», ..

    все таки ?(ё % 15=0 или ?(не ё % 15

    Для ё = 1 По 100 Цикл
    Сообщить(?( ё % 5=0, «Fizz»,»»)+ ?(ё % 3=0, «Buzz»,»»)+?(ё % 3*ё % 5, ё,»»));
    КонецЦикла;
    
    Reply
  14. Неопределено

    (9)

    «ВЫБРАТЬ
    | 0 КАК Числа
    |ПОМЕСТИТЬ РядЧисел
    |
    |ОБЪЕДИНИТЬ ВСЕ
    |
    |ВЫБРАТЬ
    | 1
    |
    |ОБЪЕДИНИТЬ ВСЕ
    |
    |ВЫБРАТЬ
    | 2
    |
    |ОБЪЕДИНИТЬ ВСЕ
    |
    |ВЫБРАТЬ
    | 3
    |
    |ОБЪЕДИНИТЬ ВСЕ
    |
    |ВЫБРАТЬ
    | 4
    |
    |ОБЪЕДИНИТЬ ВСЕ
    |
    |ВЫБРАТЬ
    | 5
    |
    |ОБЪЕДИНИТЬ ВСЕ
    |
    |ВЫБРАТЬ
    | 6
    |
    |ОБЪЕДИНИТЬ ВСЕ
    |
    |ВЫБРАТЬ
    | 7
    |
    |ОБЪЕДИНИТЬ ВСЕ
    |
    |ВЫБРАТЬ
    | 8
    |
    |ОБЪЕДИНИТЬ ВСЕ
    |
    |ВЫБРАТЬ
    | 9
    |;
    |
    |////////////////////////////////////////////////////////////­////////////////////
    |ВЫБРАТЬ
    | РядЧисел1.Числа * 10 + РядЧисел.Числа + 1 КАК Число
    |ПОМЕСТИТЬ ВТ_Числа
    |ИЗ
    | РядЧисел КАК РядЧисел,
    | РядЧисел КАК РядЧисел1
    |;
    |
    |////////////////////////////////////////////////////////////­////////////////////
    |ВЫБРАТЬ
    | ВЫБОР
    |  КОГДА ВТ_Числа.Число — (ВЫРАЗИТЬ(ВТ_Числа.Число / 15 КАК ЧИСЛО(3, 0))) * 15 = 0
    |   ТОГДА «»FizzBuzz»»
    |  ИНАЧЕ ВЫБОР
    |    КОГДА ВТ_Числа.Число — (ВЫРАЗИТЬ(ВТ_Числа.Число / 5 КАК ЧИСЛО(3, 0))) * 5 = 0
    |     ТОГДА «»Buzz»»
    |    ИНАЧЕ ВЫБОР
    |      КОГДА ВТ_Числа.Число — (ВЫРАЗИТЬ(ВТ_Числа.Число / 3 КАК ЧИСЛО(3, 0))) * 3 = 0
    |       ТОГДА «»Fizz»»
    |      ИНАЧЕ ВТ_Числа.Число
    |     КОНЕЦ
    |   КОНЕЦ
    | КОНЕЦ КАК Результат
    |ИЗ
    | ВТ_Числа КАК ВТ_Числа»;

    Показать

    Reply
  15. Serj1C

    (12)

    Немного короче:

    Для ё = 1 по 100 Цикл
    Сообщить(?(ё%3*ё%5, ё, ?(ё%3, «», «Fizz»)+?(ё%5, «», «Buzz»)));
    КонецЦикла;
    
    Reply
  16. Serj1C

    (15) И еще пару байт можно срезать, используя английские синонимы:

    Для ё = 1 по 100 Do
    Message(?(ё%3*ё%5, ё, ?(ё%3, «», «Fizz»)+?(ё%5, «», «Buzz»)))
    EndDo
    
    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *