N-movers: quanta parte della tavola infinita posso raggiungere?


48

Mosse singole

La scacchiera è una griglia quadrata infinita di 2 dimensioni, come una scacchiera senza limiti. Un pezzo con valore N (un motore N ) può spostarsi su qualsiasi quadrato che è esattamente la distanza della radice quadrata di N dal suo quadrato attuale (distanza euclidea misurata da centro a centro).

Per esempio:

  • Un motore a 1 movimento può spostarsi su qualsiasi quadrato adiacente orizzontalmente o verticalmente
  • Un 2-mover può spostarsi in qualsiasi quadrato diagonalmente adiacente
  • Un motore a 5 mosse si muove come un cavaliere di scacchi

Si noti che non tutti gli N-movers possono muoversi. Un 3-mover non può mai lasciare il suo quadrato attuale perché nessuno dei quadrati sul tabellone è a una distanza esattamente di radice 3 dal quadrato corrente.

Mosse multiple

Se è permesso spostarsi ripetutamente, alcuni pezzi possono raggiungere qualsiasi quadrato sul tabellone. Ad esempio, un 1-mover e un 5-mover possono entrambi fare questo. Un 2-mover può muoversi solo in diagonale e può raggiungere solo la metà dei quadrati. Un pezzo che non può muoversi, come un 3-mover, non può raggiungere nessuno dei quadrati (il quadrato iniziale non viene considerato "raggiunto" se non si verifica alcun movimento) .

1-motore 2-motore 3-motore 4-motore 5-motore 8-motore 9-motore 10-Mover 20-Mover 25-Mover 40-Mover 64-motore 65-motore 68-Mover

Le immagini mostrano quali quadrati possono essere raggiunti. Maggiori dettagli su hover. Clicca per ingrandire l'immagine.

  • I quadrati raggiungibili in 1 o più mosse sono contrassegnati in nero
  • I quadrati raggiungibili esattamente in 1 movimento sono indicati da pezzi rossi
    (a parte il 3-mover, che non può muoversi)

Quale percentuale della tavola può raggiungere un dato N-mover?

Ingresso

  • Un numero intero positivo N

Produzione

  • La proporzione della tavola che un N-mover può raggiungere
  • Questo è un numero compreso tra 0 e 1 (entrambi inclusi)
  • Per questa sfida, è consentita la produzione come frazione in termini più bassi, come 1/4

Quindi per input 10, entrambi 1/2e 0.5sono output accettabili. Anche l'output come numeratore e denominatore separati è accettabile, per includere le lingue che non supportano né float né frazioni. Ad esempio, 1 2oppure [1, 2].

Per le uscite intere (0 e 1), uno qualsiasi dei seguenti sono formati accettabili:

  • Per 0: 0, 0.0, 0/1, 0 1,[0, 1]
  • per 1: 1, 1.0, 1/1, 1 1,[1, 1]

punteggio

Questo è il codice golf. Il punteggio è la lunghezza del codice in byte. Per ogni lingua, vince il codice più breve.

Casi test

Nel 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
Ho pubblicato questa domanda su Math.SE: math.stackexchange.com/questions/3108324/…
infmagic2047

Congettura interessante!
trichoplax,

1
"Un pezzo che non può muoversi, come un 3-mover, non può raggiungere nessuno dei quadrati". È interessante notare che, anche se conti il ​​quadrato iniziale, poiché la tavola è infinita, converge comunque a 0 in proporzione.
Beefster

@Beefster buon punto. Sono andato in questo modo per rendere il limite più facile da trovare senza dover andare fino all'infinito ...
trichoplax,

2
La domanda math.se di @ infmagic2047 sull'approccio di factoring principale ora ha una risposta con una prova completa .
Ørjan Johansen,

Risposte:


19

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

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)

Provalo online!

-4 byte grazie @Arnauld!

Approccio originale, 125 byte

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

Provalo online!

Ispirato al video Pi nascosto in regolarità prime da 3Blue1Brown.

Per ciascun fattore primo nella fattorizzazione del numero, calcolare :pnf(pn)

  • Se è dispari e - . Perché non c'è posto dove andare.np3 (mod 4)f(pn)=0
  • Se è pari e - .np3 (mod 4)f(pn)=1pn
  • Se - .p=2f(2n)=12n
  • Se - .p1 (mod 4)f(pn)=1

Moltiplica tutti quei valori di funzione, eccoci qui.

Aggiornare

Grazie allo sforzo dei collaboratori di Math.SE, l'algoritmo è ora supportato da una prova


Il video contiene una prova? Sto provando a provare questo risultato da alcune ore ma non sono riuscito a capirlo.
infmagic2047

1
@ infmagic2047 Non proprio, ma fornisce un metodo per contare il numero di punti su un cerchio . Questo è utile per capire come può andare l'n-mover. n
Shieru Asakoto,

3
@ infmagic2047 Penso che sia banale provare i casi per ma i casi per i restanti sono abbastanza difficili da dimostrare formalmente ...q=ΠpPp{2,3} (mod 4)pep
Shieru Asakoto,

1
La domanda math.se di @ infmagic2047 su questo approccio ora ha una risposta con una prova completa .
Ørjan Johansen,

11

Mathematica, 80 byte

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

Questo codice dipende principalmente da un teorema matematico. L'idea di base è che il codice richiede la densità di un reticolo dato un gruppo elettrogeno.

Più precisamente, ci viene data una raccolta di vettori - vale a dire quelli la cui lunghezza al quadrato è N - e ci viene chiesto di calcolare la densità dell'insieme delle possibili somme di questi vettori, rispetto a tutti i vettori interi. La matematica in gioco è che possiamo sempre trovare due vettori (e il loro contrario) che "generano" (cioè le cui somme sono) lo stesso set della collezione originale. LatticeReduce fa esattamente questo.

Se hai solo due vettori, puoi immaginare di disegnare un parallelogramma identico centrato in ciascun punto raggiungibile, ma le cui lunghezze del bordo sono i vettori indicati, in modo tale che il piano sia completamente piastrellato da questi parallelogrammi. (Immagina, ad esempio, un reticolo di forme a "diamante" per n = 2). L'area di ciascun parallelogramma è il determinante dei due vettori generatori. La proporzione desiderata del piano è il reciproco di quest'area, poiché ogni parallelogramma ha solo un punto raggiungibile in esso.

Il codice è un'implementazione abbastanza semplice: genera i vettori, usa LatticeReduce, prendi il determinante, quindi prendi il reciproco. (Probabilmente può essere meglio giocato a golf, però)


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

11

Pulito , 189 185 172 171 171 byte

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)

Provalo online!

Trova tutte le posizioni raggiungibili nel nquadrato di lunghezza laterale accantonato sull'origine nel primo quadrante, quindi si divide n^2per ottenere la porzione di tutte le celle raggiungibile.

Questo funziona perché:

  • L'intero piano raggiungibile può essere considerato come una sovrapposizione di copie di questo nquadrato di lunghezza laterale, ciascuna accantonata su un punto raggiungibile dall'origine come se fosse l'origine.
  • Tutti i movimenti si presentano in gruppi di quattro con segni ++ +- -+ --, consentendo di estendere la piastrellatura sovrapposta attraverso gli altri tre quadranti mediante il mirroring e la rotazione.

Mi scuso: stavo guardando i casi di test che vanno da N = 10 a N = 13, mentre i casi di test includono anche N = 11 e N = 12. Hai effettivamente ragione per N = 13. +1 da parte mia :)
trichoplax,

1
@trichoplax Ho modificato i test per corrispondere alla domanda per evitare di nuovo la stessa confusione
ousurous

Ho testato ulteriormente fino a N = 145 e tutti sono corretti. Non ho potuto testare 146 su TIO a causa del timeout di 60 secondi. Mi aspetto tempi molto lunghi nelle risposte qui ...
trichoplax,

1
Da quando ho impiegato un po 'di tempo per rendermene conto: il motivo per cui gli angoli quadrati sono raggiungibili se c'è almeno una mossa (a, b), è l'equazione complessa (a + bi) (a-bi) = a ^ 2 + b ^ 2, che in forma vettoriale diventa (N, 0) = a (a, b) + b (b, -a).
Ørjan Johansen,

5

Retina 0.8.2 , 126 82 byte

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

Provalo online! Il link include casi di test. Spiegazione:

.+
$*

Converti in unario.

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

Dividi ripetutamente per fattori primi della forma 4k+1.

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

Se il risultato non è né un quadrato né due volte un quadrato, il risultato è zero.

11+
1/$.&

Calcola il reciproco come una frazione decimale.


5

Regex (ECMAScript, reciproco in uscita), 256 163 157 94 83 82 byte

-93 byte grazie a Neil
-6 byte grazie ancora a Neil
-63 byte eseguendo la divisione senza acquisire il divisore
-11 byte grazie alla simultanea divisione-per-costante opzionale di Grimy e radice quadrata
-1 byte spostando la condizione di fine partita e restituire l'acquisizione di valore nel loop come seconda alternativa, grazie a Grimy

Questo utilizza la stessa matematica della risposta JavaScript di Shieru Asakoto .

L'input è in unario. Poiché un regex puro può restituire come output solo una sottostringa dall'input (ovvero un numero naturale minore o uguale all'input), o "nessuna corrispondenza", questo regex restituisce il reciproco della proporzione della scheda che un N-mover può raggiungere. Poiché il reciproco di 0 è infinito, in questo caso restituisce "nessuna corrispondenza".

SPOILER ATTENZIONE : Per la radice quadrata, questa regex utilizza una variante dell'algoritmo di moltiplicazione generalizzata, che non è ovvio e potrebbe essere un puzzle gratificante da elaborare da solo. Per ulteriori informazioni, vedere una spiegazione per questo modulo dell'algoritmo in Trova un numero Rocco .

pp1 (mod 4)mm3 (mod 4)mm/2mm

mm/2p3 (mod 4)

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

Provalo online!
Provalo online! (solo i casi di test)

^
(?=
    (                          # 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)

Regex (ECMAScript + (? *), Uscita reciproca), 207 138 132 byte

Obsoleted facendo divisione senza catturare il divisore (cioè ora è identico a quanto sopra).

Regex (ECMAScript 2018, output reciproco), 212 140 134 byte

Obsoleted facendo divisione senza catturare il divisore (cioè ora è identico a quanto sopra).

Regex (ECMAScript, output della frazione), 80 byte

In questa versione, il numeratore viene restituito in \10(zero se non impostato / NPCG) e il denominatore in \7.

A differenza della versione con uscita reciproca:

  • Un input di zero non viene gestito correttamente (restituisce "nessuna corrispondenza" proprio come quella versione, ma a differenza di esso, che non corrisponde a un valore di output pari a zero).
  • Se il test quadrato perfetto fallisce, non torna indietro nel loop di divisione, quindi questa versione è più efficiente nei tempi di esecuzione.

Il grande svantaggio di una specifica di output come questa è che non è contenuta nel programma stesso.

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

Provalo online!
Provalo online! (solo i casi di test)

# 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
Mi dispiace, ovviamente non l'ho provato su casi di test sufficienti.
Neil,

1
@trichoplax Potresti considerare la risposta come il rapporto tra le lunghezze di due gruppi di acquisizione specifici? (Ciò renderebbe la risposta più breve in quanto ci vuole la fatica per rendere l'intera partita il risultato.)
Neil

1
Seguendo il commento di @ Neil, ho modificato per consentire l'output come numeratore e denominatore separato, in quanto sembra il più piccolo cambiamento che consente la regex pura. Fammi sapere se è ancora un problema
trichoplax,

1
-11 byte usando (((xx?)(\9*))(?=(\8*)\10+$)\8*$\11)per verificare se N o N / 2 è un quadrato.
Grimmy,

1
Ai puntatori @Deadcode ai backref non dovrebbe essere assegnato un costo in byte, poiché sono consentiti per impostazione predefinita .
Grimmy,

4

Gelatina ,  25  24 byte

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

Un collegamento monadico che utilizza la rotta del fattore primo.

Provalo online!

Come?

Æ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

25 precedenti erano:

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

Forcer bruto a programma completo ; codice forse più lungo della rotta del fattore primo (potrei tentare più tardi).

Provalo online!

Inizia creando singoli movimenti come coordinate poi ripetutamente mosse da tutte le posizioni raggiunte accumulare i risultati, tenendo modulo ndi ogni coordinata (per limitare ad un ndai nquadranti) e mantenendo quelli che sono distinti fino a raggiungere un punto fisso; infine divide il conteggio pern^2


4

05AB1E , 27 26 25 byte

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

Porta della risposta JavaScript di @ShieruAsakoto , quindi assicurati di votare anche lui!

Provalo online o verifica tutti i casi di test .

Spiegazione:

Ó                   # 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 byte

Questo programma utilizza la rotta del fattore primo. Sono in debito con Adám, dzaima, H.PWiz, J.Sallé e ngn. L'APL Orchard è un ottimo posto per imparare l'APL e sono sempre pronti ad aiutare

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

Provalo online!

Ungolfing

La parte 2 di questo codice è la stessa della versione Unicode di Dyalog di seguito, quindi in questa spiegazione mi concentrerò su ⍭*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 byte SBCS

Questo programma utilizza la rotta del fattore primo. Ho imparato alcuni trucchi mentre scrivo questo e sono profondamente in debito con Adám, dzaima, H.PWiz, J.Sallé e ngn. L'APL Orchard è un ottimo posto per imparare l'APL e sono sempre pronti ad aiutare (o questo post non sarebbe mai decollato :)

Modifica: -1 byte da ngn. -2 byte da Adám e -2 altri da ngn. -1 byte da ngn.

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

Provalo online!

Ungolfing

Questo è un programma in due parti:

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.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.