Divisibile per 1000003? Semplice, basta moltiplicare l'ultima cifra per 300001 e aggiungere!


16

Dato un numero primo Pmaggiore di 10, il tuo programma o funzione deve capire la sua regola di divisibilità x, definita come il numero intero con il valore assoluto più piccolo che produce un multiplo del primo originale quando moltiplicato per l'ultima cifra del primo e aggiunto al resto dell'originale Prime.

Esempio

Dato un input 31, l'ultima cifra è 1e il resto del numero è 3. Quindi il tuo programma deve trovare l'intero xcon un valore assoluto minimo tale che 1*x + 3sia un multiplo di 31. In questo caso, x=-3funziona, quindi ritornerebbe il programma o la funzione -3.

Dato un input 1000003, l'ultima cifra è 3e il resto del numero è 100000. Quindi il tuo programma troverebbe x=300001perché 3*300001+100000 = 1000003è un multiplo di 1000003.

Sfondo matematico

Il valore di xpuò essere utilizzato come test di divisibilità. Se un numero Nè divisibile per P, quindi l'aggiunta di xvolte l'ultima cifra di Nal resto di Nprodurrà un multiplo di Pse e solo se Nè divisibile per Pprimo.

Perché P=11, otteniamo x=-1, che equivale alla nota regola di divisibilità per 11: un numero è divisibile 11alternando la differenza delle sue cifre è divisibile per 11.

Regole

  • L'output può essere in qualsiasi forma che codifica chiaramente sia il segno che il valore dell'output.
  • L'ingresso primo sarà compreso tra 10 e 2 ^ 30.
  • Non è necessario gestire se l'input non è un numero primo o non è compreso nell'intervallo.
  • Non è necessario gestire se entrambi xe -xsono output validi (non dovrebbe accadere).
  • È consentita la forza bruta, ma sono apprezzate soluzioni più creative.
  • Questo è , quindi vince il codice più corto in ogni lingua ! Non lasciare che le risposte nelle lingue del golf ti scoraggino dal pubblicare in altre lingue.

Casi test

Input   Output
11  -1
13  4
17  -5
19  2
23  7
29  3
31  -3
37  -11
41  -4
43  13
47  -14
53  16
59  6
61  -6
67  -20
71  -7
73  22
79  8
83  25
89  9
97  -29
101 -10
103 31
107 -32
109 11
113 34
127 -38
131 -13
1000003 300001
2000003 600001
2999999 300000
9999991 -999999

3
Un'utile semplificazione: stiamo cercando il più piccolo xvalore assoluto dove 10*x-1è divisibile per l'input.
xnor

Qualcuno può fornire un suggerimento perché (3 / (n % 5 * 2 - 5) * n + 1) / 10e (n % 5 * 2 - 5^2) * n / 10 + 1sono in grado di trovare un valore assoluto minimo per qualcosa del genere? La mia prima intuizione sarebbe stata quella di calcolare il minimo comune multiplo usando il massimo comune divisore calcolato con l'algoritmo di Euclide.
David Foerster,

1
@DavidFoerster Dato un numero, puoi rimuovere l'ultima cifra, moltiplicarla per un numero x, aggiungerlo e ottenere ancora un numero divisibile per n. Se moltiplichiamo quindi il nuovo numero per 10 e sottraggiamo il numero originale, esso rimane ancora divisibile per n. Il commento di xnor segue quindi da qualche algebra. Il prossimo passo è riorganizzare la formula in modo che dia xin termini di n: x = (k*n+1)/10. Vogliamo che il più piccolo in assoluto xin modo da quindi vogliamo il più piccolo in assoluto k, e questo deve essere a seconda di quale uno dei -3, -1, 1o 3(a seconda del n's ultima cifra) che rende la divisione esatto.
Neil,

Risposte:


14

JavaScript (ES6), 32 25 23 byte

f=
n=>(3/(n%5*2-5)*n+1)/10
<input type=number min=1 oninput=o.textContent=this.value%5*(this.value%2)?f(this.value):``><pre id=o>

3/(n%5*2-5)sarebbe scritto 9/n(mod -10)se avessi accesso a una divisione modulo bilanciata. Modifica: salvato 2 byte grazie a @EgorSkriptunoff


3
Puoi salvare 2 byte sostituendo n=>((n%10*2%14-3)*n+1)/10conn=>(3/(n%5*2-5)*n+1)/10
Egor Skriptunoff il


@KevinCruijssen Probabilmente anche un poliglotta mancante per Java 8 ... oh aspetta, vedo la tua risposta ora!
Neil,

@Neil Hai ragione. Di solito invio risposte Java, quindi stavo già lavorando su una porta di xnor quando ho visto la tua risposta. Inserito in entrambi i modi come una porta noiosa che ti accredita.
Kevin Cruijssen,

8

Python 2 , 27 byte

lambda n:(n%5*2-5^2)*n/10+1

Provalo online!

Le operazioni vengono eseguite da sinistra a destra: (((n%5)*2)-5)^2 .

Ho usato il mio forzante aritmetico bruto per trovare l'espressione n%5*2-5^2da eseguire {1:-1,3:3,2:-3,4:1}[k], prendendo l'inverso negativo di un residuo mod 5 nell'intervallo [-2..2].


Questo forcer aritmetico è disponibile pubblicamente da qualche parte?
Lynn,

È l'unica espressione trovata o stampa solo la prima di una determinata lunghezza? ( 3/(n%5*2-5)è della stessa lunghezza di(n%5*2-5^2) .)
Neil,

@Lynn No, potrei ripulirlo e pubblicarlo quando ho tempo.
xnor

1
@Neil Ha trovato solo equivalenti e n%5*2-6^3. Ho solo alzato lo sguardo alla lunghezza dell'espressione senza parentesi, mentre 3/(n%5*2-5)è più lunga di due caratteri ma consente di risparmiare sulle parentesi esterne a causa della precedenza. La ricerca di espressioni di questa lunghezza dovrebbe richiedere del tempo. Questo caso d'uso suggerisce un'opzione per trovare solo espressioni che possono essere utilizzate in un determinato contesto tramite la loro operazione più esterna con precedenza abbastanza elevata.
xnor

6

Gelatina ,10 8 byte

,N⁵æiAÞḢ

Provalo online!

spiegazioni

,N       Get [Input, -Input].
⁵æi      Modular inverse of 10 mod each of [Input, -Input].
AÞ       Sort by absolute value.
Ḣ        First.

+1 Non ho mai visto un invio di Jelly con un registro che salva effettivamente i byte
Mr. Xcoder

@ Mr.Xcoder Era perché non l'ho giocato bene.
jimmy23013,




5

Japt , 16 anni 9 byte

Risparmiato troppi byte grazie a un'osservazione di @xnor

_*AÉ vU}c

Provalo online!Potrebbe richiedere un paio di secondi per input più grandi.

Spiegazione

_  *AÉ  vU}c    Implicit: U = input integer
Z{Z*A-1 vU}c    Ungolfed
Z{        }c    Loop through each integer Z in [0, -1, 1, -2, ...] and yield the first where
  Z*A             Z times 10
     -1           minus 1
        vU        is divisible by the input.
                Implicit: output result of last expression




1

Python 2 , 44 43 byte

(Cancellati 44 sono ancora 44.) Grazie a Fireflame241 per aver salvato un byte!

P=input();i=P/3
while i*10%P-1:i-=1
print i

Provalo online!

C'è esattamente un numero tra 0e P-1che è un inverso di 10. Ma se quell'inverso usembra essere maggiore di P/2, allora (u-P)è anche un inverso e ha un valore assoluto minore di u. Quindi si scopre che stiamo davvero cercando il numero univoco xtra -P/2e P/2che è un contrario di10 .

Il codice sopra fa esattamente questo, iniziando da (il piano di) P/2, e scendendo verso il basso fino a raggiungere un inverso. Questo deve accadere per un numero maggiore di -P/2fino a quando Pè un numero maggiore di 10. Più precisamente, terminerà se e solo se Pè coprime10 .

Modifica: si scopre che xè garantito che si trova tra -P/3e P/3, quindi la versione corrente inizia alle P/3e scende da lì. Vedi la sezione etichettata Migliorato per una spiegazione di questo.

Spiegazione matematica

Non è stato immediatamente ovvio per me perché il test di divisibilità ha funzionato. Ecco una spiegazione, nel caso qualcuno si stesse chiedendo.

Sia Pun numero primo, maggiore di 10, la cui ultima cifra è b. così

P = 10a + b

dove a > 0e 0 <= b < 10. Infatti bè o 1, 3, 7o 9, perché una maggiore privilegiata di 10fine mosto in una di queste cifre.

Ora supponiamo bx + a = 0 (mod P). Poi

a = -bx (mod P)

10a + b = 10(-bx) + b (mod P)

0 = 10(-bx) + b (mod P)

0 = b(1 - 10x) (mod P)

Poiché Pè primo, gli interi mod Psono un dominio integrale . Quindi b = 0 (mod P), oppure 1 - 10x = 0 (mod P).

Lo sappiamo 0 <= b < 10 < P, quindi se b = 0 (mod P)allora b = 0. Ma abbiamo detto bè o 1, 3, 7o 9, quindi questo è impossibile. Pertanto 1 - 10x = 0 (mod P), così 10x = 1 (mod P). In altre parole, xè l'inverso di 10, modulo P.

Supponiamo ora che Nsia un numero intero non negativo la cui ultima cifra è d, quindi N = 10c + d. abbiamo una catena di istruzioni equivalenti:

10c + d = 0 (mod P)

<==> 10xc + dx = 0 (mod P)

<==> c + dx = 0 (mod P)

QED.

Utilità?

Mi chiedevo anche se il test di divisibilità (dato N = 10c + d, sostituito Nda dx + c) sarebbe effettivamente produttivo nella pratica. O almeno, sostituisce in modo affidabile Nun numero inferiore a N(in valore assoluto)?

Supponiamo N = 10c + d, dove c >= 0e 0 <= d < 10. Pertanto 10c = N - d <= N. Per la disuguaglianza del triangolo,

|c + dx| <= |c| + |dx| = c + d|x| <= N/10 + d|x|

< N/10 + 10|x| <= N/10 + 10P/2 = N/10 + 5P

Quindi se 5P <= 9N/10, allora |c + dx| < N.

In particolare, se N >= 6P, allora |c + dx| < N. Così, dato Piniziamo calcolando 2P, 3P, ..., 6P, insieme x. Poi dato N, si corre il test divisibilità ripetutamente fino a raggiungere un numero minore o uguale a 6P, e controllare se il risultato è uno qualsiasi dei numeri 0, P, 2P, ..., 6P.

(Ovviamente, ogni volta che raggiungiamo un numero negativo, lo sostituiamo con il suo valore assoluto, che va bene poiché qè divisibile per Pse e solo se lo (-q)è.)

Vincolato migliorato

Ho notato che |x|/Pnon sembrava essere mai vicino 1/2. In effetti sembrava che fosse sempre meno di 1/3... o ad un esame più attento, era sempre molto vicino a uno 1/10o l'altro 3/10. Il più grande che sia mai sembrato essere 4/13(cosa che succede quando P=13e x=4). Perché dovrebbe essere?

Sia uun numero intero e supponiamo che 10u = kP + 1per un numero intero k, così uè un inverso di 10, modulo P. Quindi sappiamo anche che kè relativamente importante 10, poiché k(-P)equivale a 1modulo 10.

Ora sappiamo che le inverse di 10modulo Pdifferiscono tutte per multipli di P, quindi possiamo prendere l'intero ue aggiungere o sottrarre multipli di Pa piacimento, e il risultato sarà sempre un inverso di 10modulo P. Supponiamo che scegliamo di sottrarre Pda u: otteniamo

10(u - P) = 10u - 10P = kP + 1 - 10P

10(u - P) = (k - 10)P + 1

In altre parole, diminuire (rispettivamente aumentare) udi Pcorrisponde a diminuire (aumentare) kdi 10. Desideriamo aggiungere / sottrarre multipli di Pda ufino a quando il lato sinistro non viene minimizzato in valore assoluto; ma il lato sinistro è ridotto al minimo esattamente quando il lato destro è ridotta al minimo, e quindi vogliamo aggiungere / sottrarre 10dal kfino a quando il lato destro è ridotto al minimo in valore assoluto.

Ma sappiamo che questo avverrà quando kè compreso tra -5e 5, e quindi (in quanto kè relativamente privilegiata per 10) questo mezzo kè o -3, -1, 1o 3. (Questo è il contenuto del commento di @ Neil sotto l'OP. Grazie, Neil! )

Così, quando |u|è ridotto al minimo (cioè u=x), avremo x/P = u/P = k/10 + 1/(10P), in cui kè o -3, -1, 1o 3. Pertanto |x|/P <= 3/10 + 1/(10P). Equivalentemente, |x| <= (3P + 1)/10.

Inoltre, questa disuguaglianza è severa P=11, perché P=11abbiamo x=-1e k=-1. Il più piccolo Pper cui vale l'uguaglianza è P=13(dove x=4e k=3).

Quindi il più grande che |x|/Pabbia mai ottenuto è 3/10 + 1/(10*13), perché P=13è il primo primo per cui abbiamo k=3, e tra quelli con k=3, il 1/(10P)termine è più grande quando Pè il più piccolo (cioè, a P=13). Pertanto, per tutti P, abbiamo anche |x|/P <= 3/10 + 1/130 = 4/13 < 1/3. Questo spiega perché nel codice sopra possiamo inizializzare i = P/3piuttosto che dover iniziare da P/2.

Inoltre, ora è possibile migliorare i limiti nella sezione Utilità sopra.

Lemma : Lascia N = 10c + ddove c > 0e 0 <= d <= 9. Poi c + d|x| < N/10 + 9(3P + 1)/10. (Nota la disuguaglianza rigorosa.)

Prova di Lemma: per casi. Caso I: d = 0così N = 10c. Poi c + d|x| = c = N/10 < N/10 + 9(3P + 1)/10.

Caso II: 0 < d <= 9. Quindi 10c = N - d < N, quindic < N/10 . Pertanto c + d|x| < N/10 + d|x| <= N/10 + 9|x| <= N/10 + 9(3P + 1)/10. QED.

Quindi, se N > 3P(e N = 10c + dcome prima), allora

3P + 1 <= N

9(3P + 1)/10 <= 9N/10

N/10 + 9(3P + 1)/10 <= N

c + d|x| < N/10 + 9(3P + 1)/10 <= N

Quindi, se N > 3Pallorac + d|x| < N .

Pertanto, dobbiamo solo trovare P, 2Pe 3P, insieme a x. Dato N > 0, mentre N > 3P, sostituiamo Ncon |c + dx|, che diminuisce N. Alla fine avremo N <= 3P; a quel punto ci fermiamo e verificare se Nè uguale a uno qualsiasi dei numeri 0, P, 2P, o 3P.

Non possiamo fare di meglio che 3Pin generale. Ad esempio supponiamo P = 13e N = 39, quindi x = 4. Quindi sostituendo Ncon dx + c = 9(4) + 3foglie Ninvariate.


Spiegazione molto bella! È possibile salvare un byte spostandosi -1all'esterno della parentesi: 43 byte
fireflame241

@ fireflame241 Grazie mille! Potrei affermare che l'ho lasciato a 44 solo per poterlo cancellare (anche se questa sarebbe una bugia).
Mathmandan,

1

Spazio bianco , 92 byte

Si noti che la sintassi di questo linguaggio è composta solo da spazi bianchi , quindi ogni carattere di spazi bianchi è stato prefissato qui con S, T o L (corrispondenti rispettivamente a Space, Tab e Linefeed). Questi possono essere rimossi senza perdere funzionalità, ma sono inclusi qui per visualizzarli correttamente.

S S S L
T   L
T   T   S S S L
T   T   T   S L
S S S S T   T   L
T   S S L
S L
T   S S S T S T L
T   S T T   S L
S T S S S S S S T   S T L
T   S S T   T   S T S S S S T   L
T   S S S S S S T   S T S L
T   S T S T L
S T L
L
L
.

Provalo online!


1

Japt , 14 byte

Ispirato dalla soluzione di Neil .

Ì*2%E-3 *UÄ /A

Provalo online!

Spiegazione:

  Ì  *2%E-3 *UÄ  /A
((UgJ*2%E-3)*U+1)/A
  U                  // Implicit U = Input
   gJ                // Get the char at index -1 (last char)
     *2              // Multiply by 2
       %E            // Mod 14
         -3          // Minus 3
            *U+1     // Multiply by U+1
                 /A  // Divided by 10 

0

Pyke , 10 byte

~IIT*tR%)h

Provalo qui!

~I         -   Integers
  I     )  -  filter(^, not v)
   T*t     -    ^ *10 -1
      R%   -   input % ^
         h - ^[0]

0

Excel, 27 byte

=0.3/(MOD(A1,5)*2-5)*A1+0.1

Potrebbe essere inserito nella cella come

=.3/(MOD(A1,5)*2-5)*A1+.1

per 25 byte, ma Excel si aggiorna automaticamente.


In realtà penso che ti sia permesso di rivendicare il numero di byte che devi inserire (ma sono troppo pigro per controllare meta).
Neil,
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.