Игра, которая проверяет вашу программистскую логику

Игра, которая проверяет вашу программистскую логику

Разбираем типичное задание на собеседованиях

Чтобы понять, как потенциальный программист умеет писать код, на собеседованиях любят давать небольшие задачки на программирование. Сегодня разберём одну из них и посмотрим, какие там могут быть подводные камни и на что стоит обратить внимание.

Задача — написать программу для игры FizzBuzz

Есть детская игра FizzBuzz, где нужно называть числа подряд, соблюдая всего три правила:

  1. Если число делится на 3, вместо него надо сказать «Fizz».
  2. Если число делится на 5, вместо него надо сказать «Buzz».
  3. А если число делится одновременно на 3 и на 5, то надо вместо него сказать «FizzBuzz».

Например, в этой игре первые 20 чисел будут выглядеть так:

1

2

Fizz (3 делится на 3)

4

Buzz (5 делится на 5)

Fizz (6 делится на 3)

7

8

Fizz

Buzz

11

Fizz

13

14

FizzBuzz (15 делится одновременно на 3 и 5)

16

17

Fizz

19

Buzz

Нужно написать код на любом языке программирования, который выведет первые 100 чисел в этой игре.

В чём смысл задания

Цель человека, который проводит собеседование, — посмотреть, как вы решаете программистские задачи.

Одни кандидаты начинают сразу писать код, по пути исправляя ошибки, запуская всё заново, исправляя снова, дописывая то, чего не хватает, и так подход за подходом. Другие сначала составляют план решения, схемы и пробуют решить её алгоритмически — сразу нарисовать для себя полную картину, чтобы потом запрограммировать её за один подход. Третьи делают иначе — начинают с самого простого кода, который делает только базовые вещи, а потом начинают её усложнять, пока программа не будет делать то, что нужно. 

С другой стороны, сразу будет видно, как именно вы пишете и оформляете код: ставите ли отступы и комментарии, делите ли код на функции и т. д.

А ещё задание достаточно простое, чтобы сделать его за несколько минут, и достаточно сложное, чтобы проверить всё, что нужно на начальном этапе. Дело в том, что для решения нужно предусмотреть ситуации, когда:

  • число делится на 3 — и вывести одно слово;
  • число делится на 5 — и вывести другое слово;
  • число делится на 3 и 5 одновременно — и вывести третье слово;
  • число не подходит ни под одно из этих условий — и надо тогда вывести само число.

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

Быстрый подход

Попробуем решить задачу в лоб: сделаем цикл от 1 до 100 и просто проверим все условия по очереди. Используем для этого % — оператор взятия остатка от деления. Если, например, число делится на 3 без остатка, то остаток равен нулю — по этому признаку мы сможем найти все числа, вместо которых надо сказать

«Fizz»:
// перебираем числа от 1 до 100
for (var i = 1; i <= 100; i++) {
	// если число делится на три
	if (i % 3 == 0) {
		console.log('Fizz');
	}

	// если число делится на 5
	if (i % 5 == 0) {
		console.log('Buzz');
	}

	// если не делится ни на 3, ни на 5, то выводим само число
	if ((i % 3 != 0) && (i % 5 != 0)) {
		console.log(i);
	}
}
Игра, которая проверяет вашу программистскую логику

Программа вроде работает, но вместо одного слова FizzBuzz на числе 15 она вывела два отдельных слова, а это неправильно. Значит, наше решение было слишком быстрым и надо подумать ещё.

Добавляем отдельную проверку для FizzBuzz

Чтобы исправить ситуацию, добавим в код ещё одну проверку, которая выведет одно слово FizzBuzz в нужный момент — когда число делится одновременно на 3 и 5. Но нам тогда придётся поправить и все остальные условия, когда мы просто делили на 3 и 5, чтобы программа не реагировала на них в этом случае:

// перебираем числа от 1 до 100
for (var i = 1; i <= 100; i++) {
	// если число делится только на три
	if ((i % 3 == 0) && (i % 5 != 0)) {
		console.log('Fizz');
	}

	// если число делится только на 5
	if ((i % 5 == 0) && (i % 3 != 0)) {
		console.log('Buzz');
	}

	// если делится одновременно на 3 и 5
	if ((i % 3 == 0) && (i % 5 == 0)) {
		console.log('FizzBuzz');
	}

	// если не делится ни на 3, ни на 5, то выводим само число
	if ((i % 3 != 0) && (i % 5 != 0)) {
		console.log(i);
	}
}
Игра, которая проверяет вашу программистскую логику

Делаем красивый код

Формально мы решили задачу — программа делает всё, что требовалось по условиям. Но наш код выглядит очень неопрятно: в нём сложно разбираться, он громоздкий и в нём слишком много условий и проверок. Если мы хотим на собеседовании показать себя с лучшей стороны, его нужно оптимизировать — убрать все повторы и сделать проще его поддержку в будущем.

Для начала уберём огромные скобки с множеством сравнений, используя конструкцию else-if:

// перебираем числа от 1 до 100
for (var i = 1; i <= 100; i++) {
	// если делится одновременно на 3 и 5
	if ((i % 3 == 0) && (i % 5 == 0)) {
		console.log('FizzBuzz');
	}

	// иначе, если число делится только на три
	else 
		if (i % 3 == 0) {
		console.log('Fizz');
	}

		// если число делится только на 5
		else 
			if (i % 5 == 0) {
			console.log('Buzz');
		}

			// иначе, если всё предыдущее не подходит, то выводим само число
			else 
				console.log(i);
			
}

Код стал выглядеть проще, но его всё ещё сложно поддерживать. Что, если нам в будущем понадобится поменять правила и вместо чисел 3 и 5 нужно будет проверять 4 и 7? В этом случае нам нужно будет пройти по всему коду и заменить одно число на другое, и так до тех пор, пока не будут сделаны все замены. Гораздо проще сделать так, чтобы нам было достаточно поменять значение только в одном месте и не выискивать в программе остальные значения. Обычно для этого используют переменные, но в нашем случае можно сделать изящнее:

// перебираем числа от 1 до 100
for (var i = 1; i <= 100; i++) {
	// здесь будем хранить то, что надо вывести на экран
	var output = '';
	// если делится на 3 — добавляем Fizz
	if (i % 3 == 0) { output += 'Fizz' }
	// если делится на 5 — добавляем Buzz
	if (i % 5 == 0) { output += 'Buzz' }

	// если ничего не добавили — добавляем само число
	if (output == '') { output = i}

	// выводим результат на экран
	console.log(output)	
}

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

  1. Все числа у нас используются только один раз — чтобы их поменять на другие, достаточно сделать это в одном месте, и всё будет работать правильно.
  2. Мы сделали переменную output — в неё мы добавляем текст, если сработало какое-то условие. Так мы получаем то Fizz, то Buzz, то FizzBuzz, когда текст добавляется два раза, по каждому условию.
  3. В конце мы проверяем, есть ли что-то в этой переменной. Если нет, то, значит, не сработало ни одно правило и нужно вывести само число.

Что дальше

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

Текст:

Михаил Полянин

Редактор:

Максим Ильяхов

Художник:

Алексей Сухов

Корректор:

Ирина Михеева

Вёрстка:

Кирилл Климентьев

Соцсети:

Виталий Вебер

Получите ИТ-профессию
В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства.
Начать карьеру в ИТ
Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию
Еще по теме
Что такое Kotlin?
Что такое Kotlin

И зачем он андроид-разработчику.

easy
«Программисты, которые умеют писать алгоритмы, — нишевая профессия»
«Программисты, которые умеют писать алгоритмы, — нишевая профессия»

Мнение работодателя Коли Митина.

easy
Как учатся нейронки

Самое простое объяснение на картинках.

hard
Зачем нужны счётчики аналитики на сайте и что они умеют
Зачем нужны счётчики аналитики на сайте и что они умеют

Переходим на новый уровень настройки сайтов.

easy
Непрерывный цикл разработки — это как?
Непрерывный цикл разработки — это как?

CI/CD на простых примерах

medium
Объясняем объекты

Главное понятие современных подходов к программированию.

hard
Как называть переменные и функции, чтобы вас уважали бывалые программисты
Как называть переменные и функции, чтобы вас уважали бывалые программисты

Если вы опытный разработчик, покажите эту статью начинающим.

medium
Большой разбор: как ИИ играет в змейку

Современные технологии против игры прошлого века.

medium
Как устроена радиосвязь
Как устроена радиосвязь

Wi-Fi, 4G, 5G и другие приключения электромагнитного поля

medium
Как получить удалённый доступ к компьютеру

Разбор систем и подходов.

medium
medium