Короткий пост, просто хотел поделиться одним изящным открытием, которое я сделал сегодня ранее. Для тех из вас, у кого большой опыт работы с Wolfram Mathematica, это может быть старая шляпа.
Но для тех из вас, кто иногда играет с функциональным программированием с помощью Wolfram Alpha, Scastie или чего-то еще, что вы используете для экспериментов с функциональным программированием, это может быть откровением.
В Wolfram Mathematica есть понятие чистые функции. С некоторыми оговорками вы можете использовать чистые функции в Wolfram Alpha. Фактически, перейдите прямо сейчас на Wolfram Alpha и введите это:
Select[Prime[Range[100]], PrimeQ[3# + 4] &]
Вероятно, это то, что вы бы набрали, если вам интересно, какие простые числа p также дают простые числа для 3 p + 4. Например, 5 является таким простым числом, так как 3 × 5 + 4 = 19. Напротив, мы видим, что 7 не такое простое число, поскольку 3 × 7 + 4 = 25 = 5².
Wolfram Alpha дает правильный ответ на приведенное выше утверждение Wolfram Mathematica: 3, 5, 11, 13, 19 и т. Д. И т. Д. На 541, которое оказывается сотым простым числом.
Итак, Range[100]
просто дает нам целые числа от 1 до 100, а Prime[Range[100]]
дает нам простые числа, проиндексированные целыми числами от 1 до 100, то есть 2, 3, 5, 7, 11, 13, 17, 19 и так далее до 541.
Затем Select
сообщает Mathematica, что мы хотим, чтобы она выбрала из этого списка элементы, которые возвращают True
для заданного логического значения, в данном случае PrimeQ[3# + 4] &
.
#
«вытягивает» число из списка, умножает его на 3 и добавляет 4 (вы можете написать 3 * # + 4
, если хотите). Чтобы система Mathematica знала, что мы вызываем чистую функцию, нам нужно поставить &
перед закрывающей фигурной скобкой Select
.
Что, если вы хотите повторить 3 x + 4 несколько раз, начиная с x = 3 и передав результат в следующий x? В Mathematica вы можете использовать NestList
. Это также будет работать в Wolfram Alpha:
NestList[3# + 4 &, 3, 20]
#
здесь сначала обозначает начальный x, а затем предыдущие 3 x + 4, которые становятся новым x. И снова нам нужно &
, чтобы система Mathematica знала, что мы вызываем чистую функцию. Затем запятая и наш начальный аргумент, в данном случае 3. И после этого 20 означает, что мы хотим повторить это двадцать раз.
Результат: 3, 13, 43, 133, 403, 1213, 3643 и т. Д. Эти числа быстро становятся большими, хотя нам не нужно беспокоиться о переполнении 32- или 64-битного целочисленного примитива.
Как видите, некоторые из этих чисел, например 13 и 43, простые, другие - составные, например 133 = 7 × 19.
Это может заставить нас задуматься: существуют ли простые числа p такие, что мы можем повторить 3 x + 4 четыре раза и получить только простые числа?
Мы могли создать логическую функцию и использовать ее в Select
, что-то вроде
specNumberQ[n_] := (Union[PrimeQ[NestList[3# + 4 &, n, 4]]] == {True});
Это кажется неэлегантным. Даже если мы не сохраним блокнот Mathematica, будет напрасно называть эту функцию, которую мы, возможно, никогда больше не будем использовать.
Должен быть способ использовать две чистые функции в одной строке (это нормально, если строка переносится по длине), одну для NestList
, другую для Select
.
Я не буду утомлять вас списком всех неправильных вещей, которые я пробовал. Я хочу убедиться, что вы понимаете, что это решение, такое простое и элегантное, было не первым, что я пробовал, и даже не вторым или третьим:
Select[Prime[Range[1000]], Union[PrimeQ[NestList[(3# + 4 &), #, 4]]] == {True} &]
Обратите внимание, что 3# + 4 &
заключен в круглые скобки. Таким образом, я сообщаю Mathematica, что объем итерации чистой функции ограничен первым аргументом NestList
, что позволяет Mathematica понять, что следующий #
означает число из Prime[Range[1000]]
.
Однако это не будет работать в Wolfram Alpha. «Wolfram | Alpha не понимает ваш запрос». Ну что ж.
В любом случае, в системе Mathematica этот запрос дает только один результат: 3203. Мы проверяем, что 9613, 28843, 86533 и 259603 - все простые числа, но 778813 = 7 × 31 × 37 × 97. Если мы увеличим 1000 в Range
, скажем, 10000, мы могли бы получить больше цифр.
Что еще более важно, если вам когда-нибудь понадобится использовать две чистые функции в одной строке в Mathematica, теперь вы знаете, как это сделать: используйте круглые скобки.
На самом деле, как оказалось, по крайней мере, для этого конкретного примера скобки не нужны. Только что я подтвердил, что
Select[Prime[Range[1000]], Union[PrimeQ[NestList[3# + 4 &, #, 4]]] == {True} &]
дает правильный результат. При правильном размещении амперсандов Mathematica правильно поймет, откуда берется аргумент для каждой чистой функции.
Я надеюсь, что вы получите от этого какую-то пользу или, по крайней мере, думаете, что это может быть вам полезно в будущем.