Test di divisibilità impaziente


14

Il tuo compito è scrivere un programma o una funzione che determini se un numero è divisibile per un altro. Il trucco è che dovrebbe dare una risposta il più presto possibile , anche se non sono state fornite tutte le cifre del numero.

Il tuo programma dovrebbe prendere un numero intero D ≥ 2 e quindi una serie di cifre come input. Questi rappresentano le cifre di un altro numero intero N ≥ 1, iniziando dalla cifra meno significativa. Al primo punto che N sia necessario o non deve essere divisble da D , il programma dovrebbe uscita la risposta appropriata e uscire. Se viene raggiunta la fine dell'input, dovrebbe uscita se l'intero N è divisibile per D .

Ecco un elenco di formati di input accettabili per N (lascia un commento se pensi che dovrebbe essere consentito qualcosa che non è incluso):

  • Input standard : le cifre sono indicate su righe separate; la fine dell'input è EOF o un valore speciale; exit indica che la funzione ritorna o il programma esce.

  • Ingresso analogico : tramite ad esempio sequenze di tasti o dieci pulsanti che rappresentano ciascuna cifra; la fine dell'input è un valore speciale; exit indica che la funzione ritorna o il programma esce.

  • Funzione con stato globale : chiamata ripetutamente con cifre successive; la fine dell'input è un valore speciale; exit indica che la funzione restituisce un valore non nullo. Se si utilizza lo stato globale, è necessario cancellarlo dopo la restituzione di un valore o in caso contrario ripristinarlo in modo tale che la funzione funzioni più volte .

  • Funzione al curry : restituisce un'altra funzione da chiamare con la cifra successiva o un valore; la fine dell'input è un valore speciale o chiama la funzione senza argomento; exit indica che la funzione restituisce una risposta anziché un'altra funzione.

  • Prompt della GUI o simile : visualizzato ripetutamente; la fine dell'input è "annulla" o equivalente, o un valore speciale; exit indica che i prompt non vengono più visualizzati.

  • Funzione Iteratore : input è un oggetto o una funzione stateful che restituisce la cifra successiva quando viene chiamato, la fine dell'ingresso è un'eccezione o un valore speciale; exit indica che l'iteratore smette di essere chiamato.

L'input per D e l'output possono essere eseguiti con qualsiasi metodo standard accettabile .

Casi test:

2;   6               => true
5;   6               => false
20;  0 3             => false
20;  0 4             => true
100; 1               => false
100; 0 0             => true
100; 0 2             => false
4;   2 4             => false
4;   2 5             => true
4;   2 [eof]         => false
4;   4 [eof]         => true
625; 5 5             => false
625; 5 7 2           => false
625; 5 7 3 6         => false
625; 5 7 3 4         => true
7;   9 3 4 [eof]     => false
7;   9 3 4 5 [eof]   => true
140; 0 3             => false
140; 0 4 5 [eof]     => false
140; 0 4 5 1 [eof]   => true
14;  4 5 1 4 [eof]   => false
14;  4 5 1 4 1 [eof] => true

Penso che dovremmo presumere che verrà fornita una cifra ogni volta che la nostra soluzione richiede input, giusto? E dovrebbe essere un programma completo, poiché questo è il modo oggettivo per garantire che l'input venga dato cifra per cifra, no? (La sfida dice "programma o funzione", hmm ...)
Erik the Outgolfer

1
@EriktheOutgolfer Il formato di input è spiegato in dettaglio nell'elenco puntato nella domanda.
Maniglia della porta

1
Stavo solo pensando a come possono essere oggettivi quei formati ... Immagino che smetterò di usare il nitpicking e inizierò a risolverlo . :-)
Erik the Outgolfer,

1
C'è qualcosa di sbagliato nel prendere un elenco come digitsinput con un valore speciale per EOF?
Jonathan Allan,

1
@EriktheOutgolfer non se esiste un valore EOF, a meno che non abbia frainteso qualcosa. Per esempio diciamo che tutto il valore è 132 e il potenziale divisore è 4 quindi []e [2]niente di ritorno diverso falseo true(tra cui la stessa funzione, ecc ...), mentre [2,3], [2,3,1]e [2,3,1,EOF]ritorno true. Mi sembra il più vicino all'opzione dello stato globale.
Jonathan Allan,

Risposte:


9

JavaScript (ES6), 70 byte

Formato di input: funzione al curry

-101

p=>(q='',g=(d,t=k=z=!~d||(q=d+q,p))=>k--?g(d,t-=(k+q)%p<1):t?t-z&&g:1)

Provalo online!

Come?

pqn0K<p

(1)K×10n+q(modp)

Xpm10K<pX=mp+K

X×10n+q(modp)=(mp+K)×10n+q(modp)=(mp×10n(modp))+(K×10n+q(modp))(modp)=0+(K×10n+q(modp))(modp)=K×10n+q(modp)

(1)00K<p0Kp

(1)00K<p

(1)q

Commentate

p => (                       // p = divisor
  q = '',                    // q = dividend stored as a string, initially empty
  g = (                      // g() = curried function taking:
    d,                       //   d = next digit
    t =                      //   t = number of iterations yielding a non-zero value
    k =                      //   k = total number of iterations to process
    z =                      //   z = copy of k
      !~d ||                 //   if d == -1 (meaning EOF), use only 1 iteration
                             //   so that we simply test the current value of q
      (q = d + q, p)         //   otherwise, prepend d to q and use p iterations
  ) =>                       //
    k-- ?                    //   decrement k; if it was not equal to zero:
      g(                     //     do a recursive call to g():
        d,                   //       pass the current value of d (will be ignored anyway)
        t -= (k + q) % p < 1 //       test (k + q) % p and update t accordingly
      )                      //     end of recursive call
    :                        //   else:
      t ?                    //     if t is greater than 0:
        t - z && g           //       return 0 if t == z, or g otherwise
      :                      //     else:
        1                    //       return 1
)                            //

2

Lotto, 177 169 byte

@set n=
@set g=1
:l
@set/ps=
@if %s%==- goto g
@set n=%s%%n%
@set/ae=%1/g,g*=2-e%%2,g*=1+4*!(e%%5),r=n%%g
@if %g% neq %1 if %r%==0 goto l
:g
@cmd/cset/a!(n%%%1)

Prende dcome parametro della riga di comando e legge le cifre nsu righe separate con -come marker EOF. Uscite 1per divisibili, in 0caso contrario. Spiegazione:

@set n=

Inizializzazione nsulla stringa vuota.

@set g=1

g è gcd(d, 10**len(n))

:l

Inizia un ciclo leggendo le cifre.

@set/ps=

Leggi la cifra successiva.

@if %s%==- goto g

Interrompere l'elaborazione su EOF.

@set n=%s%%n%

Prepara la cifra successiva a n.

@set/ae=%1/g,g*=2-e%%2,g*=1+4*!(e%%5),r=n%%g

Aggiorna gora che len(n)è aumentato e calcolato n%g.

@if %g% neq %1 if %r%==0 goto l

Se rè diverso da zero, allora dsicuramente non si divide n, perché g, un fattore di d, no. Se rè zero, allora sappiamo solo se ddivide nse guguale a d, quindi se non lo è, continua il ciclo.

:g

Rompere il ciclo di lettura delle cifre qui su EOF.

@cmd/cset/a!(n%%%1)

Calcola e genera implicitamente il risultato.

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.