Quadrati modulo magico


11

Sono un grande fan della teoria dei numeri. Una cosa importante nella teoria dei numeri è l'aritmetica modulare; la definizione essendo se e solo se m \ mid ab . Una cosa divertente da fare è aumentare i poteri: specialmente quando il modulo è un numero primo. In particolare, è stato dimostrato che se a e m sono relativamente primi (non condividono fattori comuni oltre a 1 ), allora esiste un numero e tale che a ^ e \ equiv 1 \ mod m .abmodmmabam1eae1modm

Spiegherò cos'è l'esercizio con un esempio. Prendiamo un modulo m=7 . Un possibile output del programma o della funzione sarebbe:

3 2 6 4 5 1
2 4 1 2 4 1
6 1 6 1 6 1
4 2 1 4 2 1
5 4 6 2 3 1
1 1 1 1 1 1

Ogni riga è un elenco dei poteri del primo numero in quella riga: la prima riga è 3,32,33,,36 , che equivale a 3,2,6,4,5,1 modulo 7 . La seconda fila del quadrato sopra è il potere di 2 , eccetera, fino all'ultima fila, che sono solo poteri di 1 .

Questo è un quadrato modulo magico perché:

  • Il quadrato è simmetrico; cioè, la i esima colonna è la stessa della i esima riga.
  • Tutti i valori da 1 a m1 visualizzati almeno una volta.

Di seguito è l'unico altro output valido per , a partire da potenze di :m=75

5 4 6 2 3 1
4 2 1 4 2 1
6 1 6 1 6 1
2 4 1 2 4 1
3 2 6 4 5 1
1 1 1 1 1 1

La sfida

Crea una funzione o un programma che dia un poutput primo ad un magico modulo quadrato, cioè un quadrato con lunghezze laterali p-1, in modo tale che ogni riga sia un elenco dei poteri consecutivi del primo elemento della riga e lo stesso per le colonne. Tutti i numeri tra 0e pdevono essere presenti e il quadrato può contenere solo numeri in quell'intervallo.

L'input è un numero o una stringa e l'output può essere ascii, una matrice, una matrice di array (qualsiasi formato ragionevole).

Questo è code-golf, quindi vince il codice più corto.


Sequenza OEIS correlata: A001918 (il valore più basso valido per l'angolo superiore sinistro).
Arnauld

2
" Spiegherò cos'è l'esercizio con un esempio. " Non farlo. Spiegalo nei suoi termini e poi fai un esempio per illustrare. Penso che quello che stai chiedendo sia una matrice tale che sia una radice primitiva modulo e , ma è un grande sforzo per estrarre tale specifica dalla domanda così com'è. UNUN1,1pUNio,j=UN1,1iojmodp
Peter Taylor

2
@PeterTaylor vero, e questo è ciò che intendo, ma in primo luogo, rovina parte del divertimento dell'esplorazione, e in secondo luogo, si basa sulla conoscenza delle radici primitive e dell'aritmetica modulare. Volevo che questa domanda rispondesse a un pubblico più ampio di così, quindi ho cercato di spiegare cosa intendo in termini più semplici.
vrugtehagel

Risposte:


5

Gelatina , 13 10 byte

-3 grazie a Nick Kennedy

Si sente come il codice ripetuto dovrebbe essere è il golf-in grado, ma io sono non sono riuscito d it ...

*€Ṗ%µQƑƇḢị

Provalo online! (piè di pagina dei formati piuttosto come griglia)

Come?

*€Ṗ%µQƑƇḢị - Link: integer, p
 €         - for each n in [1..p]
*          -   exponentiate with:
  Ṗ        -     pop = [1..p-1]
           - ...i.e [[1^1,1^2,...,1^(p-1)],[2^1,2^2,...,2^(p-1)],...,[....,p^(p-1)]]
   %       - modulo p
    µ      - start a new monadic chain (call that list of lists X)
       Ƈ   - keep those which:
      Ƒ    -   are invariant under:
     Q     -     de-duplicate
        Ḣ  - head
         ị - index into the list of lists X


Ahha, ora mi sento lento; p grazie!
Jonathan Allan

3

Carbone , 36 byte

≔E…¹θ﹪Xι…¹θIθηE⊟Φη⁼¹№ι¹⪫E§η⊖ι◧IλL⊖θ 

Provalo online! Il collegamento è alla versione dettagliata del codice. Nota: spazio finale. Spiegazione:

≔E…¹θ﹪Xι…¹θIθη

Creare un p-1dalla p-1serie di potenze di 1..p-1indici 1..p-1(modulo p).

E⊟Φη⁼¹№ι¹

Mappa su una delle righe che ne ha esattamente una 1.

⪫E§η⊖ι◧IλL⊖θ 

Riorganizzare le righe nell'ordine indicato dalla riga selezionata e formattare l'output.




2

JavaScript (ES7),  91  86 byte

p11

f=(p,k)=>(g=k=>[...Array(i=p-1)].map(_=>k**++i%p))(k).sort()[1]>1?g(k).map(g):f(p,-~k)

Provalo online!


JavaScript (ES6),  92  87 byte

Questa versione utilizza esponenziazione modulare per supportare valori di input (molto) più elevati.

f=(p,k)=>(g=k=>[...Array(p-1)].map(_=>n=n*k%p,n=1))(k).sort()[1]>1?g(k).map(g):f(p,-~k)

Provalo online!

Come?

Trovare la prima fila

1K<pgun'K(n)=Knmodp1n<p

g = k =>              // k = input
  [...Array(p - 1)]   // generate an array of size p - 1
  .map(_ =>           // for each entry in there:
    n = n * k % p,    //   update n to (n * k) mod p
    n = 1             //   starting with n = 1
  )                   // end of map()

Knun'K(n)=11

g(k).sort()[1] > 1

Funziona anche in ordine lessicografico - che è il comportamento predefinito di sort()- perché:

  • 1
  • 11

Esempio:

p=17

  • K=1
    • un'1=[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
    • [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
  • K=2
    • un'2=[2,4,8,16,15,13,9,1,2,4,8,16,15,13,9,1]
    • [1,1,13,13,15,15,16,16,2,2,4,4,8,8,9,9]
  • K=3
    • un'3=[3,9,10,13,5,15,11,16,14,8,7,4,12,2,6,1]
    • [1,10,11,12,13,14,15,16,2,3,4,5,6,7,8,9]

Costruire la matrice

Kg(K)gg(K)

Questa parte può essere semplicemente scritta come:

g(k).map(g)

.indexOf(1)>p-3salva 3 byte sopra .every.
Neil

@ Grazie Grazie. Ma ho trovato un modo più breve dopo una buona notte di sonno. :)
Arnauld

2

Zsh , 117 90 byte

b=$1
c=(eval set -- '$[x**'{1..$[b-1]}%b\])
for ((;${#${(u)@}}-b+1;++x))$c
for x;$c&&<<<$@

Provalo online! Provalo online!

Possa Dio avere misericordia della mia anima. Ci sono un sacco di cattive pratiche tutte racchiuse qui, lasciatemi spiegare almeno il più grande trasgressore:

c=(eval set -- '$[x**'{1..$[b-1]}%b\])
                      {1..$[b-1]}        # brace expansion, expands immediately
               '$[x**'           %b\]    # string literals, expand during eval
   eval set --                           # sets the positional parameters
c=(                                   )  # defines c to the words contained

Esempio per b=4:

c=(eval set -- '$[x**'{1..$[b-1]}%b\])
c=(eval set -- '$[x**'{1..3}%b\]     )                # $[b-1] => 3
c=(eval set -- '$[x**1%b]' '$[x**2%b]' '$[x**3%b]' )  # brace expansion

Infine, dove $cappare nel resto del programma, gli elementi dell'array vengono valutati come eval set -- .....

Infine, ${#${(u)@}}conta gli elementi univoci nei parametri posizionali (es: c'è un ciclo / ci sono 1s?)

Commenti rilevanti per la risposta 117 byte di seguito.


Sfide che dobbiamo superare:

  • Nessuna matrice multidimensionale o nidificata. Invece stampiamo le stringhe mentre le inseriamo in un ciclo.
  • Opzioni per il test se una determinata riga ha più 1:
    • ${#${(M)a:#1}: :#rimuove la corrispondenza e (M)inverte la corrispondenza. Quindi, questo si espanderà al numero ( ${# }) di 1s nell'array. Sfortunatamente questa espansione non gioca bene con l'aritmetica del loop che usiamo qui. In tal caso, potrebbe potenzialmente salvare un byte.
    • ${${:-1}:*a}: Questa è l'intersezione tra il singleton 1e il set a. Questo si espanderà al singolo 1se si trova nell'array. Usando questa opzione, salviamo un personaggio qui, ma perdiamo 1 in totale dover rimandare aggiungendo le 1s nell'ultima riga e colonna fino alla fine.
f(){ # f [element] [modular base], puts powers up to n-2 into array $a
    a=()
    for i ({1..$[$2-2]})
        a+=($[$1**i%$2])
}
a=(1)                     # put 1 in a to force first loop iteration
for ((;${${:-1}:*a};))    # test for 1 in array $a
    f $[++x] $1           # increment x, iterate through all elements mod $1
for y ($a 1){             # for all elements in the [last array, 1]
    f $y $1               # put that row in $a
    <<<$a\ 1              # print out $a with 1 appended (space-delimited string)
}

1

Perl 6 , 65 57 byte

{.[|.first(*.Set+2>$_)]}o{.&{@=(($++X**1..^$_)X%$_)xx$_}}

Provalo online!

Probabilmente c'è un modo per emettere il quadrato stesso, ma questo fa lo stesso processo indicato nella domanda, ordinando gli elenchi in base alla loro posizione nel primo elenco che è solo una permutazione da 1 a input-1. Restituisce come un elenco di elenchi.

A proposito, c'è un sacco di fantino in giro, cercando di aggirare alcune delle fastidiose limitazioni di Perl 6 che coinvolgono sequenze contro array e variabili anonime.

Spiegazione:

                               $++               xx$_    # Map 0 to i-1 to
                              (   X**1..^$_)             # n, n^2, n^3... n^(i-1)
                             (              X%$_)        # All modulo i
{                      }o{.&{                        }}  # Pass to the next function
 .[                   ]    # Index into that list of lists
   |.first(          )     # The list of the first list that
           *.Set+2>$_        # Has all the elements in the range 1 to i-1


1

05AB1E , 19 16 byte

LεI<LmI%}ÐΘOÏн<è

-3 byte grazie a @Emigna .

Provalo online (il piè di pagina è per stampare graziosamente l'elenco 2D).

Spiegazione:

L          # Create a list in the range [1, (implicit) input]
 ε         # Map each number `y` in the list to:
  I<L      #  Create a list in the range [1, input-1]
     m     #  Get number `y` to the power of each number in this list
      I%   #  Take modulo-input on each number
         # After the map: triplicate this modified matrix
   ΘO      # Get the amount of 1s in each row
     Ï     # And only leave the rows with exactly one 1
      н    # Then only leave the first row which contains a single 1
       <   # Decrease each value by 1 to make it 0-indexed
        è  # And index each into the rows of the modified matrix to create a new matrix
           # (which is output implicitly as result)

1
LεI<LmI%}ÐΘOÏн<èper 16 byte.
Emigna,

@Emigna Grazie! Non avevo capito che sarebbe bastato invece di UΣXykme.
Kevin Cruijssen,



0

APL (NARS), 29 caratteri, 58 byte

{k←⍵∣⍺*⍳⍵-1⋄⊃{m∣k*⍵}¨⍳¯1+m←⍵}

test:

  f←{k←⍵∣⍺*⍳⍵-1⋄⊃{m∣k*⍵}¨⍳¯1+m←⍵}
  3 f 7
3 2 6 4 5 1
2 4 1 2 4 1
6 1 6 1 6 1
4 2 1 4 2 1
5 4 6 2 3 1
1 1 1 1 1 1
  5 f 7
5 4 6 2 3 1
4 2 1 4 2 1
6 1 6 1 6 1
2 4 1 2 4 1
3 2 6 4 5 1
1 1 1 1 1 1 
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.