Эники-беники, или проблему решает морж

 Эники-беники, или проблему решает морж

 

Хотите готовиться со мной к ЕГЭ?
Пишите:
ydkras@mail.ru
Немного обо мне. 

 

"Если вы можете решить задачу - это упражнение.
Если нет - то это проблема."
Ричард Беллман

 

 ...Ученики бывают разные. Не знаю, как другим, но лично мне больше нравятся такие, которые думают сами и заставляют думать меня. 

Недавно одна ученица (из тех, что мне нравятся) сказала, что у нее трудности с задачей. Задача следующая: программа на Питоне сначала вводит строчку с именами детей (Аня, Боря, Вова, Галя, Дима и т.д.) Предполагается, что дети стали в круг и с помощью считалки выбирают, кому водить. Вторая строчка - как раз считалка. Программа должна напечатать имя того, кому водить. Я удивился: в чем проблема-то? Сделаем из первой строчки список имен, подсчитаем количество слов во второй строчке и напечатаем элемент списка имен с индексом (n-1)%k, где n - количество слов в считалке, а k - количество детей. Ученица сказала: проблема в том, что программа должна состоять из одной строчки

М-да. Хорошо, я могу использовать в выражении конструкцию input().split() и получить список имен. Следующий оператор input() введет строчку со считалкой, конструкция len(input().split()) даст мне число слов в считалке. Но как мне получить число слов в списке имен, чтобы определить индекс водящего? Для этого надо как-то вернуться назад, к списку имен.

Моё предложение написать в одной строке два оператора Питона, разделив их точкой с запятой, было с негодованием отвергнуто. 

Сгоряча я назвал задачу садизмом в особо изощренной форме. Но... Если рассуждать логически, то вряд ли ученикам предложат проблему, не имеющую решения. Значит, нужное средство должно существовать. И оно нашлось.

Оказывается, в Питоне 3.8 есть два оператора присваивания. С первым знаком любой, кто написал на нём хоть одну программу чуть посложнее, чем print('Hello, world'). Второй же специально предназначен для использования внутри выражений и обозначается комбинацией символов ":=", столь хорошо знакомой паскалистам (и ещё не вымершим знатокам алгола-60). Жаргонное название этого оператора - "моржовый оператор". Гуглите, а кому лень, дам пару ссылок. Во-первых, "Моржовый оператор в Питон". Во-вторых, "Инструкции присваивания в Питон"  (см. примеры 8 и 9 в конце статьи).

Приведу решение задачи:

print((names:=input().split())[(len(input().split())-1)%len(names)])

Моржовый оператор names:=input().split() создает список имен и сохраняет его в переменной names. Круглые скобки, в которые он заключен, необходимы: без них переменной names будет присвоен не весь список, а лишь один его элемент. При вычислении индекса используется длина этого списка. 

Моржовый оператор помог решить и другую задачу: найти сумму всех целых чисел от 1 до n. Число n вводится с клавиатуры и может быть и отрицательным. Разумеется, и тут требовалось решить задачу в одну строчку.

Данная сумма - арфиметическая прогрессия. Формула суммы арифметической прогрессии хорошо известна: (a+b)*n/2, где a и b - крайние члены прогрессии, а n - число членов. 

В нашем случае крайние члены - это 1 и n, а число членов дает выражение abs(n-1)+1. Приведу решение без дальнейших комментариев:

print((1+(n:=int(input())))*(abs(n-1)+1)//2)


Комментарии

Популярные сообщения из этого блога

Задача 9 (Excel) в 2023 г.

Питон и таблицы истинности

Задача 1 ЕГЭ по информатике - решаем на Питоне