Задание
Принимая в качестве входных данных натуральное число, ваша задача состоит в том, чтобы вывести истинное или ложное значение в зависимости от того, является ли ввод факториалом какого-либо натурального числа. Вы можете предположить, что введенный номер всегда будет в диапазоне номеров, поддерживаемых вашим языком, но вы не должны злоупотреблять типами собственных чисел, чтобы тривиализировать проблему .
Стандартные лазейки применяются.
вход
Вам будет дано натуральное число (типа Integer
или аналогичного).
Вы можете принимать входные данные любым способом, за исключением того, что он входит в предопределенную переменную. Чтение из файла, консоли, диалоговое окно ( prompt
), поле ввода и т.д. допускается. Ввод в качестве аргумента функции также допускается!
Выход
Ваша программа должна выводить истинное или ложное значение в зависимости от того, является ли введенное число факториалом какого-либо натурального числа.
Убедитесь, что ваши значения truey / falsey согласуются для всех входных данных, т. Е. Если вы используете пару 1 и 0 для обозначения значений truey и falsey соответственно, то ваша программа должна вывести 1 для всех входных данных, которые должны иметь истинные значения, и 0 для все входы, которые должны иметь ложные значения.
Вы можете получать вывод любым способом, кроме записи в переменную. Запись в файл, консоль, экран и т. Д. Разрешена. Функция также return
разрешена!
Ваша программа не должна выдавать ошибки для любого ввода!
Тестовые случаи
Input Output
1 Truthy (0! or 1!)
2 Truthy (2!)
3 Falsey
4 Falsey
5 Falsey
6 Truthy (3!)
7 Falsey
8 Falsey
24 Truthy (4!)
120 Truthy (5!)
Критерий победы
Это код-гольф , поэтому выигрывает самый короткий код в байтах!
источник
1
?Ответы:
Брахилог , 1 байт
Попробуйте онлайн!
объяснение
ḟ
является встроенным, который утверждает следующее соотношение: его вывод является факториалом его ввода. Мы просто даем ему заданный вывод и видим, будет ли он успешным с переменным вводом.источник
true.
это утверждение, аtrue
не)Желе , 3 байта
Попробуйте онлайн!
1 для да, 0 для нет.
Как это работает
источник
Желе , 4 байта
Не самый короткий ответ Jelly, но он довольно эффективен.
Попробуйте онлайн!
Как это работает
источник
ECMAScript Regex,
733+690+158119118(117🐌)байтовМой интерес к регулярным выражениям возник с новой силой после более чем 4,5 лет бездействия. Поэтому я отправился на поиски более естественных наборов чисел и функций, которые соответствовали бы унарным регулярным выражениям ECMAScript, возобновил совершенствование своего механизма регулярных выражений и также начал совершенствовать PCRE.
Я очарован чуждостью построения математических функций в регулярном выражении ECMAScript. К проблемам следует подходить с совершенно иной точки зрения, и до момента появления ключевого понимания неизвестно, решаются ли они вообще. Это заставляет создавать гораздо более широкую сеть, чтобы определить, какие математические свойства могут быть использованы для решения конкретной задачи.
Сопоставление факторных чисел было проблемой, которую я даже не рассматривал в 2014 году - или, если бы я сделал, только на мгновение, отклонил бы ее как слишком маловероятную, чтобы быть возможной. Но в прошлом месяце я понял, что это можно сделать.
Как и в других моих статьях по регулярным выражениям ECMA, я дам предупреждение: я настоятельно рекомендую научиться решать унарные математические задачи в регулярных выражениях ECMAScript. Для меня это было увлекательное путешествие, и я не хочу испортить его тем, кто потенциально может попробовать его сами, особенно тем, кто интересуется теорией чисел. См. Этот более ранний пост для списка последовательно рекомендованных спойлером рекомендованных проблем, чтобы решить одну за другой.
Так что не читайте дальше, если вы не хотите, чтобы какая-то продвинутая магия унарных регулярных выражений была испорчена для вас . Если вы действительно хотите сами разобраться в этой магии, я настоятельно рекомендую начать с решения некоторых проблем в регулярном выражении ECMAScript, как описано в этом посте, связанном выше.
Это была моя идея:
После того, как я немного поработал над этим и тем временем создал несколько других регулярных выражений, я решил написать факториальное регулярное выражение. Это заняло несколько часов, но в итоге все заработало. В качестве дополнительного бонуса алгоритм может возвращать обратный факториал как совпадение. Этого даже не избежать; по самой природе того, как это должно быть реализовано в ECMA, необходимо сделать предположение о том, что такое обратный факториал, прежде чем делать что-либо еще.
Недостатком было то, что этот алгоритм был создан для очень длинного регулярного выражения ... но я был рад, что в итоге ему потребовалась методика, используемая в моем регулярном выражении умножения 651 байт (которое оказалось устаревшим, потому что другой метод сделал для 50 байт регулярное выражение). Я надеялся, что возникнет проблема, требующая этого трюка: работа с двумя числами, которые являются степенями одной и той же базы, в цикле, путем однозначного их сложения и разделения на каждой итерации.
Но из-за сложности и длины этого алгоритма я использовал молекулярные взгляды (формы
(?*...)
) для его реализации. Это особенность не в ECMAScript или любом другом распространенном движке регулярных выражений, а та, которую я реализовал в своем движке . Без каких-либо захватов внутри молекулярного обзора он функционально эквивалентен атомному прогнозированию, но с захватами он может быть очень мощным. Движок вернется назад, и это может быть использовано для предположения значения, которое циклически перебирает все возможности (для последующего тестирования) без использования символов ввода. Их использование может сделать реализацию более чистой. (Внешний вид переменной длины по меньшей мере равен по мощности молекулярному взгляду, но последний имеет тенденцию создавать более прямые и элегантные реализации.)Таким образом, длины в 733 и 690 байтов фактически не представляют ECMAScript-совместимые воплощения решения - отсюда и «+» после них; Конечно, возможно перенести этот алгоритм на чистый ECMAScript (который немного увеличит его длину), но я не смог обойти это ... потому что я подумал о гораздо более простом и более компактном алгоритме! Тот, который может быть легко реализован без молекулярных взглядов. Это также значительно быстрее.
Этот новый, как и предыдущий, должен угадать обратный факториал, перебирая все возможности и проверяя их на совпадение. Он делит N на 2, чтобы освободить место для работы, которую он должен выполнить, а затем запускает цикл, в котором он многократно делит входные данные на делитель, который начинается с 3 и увеличивается каждый раз. (Таким образом, 1! И 2! Не могут быть сопоставлены основным алгоритмом, и должны рассматриваться отдельно.) Делитель отслеживается путем добавления его к коэффициенту выполнения; эти два числа могут быть однозначно разделены, потому что, предполагая M! == N, текущий коэффициент будет делиться на M, пока он не станет равен M.
Поэтому мне нравится, что эту проблему удалось снизить до еще меньшей сложности, чем мой регулярный код Фибоначчи, оптимизированный для гольфа , но я вздыхаю с разочарованием, что моей технике мультиплексирования «силы одного и того же основания» придется ждать еще одной проблемы это на самом деле требует этого, потому что это не так. Это история моего 651-байтового алгоритма умножения, замененного 50-байтовым, снова и снова!
Редактировать: мне удалось отбросить 1 байт (119 → 118) с помощью трюка, найденного Грими, который может дополнительно сократить деление в случае, когда коэффициент гарантированно будет больше или равен делителю.
Без дальнейших церемоний, вот регулярное выражение:
Верная / ложная версия (118 байт):
^((x*)x*)(?=\1$)(?=(xxx\2)+$)((?=\2\3*(x(?!\3)xx(x*)))\6(?=\5+$)(?=((x*)(?=\5(\8*$))x)\7*$)x\9(?=x\6\3+$))*\2\3$|^xx?$
Попробуйте онлайн!
Возвращает обратный факториал или несоответствие (124 байта):
^(?=((x*)x*)(?=\1$)(?=(xxx\2)+$)((?=\2\3*(x(?!\3)xx(x*)))\6(?=\5+$)(?=((x*)(?=\5(\8*$))x)\7*$)x\9(?=x\6\3+$))*\2\3$)\3|^xx?$
Попробуйте онлайн!
Возврат обратного факториала или отсутствие совпадения в ECMAScript +
\K
(120 байт):^((x*)x*)(?=\1$)(?=(xxx\2)+$)((?=\2\3*(x(?!\3)xx(x*)))\6(?=\5+$)(?=((x*)(?=\5(\8*$))x)\7*$)x\9(?=x\6\3+$))*\2\K\3$|^xx?$
И свободная версия с комментариями:
Полная история моих оптимизаций по гольфу этих регулярных выражений находится на github:
регулярное выражение для сопоставления факторных чисел - метод сравнения множественности, с молекулярным lookahead.txt
регулярное выражение для сопоставления факториальных чисел ( текст, показанный выше)
((x*)x*)
((x*)+)
((x+)+)
\2
Механизм регулярных выражений .NET не эмулирует это поведение в режиме ECMAScript, и, таким образом, работает 117-байтовое регулярное выражение:
Попробуйте онлайн! (версия с экспоненциальным замедлением, с механизмом регулярных выражений .NET + эмуляция ECMAScript)
источник
JavaScript (ES6),
302928 байтОжидает положительное целое число. Возвращает
-1
за фальшивку и-2
за правдивость.Примечание : эта функция поддерживает довольно большие входные данные (вы должны прочитать это как «довольно большой для JS»). Он должен безопасно работать до 2 53 - 1 . Он наверняка потерпит неудачу, начиная с N = 121 645 100 408 831 992 , этот вход округляется до 19! = 121 645 100 408 832 000 из-за кодировки IEEE-754. Там могут быть и другие ложные положительные результаты до 121,645,100,408,831,991 из - за ошибок округления, но я не знаю точно.
источник
~
в конце.Python 3 ,
3938 байтРекурсивная функция , принимающая целое число,
n
, возвращая логическое значение , представляющее inversley результата (truthy:False
, falsey:True
)Попробуйте онлайн!
Неоднократно делится
n
наi
, с начальным значением1
, до тех пор, пока остаток не станет меньше или равен, а1
затем проверяет, будет ли этот остаток меньше1
, только факториалы будут заканчиваться остатком, равным1
, и<
на байт короче, чем==
.источник
1
для всех факториалов, за исключением1
которых оно возвращаетсяTrue
.Java 8, 46 байт
Это основано на записи Романа Грефа, с которой я смог выбить дюжину или около того байтов. Я бы предложил это там, но у меня пока недостаточно репутации, чтобы комментировать! Мой модифицированный код бегуна:
источник
Retina ,
5038 байт12 байтов сохранены благодаря @Neil, объединяя сокращение цикла и избавляясь от
;
Попробуйте онлайн!
Выходы
1
для истины и0
ложного..+
соответствует всему числу1¶$&$*
заменив его1
следующим символом перевода строки и соответствиемОставшаяся программа делит унарное число в нижней строке путем последовательного увеличения натуральных чисел, отслеживая в верхней строке, в то время как это возможно.
+`
цикл, пока строка не останется прежней^(1+)¶(\1)+$
сопоставьте верхнюю строку многие1
s и кратные ей многие1
s в нижней строке и замените ее на1$1¶$#2$*
в верхней строке много1
s с другим1
, то есть увеличивается число, представленное верхней строкой, на 1, за которым следует новая строка и количество совпадений верхней строки в нижней строке (т. е. количество совпадений второй группы захвата) ) многие1
s, то есть деление нижнего числа на верхнее числоКак только это уже невозможно сделать,
¶.$
дать количество совпадений этого регулярного выражения, т.е. существует ли единица1
в нижней строке, что происходит, только если число является факториаломЕсли вместо значений «истина / ложь» разрешено без сбоев / сбоев, тогда я могу получить
3634 байта.Это идет по тому же подходу, но объединяет
$*
в третью и четвертую строчки. Третья строка и далее является частью того же цикла,{
сокращенно,+(
где(
группируются оставшиеся строки в цикле. Факториалы заканчиваются выходом программы из цикла, в то время как нефакториалы застревают в цикле до тех пор, пока Retina не сгенерирует исключение OverflowException, вызванное неудачной последней заменой, в результате чего дно будет в унарном, а не в десятичном виде, и в первой замене цикла преобразует нижнюю строку из десятичной в одинарную, поэтому она быстро взрывается.источник
1
как это подразумевается, когда$*
в конце замены.$*
две другие строки.05AB1E , 4 байта
Попробуйте онлайн!
объяснение
источник
L
выдает его ввод? Кроме того,Å!
выдает список факториалов, меньших или равных входным данным.D
здесь не нужно . Хорошо пойматьÅ!
. Я всегда забываю о списке команд. Это не спасет ни одного байта, но наверняка будет более эффективным.C ++,
10210092 байтаПеребирает все значения от
0
доn
и вычисляет факториал, а затем проверяет, равно ли оноn
.Спасибо Кристоф! (сохранено 8 байт)
источник
int a(int n){int i=n,j=0;for(;i;)j|=lround(exp(lgamma(i--+1)))==n;return j;}
.lround
иlgamma
уже C ++ 11, так что может просто#include<cmath>
. Может быть, вы можете еще больше улучшить мои предложения :)Haskell ,
4326 байтовПопробуйте онлайн!
источник
f n=elem n$scanl1(*)[1..n]
смешно неэффективно, но короче.40430
без заметной задержки.divMod
по[1..]
порядку, пока не достигну нулевого остатка с коэффициентом 1 (факториал) или ненулевым остатком (не факториал), но, похоже, это не правильный подход. Я нашел это симпатичное решение из 46 символов, хотя:f|let x%n=mod n x==0&&(x+1)%div n x||n==1=(1%)
.Haskell , 38 байт
Попробуйте онлайн! Пример использования:
(2#) 24
. ВозвращаетTrue
илиFalse
.Это самое короткое, что я мог получить, оставаясь при этом очень эффективным. Даже для таких больших чисел, как
результат сразу дается. Решение работает путем деления входного
n
пути ,m = 2,3,4,5,...
пока либо результат не представляет собой один илиn
не делится наm
.Для более короткого, но невероятно неэффективного 26-байтового решения, которое вычисляет
n!
входные данные, которые не являются факториалами, смотрите здесь .источник
MATL , 5 байтов
Попробуйте онлайн!
объяснение
источник
Фурье ,
4039 байтПопробуйте это на FourIDE!
В основном умножает число N на увеличивающуюся величину до тех пор, пока N не станет равным (выход 1) или больше (выход 0) входа.
Пояснение псевдокод:
источник
Japt ,
86 байтПопробуйте онлайн!
Это выводит 0 для false и 1 для true.
объяснение
источник
aU ¦J
чтобыx¥U
(сопоставьте каждыйX
кX==U
и сумма), хотя это не будет работать на TIO.2
потому чтоo
даст только вам[0,1]
. Вот исправление с сохранением 1 байта.Perl 5, 31 байт
Ввод осуществляется через STDIN, выход - через код выхода (1 для факториала, 0 для нефакториала).
Входные данные делятся на последовательные целые числа до тех пор, пока они не станут равны 1 или некоторой доле меньше единицы, что усечено в результате.
источник
Perl 6 , 29 байт
Попробуй это
Expanded:
источник
{$_∈[\*] 1..$_}
. Еще один интересный подход2>*.polymod(1..*).sum
.setlX , 32 байта
Создает функцию под названием
f
которой вы используете свой потенциальный факториал в качестве параметра.Это работает с произвольным целочисленным размером, но это довольно неэффективно.
(кстати: это мое первое участие в программировании)
источник
C (gcc), 33 байта
Обратите внимание, что некоторые авторы определяют «натуральное число» как положительное целое число. Поэтому мне все равно, что
f(0)
вызывает бесконечную рекурсию.источник
R ,
2822 байтаПопробуйте онлайн!
источник
C # (.NET Core) , 68 байт
Попробуйте онлайн!
Не самое короткое решение, но работает с действительно большими числами. Ссылка TIO включает в себя пример с
10000!
.Вот более короткая версия, которая использует
int
максимальное значение 2147483647 .C # (.NET Core) , 45 байт
Попробуйте онлайн!
Благодарим @KevinCruijssen за игру в гольф по 3 байта в обоих ответах!
источник
&&
Может быть golfed , чтобы&
и тянущийся;
не должен учитываться для функций лямбды. Кроме того, не можетulong k=2
бытьuint k=2
в вашем 50-байтовом ответе?&
против&&
. Я думал, что получаю переполнение стека, но это, кажется, работает в конце концов.ulong
64 бит, аuint
32. Похоже, что другие используют,int
так что, возможно, я просто буду использовать это для короткой версии. Что касается трейлинга;
, это полные функции, а не лямбды, так что я думаю, что мне нужно их включить?/
и%
междуulong
иuint
, но неulong
иint
. Не знал этого :)double
вы начинаете видеть округление в какой-то момент - например, 24! и 120! провал. ХотяSystem.Numerics.BigInteger
имеет большую точность,int
это самый короткий ответ :)&&
оператор короткого замыкания , Но это код гольфа;) Рад, что вам нравится10000!
пример!C ++ (лязг), 51 байт
Рекурсия выигрывает, если играть в гольф.
51 байт, ноль - это правда:
int f(int n,int i=2){return n<2?!n:n%i|f(n/i,i+1);}
Это жертвует довольно большой скоростью за 1 байт экономии. Заменить
|
с ,||
чтобы сделать это быстро, из - за оценки короткого замыкания логического ИЛИ.Попробуйте онлайн! (Медленная версия 51 байт)
Попробуйте онлайн! (52 байт, быстрая версия)
Ungolfed медленная версия:
Ungolfed быстрая версия:
Есть много способов изменить это.
52 байта, ненулевое значение true:
int f(int n,int i=2){return n<2?n:n%i?0:f(n/i,i+1);}
Попробуйте онлайн!
52 байта, ноль - это правда:
int f(int n,int i=2){return!n?1:n%i?n-1:f(n/i,i+1);}
Попробуйте онлайн!
Прежде чем прибегнуть к рекурсии, я попытался сделать несколько итерационных версий, и они подошли близко.
54 байта, ненулевое значение true:
int f(int n){for(int i=2;n>1;)n=n%i?0:n/i++;return n;}
Попробуйте онлайн!
54 байта, ноль - истина (основано на представлении Романа Грефа Java 8 ):
int f(int n){int a=1,i=0;for(;a<n;a*=++i);return a-n;}
Попробуйте онлайн!
Теперь, для дна ствола, рекурсивные версии без
n==0
обработки (я считаю их недействительными, потому что 0 - натуральное число, и любое определение, в котором оно не используется, для «натуральных чисел» очень ограниченного использования). В следующих версиях бесконечная рекурсияf(0)
запускает segfault из-за переполнения стека, или с помощью компиляторов, которые оптимизируют его для итерации, зацикливается бесконечно:48 байтов, ноль - это правда:
int f(int n,int i=2){return n%i?n-1:f(n/i,i+1);}
Попробуйте онлайн!
48 байтов, ноль - истина (на основе 33-байтового представления Хагена фон Эйтцена C (gcc) ):
int f(int n,int e=0){return n%++e?n-1:f(n/e,e);}
Попробуйте онлайн!
источник
Mathematica, 20 байтов
другая версия для проверки больших чисел (см. комментарии)
тесты до 1000!
источник
Range[#]
наRange@#
:)!Range@#!~FreeQ~#&
.Cubix , 24 байта
Попробуйте онлайн
Cubified
Начнем с нажатия
1
,I
nput,1
на стек. Это будет наш индекс, наша цель и наш аккумулятор, соответственно.Затем мы зациклимся. На каждой итерации мы вычитаем аккумулятор из входных данных. Если результат равен 0, мы закончили, поэтому мы нажимаем
1
, выполняем и завершаем работуO
. Если оно отрицательное, мы зашли слишком далеко, поэтому мы нажимаем0
,O
выводим и выходим. В противном случае мы видимисточник
Нейм , 8 байт
Объяснение:
Попытайся!
Neim , 3 байта (не конкурирует)
Неконкурентные, так как токен содержимого и факториальный токен были добавлены после вызова.
Объяснение:
Попытайся!
источник
> <> ,
2422 байта-2 байта благодаря @ Аарону
Я пробую новый язык (так как моя лицензия на Mathematica истекла ...)
Попробуйте онлайн или на рыбной площадке
Предполагается, что входной номер уже находится в стеке и возвращает 0 или 1. Он работает, умножая вместе первые n чисел до тех пор, пока они не перестанут быть меньше, чем ввод, а затем печати 1, если он равен входу, и 0, если он не ' т.
источник
v>\n<^
в\\n/
; смотрите здесьAPL (Dyalog Unicode) , 5
67байтGolfed байт путем изменения
×/
в!
благодаря Эрику OutgolferПопробуйте онлайн!
объяснение
источник
N∊×\⍳N←⎕
Как это принять аргумент? Яn
нигде не вижу . Это специфичная для Dyalog вещь?(⊢∊(×/⍳)) right_argument
как вы видите по ссылке TIO. И⊢
относится к правильному аргументу.⊢∊×\ä⍳
, «Правильное» (но более длинное) решение было бы0=1|!⍣¯1
; "Является ли обратный факториал целым числом?"JavaScript (ES6), 71 байт
Это принимает входные данные в качестве аргумента функции и
alert
выводит их. Выходы0
для фальси и1
правды.объяснение
Программа состоит из двух функций
f
иg
.f
является рекурсивной факториально-вычислительной функцией иg
является основной функцией программы.g
предполагает наличие единственного аргументаn
. Он определяет аргумент по умолчаниюr
со значением 0 и другой аргумент по умолчанию со значением0
. Затем он перебирает все целые числа от 0 доn
и на каждой итерации проверяет, равна ли функция,f
примененная надi
(текущий индекс)n
, т. Е.n
Является ли факториал изi
. Если это случается так,r
значение «s устанавливается равным 1. В конце функции,r
являетсяalert
ред.Тестовый фрагмент
( Примечание . Фрагменты выводятся с использованием,
console.log()
как никто не любит слишком много этих надоедливыхalert()
s. )источник
QBIC ,
2119 байтовобъяснение
предварительно
Объяснение:
источник
Java 8, 59 байт
Testcode
источник