Определите, является ли число в 2017 году сыпучим без простых чисел в исходном коде


41

Из всех тех лет, в которых я принимал участие в этом испытании, 2017 год - это первый год, который стал лучшим номером. Так что вопрос будет о простых числах и их свойствах.

Ваша задача состоит в том, чтобы создать программу или функцию, которая будет принимать произвольно большое положительное целое число в качестве входных данных и выводить или возвращать, независимо от того, является ли число 2,017-хрупким, то есть, равен ли самый большой простой коэффициент в этом числе 2,017 или меньше.


Некоторые примеры входов и их выходов:

1 (has no prime factors)
true

2 (= 2)
true

80 (= 2 x 2 x 2 x 2 x 5)
true

2017 (= 2017)
true

2019 (= 3 x 673)
true

2027 (= 2027)
false

11111 (= 41 x 271)
true

45183 (= 3 x 15061)
false

102349 (= 13 x 7873)
false

999999 (= 3 x 3 x 3 x 7 x 11 x 13 x 37)
true

1234567 (= 127 x 9721)
false

4068289 (= 2017 x 2017)
true

Ваша программа не должна буквально выводить trueи false- любые значения «истина» или «ложь», и фактически любые два разных вывода, которые согласуются между истинными и ложными случаями, хороши.


Тем не менее, вы не можете использовать какие-либо простые числа в вашем исходном коде. Простые числа бывают двух типов:

  • Символы или последовательности символов, представляющие литералы простых чисел.

    • Символы 2, 3, 5и 7являются незаконными в языках , где числа являются допустимыми лексемы.

    • Число 141является незаконным, потому что оно содержит 41, хотя 1и 4в противном случае действительны.

    • Символы Bи D(или bи d) являются недопустимыми в языках, где они обычно используются как 11 и 13, таких как CJam или Befunge.

  • Символы, которые имеют простые значения Unicode или содержат простые байты в их кодировке.

    • Символы %)+/5;=CGIOSYaegkmqявляются недопустимыми в ASCII, а также символ возврата каретки.

    • Символ óнедопустим в UTF-8, потому что 0xb3в нем есть его кодировка . Однако в ISO-8859-1 его кодировка проста 0xf3, что является составной и, следовательно, все в порядке.

Самый короткий код для выполнения вышеуказанного на любом языке выигрывает.


Дополнительное примечание: «рыхлый» является улучшением, принятым по сравнению со старым и неописательным «гладким» в этом контексте.
Грег Мартин

1
Должны ли правдивые и ложные ценности быть последовательными? Или они могут отличаться, если они правдивы или ложны?
Луис Мендо

10
Отсутствие =правил исключает большинство стандартных языков ...
Нил

4
-1 для дел Х без вызова Y. Это действительно довольно тривиально скрыто за довольно ненужным набором ограничений персонажей
Downgoat

1
Мне не нравится, что они были сколь угодно большими. Было бы лучше, если бы они поднялись до 2 ^ 31-1.
Биджан,

Ответы:


37

Желе , 8 байт

44‘²!*ḍ@

Попробуйте онлайн! Обратите внимание, что тестовые случаи 11111 и выше - это слишком много для TIO.

верификация

$ source="34,34,fc,82,21,2a,d5,40"
$ xxd -ps -r > 2017.jelly <<< $source
$ xxd -g 1 2017.jelly
0000000: 34 34 fc 82 21 2a d5 40                          44..!*.@
$ eval printf '"%d "' 0x{$source}; echo # Code points in decimal
52 52 252 130 33 42 213 64
$ test_cases="1 2 80 2017 2019 2027 11111 45183 102349 999999 1234567 4068289"
$ for n in $test_cases; do printf "%11d: %d\n" $n $(jelly f 2017.jelly $n); done
      1: 1
      2: 1
     80: 1
   2017: 1
   2019: 1
   2027: 0
  11111: 1
  45183: 0
 102349: 0

Тестовый пример 999999 работал в течение 13 часов. Я пессимистично отношусь к вычислениям 2025 года! 4068289 ...

Как это работает

44‘²!*ḍ@  Main link. Argument: n

44        Yield 44.
  ‘       Increment to yield 45.
   ²      Square to yield 2025.
          Note that no integers in [2018, ..., 2025] are prime numbers.
    !     Take the factorial of 2025.
     *    Raise it to the n-th power.
          This repeats all prime factors in 2025! at least n times, so the result
          will be divisible by n if (and only if) all of its prime factors fall
          in the range [1, ..., 2025].
      ḍ@  Test the result for divisibility by n.

22
Вы жестоки к числам. :)
Грег Мартин

3
@GregMartin ба. Я видел ответ (на другом языке), где ввод размера 6 будет загружать память в течение нескольких часов, а затем аварийно завершится. Я просто скажу (2^n)!. Это также требует данных шести размеров, но, по крайней мере, входные данные представлены в десятичном алфавите, а не в двоичном.
Джон Дворак

Разве это не 13 байтов? Деннис, у тебя так много репутации, что я уверен, что я здесь ошибаюсь, хахах 😬
Альберт Реншоу

7
@AlbertRenshaw В UTF-8 действительно было бы 13 байт, но Jelly использует пользовательскую кодовую страницу, которая кодирует все символы, которые она понимает, как один байт каждый.
Деннис

3
@ Денис знал, что будет объяснение; очень здорово узнать, спасибо!
Альберт Реншоу

11

Желе , 8 символов, 14 байтов UTF-8

Æf½ṀḤ<90

Попробуйте онлайн!

Jelly обычно использует свою собственную кодовую страницу для программ. Тем не менее, большинство встроенных встроенных функций начинаются с Æкодовой точки 13; не очень полезно К счастью, интерпретатор также поддерживает UTF-8, который имеет более дружественную кодировку.

верификация

Эта программа, в UTF-8, hexdumps, как это:

00000000: c386 66c2 bde1 b980 e1b8 a43c 3930  ..f........<90

Проверка того, что все байты являются составными:

$ for x in c3 86 66 c2 bd e1 b9 80 e1 b8 a4 3c 39 30; do factor $((0x$x)); done
195: 3 5 13
134: 2 67
102: 2 3 17
194: 2 97
189: 3 3 3 7
225: 3 3 5 5
185: 5 37
128: 2 2 2 2 2 2 2
225: 3 3 5 5
184: 2 2 2 23
164: 2 2 41
60: 2 2 3 5
57: 3 19
48: 2 2 2 2 3

Проверка того, что все кодовые точки Unicode являются составными:

$ perl -Mutf8 -E '$a = ord, print `factor $a` for split //, "Æf½ṀḤ<90"'
198: 2 3 3 11
102: 2 3 17
189: 3 3 3 7
7744: 2 2 2 2 2 2 11 11
7716: 2 2 3 643
60: 2 2 3 5
57: 3 19
48: 2 2 2 2 3

Только лексема анализируется как число 90. Ни один из 9, 0и 90не простые.

объяснение

Основное математическое понимание здесь состоит в том, что 45² - это 2025, который аккуратно падает между 2017 (текущий год) и 2027 (следующий штрих). Таким образом, мы можем взять квадратный корень каждого простого множителя числа и посмотреть, превышает ли оно 45. К сожалению, мы не можем писать 45из-за литерала 5, поэтому мы должны удвоить его и сравнить с 90 вместо этого.

Æf½ṀḤ<90
Æf        In the list of prime factors,
  ½       taking the square root of each element
   Ṁ      then taking the largest element
    Ḥ     and doubling it
     <90  produces a result less than 90.

2
Разве Jelly не требует флаг (1 байт) для использования UTF-8?
Луис Мендо

@LuisMendo: интерпретатор командной строки делает, но переводчик в Try It Online! настроен по-другому и не требует этого. Так что это всего лишь случай выбора переводчика, который интерпретирует вашу программу так, как вы хотите. (В любом случае, рассматриваемый флаг uявляется составным, поэтому нужно просто изменить счет, а не что-то, что делает его недействительным.)

10

Mathematica, 62 58 55 байт

Последние три сохраненных байта полностью принадлежат Мартину Эндеру!

#4<4||#<44*46&&#6[#^-1#4]&[Divisors[#][[6-4]],,,#,,#0]&

Безымянная функция, принимающая положительный целочисленный аргумент и возвращающая Trueили False.

Рекурсивный алгоритм, #4<4являющийся истинным базовым случаем (нам нужно только вернуть Trueзначение 1, но с дополнительными базовыми случаями все в порядке). В противном случае мы вычисляем второй наименьший делитель (который обязательно является простым) для ввода с помощью Divisors[#][[6-4]]; если оно больше, чем 2024 ( 44*46), то мы завершаем работу с помощью False, в противном случае мы вызываем функцию рекурсивно (используя #6set to #0) на входе, деленном на этот маленький простой множитель #(который мы должны выразить как #^-1время ввода #4, поскольку /это запрещено).

Конструктивно, первая половина #4<4||#<44*46&&#6[#^-1#4]&является анонимная функция из шести аргументов, вызывается с аргументами Divisors[#][[6-4]], Null, Null, #, Null, и #0; это обойти запрет на персонажах 2, 3и 5.

Предыдущая версия, которая сохранила четыре байта путем замены 8018-6000на 44*46, вдохновлена ответом желе от ais523 (Мартин Эндер также, кажется, был вдохновлен комментарием ais523):

#<4||Divisors[#][[6-4]]<44*46&&#0[Divisors[#][[6-4]]^-1#]&

Это было довольно неприятно: я до сих пор не знаю, как на самом деле установить переменную в Mathematica при таких ограничениях! Как =и eв Setотвергнуты. Избежать +и )было тоже проблемой, но не слишком сложно обойтись за счет большего количества байтов.


Возможно, вы могли бы установить лямбда-параметр, а не переменную. (Тем не менее, #2это также будет запрещено, поэтому вам нужно быть осторожным с тем, как вложены ваши лямбды, и отсутствие скобок может сделать это трудным.)

Реализация предложения @ ais523 сохраняет три байта: #4<4||#<44*46&&#6[#^-1#4]&[Divisors[#][[6-4]],,,#,,#0]&выдает кучу предупреждений, потому что теперь он пытается Divisors[#][[2]]до того, как убедиться, что ввод больше 1 (или 3), но результат по-прежнему правильный.
Мартин Эндер

О, чувак, это чертовски хитро.
Грег Мартин

7

Хаскелл, 48 47 байтов

\n->[snd$[product[1..44*46]^n]!!0`divMod`n]<[1]

В основном перевод Денниса Желе ответ . xnor сохранил байт.

Используется […]!!0в круглых скобках, потому что )это запрещено, и snd+, divModпотому что mв modи remзапрещено.


Хороший трюк с DivMod! Я думаю , вы можете заменить !!0<1с <[1]. Но, похоже, он замкнут для использования в divкачестве [\p n->p^n`div`n*n>p^n-1]!!0$product[1..44*46].
xnor

Там также \n->[0|p<-[product[1..44*46]^n],0<-[p,p-n..0]], который использует, что выходные данные должны только быть последовательными.
xnor

@xnor Не стесняйтесь публиковать их как отдельные ответы, я думаю, что они значительно отличаются от моих ^^
Линн

6

Пайк, 10 8 7 9 байт

P_Z|hwMX<

Попробуй это здесь!

Сохранено 1 байт, используя способ генерации Денниса 2025

P         -     factors(input)
 _        -    reversed(^)
  Z|      -   ^ or 0
    h     -  ^[0] or 1
        < - ^ < V
     wM   -  ⁴45 (ord("M")-32)
       X  -  ^**2

5

Брахилог , 9 10 байт

*$ph$r*<90

Попробуйте онлайн!

В основном использую тот же алгоритм, что и мой другой ответ. $phнаходит первый ( h) простой фактор ( $p); это самый большой главный фактор, поскольку списки главных факторов Брахилога идут от самого большого к наименьшему. Затем я беру квадратный корень ( $r), double ( *) и проверяю, не меньше ли 90 ( <90).

Сначала мне пришлось удвоить ввод, потому что у 1 нет простых факторов (и, следовательно, нет первого простого фактора). Это добавляет дополнительный простой коэффициент 2, который не может повлиять на то, является ли число пригодным для 2017 года, но предотвращает сбой при обработке 1.


5

На самом деле , 9 байтов

τyM:44u²≥

Спасибо Деннису за большое количество байтов!

Попробуйте онлайн!

Объяснение:

τyM:44u²≥
τyM        largest prime factor of 2*input (doubled to deal with edge case of n = 1)
   :44u²   2025 (2027 is the next prime after 2017, so any number in [2017, 2026] can be used here - 2025 is very convenient)
        ≥  is 2025 greater than or equal to largest prime factor?

5

Математика, 66 74 байта

Спасибо Деннису за указание на то, что U+F4A1это запрещено.

Fold[Function[{x,d},And[x,Tr[Divisors@d^0]>6-4||d<44*46]],0<1,Divisors@#]&

Объяснение:

Divisors@#: Список целочисленных делителей первого аргумента # .

0<1: Гольф для True(также избегает использования буквыe ).

Divisors@d^0: Список формы {1, 1, ..., 1}с длиной, равной количеству делителейd .

TrДля плоского списка Trвозвращает сумму этого списка. Таким образом Tr[Divisors@d^0]возвращает число делителейd .

Function[{x,d},And[x,Tr[Divisors@d^0]>6-4||d<44*46]]: Анонимная функция с двумя аргументами xи d. Идея заключается в том, что dэто делитель, #и мы проверяем, является ли он составным или меньше или равен 2017(включительно). 2017хрупкость эквивалентна всем делителям, удовлетворяющим этому условию. Как обнаружил ais523 , простое число меньше или равно 2017эквивалентно простому числу меньше 2025. Как отметил Грег Мартин , достаточно проверить, меньше ли оно 2024=44*46. Аргумент xдействует как накопитель того, удовлетворяют ли все встречающиеся до сих пор делители этому свойству. Мы тогда уехалиFold эту функцию через все делители #с начальным значениемTrue, поскольку у нас нет доступа ни к, Mapни /@.


1
Способ бороться через ограничения!
Грег Мартин

2

05AB1E , 10 байтов

fθ46n99-›È

Возвращает 1, если истина, 0 в противном случае.

Попробуйте онлайн!

объяснение

f          # Push the list of prime factors (ordered)
 θ         # Get the last element
  46n99-   # Push 2017 (46² - 99)
        >  # Push 1 if the last prime factor is greater than 2017, 0 otherwise
         È # Is the resulting number even ? Transforms 1 to 0 and 0 to 1.
           # Implicit display

Добро пожаловать в PPCG!
Мартин Эндер

1

MATL , 15 байт

t:\~ftZp*44QU<A

Выходные данные не 0для 2017 года или 1для 2017 года.

Попробуйте онлайн! Или проверьте все тестовые случаи .

Эта программа проверяет, что все байты являются составными.

объяснение

t       % Implicit input n. Duplicate
:       % Range [1 2 ... n]
\       % Modulo. Gives 0 for divisors of n
~f      % Indices of zero values
t       % Duplicate
Zp      % Is-prime. Gives 1 for primes, 0 for composites
*       % Multiply
44QU    % 44, add 1, square: 2025
<       % Less than, element-wise
A       % True (1) if all entries are nonzero

1

Баш, 144 байта

Кодировка ASCII:

{
printf '[ '
`tr D-Z _-z <<<KFH`tor $1|tr -d :|`tr B-Z _-z <<<JUH`p -o '[0-9]*$'
printf ' -lt $[24*86-46] ]'
}|tr \\n \ |`tr B-Z _-z <<<EDVK`

Как обычно для оболочки, код выхода указывает на успех (0) или сбой (не 0).

Это фактически другое написание

[ factor $1|tr -d :|grep -o '[0-9]*$' -lt 2018 ]

Мы получаем самый большой фактор с factor $1|grep -o '[0-9]*$'; tr -d :является специальным случаем для ввода = 1.

Выражение $[6*6*69-466]оценивается до 2018 года.

Было сложно использовать trдля имен команд и все еще использовать подстановку команд - я не мог использовать форму вложенности $( ), поэтому я закончил тем, что отправил трубку в другой Bash, чтобы оценить результат.

Результаты теста:

$ for i in 1 2 80 2017 2019 2027 11111 45183 102349 999999 1234567 4068289; do printf '%d %s\n' $i `./105241.sh $i  && echo true || echo false`; done
1 true
2 true
80 true
2017 true
2019 true
2027 false
11111 true
45183 false
102349 false
999999 true
1234567 false
4068289 true

Подтверждение кодов символов:

$ grep -v '^#' ./105241.sh | perl -n -Mutf8 -E '$a = ord, print `factor $a` for split //, $_' | grep -v ': .* ' | wc -l
0




0

Braingolf , 11 байт [очень неконкурентный]

VRp#ߢ-?0:1

Попробуйте онлайн!

Не читается из-за ߢ какие винты с числами, однако все еще работает в интерпретаторе.

Я даже не заметил ограничений на символы, когда писал это, но все, что мне нужно было сделать, это изменить странный символ юникода с 2017 года на 2018 год.

Учитывая, что 2018 не простое число, любое простое число <= 2018также<= 2017

объяснение

VRp#ߢ-?0:1  Implicit input from command-line args
VR            Create stack2, return to stack1
  p           Split last item into prime factors, push each one to stack in asc order
   #ߢ         Push 2018
     -      Subtract last 2 items (highest prime factor - 2017)
      ?     If last item > 0..
       0    ..push 1
        :   Else..
         1  ..Push 1
            Implicit output of last item on stack
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.