Problema di Giuseppe Flavio con tre ingressi


22

C'è una domanda su questo sito che è simile a questa domanda, ma ho aggiunto una svolta.

Hai tre input, il numero di persone nel cerchio n , la k -esima persona contata ad ogni passo e la q -esima persona che sopravvive. Le persone nel cerchio sono numerate da 1 a n .

Ad esempio, in una cerchia di 20 persone, la ventesima persona che sopravvive è la prima persona rimossa, il diciannovesimo sopravvissuto è la seconda persona rimossa e così via. Normalmente, il problema di Giuseppe Flavio è determinare l' ultima persona rimossa, qui chiamata il primo sopravvissuto.

Scrivi il programma o la funzione più breve che, con questi tre ingressi, restituisce il numero della persona q -sopravvissuta.

Se ci sono problemi con chiarezza, per favore fatemelo sapere.

Qualche esempio:

>>> josephus(20, 3, 9)
4
>>> josephus(4, 3, 1)
1
>>> josephus(100, 9, 12)
46

Modifica: supponiamo che tutti gli input siano validi. Cioè nessuno chiederà 0 o nessun numero negativo e nessuno chiederà il 20 ° sopravvissuto in un cerchio di 5 persone (ovvero 1 ≤ q ≤ n)

Modifica: accetterò una risposta a mezzanotte UTC + 7 all'inizio del 2 dicembre.


1
Pubblica le tue soluzioni come risposte invece di includerle nella domanda.
Maniglia della porta

Fatto. Mi dispiace per quello
Sherlock9,

1
Per chiarimenti, se q=1questo è esattamente lo stesso della domanda di Josephus collegata, giusto?
AdmBorkBork,

@TimmyD Exactly
Sherlock9

Risposte:


5

Pyth, 16 byte

eu.<PGvzh-QvwShQ

Provalo online: dimostrazione o suite di test

L'input è nella forma k<newline>n<newline>q.

Spiegazione:

eu.<PGvzh-QvwShQ   implicit: z = first input line (string)
                             Q = second input line (integer)
              hQ   Q + 1
             S     the range [1, 2, ..., Q+1]
 u      h-Qvw      apply the following statement (Q-input()+1) times to G=^
    PG                remove the last number of G
  .<  vz              and rotate eval(z) to the left
e                  print the last number of the resulting list  

7

Piet, 280 273 codici

inserisci qui la descrizione dell'immagine

Modifica: l' ho abbattuto ancora un po ', e penso di poterlo giocare ancora di più, ma deve ancora venire. Per ora, sono solo felice che funzioni e che ho avuto spazio per firmarlo nell'angolo in basso a sinistra. Due idee che devo salvare più codici sono a) per cambiare le istruzioni di fine pop, push 1, add, out num(pop n, output r + 1) eb) per duplicare di nuovo nell'angolo in basso a sinistra per salvare i codici nella manipolazione dello stack più avanti nel ciclo.

L'immagine sopra è il mio codice a 8 pixel per codice. In generale, è lo stesso algoritmo della mia risposta Python, ma con gli input nell'ordine di k , q , n . In pratica, c'è anche molta manipolazione dello stack. Puoi provarlo qui aprendo l'immagine lì ed eseguendo il codice con esso.

Spiegazione

Questo è un ungolfing graduale della soluzione.

in num    get k
dup       Stack: k k
push 1
subtract  Stack: k k-1
in num    get q
dup       Stack: k k-1 q q
dup       Stack: k k-1 q q q
push 4
push 2
roll      Stack: k q q k-1 q
mod       Stack: k q q r
in num    get n
# note: the loop will return to the following codel
dup       Stack: k q q r n n
push 4
push 3
roll      Stack: k q r n n q
greater   1 or 0
pointer   Here the loop begins. If q>n, the pointer moves clockwise.
          Else, it points straight ahead

LOOP:     Stack: k i r n (i=q at the start of the loop)
push 4
push 2
roll      Stack: r n k i
push 1
add       Stack: r n k i=i+1
push 2
push 1
roll      Stack: r n i k
dup       Stack: r n i k k
push 5
push 4
roll      Stack: n i k k r
add       Stack: n i k m=r+k
push 3
push 2
roll      Stack: n k m i
dup       Stack: n k m i i
push 3
# here it turns the corner
push 1
roll      Stack: n k i m i
mod       Stack: n k i r=m%i
push 4
# here it turns the corner and avoids the black codels
push 1
roll      Stack: r n k i
dup       Stack: r n k i i
push 5
push 3
roll      Stack: k i i r n
dup       Stack: k i i r n n
# and we meet up with the dark green codel once more
push 4
push 3
roll      Stack: k i r n n i
greater   Stack: k i r n (0 or 1)
pointer   if else again

# else    Stack: k i r n
push 2    
push 1
roll      Stack: k i n r
# and turn the corner
push 1
add       Stack: k i n r+1
out num   print r+1
# turn the corner into the end pattern (the shape with the black edges)
END

Non stai contando lo spazio vuoto? C'è un meta post da qualche parte su come segnare Piet? Probabilmente ci dovrebbe essere.
Sparr,

@Sparr, sto contando lo spazio vuoto. Si tratta di un codice 21 per immagine del codice 13, quindi il punteggio è 273 codici.
Sherlock9

Ah, ho contato male. Scusate.
Sparr,

4

CJam, 22 20 19 byte

q~_,@a@*{m<)\}%\~=)

Questo legge l'input come q k n. Provalo online nell'interprete CJam .

Come funziona

q~                   Read and evaluate all input. This pushes q, k, and n.
  _,                 Push A := [0 ... n-1].
    @a               Rotate on top of the stack and wrap it in an array.
      @*             Rotate the original n on top and repeat [k] n times.
        {    }%      For each of the n k's:
         m<            Rotate A k units to the left.
           )\          Pop the last element and swap it with A.
               \~    Swap the resulting array with q and apply bitwise NOT.
                 =)  Select the corresponding element and add 1 to it.

3

Golfscript, 58 56 55 35 31 30 byte

Supponendo che i tre input siano già nello stack, nell'ordine n , k , q

~1$(1$%3$),@),-{\2$+\%}%\)])\;

Questa soluzione presuppone che devo liberarmi di tutto tranne che della risposta finale.

Come funziona

Vedi j(n,k,q)nella mia soluzione Python 3 per maggiori dettagli.

~                                   Read the inputs n, k, q
 1$(                                Duplicate k, decrement
    1$                              Duplicate q
      %                             (k-1)%q
       3$),                         Create array [0..n+1]
           @),                      Create array [0..q+1]
              -                     Subtract the second array from the first,
                                        leaving only [q+1..n+1]
               {      }%            Map the following statement onto [q+1..n+1].
                                        The numbers from this array will be denoted i.
                \                   Swap i and r
                 2$+                Duplicate k, add to r
                    \               Swap r and i
                     %              r mod i
                        \)          Swap the leftover array from map with r, increment
                          ]         Put the whole stack into an array
                           )        Remove the last member of the array, r
                            \;      Pop the array, leaving only the result

Edit 1: Usata @ suggerimento di Maniglia (Aggiunto un + per ottenere tutti gli ingressi nella matrice)

In precedenza,

\.(2$2$*1$4$%-{.5$3$*>!}{~)2$*1$/~)}while 4$3$*\-)\;\;\;\;

Modifica 2: Aggiunto ~, secondo le regole del wiki, e abbreviato il codice. Grazie @Dennis

In precedenza,

[\.(2$2$*1$4$%-{.5$3$*>!}{~)2$*1$/~)}while 4$3$*\-)]+)\;

Modifica 3: implementato un algoritmo più breve.

In precedenza,

~\.(2$2$*1$4$%-{.5$3$*>!}{~)2$*1$/~)}while 4$3$*\-)]-1=

Modifica 4: capito che potrei usare %come mappa.

In precedenza,

~1$(1$%{1$4$<}{\)\2$+1$%}while)])\;

Modifica 5: modifica minore. Cambiato 2$per @fare [0..q-1]e 3$per 2$recuperare k. Ho salvato un morso

In precedenza,

~1$(1$%3$),2$),-{\3$+\%}%\)])\;

1
\;\;\;\;può essere sostituito con ])\;(avvolgere in array, uncons, swap e pop).
Maniglia della porta

Modificato il mio codice per chiarezza @Dennis.
Sherlock9,

Va bene @Dennis. Aggiunto ~ e modificato la domanda per consentire solo programmi e funzioni. Hai altri suggerimenti?
Sherlock9,

No, tutto bene. :)
Dennis,

2

JavaScript (ES6), 56 byte

(n,k,q)=>{r=(k-1)%q;for(i=q;i<n;r=(r+k)%++i);return r+1}

Ungolfed

Fondamentalmente un adattamento JavaScript della risposta Python di @ Sherlock9 .

(n,k,q)=>{
  r=(k-1)%q;
  for(i=q;i<n;r=(r+k)%++i);
  return r+1
}

Test

n = <input type="number" id="N" value="100" /><br />
k = <input type="number" id="K" value="9" /><br />
q = <input type="number" id="Q" value="12" /><br />
<button onclick="result.innerHTML=(

(n,k,q)=>{r=(k-1)%q;for(i=q;i<n;r=(r+k)%++i);return r+1}

)(+N.value,+K.value,+Q.value)">Go</button><br />
<pre id="result"></pre>


Non definirei la tua versione non giocata come non giocata: P
Fondo Monica's Lawsuit

1

Mathematica, 50 byte

<<Combinatorica`
Tr@Position[Josephus@##2,1+#2-#]&

Una funzione anonima. Accetta input nell'ordine q,n,k.


1

C, 81 73 byte

Basato sull'implementazione Javascript di @ user81655 della mia risposta Python.

Modifica: rimosso i

int j(int n,int k,int q){int r=(k-1)%q;for(;q<n;r=(r+k)%++q);return r+1;}

Test

#include <stdio.h>
int j(int n,int k,int q){int r=(k-1)%q;for(;q<n;r=(r+k)%++q);return r+1;}
int main()
{
    printf("%d\n", j(20,3,9));
    return 0;
}

In alcune versioni di C, è possibile eliminare intprima i nomi dei parametri.
Finanzia la causa di Monica il

1

Python 3, 72 66 62 byte

Una funzione di programmazione dinamica in 62 byte. Adattato dall'algoritmo su Wikipedia. C'era un'implementazione diretta di questo algoritmo quando q = 1 (cioè i = 1, r = 0) su quella pagina, ma vedo che ora è stato rimosso.

Modifica 1: ho rimosso iper salvare 4 byte. La spiegazione rimane invariata.

Modifica 2: Calcolo errato nel conteggio dei byte. Stavo usando \r\nper EOL e non ho notato quando questo ha aggiunto 3 byte. Ho ridotto il mio conteggio di byte di conseguenza.

def j(n,k,q):
 r=(k-1)%q
 while q<n:q+=1;r=(r+k)%q
 return r+1

Come funziona

def j(n,k,q):
 i=q;r=(k-1)%q              We start with the smallest possible circle to have a q-th
                                survivor, a circle of q people.
 while i<n:i+=1;            Iterate from q to n
                r=(r+k)%i   Every time you add people to the circle, r increases by k, 
                                modulo the current size of the circle i.
 return r+1                 Return the result.

Grazie a @Dennis per avermi ricordato che avrei dovuto spiegare il mio codice (anche se solo implicitamente, perché ne includeva uno nella sua risposta). Se qualcosa non è chiaro, per favore fatemi sapere.

Modificare:

In precedenza,

Una funzione iterativa che viene adattata da Concrete Mathematics da Graham, Knuth e Patashnik. Sebbene questo algoritmo sia più lungo, è più veloce per n grandi e piccoli k .

def t(n,k,q):
 m=k-1;z=q*k-m%q
 while z<=n*m:z=-(-z*k//m)
 return n*k-z+1

1
Sembra che tu abbia tagliato qualcosa nel copiare e incollare, c'è un impiccagione +.
xnor

1

PHP, 71 byte

Basato sulle risposte di @ Sherlock9. Vedi la sua risposta Python per l'algoritmo.

function a($n,$k,$q){for($r=($k-1)%$q;$q<$n;$r=($r+$k)%++$q);echo$r+1;}

In alternativa, ecco il mio approccio ingenuo originale senza algoritmo. Questo utilizza un array per contrassegnare quali persone sono state trovate.

91 byte

function a($n,$k,$q){for($r=--$i;$q<=$n;++$i%$k||$c[$r]=$q++)while($c[$r=++$r%$n]);echo$r;}

1

Haskell, 48 47 43 byte

(n!k)q=1+foldl(mod.(k+))(mod(k-1)q)[q+1..n]

Basato su un algoritmo Haskell sulla pagina del codice Rosetta della funzione Josephus con due input. I suggerimenti per il golf sono i benvenuti.

Modifica: I miei ringraziamenti a nimi per l'aiuto con il golf sul primo algoritmo tramite suggerimento di una versione senza punti e per l'aiuto con il golf sul secondo algoritmo facendomi sapere che la untilparola chiave esiste.

(n#k)q|m<-k-1=1+n*k-until(>n*m)(\z-> -div(-z*k)m)(q*k-mod m q)

Una versione dell'algoritmo alla fine della mia risposta Python adattata da Concrete Mathematics di Graham, Knuth e Patashnik. Sebbene questo algoritmo sia più lungo a 62 byte e non sia stato ridotto al minimo quanto il primo, è più veloce per grandi ne piccoli k.

Ungolfed:

Primo algoritmo

jos_g num step q = 1 + foldl (\x -> mod (x + step) ) (mod (step-1) q) [q+1..num]

Secondo algoritmo

jos_gkp num step q
    -- ceiling throws a type-related fit with ceiling(z*k/(k-1))
    -- better to use - div (-z * k) (k - 1)
    | m <- step-1 = 1 + num*step - until (>num*m)(\z-> -div (-z*k) m) (q*step - mod m q) 

Quindi hai scelto questa domanda per imparare nuove lingue con? 6/10 delle risposte sono tue: P
Mego,

@Mego L'ho menzionato in chat: DI mi ha chiesto se avrei dovuto postarlo comunque e hanno detto di andare avanti. Inoltre sì. I miei amici mi hanno detto che questo è il mio "Ciao, mondo!" per le nuove lingue: D
Sherlock9,

Non sto dicendo che questa è una brutta cosa. Sono solo divertito, tutto qui.
Mego

@ Sherlock9: si può usare untilper una traduzione (più o meno) diretto della versione di Python del 2 ° algoritmo: (n#k)q|m<-k-1=1+n*k-until(>n*m)(\z-> -div(-z*k)m)(q*k-mod m q).
nimi,

Dio ti benedica, @nimi: DI stava sbattendo la testa su quel problema da anni, provando foldled elenchi infiniti e ogni sorta di cose. Grazie per l'aiuto!
Sherlock9

1

GameMaker Language (GML), 88 byte

Basato sulla risposta di @ user81655

r=argument0
k=argument1
q=argument2
r=(k-1)mod q;for(i=q;i<n;r=(r+k)mod ++i){}return r+1

1

Gelatina , 14 13 byte

Rµṙ⁴ṖµL>⁵µ¿⁴ị

TryItOnline!

Come?

Rµṙ⁴ṖµL>⁵µ¿⁴ị - Main link: n, k, q
 µ            - monadic chain separation
R             - range(n): [1,2,3,...,n] - the circle of people
     µ   µ¿   - while
      L       -     length
       >      -     greater than
        ⁵     -     5th program argument (3rd input), i.e. q
  ṙ           -         rotate left by
   ⁴          -         4th program argument (2nd input) i.e. k
    Ṗ         -         pop - remove the rightmost person
            ị - get index
           ⁴  - 4th program argument (2nd input), i.e. k

0

Rubino, 53 48 byte

Una lambda.

->n,k,q{r=(k-1)%q;(q+=1;r=(r+k)%q)while q<n;r+1}

Come funziona

def j(n,k,q)
  r=(k-1)%q   # r starts at j[q,k,q]
  while q<n
    q+=1
    r=(r+k)%q # Every time you add people to the circle, r increases by k, 
              # modulo the current size of the circle q.
  end
  r+1         # Return the result.
end
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.