enum
Чему равно значение Test::b и почему?
Заголовок раздела «Чему равно значение Test::b и почему?»-
enum Test{a = 1,b = 2,};
-
enum Test{a = 1,b,};
-
enum Test{a,b,};
-
enum Test{a = -1,b,};
-
enum Test{a = (5 + 10 * 5) / 5,b,};
-
enum Test{other = 5,a = other + 6,b,};
-
Запишите ответ как целое число и как символ.
enum Test{a = '5',b = '7',}; -
Запишите ответ как целое число и как символ.
enum Test{a = '5',b,}; -
Запишите ответ как целое число и как символ.
enum Test{a = 'b',b,}; -
Запишите ответ как целое число.
enum Test{a = 'a' + '1',b,};
Почему?
Заголовок раздела «Почему?»Почему enum class лучше чем enum?
Перечислите.
(Ответы есть в видео).
Обезвреживание бомбы.
Заголовок раздела «Обезвреживание бомбы.»На каждой бомбе 3 провода, все разных цветов: красный, желтый, зеленый. Нужно написать программу, которая определяет, какой провод нужно перерезать, чтобы отключить таймер бомбы.
По характеристикам бомбы можно определить верный провод. Характеристики следующие:
- Один из портретов: Ленин, George Washington, Гитлер;
- Один из цветов лампочки: синий, белый, красный;
- Один из 2 состояний тумблера (включен или выключен);
- Значение на циферблате, от 1 до 100.
Определить нужный провод можно по следующим правилам:
- Если портрет Ленина, бомба не взорвется, ничего резать не надо;
- С цветом лампочки связано значение. Синий - 11, белый - 15, красный - 35. Если значение на циферблате меньше этого значения, нужно резать красный провод.
- Если портрет Гитлера, цвета лампочки смещаются на 1 в предыдущем пункте. То есть, синий будет иметь значение белого (15), белый - красного (35), а красный - синего (11).
- Если числовое значение цвета лампочки равно значению на циферблате, нужно резать зеленый провод.
- Иначе, нужно резать желтый провод.
- Если тумблер включен, то, какой провод нужно порезать, смещается обратно на 1. Вместо зеленого - желтый, вместо желтого - красный, вместо красного - зеленый.
- Если значение циферблата делится на 4, нужный провод смещается вперед на это значение.
Сделайте основную логику в виде функции,
принимающей параметрами характеристики бомбы,
и возвращающую нужное действие (какой провод перерезать, и если вовсе нужно перерезать).
В main напишите тесты через assert.
Можете сделать со вводом данных с клавиатуры, но не обязательно.
Рекомендации:
- Определите
enum class-ы там, где есть фиксированный список возможных объектов. Например, цвета лампочки, личность на портрете, цвет провода, положение переключателя. - Если состояния всего 2, можно
enumне делать, а моделировать ситуацию черезbool. - Если с каждым из членов
enum-а связано какое-то значение, используйте look-up table илиswitchдля их связывания. Возможно также присвоить самому члену это значение, но делайте это только если код не зависит от того, что они на 1 следуют друг за другом по значению. - Конвертируйте объект типа определенного
enum classвintи обратно черезstatic_cast. - Сдвиг вперед или назад осуществите через модулярную арифметику.
- Используйте early return, когда решение находится ранее.
Кто сделал, сделайте мне PR с тест-кейсами :)
Я сам эту программу не делал.
Модулярная арифметика?
Идея возвращаться на начало при переходе за конец, и переходить на конец при заходе обратно за начало. Как если змейка уходит за правый край, она должна появиться в том же ряду, слева.
Для нужно использовать оператор остатка от деления. Он как бы отсекает факт полного прохода через весь ряд, или достижение конца чего бы то ни было, как, например, конца массива с числами.
Если в массиве 3 элемента, чтобы пройти вперед на одну позицию, с возвратом на старт при достижении конца, нужно взять остаток от деления на 3 после перехода на следующий индекс.
int i = 0;i = (i + 1) % 3; // i == 1i = (i + 1) % 3; // i == 2i = (i + 1) % 3; // i == 0i = (i + 1) % 3; // i == 1i = (i + 1) % 3; // i == 2Если смещение больше чем 3, все лишние переходы полностью через весь промежуток значений будут поглощены применением оператора остатка от деления.
int i = 0;i = (i + 12) % 3; // i == 0i = (i + 13) % 3; // i == 1С переходом назад есть одна проблема если поступим тем же путем.
Оператор % для отрицательных чисел дает отрицательный результат.
int i = 1;i = (i - 1) % 3; // i == 0i = (i - 1) % 3; // i == -1i = (i - 1) % 3; // i == -2i = (i - 1) % 3; // i == 0Это можно обойти, добавив 3 к сумме перед тем, как отнять 1, потому что лишняя 3 удалится оператором остатка от деления.
int i = 1;i = (i - 1 + 3) % 3; // i == 0i = (i - 1 + 3) % 3; // i == 2i = (i - 1 + 3) % 3; // i == 1i = (i - 1 + 3) % 3; // i == 0Это сработает только если мы отнимаем число, которое меньше того, на которое делим (3). Если нужно чтобы работало при отнимании любого отступа, можно сначала посчитать остаток, чтобы в случае отрицательного результата сделать его не меньше чем -2, после чего добавить 3, чтобы сделать его положительным, после чего снова взять остаток, чтобы удалить добавленную 3 для того случая, когда на 1-ом этапе уже вышло положительное число.
int i = 1;int offset = -5; // 1 целый массив назад, и еще 2 позицииi = (((i + offset) % 3) + 3) % 3; // 2
// _0_ offset = -5, i = 1 > -3 = нет эффекта// 0__ offset = -4 >// __0 offset = -3 >// _0_ offset = -2// 0__ offset = -1// __0 offset = 0, i = 2Тут есть и другие подходы, смотри инфу.
Как обозначить отсутствие значения?
В случае, если это enum, можете выделить отдельное значение под это.
Обычно, такой член имеет имя None.
Можете вписать его как первый член enum-а, тогда его значение будет, очевидно, 0.
В этом случае будет логичнее дать None другое значение,
чтобы можно было продолжать использовать модулярную арифметику для значений цвета,
вставив None вконец enum-а, или задав вручную, например, -1.
Но можно и обойти крайние случаи дополнительными проверками, оставив None на 0.
Также можно использовать структуру для ответа, добавив в нее отдельное bool поле,
указывающее, если провод нужно резать вообще.
enum class BombWireColor{ Red, Yellow, Green,};
struct BombDefusionDecision{ bool shouldDefuse; BombWireColor wireColor;};
BombDefusionDecision decideBombDefusion(BombCharacteristics bomb){ if (bomb.portrait == Portrait::Lenin) { BombDefusionDecision result{};
// После {} и так false. // result.shouldDefuse = false;
return result; }
// ...
return { .shouldDefuse = true, .wireColor = BombWireColor.Green, };};
int main(){ BombDefusionDecision decision = decideBombDefusion({ ... }); if (decision.shouldDefuse) { std::cout << "Cutting the " << getWireColorString(decision.wireColor) << " wire" << std::endl; }}Это же можно сделать через std::optional.