Гадалка угадает число

Думаешь, твои мысли скрыты? Наша мистическая гадалка угадает число, которое ты загадашь! Проверь интуицию и удивись магии прямо сейчас.

Тема «Гадалка угадает число» часто встречается в учебных курсах по программированию, на форумах о Python и в конкурсах по алгоритмике. Суть проста: пользователь задумывает целое число в известном диапазоне, а программа (или «гадалка») определяет его, задавая минимум вопросов. В этой статье мы разберём, как построить такую гадалку, какие алгоритмы используют для минимального количества попыток, и покажем готовый пример на Python.


Содержание

  1. Что такое «гадалка» в программировании?
  2. Математическая модель задачи
  3. Бинарный поиск – оптимальная стратегия
  4. Реализация на Python
  5. Вариации: магический квадрат, деление диапазона, адаптивные стратегии
  6. Тестирование и отладка

Что такое «гадалка» в программировании?

Термин «гадалка» (англ. guessing game) в контексте программирования обозначает интерактивное приложение, которое пытается определить заранее неизвестное значение, опираясь только на ответы пользователя. Чаще всего речь идёт о числах, но аналогичные задачи решаются для слов, цветов, фигур и т.д.

Ключевые требования к гадалке:

  • Работать в заранее заданном диапазоне (например, от 1 до 100).
  • Определять число за минимальное количество вопросов.
  • Вести диалог с пользователем, предоставляя понятные подсказки.

Почему «гадалка» интересна?

  • Позволяет познакомиться с алгоритмами поиска (бинарный поиск, интервальный поиск).
  • Учит писать интерактивный ввод‑вывод в консольных приложениях.
  • Служит отличной базой для изучения тестирования и обработки ошибок.

Математическая модель задачи

Пусть пользователь загадывает целое число n из диапазона [L, R] (включительно). Программа может задавать один из трёх вопросов:

  1. «Ваше число больше k?»,
  2. «Ваше число меньше k?»,
  3. «Ваше число равно k?».

Ответы «да»/«нет» (или «больше», «меньше», «равно») позволяют сузить диапазон. В идеальном случае каждый вопрос делит текущий диапазон пополам – тогда количество вопросов q удовлетворяет условию:

2q ≥ (R‑L+1)

Отсюда получаем минимальное количество шагов:

q = ⌈log₂(R‑L+1)⌉

Для диапазона 1…100 это ⌈log₂100⌉ = 7 вопросов.


Бинарный поиск – оптимальная стратегия

Самый простой и эффективный способ реализовать «деление пополам» – использовать бинарный поиск. Алгоритм:

  1. Установить left = L, right = R;
  2. Пока left ≤ right:
    1. Вычислить среднее: mid = (left + right) // 2.
    2. Спросить пользователя: «Ваше число больше mid?».
      Если ответ «да», установить left = mid + 1.
      Если ответ «нет», спросить «Ваше число меньше mid?».
      • Если «да», установить right = mid ‒ 1.
      • Если «нет», значит mid – загаданное число, вывести результат и завершить.

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


Реализация на Python

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

#!/usr/bin/env python3

"""
Гадалка угадает число, задуманное пользователем.
Диапазон: от 0 до 1000 (включительно).
Алгоритм – бинарный поиск, минимальное количество вопросов.
"""

def ask(question: str) -> str:
 answer = input(question + " (y/n): ").strip.lower
 while answer not in ("y", "n"):
 answer = input("Пожалуйста, введите 'y' (yes) или 'n' (no): ").strip.lower
 return answer
def guess_number(left: int = 0, right: int = 1000) -> None:
 attempts = 0
 print(f"Загадайте целое число от {left} до {right}. Я попытаюсь его угадать.")
 while left <= right:
 attempts += 1
 mid = (left + right) // 2
 # 1) Больше?
 if ask(f"Ваше число больше {mid}?") == "y":
 left = mid + 1
 continue
 # 2) Меньше?
 if ask(f"Ваше число меньше {mid}?") == "y":
 right = mid ‒ 1
 continue
 # Если ответ «нет» на оба вопроса – значит ровно mid
 print(f"
Я угадал! Ваше число – {mid}.")
 print(f"Потребовалось попыток: {attempts}")
 return
 # Если цикл завершился без совпадения (корректность ввода нарушена)
 print("
Что‑то пошло не так: диапазон исчерпан. Проверьте свои ответы.")

if __name__ == "__main__":
 guess_number

Что делает код?

  • Функция ask гарантирует, что пользователь вводит только y (yes) или n (no).
  • Переменные left и right хранят текущие границы диапазона.
  • Внутри цикла вычисляется mid – середина диапазона.
  • Последовательно задаются два вопроса: «больше?» и «меньше?». Если оба ответа «нет», значит mid – загаданное число.
  • Счётчик attempts фиксирует количество сделанных вопросов.

Запустив программу, пользователь получит диалог, похожий на:

Загадайте целое число от 0 до 1000. Я попытаюсь его угадать.
Ваше число больше 500? (y/n): n
Ваше число меньше 500? (y/n): y
...
Я угадал! Ваше число – 317.
Потребовалось попыток: 7

Вариации и альтернативные подходы

Магический квадрат

Один из интересных способов «угадывать» числа – использовать магический квадрат. В нём числа располагаются так, что суммы по строкам, столбцам и диагоналям одинаковы. При правильном построении пользователь может «выбрать» ячейку, а система по её координатам быстро вычисляет задуманное число. Однако такой метод требует предварительного построения таблицы и удобен лишь для небольших диапазонов (до 9×9).

Деление диапазона не пополам, а по «правилу 3‑х»

Если хочется уменьшить количество вопросов за счёт более «интеллектуального» деления, можно задавать не один, а два сравнения одновременно:

  1. Выбираем две границы a и b (например, 1/3 и 2/3 от текущего диапазона).
  2. Спросить: «Ваше число ≤ a?», «Ваше число ≤ b?». По двум ответам получаем три поддиапазона, каждый в среднем в 1/3 от исходного.

Теоретически это даёт ⌈log₃(N)⌉ шагов, но в реальности из‑за необходимости задавать два вопроса за один «раунд» сложность интерфейса возрастает.

Адаптивные стратегии с учётом вероятностных предположений

Если известна априорная вероятность (например, пользователь чаще загадывает числа ближе к середине), можно использовать информационную энтропию и выбирать точку разделения, минимизирующую ожидаемое количество вопросов. Это уже выходит за рамки простых учебных примеров, но иллюстрирует связь задачи с теорией информации.


Тестирование и отладка

Для уверенности в корректности гадалки рекомендуется написать автоматические тесты. Ниже показан простой подход с использованием unittest и имитации ввода через io.StringIO:

import unittest
from unittest.mock import patch
import io

class TestGuessNumber(unittest.TestCase):
 def simulate(self, secret, left=0, right=100):
 # Генерируем последовательность ответов «y/n» для бинарного поиска
 answers = []
 l, r = left, right
 while l <= r:
 mid = (l + r) // 2
 if secret > mid:
 answers.append('y') # больше
 answers.append('n') # не меньше
 l = mid + 1
 elif secret < mid:
 answers.append('n') # не больше
 answers.append('y') # меньше
 r = mid ⎼ 1
 else:
 answers.append('n')
 answers.append('n')
 break
 return '\n'.join(answers) + '\n'

 @patch('sys.stdout', new_callable=io.StringIO)
 def test_random_numbers(self, mock_stdout):
 for secret in [0, 1, 50, 99, 100]:
 user_input = self;simulate(secret)
 with patch('sys.stdin', new=io.StringIO(user_input)):
 from guess_game import guess_number # предполагаем, что код в guess_game.py
 guess_number(0, 100)
 output = mock_stdout.getvalue
 self.assertIn(f'Ваше число – {secret}', output)

if __name__ == '__main__':
 unittest.main

Тест генерирует ответы «y/n» автоматически, имитируя поведение реального пользователя, и проверяет, что программа корректно выводит задуманное число.


«Гадалка угадает число» – классический учебный пример, который одновременно знакомит с:

  • Алгоритмами бинарного поиска и их теоретическим минимумом.
  • Практикой написания интерактивных консольных приложений.
  • Тестированием пользовательского ввода.
  • Различными вариациями (магический квадрат, деление на три, вероятностные подходы).

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

Помните: главное – задавать вопросы, которые максимально «разрезают» пространство вариантов. И тогда ваша гадалка действительно будет угадывать числа за минимальное количество попыток!


Дата публикации: 28 апреля 2026 г.