> 1
> Input
>> 1…2
>> L!
>> L+1
>> L∣2
>> L⋅R
>> 2%L
>> Each 4 3
>> Each 5 9
>> Each 6 10
>> Each 7 11 3
> {0}
>> 12∖13
>> Each 8 14
>> L≠1
>> Each 16 15
>> Each 7 17 15
>> 18∖13
>> [19]
>> 2’
>> 21⋅20
>> Output 22
Попробуйте онлайн!
Это возвращает пустой список для простых чисел Pillai, и непустой список в противном случае.
Как это устроено
Whispers был разработан для манипулирования действительными / комплексными числами, с небольшим количеством команд массива, добавленных для хорошей меры, следовательно, многократное использование Each
для итерации по сгенерированным спискам.
Немного предыстории о Whispers:
Шепот немного отличается по пути выполнения от большинства других языков. Вместо того, чтобы работать по каждой строке линейно, только с ветвлением в условных выражениях, Whispers начинается с последней строки в файле, начинающейся с >
(правила немного сложнее, но это все, что нам нужно знать на данный момент), и значения чисел различаются в зависимости от того, начинается ли строка с >
или >>
.
Если строка начинается с >
, например, > 1
или> Input
, это постоянная строка - она каждый раз возвращает одно и то же значение. Здесь числа представляют их числовую форму, поэтому первая строка всегда будет возвращать 1 при вызове.
Однако, если строка начинается с >>
, числа обрабатываются как ссылки на другие строки, вроде вызовов функций, если хотите. Например, в строке >> 1…2
это не выполняет …
команду для целых чисел 1 и 2 , а скорее для значений, возвращаемых из строк 1 и 2 . В этом случае эти значения являются целым числом 1 и любым целым числом, которое мы передаем в качестве входных данных.
Для этого примера давайте рассмотрим ввод 23 . Имейте в виду, что из-за предварительной обработки Whispers вторая строка ( > Input
) преобразуется в > 23
.
Наша первая команда в строке 3: >> 1…2
. …
является диадическим диапазоном, в данном случае от 1 до 23 , что дает {1, 2, ... 22, 23} . Далее перейдем к строкам с 9 по 12 :
>> Each 4 3
>> Each 5 9
>> Each 6 10
>> Each 7 11 3
Здесь у нас есть 4 последовательных Each
оператора, каждое из которых повторяется по предыдущему результату, по существу отображая 4 команды в массиве в строке 3 : диапазон. Первые три утверждения - это простые карты со строками 4 , 5 и 6 :
>> L!
>> L+1
>> L∣2
Эти три команды над целым числом n дают (n! +1) ∣x , где ! обозначает факториал , ∣ обозначает делимость, а х - вход. Наконец, строка 12 имеет структуру двоичной карты .
Диадическая карта структура занимает три целых числа: цель, левые и право, каждый из индексов других линий. Здесь мы сжимаем влево и вправо, чтобы создать список пар, а затем сокращаем каждую пару с помощью диадической команды (цель). Здесь, если ввод 23 , списки {1, 2, ... 22, 23} и {0, 0, ... 1, 0} и команда
>> L⋅R
который умножает левый аргумент на правый. Это создает массив целых чисел, с 0 по индексам целых чисел, чьи факториалы увеличиваются, не делятся на входы и исходный индекс, где они находятся. Мы будем называть этот массив A . Затем мы удаляем 0 с из A , беря разницу между {0} и A :
> {0}
>> 12∖13
В нашем примере ввода это дает набор {14, 18, 22} . Затем мы берем остаток от входных данных, деленных на каждое значение в наборе, и проверяем, не равен ли этот остаток 1 :
>> 2%L
>> Each 8 14
>> L≠1
>> Each 16 15
Опять же, у нас есть список из 0 или 1 с, и нам нужно удалить 0 с и заменить 1 с исходными значениями. Здесь мы повторяем код, который мы видели выше, но >> 18∖13
вместо 12
. Наконец, мы приводим этот результирующий набор к списку для окончательной проверки. К сожалению, наш код также должен отклонять составные числа, которые соответствуют всем этим критериям, например 437 . Таким образом, мы добавляем нашу последнюю проверку, умножая наш окончательный список на простоту ввода. Из-за того, как умножение Python работает со списками, 0 заменяет его пустым списком, а 1 не имеет никакого эффекта. Таким образом, мы рассчитываем простоту ввода, умножьте это на список мs для ввода и вывода окончательного результата:
>> 2’
>> 21⋅20
>> Output 22