Перейти к содержимому

6. Логические выражения

Занятие 8. Логика: И, ИЛИ, НЕ — и Задание 2

Цель занятия: обучающиеся вычисляют логические выражения через таблицу истинности и сдают Задание 2.

Разминка-вспоминание (5 мин)

  1. Как определить чётность отрицательного числа надёжно?
  2. Первое действие с датчиком освещённости на новом месте? (интервальный возврат: занятие 3)
  3. Какие варианты пар карточек разыгрываются жеребьёвкой в Задании 2?

Разбор (worked example): полное решение Задания 2 регламента — 30 баллов

Условие (Приложение 1). Датчик вертикально, 0,5–1 см над столом. Жеребьёвка задаёт пару карточек (Ч-Ч, Ч-Б, Б-Ч, Б-Б); белая = 1, чёрная = 0. По команде судьи: ввести карточкой A, по кнопке вывести (5 б.); ввести карточкой B, по кнопке вывести (5 б.); по кнопке вывести значение (B И A) ИЛИ НЕ A (5 б.). Две проверки с разными парами, между ними перезапуск разрешён. Итого 30.

Сначала — таблица истинности на бумаге

ABB И AНЕ A(B И A) ИЛИ НЕ A
00011
01011
10000
11101

Проверка себя алгеброй: (B∧A)∨¬A = B∨¬A — выражение ложно только при A=1, B=0. Таблица, посчитанная до сдачи, — ваш контроль судейского результата: услышали вариант жеребьёвки — уже знаете ответ.

Эталонный код (C++, ESP32)

#include "stend.h"
#include <algorithm>

int reflMedian(int n = 5) {
  int v[9];
  for (int i = 0; i < n; i++) v[i] = reflection();
  std::sort(v, v + n);
  return v[n / 2];
}

void waitPress(Btn b = BTN_R) {      // ждать нажатие И отпускание — иначе одно нажатие сработает дважды
  while (!pressed(b)) delay(10);
  while (pressed(b))  delay(10);
}

void show(int v) {
  Serial.println(v);
  screen(String(v));
}

int readCard(int porog, const char* imya) {
  Serial.printf("Карточка %s → правая кнопка\n", imya);
  waitPress();
  int v = reflMedian() > porog ? 1 : 0;
  show(v);                                 // вывод введённого значения = 5 баллов
  return v;
}

void setup() {
  Serial.begin(115200);
  stendBegin();
  // Калибровка на месте (левая кнопка подтверждает каждую карточку)
  Serial.println("Калибровка: белая → левая кнопка");  waitPress(BTN_L);
  int w = reflMedian();
  Serial.println("Калибровка: чёрная → левая кнопка"); waitPress(BTN_L);
  int b = reflMedian();
  int porog = (w + b) / 2;
  Serial.printf("POROG = %d\n", porog);

  int a  = readCard(porog, "A");           // 5 баллов
  int bb = readCard(porog, "B");           // 5 баллов
  waitPress();
  bool rez = (bb && a) || !a;              // (B И A) ИЛИ НЕ A
  show(rez ? 1 : 0);                       // 5 баллов; формат 0/1 — как вводили
}

void loop() {}

Разбор: калибровка на левой кнопке, ввод на правой — судья видит две разные процедуры и не путает их; bb вместо b — имя b уже занято чёрным калибровочным значением (классический баг «переменная перезаписана»); в C++ выражение (bb && a) || !a даёт bool — выводим явно 0 или 1, чтобы формат совпал с форматом ввода; вторая проверка — просто перезапуск программы, это разрешено условием.

Приоритет логических операций: НЕ → И → ИЛИ. В (B И A) ИЛИ НЕ A скобки вокруг «НЕ A» не нужны, но ставьте их всегда — на турнире выражение дня может быть другим, а ошибка приоритета не видна глазами. Универсальный метод под любое выражение дня: выписать таблицу истинности на 4 строки, закодировать выражение со скобками, прогнать все 4 комбинации карточек дома у судьи-партнёра.

Практика

Прогнать все 4 варианта жеребьёвки

Партнёр-судья разыгрывает Ч-Ч, Ч-Б, Б-Ч, Б-Б; результат сверяется с таблицей истинности. 4 из 4.

Контрольная точка: сдача Задания 2

Наставник-судья, две проверки с разными парами, полный протокол. Цель — 30/30.

Чужое выражение

Партнёр придумывает выражение из А, В, И, ИЛИ, НЕ (пример компетенции 6.1: (А ИЛИ В) И НЕ А). Таблица на бумаге → правка одной строки кода → прогон 4 вариантов.

Типичные ошибки.

  1. Переменная калибровки перезаписала переменную ввода (b) — результат «случайно» верен в части вариантов и незаметен без полного прогона 4 комбинаций.
  2. Вывод True при вводе 0/1 — судья вправе спросить соответствие; держите один формат от ввода до результата.
  3. Кодирование выражения «на слух» без таблицы — при A=0 ошибку не видно (ответ 1 в обеих строках), она всплывает только на A=1, B=0.
  4. Пропущенная калибровка на месте сдачи — свет зала другой, оба ввода читаются как 1.

Мини-проверка выхода

Задание 2 сдано на 30/30; блиц: «при каком единственном наборе (A, B) выражение дня ложно и почему?»

Уровни сложности