Эники-беники, или проблему решает морж
Эники-беники, или проблему решает морж
Хотите готовиться со мной к ЕГЭ?
Пишите: 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)
Комментарии
Отправить комментарий