Задание №12 — Анализ строковых алгоритмов
Исполнитель Редактор получает на вход строку цифр и преобразовывает её. Редактор может выполнять две команды, в обеих командах v и w обозначают цепочки цифр.
А) заменить (v, w).
Эта команда заменяет в строке первое слева вхождение цепочки v на цепочку w. Например, выполнение команды заменить (111, 27) преобразует строку 05111150 в строку 05217150. Если в строке нет вхождений цепочки v, то выполнение команды заменить (v, w) не меняет эту строку.
Б) нашлось (v).
Эта команда проверяет, встречается ли цепочка v в строке исполнителя Редактор. Если она встречается, то команда возвращает логическое значение «истина», в противном случае возвращает значение «ложь». Строка исполнителя при этом не изменяется.
Цикл
ПОКА условие
последовательность команд
КОНЕЦ ПОКА
выполняется, пока условие истинно.
В конструкции
ЕСЛИ условие
ТО команда 1
ИНАЧЕ команда 2
КОНЕЦ ЕСЛИ
выполняется команда 1 (если условие истинно) или команда 2 (если условие ложно).
Дана программа для Редактора:
НАЧАЛО
ПОКА нашлось (12) ИЛИ нашлось (3322) ИЛИ нашлось (2222)
ЕСЛИ нашлось (12)
ТО заменить (12, 33)
КОНЕЦ ЕСЛИ
ЕСЛИ нашлось {2222)
ТО заменить (2222, 1)
КОНЕЦ ЕСЛИ
ЕСЛИ нашлось (3322)
ТО заменить (3322, 21)
КОНЕЦ ЕСЛИ
КОНЕЦ ПОКА
КОНЕЦ
На вход приведённой выше программе поступает строка, начиная с цифры «1», а затем содержащая n цифр «2» (3 < n < 10000). Определите наименьшее значение n, при котором сумма цифр в строке, получившейся в результате выполнения программы, равна 218.
Правильный ответ
177
Пояснение
Решение:
Команда заменить(v, w) — это s.replace(v, w, 1) (меняется только первое слева вхождение), команда нашлось(v) — это проверка v in s. Значит исполнителя можно точно смоделировать на Python.
Обратите внимание на порядок команд внутри цикла: три конструкции ЕСЛИ выполняются подряд, поэтому за один проход тела цикла может произойти до трёх замен. Аналитической формулы для суммы цифр здесь нет, зато условие позволяет просто перебрать все допустимые : для каждого моделируем работу Редактора и считаем сумму цифр итоговой строки.
def zamenit(s, v, w):
return s.replace(v, w, 1) # первое слева вхождение
def rabota(s):
while "12" in s or "3322" in s or "2222" in s:
if "12" in s:
s = zamenit(s, "12", "33")
if "2222" in s:
s = zamenit(s, "2222", "1")
if "3322" in s:
s = zamenit(s, "3322", "21")
return s
for n in range(4, 10000):
s = rabota("1" + "2" * n)
if sum(int(c) for c in s) == 218:
print(n, s)
break
# 177 333...3332
Первое подходящее значение — : программа превращает строку в 72 тройки и одну двойку, сумма цифр равна .
Ответ: 177