КИРИЛЛ ТКАЧЕНКО, инженер 1-й категории, ФГАОУ ВО «Севастопольский государственный университет», tkachenkokirillstanislavovich@gmail.com
Программная реализация решения головоломки «Господин S и господин P» по Арсаку в 1С
Предлагается программная реализация головоломки «Господин S и господин P» по Арсаку. Используется язык программирования 1С, рассматривается работа с подпрограммами, циклами, ветвлением, одномерными массивами
Обучению языку программирования 1С посвящено немало публикаций. Особняком стоит подход на основе решения головоломок [1]. Рассмотрим непростую головоломку – «Господин S и господин P» [2]. Она довольно известна, имеет множество программных решений [3, 4]. По этой причине использование языка 1С для построения программы, находящей решение головоломки, выглядит целесообразным.
Головоломка имеет следующее условие. Были выбраны два целых положительных числа, каждое из которых не меньше двух и не больше 99. Значение суммы этих двух целых положительных чисел было сообщено господину S и только ему, значение их произведения – господину P и только ему. В ходе диалога между S и P господин S утверждает, что господин P не знает этих двух чисел. Тогда господин P понимает, что теперь он знает эти два числа. Вслед за ним господину Sтакже становятся ясны значения этих чисел.
Пусть искомые два числа есть А и Б. В соответствии с этим диалогом необходимо породить возможные пары чисел А и Б таким образом, чтобы выполнялись три условия:
- Значение суммы Д + Е невозможно представить в виде суммы некоторых двух простых чисел.
- Значение произведения В * Г имеет единственное представление в виде суммы некоторых двух целых положительных чисел Д + Е, удовлетворяющих условию I.
- Значение суммы А + Б имеет единственное представление в виде произведения двух целых положительных чисел В * Г, удовлетворяющих условию II.
В силу того, что условие III ссылается на II, а II – на I, проверку удобно осуществлять в порядке условий III, II, I.
Программный модуль управляемого приложения начинается с определения переменных ВЕРХ_ГРАН, целочисленной переменной для хранения верхней границы рассмотрения чисел, равной 99, и ПростыеЧисла – целочисленного одномерного массива, в котором будут располагаться простые числа на отрезке от 2 до 99:
Перем ВЕРХ_ГРАН;
Перем ПростыеЧисла;
Процедура Инициализация() производит установку начальных значений переменных. В частности, порождение списка простых чисел. Для построения списка простых чисел хорошо подходит решето Эратосфена [5, 6]. Процедура начинается с определения переменных Решето, в которой будут располагаться отметки о простоте чисел, а также А, Б – счетчики циклов и индексные переменные:
Процедура Инициализация()
Перем Решето;
Перем А, Б;
Верхняя граница рассмотрения чисел равна 99:
ВЕРХ_ГРАН = 99;
Создаются новые массивы Решето и ПростыеЧисла:
Решето = Новый Массив();
ПростыеЧисла = Новый Массив();
Вначале считается, что все числа в решете – простые. Для удобства адресации элементов массива заполнение начинается с нуля:
Для А = 0 По ВЕРХ_ГРАН Цикл
Решето.Добавить(Истина);
КонецЦикла;
Построение решета не относится непосредственно к головоломке, простые числа первой сотни можно задать значениями в программном коде (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97). С первого простого числа, равного 2, по границу рассмотрения кратные числа отмечаются как составные:
Для А = 2 По ВЕРХ_ГРАН Цикл
Если Решето[А] Тогда
Б = А + А;
Происходит увеличение кратного числа на шаг, равный рассматриваемому простому числу:
Пока Б <= ВЕРХ_ГРАН Цикл
Решето[Б] = Ложь;
Б = Б + А;
КонецЦикла;
КонецЕсли;
КонецЦикла;
Значения всех числа, отмеченных как простые, переносятся в массив простых чисел:
Для А = 2 По ВЕРХ_ГРАН Цикл
Если Решето[А] Тогда
ПростыеЧисла.Добавить(А);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция Простое(А) возвращает значение истина, если число А является простым, то есть содержится в массиве ПростыеЧисла:
Функция Простое(А)
Возврат ПростыеЧисла.Найти(А) <> Неопределено;
КонецФункции
Функция УсловиеI(Сум) проверяет условие I для значения Сум. Определяется целочисленная переменная А – слагаемое:
Функция УсловиеI(Сум)
Перем А;
Для всех возможных значений А, когда А может являться слагаемым, проверяется условие простоты для слагаемых суммы Сум. Если оно выполняется, то условие I для Сум не выполняется и возвращается значение Ложь:
Для А = 2 По Цел(Сум / 2) Цикл
Если Простое(А) И Простое(Сум - А) Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
Иначе условие I для Сум выполняется и получаем Истина:
Возврат Истина;
КонецФункции
Функция УсловиеII(Произв) проверяет условие II для значения произведения Произв. Определяются целочисленные переменные А и Б – множители, а также Количество – количество раз, когда выполнялось для текущей проверяемой суммы условие I:
Функция УсловиеII(Произв)
Перем А, Б;
Перем Количество;
Вначале это количество равно 0:
Количество = 0;
Для всех возможных значений первого целочисленного множителя А, если он является множителем, то определяется второй целочисленный множитель Б:
Для А = 2 По Цел(Sqrt(Произв)) Цикл
Если Произв % А = 0 Тогда
Б = Цел(Произв / А);
Если второй множитель Б принадлежит отрезку [2; ВЕРХ_ГРАН] и для суммы А + Б выполняется условие I, то инкрементируется количество выполнения условия I:
Если (2 <= Б) И (Б <= ВЕРХ_ГРАН) И УсловиеI(А + Б) Тогда
Количество = Количество + 1;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Условие II выполняется, когда условие I выполняется единственный раз:
Возврат Количество = 1;
КонецФункции
Функция УсловиеIII(Сум) проверяет условие III для значения суммы Сум. Определяются целочисленные переменные А – слагаемое; НайденноеА – найденное, удовлетворяющее условию II, значение А; Количество – количество найденных значений А:
Функция УсловиеIII(Сум)
Перем А;
Перем НайденноеА;
Перем Количество;
Вначале НайденноеА и Количество равны 0:
НайденноеА = 0;
Количество = 0;
Если для значения суммы Сум выполняется условие I, то для всех допустимых значений слагаемого А:
Если УсловиеI(Сум) Тогда
Для А = 2 По Цел(Сум / 2) Цикл
Если для произведения слагаемых выполняется условие II, то значение слагаемого А считается найденным и инкрементируется количество выполнения условий II:
Если УсловиеII(А * (Сум - А)) Тогда
НайденноеА = А;
Количество = Количество + 1;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если условие II выполняется единственный раз, возвращается найденное значение слагаемого, иначе возвращается 0:
Возврат ?(Количество = 1, НайденноеА, 0);
КонецФункции
Процедура Решение() осуществляет поиск решения головоломки. Целочисленные переменные Сум – рассматриваемая сумма, А – слагаемое по условию III, строковая переменная Рез – отображаемый результат:
Процедура Решение()
Перем Сум;
Перем А;
Перем Рез;
Для возможных значений суммы Сум, если существует слагаемое А, удовлетворяющее условию III, то есть также всем условиям I, II, III, результат – найденная пара целых положительных чисел А и (Сум – А) – сообщается пользователю:
Для Сум = 2 По ВЕРХ_ГРАН Цикл
А = УсловиеIII(Сум);
Если А > 0 Тогда
Рез = "" + А + ", " + (Сум - А);
Сообщить(Рез);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура Главная() производит инициализацию переменных и нахождение решения:
Процедура Главная()
Инициализация();
Решение();
КонецПроцедуры
Происходит вызов главной процедуры:
Главная();
В результате работы программы была получена только одна пара целых положительных чисел – 4 и 13 (см. рис.1).
Рисунок 1. Результат работы программы
Полный текст работы программы находится на сайте журнала http://samag.ru.
Полученная программа нахождения решения головоломки позволит полнее и глубже начинающему разработчику 1С освоить работу с подпрограммами, циклами, ветвлением, одномерными массивами. eof
- Ткаченко К. Программная реализация в 1С варианта головоломки «Песенка спета» по Арсаку. // «Системный администратор», № 4, 2018. – С. 47-49. URL: http://samag.ru/archive/article/3631.
- Арсак Ж. Программирование игр и головоломок / Ж. Арсак. – М.: Наука, 1990. – 224 с.
- Sum and Product Puzzle // Wikipedia. URL: https://en.wikipedia.org/wiki/Sum_and_Product_Puzzle (дата обращения: 22.10.2018).
- Sum and Product Puzzle // Rosetta Code. URL: http://rosettacode.org/wiki/Sum_and_Product_Puzzle (дата обращения: 21.10.2018).
- Перминов О.Н. Программирование на языке Паскаль / О.Н. Перминов. – М.: Радио и связь, 1988. – 224 с.
- Sieve of Eratosthenes // Rosetta Code. URL: http://rosettacode.org/wiki/Sieve_of_Eratosthenes (дата обращения: 07.11.2018).
Ключевые слова: 1С, головоломка, программирование.
Facebook
Мой мир
Вконтакте
Одноклассники
Google+
|