Una formula per i congressi


10

Il teorema del residuo cinese può essere abbastanza utile nell'aritmetica modulare.

Ad esempio, considera la seguente serie di relazioni di congruenza:

Set di congruenza

Per insiemi di relazioni di congruenza come questa, in cui tutte le basi ( 3, 5, 7in questo esempio) sono coordinate tra loro, ci sarà un solo e un intero ntra 1e il prodotto delle basi ( 3*5*7 = 105in questo esempio) inclusivo che soddisfa le relazioni .

In questo esempio, il numero sarebbe 14, generato da questa formula:

formula

dove 2, 4, and 0sono dati dall'esempio sopra.

70, 21, 15sono i coefficienti della formula e sono dipendenti dalle basi 3, 5, 7.

Per calcolare i coefficienti della formula ( 70, 21, 15nel nostro esempio) per un insieme di basi, utilizziamo la seguente procedura.

Per ogni numero ain una serie di basi:

  1. Trova il prodotto di tutte le altre basi, indicato come P.
  2. Trova il primo multiplo di Pquello lascia un resto di 1quando diviso per a. Questo è il coefficiente di a.

Ad esempio, per calcolare il coefficiente che corrisponde alla base 3, troviamo il prodotto di tutte le altre basi (cioè 5*7 = 35) e quindi troviamo il primo multiplo di quel prodotto che lascia un resto di 1quando diviso per la base.

In questo caso, 35lascia un resto di 2quando diviso per 3, ma 35*2 = 70lascia un resto di 1quando diviso per 3, così 70è il coefficiente corrispondente per 3. Allo stesso modo, 3*7 = 21lascia un resto di 1quando diviso per 5e 3*5 = 15lascia un resto di 1quando diviso per 7.

In poche parole

Per ogni numero ain un set di numeri:

  1. Trova il prodotto di tutti gli altri numeri, indicato come P.
  2. Trova il primo multiplo di Pquello lascia un resto di 1quando diviso per a. Questo è il coefficiente di a.

La sfida

  • La sfida è, per un insieme di due o più basi, trovare l'insieme dei coefficienti corrispondenti.
  • Il set di basi è garantito per essere co-prime a coppie e ogni base è garantita per essere maggiore di 1.
  • Il tuo input è un elenco di numeri interi come input [3,4,5]o stringa separata da spazio "3 4 5"o comunque i tuoi input funzionano.
  • L'output dovrebbe essere un elenco di numeri interi o una stringa separata da spazio che indica l'insieme di coefficienti.

Casi test

input             output
[3,5,7]           [70,21,15]
[2,3,5]           [15,10,6]
[3,4,5]           [40,45,36]
[3,4]             [4,9]
[2,3,5,7]         [105,70,126,120]
[40,27,11]        [9801,7480,6480]
[100,27,31]       [61101,49600,56700]
[16,27,25,49,11]  [363825,2371600,2794176,5583600,529200]

Mille grazie a Leaky Nun per il suo aiuto nello scrivere questa sfida. Come sempre, se il problema non è chiaro, per favore fatemi sapere. Buona fortuna e buon golf!


Ci saranno sempre 3 numeri nell'input?
xnor

@xnor Nope. Casi di test modificati.
Sherlock9,

Risposte:


5

Haskell, 61 55 53 byte

f x=[[p|p<-[0,product x`div`n..],p`mod`n==1]!!0|n<-x]

Definisce una funzione fche accetta input e fornisce output come un elenco di numeri interi.

f x=[                                          |n<-x]  (1)
              product x                                (2)
                       `div`n                          (3)

Innanzitutto eseguiamo il ciclo su tutti i numeri interi nell'input (1). Quindi prendiamo il prodotto di tutti i numeri interi (2) e dividiamo per n per ottenere solo il prodotto dei nnumeri non interi, che è P(3).

           [0,               ..]                       (4)
     [p|p<-                     ,p`mod`n==1]           (5)
                                            !!0        (6)

Quindi usiamo il risultato ( P) come valore del passo per un intervallo che inizia da zero (4). Prendiamo il risultato [0, P, 2P, 3P, ...]e lo filtriamo su valori per i quali il risultato di un'operazione mod-n è uno (5). Infine, prendiamo il primo elemento, che funziona grazie alla valutazione pigra (6).

Grazie a @xnor per 2 byte!


1
Benvenuto in haskell! Penso che il tuo quotpossa essere un div, e headpuò esserlo !!0.
xnor

4

Gelatina , 11 7 byte

P:*ÆṪ%P

Provalo online! o verifica tutti i casi di test .

sfondo

Sia P e un strettamente positiva, coprimi interi.

Il processo in due fasi nella domanda - trovare un multiplo di P che lascia un resto di 1 quando diviso per un - può essere descritto dalla seguente equazione di congruenza.

equazione di congruenza lineare

Con il teorema di Euler-Fermat , abbiamo

Teorema di Eulero-Fermat

dove φ indica la funzione totient di Eulero . Da questo risultato, deduciamo quanto segue.

formula per l'equazione di congruenza lineare

Infine, poiché la sfida ci richiede di calcolare Px , lo osserviamo

formula per il risultato finale

dove Pa può essere calcolato come il prodotto di tutti i moduli.

Come funziona

P:*ÆṪ%P  Main link. Argument: A (list of moduli)

P        Yield the product of all moduli.
 :       Divide the product by each modulus in A.
   ÆṪ    Apply Euler's totient function to each modulus.
  *      Raise each quotient to the totient of its denominator.
     %P  Compute the remainder of the powers and the product of all moduli.

2

J, 13 byte

*/|5&p:^~*/%]

Basato sulla straordinaria risposta di @Dennis .

uso

Alcuni casi di test necessiteranno dell'input come numeri interi estesi che hanno un suffisso x.

   f =: */|5&p:^~*/%]
   f 3 5 7
70 21 15
   f 40x 27 11
9801 7480 6480
   f 16x 27 25 49 11
363825 2371600 2794176 5583600 529200

Spiegazione

*/|5&p:^~*/%]  Input: list B
         */    Reduce B using multiplication to get the product of the values
            ]  Identity function, get B
           %   Divide the product by each value in B, call the result M
   5&p:        Apply the totient function to each value in B, call the result P
       ^~      Raise each value in M to the power of its corresponding value in P
*/             The product of the values in B
  |            Compute each power modulo the product and return

Provalo qui.




1

Gelatina, 14 13 byte

P:×"Ḷð%"’¬æ.ḷ

Salvato un byte grazie a @ Dennis !

Utilizza il processo descritto nelle specifiche della sfida. L'input è un elenco di basi e l'output è un elenco di coefficienti.

Provalo online o Verifica tutti i casi di test .

Spiegazione

P:×"Ḷð%"’¬æ.ḷ  Input: a list B
P              Get the product of the list
 :             Divide it by each value in the B, call it M
    Ḷ          Get a range from 0 to k for k in B
  ×"           Vectorized multiply, find the multiples of each M
     ð         Start a new dyadic chain. Input: multiples of M and B
      %"       Vectorized modulo, find the remainders of each multiple by B
        ’      Decrement every value
               If the remainder was 1, decrementing would make it 0
         ¬     Logical NOT, zeros become one and everything else becomes 0
            ḷ  Get the multiples of M
          æ.   Find the dot product between the modified remainders and the multiples
               Return

1

JavaScript (ES6), 80 byte

a.map(e=>[...Array(e).keys()].find(i=>p*i/e%e==1)*p/e,p=a.reduce((i,j)=>i*j))

Ho provato l'algoritmo euclideo esteso ma ci vogliono 98 byte:

a=>a.map(e=>(r(e,p/e)+e)%e*p/e,p=a.reduce((i,j)=>i*j),r=(a,b,o=0,l=1)=>b?r(b,a%b,t,o-l*(a/b|0)):o)

Se i valori sono tutti primi, ES7 può farlo in 56 byte:

a=>a.map(e=>(p/e%e)**(e-2)%e*p/e,p=a.reduce((i,j)=>i*j))

1

Python + SymPy, 71 byte

from sympy import*
lambda x:[(prod(x)/n)**totient(n)%prod(x)for n in x]

Questo utilizza l'algoritmo della mia risposta Jelly . L'I / O è in forma di elenchi di numeri SymPy.


1

Python 2, 87 84 byte

Una semplice implementazione dell'algoritmo. Suggerimenti di golf benvenuti.

a=input();p=1
for i in a:p*=i
print[p/i*j for i in a for j in range(i)if p/i*j%i==1]

Un programma completo risparmierebbe 3 byte.
Dennis,

1

Cheddar , 64 byte

n->n.map(i->(|>i).map(j->(k->k%i>1?0:k)(n.reduce((*))/i*j)).sum)

Dovrei aggiungere uno .productche fa .reduce((*))per gli array ...
Downgoat

0

GAP , 51 byte

GAP ha una funzione che può calcolare l'esempio motivante con ChineseRem([2,5,7],[2,4,0]), ma che non rende ancora così facile ottenere i coefficienti. Possiamo ottenere il n-esimo coefficiente usando la lista con uno nella n-esima posizione e azzerando le altre posizioni come secondo argomento. Quindi dobbiamo creare questi elenchi e applicare la funzione a tutti loro:

l->List(Basis(Integers^Size(l)),b->ChineseRem(l,b))

0

Lotto, 148 byte

@set p=%*
@set/ap=%p: =*%
@for %%e in (%*)do @for /l %%i in (1,1,%%e)do @call:l %%e %%i
@exit/b
:l
@set/an=p/%1*%2,r=n%%%1
@if %r%==1 echo %n%

0

In realtà, 14 byte

Questo utilizza l'algoritmo nella risposta Jelly di Dennis . Un'altra risposta basata sulla mia risposta Python è imminente. Suggerimenti di golf benvenuti. Provalo online!

;π;)♀\;♂▒@♀ⁿ♀%

Come funziona

                 Implicit input a.
;                Duplicate a.
 π;)             Take product() of a, duplicate and rotate to bottom.
    ♀\           Integer divide the product by each element of a. Call this list b.
      ;♂▒        Take that list, duplicate, and get the totient of each element.
         @♀ⁿ     Swap and take pow(<item in b>, <corresponding totient>)
            ♀%   Modulo each item by the remaining duplicate product on the stack.
                 Implicit return.

Un'altra risposta basata sulla mia risposta Python a 22 byte. Suggerimenti di golf benvenuti. Provalo online!

;π╖`╝╛╜\╛r*"╛@%1="£░`M

Come funziona

            Implicit input a.
;π╖         Duplicate, take product of a, and save to register 0.
`...`M      Map over a.
  ╝           Save the item, b, in register 1.
  ╛╜\         product(a) // b. Call it P.
  ╛r          Take the range [0...b].
  *           Multiply even item in the range by P. Call this list x.
  "..."£░     Turn a string into a function f.
              Push values of [b] where f returns a truthy value.
    ╛@%         Push b, swap, and push <item in x> % b.
    1=          Does <item> % b == 1?
            Implicit return.
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.