Determine si un número es 2017 friable sin primos en su código fuente

41

De todos los años que llevo haciendo este desafío, 2017 es el primer año que ha sido un número primo. Entonces la pregunta será sobre los números primos y sus propiedades.

Su tarea es producir un programa o función que tome un entero positivo arbitrariamente grande como entrada, y genere o devuelva si el número es 2.017-friable , es decir, si el factor primo más grande en ese número es 2.017 o menos.


Algunos ejemplos de entradas y sus salidas:

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

Su programa no tiene que emitir literalmente truey false- cualquier valor verdadero o falso, y de hecho, dos salidas diferentes que sean consistentes entre los casos verdadero y falso están bien.


Sin embargo, no puede usar ningún primo en su código fuente. Los premios vienen en dos tipos:

  • Caracteres, o secuencias de caracteres, que representan literales de números primos.

    • Los personajes 2, 3, 5, y 7son ilegales en lenguas cuando los números son símbolos válidos.

    • El número 141es ilegal porque contiene 41, aunque sea ​​válido 1y de 4otra manera.

    • Los caracteres By D(o by d) son ilegales en los idiomas en los que generalmente se usan como 11 y 13, como CJam o Befunge.

  • Caracteres que tienen valores Unicode con valores primos o que contienen bytes con valores primos en su codificación.

    • Los caracteres %)+/5;=CGIOSYaegkmqson ilegales en ASCII, así como el carácter de retorno de carro.

    • El carácter óes ilegal en UTF-8 porque tiene su codificación 0xb3. Sin embargo, en ISO-8859-1, su codificación es simple 0xf3, que es compuesta y, por lo tanto, está bien.

El código más corto para hacer lo anterior en cualquier idioma gana.

Joe Z.
fuente
Nota al margen: "friable" es una mejora que se está adoptando sobre el "suave" antiguo y no descriptivo en este contexto.
Greg Martin
1
¿Los valores de verdad y falsedad deben ser consistentes? ¿O pueden variar siempre que sean verdaderos o falsos?
Luis Mendo
10
La falta de =reglas descarta la mayoría de los idiomas estándar ...
Neil
44
-1 para un desafío X sin Y. Es realmente bastante trivial escondido detrás de un conjunto de restricciones de personajes bastante innecesario
Downgoat el
1
No me gusta la parte de que sean arbitrariamente grandes. Sería mejor si subieran a 2 ^ 31-1.
Bijan

Respuestas:

37

Jalea , 8 bytes

44‘²!*ḍ@

Pruébalo en línea! Tenga en cuenta que los casos de prueba 11111 y superiores son demasiado para TIO.

Verificación

$ 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

El caso de prueba 999999 ha estado funcionando durante 13 horas. ¡Soy pesimista sobre la informática 2025! 4068289 ...

Cómo funciona

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.
Dennis
fuente
22
Eres cruel con los números. :)
Greg Martin
3
@GregMartin bah. He visto una respuesta (en un idioma diferente) donde una entrada de tamaño 6 acapararía la memoria durante varias horas y luego se bloquearía. Sólo voy a decir: (2^n)!. Esto también sirve para entradas de seis tamaños, pero al menos las entradas están en un alfabeto decimal en lugar de uno binario.
John Dvorak el
¿No son estos 13 bytes? Dennis, tienes tanta reputación que estoy seguro de que soy yo quien está cometiendo un error aquí jaja. 😬
Albert Renshaw
77
@AlbertRenshaw De hecho, serían 13 bytes en UTF-8, pero Jelly usa una página de códigos personalizada que codifica todos los caracteres que entiende como un solo byte cada uno.
Dennis
3
@ Dennis sabía que habría una explicación; muy bueno para aprender, gracias!
Albert Renshaw
11

Gelatina , 8 caracteres, 14 bytes de UTF-8

Æf½ṀḤ<90

Pruébalo en línea!

Jelly normalmente usa su propia página de códigos para los programas. Sin embargo, la mayoría de sus incorporaciones relacionadas con los principales comienzan con Æ, que es el punto de código 13; No muy útil. Afortunadamente, el intérprete también es compatible con UTF-8, que tiene una codificación más amigable.

Verificación

Este programa, en UTF-8, hexdumps como este:

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

Verificación de que todos los bytes son compuestos:

$ 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

Verificación de que todos los puntos de código Unicode son compuestos:

$ 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

El único token analizado como un número es 90. Ninguno de 9, 0y 90son primos.

Explicación

La idea matemática principal aquí es que 45² es 2025, que cae claramente entre 2017 (el año actual) y 2027 (el próximo primer año). Por lo tanto, podemos sacar la raíz cuadrada de cada factor primo del número y ver si alguno excede 45. Desafortunadamente, no podemos escribir 45debido al literal 5, por lo que tenemos que duplicarlo y compararlo con 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.

fuente
2
¿Jelly no requiere una bandera (1 byte) para usar UTF-8?
Luis Mendo
@LuisMendo: ¡El intérprete de línea de comandos sí, pero el intérprete de Try It Online! está configurado de manera diferente y no lo requiere. Así que este es solo un caso de elegir el intérprete que interpreta su programa de la manera que desee. (En cualquier caso, la bandera en cuestión, ues compuesta, por lo que solo sería una cuestión de cambiar el puntaje en lugar de algo que lo invalide.)
10

Mathematica, 62 58 55 bytes

¡Los últimos tres bytes guardados se deben totalmente a Martin Ender!

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

Función sin nombre que toma un argumento entero positivo y devuelve Trueo False.

Algoritmo recursivo, #4<4siendo el caso base verdadero (solo necesitamos que regrese Truea la entrada 1, pero los casos base adicionales están bien). De lo contrario, calculamos el segundo divisor más pequeño (que es necesariamente primo) de la entrada con Divisors[#][[6-4]]; si es mayor que 2024 ( 44*46), salimos con False, de lo contrario llamamos a la función de forma recursiva (usando #6set to #0) en la entrada dividida por este pequeño factor primo #(que tenemos que expresar como #^-1veces la entrada #4, ya /que no está permitido).

Estructuralmente, la primera parte #4<4||#<44*46&&#6[#^-1#4]&es una función anónima de seis argumentos, siendo llamado con argumentos Divisors[#][[6-4]], Null, Null, #, Null, y #0; esto es para moverse por la prohibición de los personajes 2, 3y 5.

Versión anterior, que ahorró cuatro bytes al reemplazar 8018-6000con 44*46, inspirada en la respuesta Jelly de ais523 (Martin Ender también parecía inspirado por un comentario de ais523):

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

Esto fue bastante desagradable: ¡todavía no sé cómo establecer una variable en Mathematica bajo estas restricciones! Ambos =y los de eadentro Setestán prohibidos. Evitar +y )también fue un problema, pero no demasiado difícil de solucionar a expensas de más bytes.

Greg Martin
fuente
Quizás podría establecer un parámetro lambda en lugar de una variable. (Dicho esto, #2también sería anulado, por lo que tendría que tener cuidado con la forma en anidar sus lambdas, y la falta de paréntesis, podría hacer que difícil.)
La implementación de la sugerencia de @ ais523 ahorra tres bytes: #4<4||#<44*46&&#6[#^-1#4]&[Divisors[#][[6-4]],,,#,,#0]&arroja un montón de advertencias porque ahora lo intenta Divisors[#][[2]]antes de asegurarse de que la entrada sea mayor que 1 (o 3), pero el resultado sigue siendo correcto.
Martin Ender
Oh hombre, eso es astutamente astuto.
Greg Martin el
7

Haskell, 48 47 bytes

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

Básicamente una traducción de la respuesta de Dennis 'Jelly . xnor guardó un byte.

Se usa […]!!0como paréntesis porque )está prohibido y snd+ divModporque está prohibido min mody rem.

Lynn
fuente
Buen truco con el divMod! Creo que puedes reemplazar el !!0<1con <[1]. Pero parece que está en corto para usar divcomo [\p n->p^n`div`n*n>p^n-1]!!0$product[1..44*46].
xnor
También hay \n->[0|p<-[product[1..44*46]^n],0<-[p,p-n..0]]qué usos que las salidas solo necesitan ser consistentes.
xnor
@xnor Siéntase libre de publicarlas como respuestas separadas, creo que son lo suficientemente diferentes de las mías ^^
Lynn
6

Pyke, 10 8 7 9 bytes

P_Z|hwMX<

Pruébalo aquí!

Se guardó 1 byte utilizando la forma de Dennis de generar 2025

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

Brachylog , 9 10 bytes

*$ph$r*<90

Pruébalo en línea!

Básicamente usando el mismo algoritmo que mi otra respuesta. $phencuentra el primer ( h) factor primo ( $p); Este es el factor primo más grande, ya que las listas de factores primos de Brachylog van de mayor a menor. Luego tomo la raíz cuadrada ( $r), doble ( *), y pruebo si es menor que 90 ( <90).

Primero tuve que duplicar la entrada porque 1 no tiene factores primos (y, por lo tanto, no tiene primer factor primo). Esto agrega un factor primo adicional de 2, que no puede afectar si un número es friable en 2017, pero evita una falla al manejar 1.


fuente
5

En realidad , 9 bytes

τyM:44u²≥

¡Gracias a Dennis por muchos bytes!

Pruébalo en línea!

Explicación:

τ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?
Mego
fuente
5

Mathematica, 66 74 bytes

Gracias a Dennis por señalar que U+F4A1está prohibido.

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

Explicación:

Divisors@#: Lista de divisores enteros del primer argumento #.

0<1: Golf para True(también evita el uso de la letra e).

Divisors@d^0: Lista de la forma {1, 1, ..., 1}con longitud igual al número de divisores de d.

Tr: Para una lista plana, Trdevuelve la suma de esa lista. Por lo tanto, Tr[Divisors@d^0]devuelve el número de divisores de d.

Function[{x,d},And[x,Tr[Divisors@d^0]>6-4||d<44*46]]: Función anónima con dos argumentos xy d. La idea es que des un divisor de #y probamos para ver si es compuesto o menor o igual que 2017(inclusive). 2017-friabilidad es equivalente a todos los divisores que satisfacen esta condición. Como ais523 descubrió, ser un primo menor o igual a 2017es equivalente a ser un primo menor que 2025. Como Greg Martin señaló, es suficiente probar si es menor que 2024=44*46. El argumento xactúa como un acumulador para determinar si todos los divisores encontrados hasta ahora satisfacen esta propiedad. Luego dejamos Foldesta función a través de todos los divisores de #con valor inicialTrue, Ya que tenemos acceso ni a Mapni /@.

ngenisis
fuente
1
Manera de luchar a través de las restricciones!
Greg Martin
2

05AB1E , 10 bytes

fθ46n99-›È

Devuelve 1 si es verdadero, 0 de lo contrario.

Pruébalo en línea!

Explicación

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
Kaldo
fuente
Bienvenido a PPCG!
Martin Ender
1

MATL , 15 bytes

t:\~ftZp*44QU<A

Salidas 0para no-2017-friable o 1para 2017-friable.

Pruébalo en línea! O verificar todos los casos de prueba .

Este programa verifica que todos los bytes sean compuestos.

Explicación

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
Luis Mendo
fuente
1

Bash, 144 bytes

Codificación 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`

Como de costumbre para el shell, el código de salida indica éxito (0) o falla (no 0).

Esto es efectivamente una ortografía diferente de

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

Obtenemos el factor más grande con factor $1|grep -o '[0-9]*$'; el tr -d :es un caso especial para input = 1.

La expresión se $[6*6*69-466]evalúa a 2018.

Fue complicado usar trlos nombres de los comandos y aún usar la sustitución de comandos: no pude usar el formulario de anidación $( ), así que terminé conectando con otro Bash para evaluar el resultado.

Resultados de la prueba:

$ 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

Confirmación de códigos de caracteres:

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

Japt , 14 bytes

k æ¨44*46 ?0:1

Devuelve 1 si es verdadero, 0 si es falso.

Probarlo aquí .

Oliver
fuente
ktiene un valor primo
Encarnación de la ignorancia
0

Braingolf , 11 bytes [muy poco competitivo]

VRp#ߢ-?0:1

Pruébalo en línea!

No se puede leer debido a ߢque se atornilla con los números, sin embargo, todavía funciona en un intérprete.

Ni siquiera noté las restricciones de caracteres cuando escribí esto, pero todo lo que tuve que hacer fue cambiar el extraño carácter unicode de 2017 a 2018.

Dado que 2018 no es primo, cualquier primo <= 2018también lo es<= 2017

Explicación

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
Skidsdev
fuente