N-movers: ¿Cuánto de la placa infinita puedo alcanzar?


48

Movimientos individuales

El tablero es una cuadrícula cuadrada infinita de 2 dimensiones, como un tablero de ajedrez ilimitado. Una pieza con valor N (un N-mover ) puede moverse a cualquier cuadrado que esté a una distancia exactamente de la raíz cuadrada de N desde su cuadrado actual (distancia euclidiana medida de centro a centro).

Por ejemplo:

  • Un 1-mover puede moverse a cualquier casilla que esté adyacente horizontal o verticalmente
  • Un motor de 2 movimientos puede moverse a cualquier casilla que esté diagonalmente adyacente
  • Un jugador de 5 movimientos se mueve como un caballero de ajedrez

Tenga en cuenta que no todos los N-motores pueden moverse. Un jugador de 3 movimientos nunca puede abandonar su casilla actual porque ninguna de las casillas del tablero está a una distancia exactamente de la raíz 3 de la casilla actual.

Movimientos múltiples

Si se les permite moverse repetidamente, algunas piezas pueden alcanzar cualquier casilla en el tablero. Por ejemplo, un motor 1 y un motor 5 pueden hacer esto. Un motor de 2 movimientos solo puede moverse en diagonal y solo puede alcanzar la mitad de los cuadrados. Una pieza que no puede moverse, como un 3-mover, no puede alcanzar ninguno de los cuadrados (el cuadrado inicial no se cuenta como "alcanzado" si no se produce ningún movimiento) .

1 motor 2 motores 3 motores 4 motores 5 motores 8 motores 9 motores 10 motores 20 motores 25 motores 40 motores 64 motores 65 motores 68-mover

Las imágenes muestran qué cuadrados se pueden alcanzar. Más detalles sobre el vuelo estacionario. Haga clic para ampliar la imagen.

  • Los cuadrados accesibles en 1 o más movimientos están marcados en negro
  • Los cuadrados accesibles en exactamente 1 movimiento se muestran con piezas rojas
    (aparte del 3-mover, que no puede moverse)

¿Qué proporción del tablero puede alcanzar un determinado N-mover?

Entrada

  • Un entero positivo N

Salida

  • La proporción de la placa que puede alcanzar un N-mover
  • Este es un número del 0 al 1 (ambos incluidos)
  • Para este desafío, se permite la salida como fracción en términos más bajos, como 1/4,

Entonces, para la entrada 10, ambas 1/2y 0.5son salidas aceptables. La salida como numerador y denominador separados también es aceptable, ya que incluye idiomas que no admiten flotantes ni fracciones. Por ejemplo, 1 2o [1, 2].

Para las salidas enteras (0 y 1), cualquiera de los siguientes son formatos aceptables:

  • Para 0: 0, 0.0, 0/1, 0 1,[0, 1]
  • para 1: 1, 1.0, 1/1, 1 1,[1, 1]

Puntuación

Este es el código de golf. La puntuación es la longitud del código en bytes. Para cada idioma, gana el código más corto.

Casos de prueba

En el formato input : output as fraction : output as decimal

  1 : 1     : 1
  2 : 1/2   : 0.5
  3 : 0     : 0
  4 : 1/4   : 0.25
  5 : 1     : 1
  6 : 0     : 0
  7 : 0     : 0
  8 : 1/8   : 0.125
  9 : 1/9   : 0.1111111111111111111111111111
 10 : 1/2   : 0.5
 13 : 1     : 1
 16 : 1/16  : 0.0625
 18 : 1/18  : 0.05555555555555555555555555556
 20 : 1/4   : 0.25
 25 : 1     : 1
 26 : 1/2   : 0.5
 64 : 1/64  : 0.015625
 65 : 1     : 1
 72 : 1/72  : 0.01388888888888888888888888889
 73 : 1     : 1
 74 : 1/2   : 0.5
 80 : 1/16  : 0.0625
 81 : 1/81  : 0.01234567901234567901234567901
 82 : 1/2   : 0.5
144 : 1/144 : 0.006944444444444444444444444444
145 : 1     : 1
146 : 1/2   : 0.5
148 : 1/4   : 0.25
153 : 1/9   : 0.1111111111111111111111111111
160 : 1/32  : 0.03125
161 : 0     : 0
162 : 1/162 : 0.006172839506172839506172839506
163 : 0     : 0
164 : 1/4   : 0.25
241 : 1     : 1
242 : 1/242 : 0.004132231404958677685950413223
244 : 1/4   : 0.25
245 : 1/49  : 0.02040816326530612244897959184
260 : 1/4   : 0.25
261 : 1/9   : 0.1111111111111111111111111111
288 : 1/288 : 0.003472222222222222222222222222
290 : 1/2   : 0.5
292 : 1/4   : 0.25
293 : 1     : 1
324 : 1/324 : 0.003086419753086419753086419753
325 : 1     : 1
326 : 0     : 0
360 : 1/72  : 0.01388888888888888888888888889
361 : 1/361 : 0.002770083102493074792243767313
362 : 1/2   : 0.5
369 : 1/9   : 0.1111111111111111111111111111
370 : 1/2   : 0.5
449 : 1     : 1
450 : 1/18  : 0.05555555555555555555555555556
488 : 1/8   : 0.125
489 : 0     : 0
490 : 1/98  : 0.01020408163265306122448979592
520 : 1/8   : 0.125
521 : 1     : 1
522 : 1/18  : 0.05555555555555555555555555556
544 : 1/32  : 0.03125
548 : 1/4   : 0.25
549 : 1/9   : 0.1111111111111111111111111111
584 : 1/8   : 0.125
585 : 1/9   : 0.1111111111111111111111111111
586 : 1/2   : 0.5
592 : 1/16  : 0.0625
593 : 1     : 1
596 : 1/4   : 0.25
605 : 1/121 : 0.008264462809917355371900826446
610 : 1/2   : 0.5
611 : 0     : 0
612 : 1/36  : 0.02777777777777777777777777778
613 : 1     : 1
624 : 0     : 0
625 : 1     : 1

10
Publiqué esta pregunta en Math.SE: math.stackexchange.com/questions/3108324/…
infmagic2047

¡Conjetura interesante!
Trichoplax

1
"Una pieza que no puede moverse, como un 3-mover, no puede alcanzar ninguno de los cuadrados". Curiosamente, incluso si cuenta el cuadrado inicial, ya que el tablero es infinito, aún converge a 0 como proporción.
Beefster

@Beefster buen punto. Seguí este camino para hacer que el límite sea más fácil de encontrar sin tener que ir hasta el infinito ...
trichoplax

2
La pregunta math.se de @ infmagic2047 sobre el enfoque de factorización principal ahora tiene una respuesta con una prueba completa .
Ørjan Johansen

Respuestas:


19

JavaScript (Node.js) , 144 138 125 74 73 70 bytes

f=(x,n=2,c=0)=>x%n?x-!c?f(x,n+1)/(n%4>2?n/=~c&1:n%4)**c:1:f(x/n,n,c+1)

Pruébalo en línea!

-4 byte gracias @Arnauld!

Enfoque original, 125 bytes

a=>(F=(x,n=2)=>n*n>x?[x,0]:x%n?F(x,n+1):[n,...F(x/n,n)])(a).map(y=>r-y?(z*=[,1,.5,p%2?0:1/r][r%4]**p,r=y,p=1):p++,z=r=p=1)&&z

Pruébalo en línea!

Inspirado en el video Pi escondido en las principales regularidades de 3Blue1Brown.

Para cada factor primo en la factorización del número, calcule :pnf(pn)

  • Si es impar y - . Porque no hay lugar a donde ir.np3 (mod 4)f(pn)=0
  • Si es par y - .np3 (mod 4)f(pn)=1pn
  • Si - .p=2f(2n)=12n
  • Si - .p1 (mod 4)f(pn)=1

Multiplica todos los valores de las funciones, ahí estamos.

Actualizar

Gracias al esfuerzo de los colaboradores de Math.SE, el algoritmo ahora está respaldado por una prueba


¿El video contiene una prueba? He estado tratando de probar este resultado durante unas horas, pero no pude resolverlo.
infmagic2047

1
@ infmagic2047 En realidad no, pero ofrece un método para contar el número de puntos en un círculo . Esto es útil cuando se trata de cómo puede funcionar el n-mover. n
Shieru Asakoto

3
@ infmagic2047 Creo que es trivial probar los casos para pero los casos para los restantes son bastante difíciles de probar formalmente ...q=pPp{2,3} (mod 4)pep
Shieru Asakoto

1
La pregunta math.se de @ infmagic2047 sobre este enfoque ahora tiene una respuesta con una prueba completa .
Ørjan Johansen

11

Mathematica, 80 bytes

d[n_]:=If[#=={},0,1/Det@LatticeReduce@#]&@Select[Tuples[Range[-n,n],2],#.#==n&];

Este código depende principalmente de un teorema matemático. La idea básica es que el código solicita la densidad de una red dada un conjunto generador.

Más precisamente, se nos da una colección de vectores, es decir, aquellos cuya longitud al cuadrado es N, y se nos pide que calculen la densidad del conjunto de posibles sumas de estos vectores, en comparación con todos los vectores enteros. La matemática en juego es que siempre podemos encontrar dos vectores (y sus opuestos) que "generan" (es decir, cuyas sumas son) el mismo conjunto que la colección original. LatticeReduce hace exactamente eso.

Si tiene solo dos vectores, puede imaginarse dibujando un paralelogramo idéntico centrado en cada punto alcanzable, pero cuyas longitudes de borde son los vectores dados, de modo que el plano esté completamente en mosaico por estos paralelogramos. (Imagine, por ejemplo, una red de formas de "diamante" para n = 2). El área de cada paralelogramo es el determinante de los dos vectores generadores. La proporción deseada del plano es el recíproco de esta área, ya que cada paralelogramo tiene solo un punto alcanzable.

El código es una implementación bastante sencilla: genera los vectores, usa LatticeReduce, toma el determinante, luego toma el recíproco. (Sin embargo, probablemente se pueda jugar mejor al golf)


76 bytes:d@n_:=Boole[#!={}]/Det@LatticeReduce@#&@Select[Range[-n,n]~Tuples~2,#.#==n&]
u54112

11

Limpias , 189 185 172 171 bytes

import StdEnv
$n#r=[~n..n]
#p=[[x,y]\\x<-r,y<-r|x^2+y^2==n]
=sum[1.0\\_<-iter n(\q=removeDup[k\\[a,b]<-[[0,0]:p],[u,v]<-q,k<-[[a+u,b+v]]|all(\e=n>=e&&e>0)k])p]/toReal(n^2)

Pruébalo en línea!

Encuentra cada posición accesible en el ncuadrado de la longitud del lado arrinconado en el origen en el primer cuadrante, luego se divide n^2para obtener la porción de todas las celdas alcanzables.

Esto funciona porque:

  • Todo el plano alcanzable puede considerarse como copias superpuestas de este ncuadrado de longitud lateral, cada una arrinconada en un punto accesible desde el origen como si fuera el origen.
  • Todos los movimientos vienen en grupos de cuatro con signos ++ +- -+ --, lo que permite que el mosaico superpuesto se extienda a través de los otros tres cuadrantes mediante reflejo y rotación.

Mis disculpas: estaba mirando los casos de prueba que van de N = 10 a N = 13, mientras que sus casos de prueba incluyen N = 11 y N = 12 también. De hecho, tienes razón para N = 13. +1 de mi parte :)
trichoplax

1
@trichoplax He cambiado las pruebas para que se correspondan con la pregunta para evitar la misma confusión de nuevo
horrible

He probado más hasta N = 145 y todos son correctos. Sin embargo, no pude probar 146 en TIO debido al tiempo de espera de 60 segundos. Estoy esperando algunos tiempos muy largos en las respuestas aquí ...
trichoplax

1
Como me tomé un tiempo para darme cuenta de esto: la razón por la cual las esquinas cuadradas son accesibles si hay al menos un movimiento (a, b), es la ecuación compleja (a + bi) (a-bi) = a ^ 2 + b ^ 2, que en forma vectorial se convierte en (N, 0) = a (a, b) + b (b, -a).
Ørjan Johansen

5

Retina 0.8.2 , 126 82 bytes

.+
$*
+`^(1(1111)+)(?<!^\3+(11+))(\1)*$
1$#4$*
^(?!((^1|11\2)+)\1?$)1+
0
11+
1/$.&

Pruébalo en línea! El enlace incluye casos de prueba. Explicación:

.+
$*

Convierte a unario.

+`^(1(1111)+)(?<!^\3+(11+))(\1)*$
1$#4$*

Divide repetidamente por factores primos de la forma 4k+1.

^(?!((^1|11\2)+)\1?$)1+
0

Si el resultado no es un cuadrado ni dos veces un cuadrado, entonces el resultado es cero.

11+
1/$.&

Calcule el recíproco como una fracción decimal.


5

Regex (ECMAScript, fuera recíproco), 256 163 157 94 83 82 bytes

-93 bytes gracias a Neil
-6 bytes gracias nuevamente a Neil
-63 bytes haciendo la división sin capturar el divisor
-11 bytes gracias a la división simultánea opcional de Grimy- byte de raíz cuadrada y
-1 byte moviendo la condición de finalización y la captura de valor de retorno en el bucle como una segunda alternativa, gracias a Grimy

Utiliza las mismas matemáticas que la respuesta de JavaScript de Shieru Asakoto .

La entrada está en unario. Dado que una expresión regular pura solo puede devolver como salida una subcadena de la entrada (es decir, un número natural menor o igual a la entrada), o "sin coincidencia", esta expresión regular devuelve el recíproco de la proporción de la placa que un N-mover puedo alcanzar. Como el recíproco de 0 es infinito, en ese caso devuelve "no match".

ADVERTENCIA DE SPOILER : Para la raíz cuadrada, esta expresión regular utiliza una variante del algoritmo de multiplicación generalizado, que no es obvio y podría ser un rompecabezas gratificante para resolver por su cuenta. Para obtener más información, consulte una explicación de esta forma del algoritmo en Buscar un número Rocco .

Esta expresión regular primero entra en un ciclo que identifica todos los factores primos tales que , y divide el número de entrada por cada uno tantas veces como sea posible. Sea el resultado final de esto. Entonces, indirectamente a prueba para ver si la factorización prima de (y por tanto también el número de entrada) incluye cualquier primos elevado a una potencia impar, mediante el ensayo para ver si o es un cuadrado perfecto. Si no, entonces sí incluyó una prima tan elevada a una potencia extraña, y la expresión regular devuelve "no coincidencia"; de lo contrario, devuelve .pp1 (mod 4)mm3 (mod 4)mm/2mm

(Ahora es un poco más complicado que eso. Debido a la optimización de golf en la versión recíproca-producto, que pone a prueba no sólo y por ser un cuadrado, pero también el resultado intermedio antes de la división de cada , si el la primera prueba falla. Esto no cambia el resultado final, porque si la primera prueba cuadrada perfecta falla, al menos una potencia impar de un primo todavía estará presente en el número en cada paso, y no puede ser un cuadrado.)mm/2p3 (mod 4)

^(?=((?=(x+)(?!(\2+)(\2\3)+$)((\2{4})+$))\5|((xx?)(\8*))(?=(\7*)\9+$)\7*$\10)+$)\1

Pruébalo en línea!
Pruébalo en línea! (solo los casos de prueba)

^
(?=
    (                          # Capture return value, which will just be the value
                               # matched by the last iteration of this loop.
    # Divide tail by every one of its prime factors that's ≡1 mod 4, as many times as
    # possible.
        (?=
            (x+)               # \2 = quotient
            (?!(\2+)(\2\3)+$)  # Assert divisor is prime
            ((\2{4})+$)        # Assert divisor ≡1 mod 4; \5 = tool to make tail = \2
        )\5                    # tail = \2
    |
    # When the above alternative has been done as many times as possible:
    # Test if tail or tail/2 is a perfect square. If this test fails, the regex engine
    # will backtrack into the division loop above, and run the same perfect square
    # test on every previous number (effectively "multiplying" it by each previous P
    # in reverse, one at a time). This will not cause a failure of the test to change
    # into a success, however, because the odd power of a prime ≡3 mod 4 will see be
    # present in the number at every step. Allowing this backtracking to happen is a
    # golf optimization, and it does make the regex slower.
    # Failure of this perfect square test results in returning "no match" and indicates
    # a return value of zero.
        (                      # \7 = \8 * sqrt(tail / \8)
            (xx?)              # \8 = control whether to take sqrt(tail)
                               #                         or 2*sqrt(tail/2)
            (\8*)              # \9 = \7 - \8
        )
        (?=
            (\7*)\9+$          # Iff \8 * (\7 / \8)^2 == our number, then the first match
                               # here must result in \10==0
        )
        \7*$\10                # Test for divisibility by \7 and for \10==0
                               # simultaneously
    )+
    $                          # Require that the last iteration of the above loop was
                               # the perfect square test. Since the first alternative,
                               # the division, always leaves >=1 in tail, this guarantees
                               # that the last step is a successful perfect square test,
                               # or else the result will be "no match".
)
\1                             # Return value (which is a reciprocal)

Expresiones regulares (ECMAScript + (? *), Recíproco de salida), 207 138 132 bytes

Obsoleado haciendo división sin capturar el divisor (es decir, ahora es idéntico al anterior).

Regex (ECMAScript 2018, salida recíproca), 212 140 134 bytes

Obsoleado haciendo división sin capturar el divisor (es decir, ahora es idéntico al anterior).

Regex (ECMAScript, salida de fracción), 80 bytes

En esta versión, el numerador se devuelve en \10(cero si no está configurado / NPCG) y el denominador en \7.

A diferencia de la versión de salida recíproca:

  • Una entrada de cero no se trata correctamente (devuelve "no match" al igual que esa versión, pero a diferencia de ella, eso no corresponde a un valor de salida de cero).
  • Si la prueba del cuadrado perfecto falla, no retrocede en el ciclo de división, por lo que esta versión es más eficiente en tiempo de ejecución.

La gran desventaja de una especificación de salida como esta es que no está contenida en el programa en sí.

((?=(x+)(?!(\2+)(\2\3)+$)((\2{4})+$))\5)*((((x)x?)(\9*))(?=(\8*)\11+$)\8*$\12|x)

Pruébalo en línea!
Pruébalo en línea! (solo los casos de prueba)

# No need to anchor, since we return a match for all inputs in the domain.
# Divide tail by every one of its prime factors that's ≡1 mod 4
(
    (?=
        (x+)               # \2 = quotient
        (?!(\2+)(\2\3)+$)  # Assert divisor is prime
        ((\2{4})+$)        # Assert divisor ≡1 mod 4; \5 = tool to make tail = \2
    )\5                    # tail = \2
)*
# Test if tail or tail/2 is a perfect square. If this test succeeds, return tail as
# the denominator and 1 as the numerator.
(                          # \7 = denominator output
    (                      # \8 = \9 * sqrt(tail / \9)
        ((x)x?)            # \9 = control whether to take sqrt(tail) or 2*sqrt(tail/2);
                           # \10 = numerator output (NPCG to represent zero)
        (\9*)              # \11 = \8 - \9
    )
    (?=
        (\8*)\11+$         # Iff \9 * (\8 / \9)^2 == our number, then the first match
                           # here must result in \12==0
    )
    \8*$\12                # Test for divisibility by \8 and for \12==0
                           # simultaneously
|
# Failure of the perfect square test results in returning 0/1 as the answer, so here
# we return a denominator of 1.
    x
)

1
Lo siento, obviamente no lo había probado en suficientes casos de prueba.
Neil

1
@trichoplax ¿Podría considerar la respuesta como la relación de longitudes de dos grupos de captura específicos? (Esto realmente acortaría la respuesta, ya que toma la molestia de hacer que todo el resultado sea el resultado).
Neil,

1
Siguiendo el comentario de @ Neil, he editado para permitir la salida como numerador y denominador separados, ya que parece el cambio más pequeño que permite la expresión regular pura. Avíseme si eso sigue siendo un problema
trichoplax

1
-11 bytes usando (((xx?)(\9*))(?=(\8*)\10+$)\8*$\11)para verificar si N o N / 2 es un cuadrado.
Grimmy

1
Los punteros de @Deadcode a los backrefs no deberían tener un costo de bytes, ya que están permitidos por defecto .
Grimmy

4

Jalea ,  25  24 bytes

ÆFµ%4,2CḄ:3+2Ịị,*/ʋ÷*/)P

Un enlace monádico que usa la ruta del factor primo.

Pruébalo en línea!

¿Cómo?

ÆFµ%4,2CḄ:3+2Ịị,*/ʋ÷*/)P - Link: integer, n               e.g. 11250
ÆF                       - prime factor, exponent pairs        [[2,1], [3,2], [5,4]]
  µ                   )  - for each pair [F,E]:
    4,2                  -   literal list [4,2]
   %                     -   modulo (vectorises)                [2,1]  [3,0]  [1,0]
       C                 -   complement (1-x)                  [-1,0] [-2,1]  [0,1]
        Ḅ                -   from base 2                         -2     -3      1      
         :3              -   integer divide by three             -1     -1      0
           +2            -   add two (call this v)                1      1      3
                  ʋ      -   last four links as a dyad, f(v, [F,E])
             Ị           -     insignificant? (abs(x)<=1 ? 1 : 0)   1      1      0
                */       -     reduce by exponentiation (i.e. F^E)  2      9     625
               ,         -     pair v with that                   [1,2]  [1,9]  [3,625]
              ị          -     left (Ị) index into right (that)     1      1     625
                    */   -   reduce by exponentiation (i.e. F^E)    2      9     625
                   ÷     -   divide                                1/2    1/9  625/625
                       P - product                                 1/18 = 0.05555555555555555

Los 25 anteriores fueron:

ŒRp`²S⁼ɗƇ⁸+€`Ẏ;Ɗ%³QƊÐLL÷²

Programa completo forzador bruto ; posiblemente un código más largo que la ruta del factor primo (podría intentarlo más tarde).

Pruébalo en línea!

Comienza creando movimientos individuales como coordenadas y luego se mueve repetidamente desde todas las ubicaciones alcanzadas acumulando los resultados, tomando el módulo nde cada coordenada (para restringir a un npor ncuadrante) y manteniendo aquellos que son distintos hasta que se alcanza un punto fijo; entonces finalmente divide la cuenta porn^2


4

05AB1E , 27 26 25 bytes

ÓεNØ©<iozë®4%D≠iyÈ®ymz*]P

Puerto de la respuesta de JavaScript de @ShieruAsakoto , ¡así que asegúrese de votarlo también!

Pruébelo en línea o verifique todos los casos de prueba .

Explicación:

Ó                   # Get all prime exponent's of the (implicit) input's prime factorization
                    #  i.e. 6 → [1,1]      (6 → 2**1 * 3**1)
                    #  i.e. 18 → [1,2]     (18 → 2**1 * 3**2)
                    #  i.e. 20 → [2,0,1]   (20 → 2**2 * 3**0 * 5**1)
                    #  i.e. 25 → [0,0,2]   (25 → 2**0 * 3**0 * 5**2)
 ε                  # Map each value `n` to:
  NØ                #  Get the prime `p` at the map-index
                    #   i.e. map-index=0,1,2,3,4,5 → 2,3,5,7,11,13
    ©               #  Store it in the register (without popping)
     <i             #  If `p` is exactly 2:
       oz           #   Calculate 1/(2**`n`)
                    #    i.e. `n`=0,1,2 → 1,0.5,0.25
      ë             #  Else:
       ®4%          #   Calculate `p` modulo-4
                    #    i.e. `p`=3,5,7,11,13 → 3,1,3,3,1
          D         #   Duplicate the result (the 1 if the following check is falsey)
           i       #   If `p` modulo-4 is NOT 1 (in which case it is 3):
             yÈ     #    Check if `n` is even (1 if truthy; 0 if falsey)
                    #     i.e. `n`=0,1,2,3,4 → 1,0,1,0,1
             ®ymz   #    Calculate 1/(`p`**`n`)
                    #     i.e. `p`=3 & `n`=2 → 0.1111111111111111 (1/9)
                    #     i.e. `p`=7 & `n`=1 → 0.14285714285714285 (1/7)
              *     #    Multiply both with each other
                    #     i.e. 1 * 0.1111111111111111 → 0.1111111111111111
                    #     i.e. 0 * 0.14285714285714285 → 0
 ]                  # Close both if-statements and the map
                    #  i.e. [1,1] → [0.5,0.0]
                    #  i.e. [1,2] → [0.5,0.1111111111111111]
                    #  i.e. [2,0,1] → [0.25,1.0,1]
                    #  i.e. [0,0,2] → [1.0,1.0,1]
  P                 # Take the product of all mapped values
                    #  i.e. [0.5,0.0] → 0.0
                    #  i.e. [0.5,0.1111111111111111] → 0.05555555555555555
                    #  i.e. [0.25,1.0,1] → 0.25
                    #  i.e. [1.0,1.0,1] → 1.0
                    # (and output implicitly as result)

4

APL (Dyalog Extended) , 21 bytes

Este programa usa la ruta del factor primo. Estoy en deuda con Adám, dzaima, H.PWiz, J.Sallé y ngn. APL Orchard es un excelente lugar para aprender APL y siempre están dispuestos a ayudar

(×/÷,34|*∘≢⌸)⍭*14|⍭

Pruébalo en línea!

Ungolfing

La parte 2 de este código es la misma que en la versión de Dyalog Unicode a continuación, por lo que en esta explicación, me centraré en ⍭*1≠4|⍭

⍭*14|⍭

        Gives us a list of the prime factors of our input.
           Example for 45: 3 3 5
  14|   Checks if each prime is of the form 4k+1.
⍭*       Takes each prime to the power of 1 or 0,
           turning all the 4k+1 primes into 1s.
           Example for 45: 3 3 1

APL (Dyalog Unicode) , 41 40 36 35 bytes SBCS

Este programa usa la ruta del factor primo. Aprendí algunos trucos mientras escribía esto y estoy profundamente en deuda con Adám, dzaima, H.PWiz, J.Sallé y ngn. El APL Orchard es un gran lugar para aprender APL y siempre están dispuestos a ayudar (o esta publicación nunca hubiera despegado :)

Editar: -1 byte de ngn. -2 bytes de Adám y -2 más de ngn. -1 byte de ngn.

{(×/÷,34|*∘≢⌸)p*14|p←¯2÷/∪∧\⍵∨⍳⍵}

Pruébalo en línea!

Ungolfing

Este es un programa en dos partes:

p*14|p←¯2÷/∪∧\⍵∨⍳⍵  Part 1

      p             We can define variables mid-dfn (a function in {} brackets).
               ⍵∨⍳⍵  We take the GCD of our input 
                       with every member of range(1, input).
            ∪∧\      This returns all the unique LCMs of every prefix
                       of our list of GCDs.
                       Example for 31500: 1 2 6 12 60 420 1260 6300 31500
        ¯2÷/         We divide pairwise (and in reverse)
                       by using a filter window of negative two 2).
                       Example for 31500: 2 3 2 5 7 3 5 5
  14|p              Check if the primes are 1 modulo 4 or not
p*                   And take each prime to the power of the result (1 or 0),
                       turning the 4k+3 primes into 1s
                       and leaving any 2s and 4k+3 primes.
                       Example for 31500: 2 3 2 1 7 3 1 1

(×/÷,34|*∘≢⌸)  Part 2

(            )  We apply all this to the filtered array of primes.
         *∘≢⌸   This takes all of our primes to their exponents
                  (the number of times those primes appear in the factorization).
                  Example for 31500: 4 9 1 7
     34|       Then we take each prime modulo 4 and check if not equal to 3.
                  We will only get a falsey if any 4k+3 primes, as an even number of
                  4k+3 primes multiplied together will result in some 4m+1.
                  Example for 31500: 1 1 1 0
   ÷,           We append the results of the above condition check
                  to the reciprocals of the primes in p.
                  Example for 31500: (1/2) (1/3) (1/2) 1 (1/7) (1/3) 1 1 1 1 1 0
 ×/             We multiply it all together, resulting in a positive fraction or 0
                  depending on our condition check.
                  Example for 31500: 0
                We return the results of all our checks implicitly.
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.