L'Orda Galleggiante


28

introduzione

La pioggia finalmente si è calmata. La maggior parte dell'umanità è annegata a causa di un bug nel codice di @ user12345 . I sopravvissuti sono sparsi in un arcipelago mondiale. La comunicazione radio è aumentata e l'umanità è pronta a prosperare ancora una volta. Per nessun motivo, i pirati zombi si sono radunati nel Meridiano Primo e stanno spazzando verso ovest. L'orda divora tutto.

Problema

Il nostro scenario del giorno del giudizio può essere descritto da 5 numeri interi su un'unica riga che rappresentano un insieme di comunità insulari cooperanti. Sono ordinati da ovest (intero più a sinistra) a est (intero più a destra).

A partire dall'isola più a est, gli isolani fuggono in coppia verso la successiva isola più vicina. Curiosamente, per ogni coppia che si imbarca, solo uno di loro sopravvive mai al viaggio. Gli isolani viaggiano solo in coppia. Strane popolazioni eleggono un unico abitante per restare indietro e fornire gli ultimi aggiornamenti radiofonici sulle buffonate dell'orda pirata zombi. Le popolazioni si rifiutano di viaggiare fino a quando tutte le isole ad est di loro non hanno completato le loro migrazioni o sono morte. Quando la popolazione raggiunge l'ultima isola più occidentale, il viaggio cessa.

Il responsabile delle operazioni alla fine del mondo ha bisogno di un programma in grado di produrre i conteggi finali della popolazione di ciascun villaggio.

Esempio di input

3 8 6 0 2

Esempio di output

8 1 0 1 0

ipotesi

  • L'input può essere fornito tramite stdin, letto da un file con nome arbitrario o accettato come argomento
  • Per ogni isola, 0 <= popolazione <= 1024
  • Le popolazioni non saltano mai un'isola

Vince la risposta più breve!


Quando dici argomento, intendi come argomento per una funzione o come argomento della riga di comando per il programma?
Aleksi Torhamo

@AleksiTorhamo Arg della riga di comando, quindi non conta per il tuo totale.
Rainbolt

29
Mi piace questa storia giorno del giudizio multi-domanda-spanning.
mikhailcazi,

ri: "le popolazioni non saltano mai un'isola" - il tuo esempio mostra che la popolazione muove più isole di seguito. C'è un altro significato che mi manca?
Allen Gould,

1
@AllenGould Le popolazioni si sono effettivamente spostate su più isole, ma non ne hanno mai saltato uno. Se ci fossero 32 persone sull'isola all'estrema destra, morirebbero come 16, 8, 4, e infine 2 raggiungerebbero l'isola più a sinistra.
Rainbolt

Risposte:


26

APL, 16 caratteri

{(1e9,4⍴2)⊤2⊥⍎⍵}

L'input è fornito come stringa a questo blocco:

{(1e9,4⍴2)⊤2⊥⍵} "3 8 6 0 2"
8 1 0 1 0

o un carattere in meno se l'input viene fornito come argomento per questo blocco:

{(1e9,4⍴2)⊤2⊥⍵} 3 8 6 0 2
8 1 0 1 0

Si basa sull'idea di Ilmari Karonen in questo commento .

  • 2⊥⍵ esegue una conversione base 2 dell'input.
  • (1e9,4⍴2)⊤converte quindi questo numero nella base 2 (per le ultime quattro cifre) e nella base 1e9 per la prima, che è sufficiente per gli intervalli di input indicati sopra. ( 1e9,4⍴2crea l'elenco 1e9 2 2 2 2.)

Si noti che l'ovest in fuga viene eseguito automaticamente dalla conversione di base durante questo processo.


Questo è geniale.
Gareth,

7
APLdovrebbe essere illegale ...
Kiwy,

1
@Kiwy Non capisco il tuo commento. Perché l'APL dovrebbe essere dichiarato illegale? Sentiti libero di inviare anche la tua soluzione APL.
Howard,

4
@Kiwy: Questo è molto più del semplice utilizzo di APL ... è anche un approccio molto intelligente alla soluzione, che si adatta perfettamente a un programma APL. Questo è il golf!
Claudiu,

13

GolfScript, 23 22 caratteri

~]{{.2/@+\2%}*]}4*' '*

Un approccio iterativo. L'array viene ripetuto più volte e ogni volta un numero di coppie viene trasferito da destra a sinistra. Prova l'esempio online .

Breve spiegazione del codice:

~]       # convert input to an integer
{        # loop 4 times (enough for a 5-elements input)
  {      # inject this block into the array
    .    # duplicate (l r r)
    2/   # determine surviving people (l r r%2)
    @+\  # add to the left (l+r/2 r)
    2%   # determine remaining people (l+r/2 r%2)
  }*
  ]      # make array again of the results
}4*
' '*     # format output

1
+1, questo è abbreviato di qualsiasi cosa potessi trovare. Ora, se non fosse solo per quella fastidiosa "sosta sull'isola più occidentale", ~]{2base}2*' '*farebbe il trucco ...
Ilmari Karonen,

@IlmariKaronen Scegli la lingua giusta (vedi la soluzione APL ) e la fastidiosa regola diventa a posto.
Howard,

8

GolfScript (25 caratteri)

~]-1%{\.1&\2/@+}*]-1%' '*

Demo online

Soluzione piuttosto semplice: esiste un approccio più interessante che definisce il valore di output per ogni isola in funzione dei valori di input, ma non credo che possa essere golfato quasi fino a seguire effettivamente l'algoritmo di ridistribuzione descritto nella domanda.


7

Javascript / ES6 (69)

Giocare con gli operatori bit a bit:

  • x&=1 mantiene il bit più basso (1 se dispari, 0 se pari)
  • x>>1 è divisione per 2 per numeri interi
f=a=>{a=a.split(' ');for(i=5;--i;a[i]&=1)a[i-1]-=-(a[i]>>1);return a}

Versione senza ES6:

function f(a){a=a.split(' ');for(i=5;--i;a[i]&=1)a[i-1]-=-(a[i]>>1);return a}

Esempi:
f("3 8 6 0 2")ritorni [8, 1, 0, 1, 0]
f("0 997 998 999 1000")ritorni[935, 0, 1, 1, 0]


1
Vedi i commenti di Rusher su una delle risposte di Python; l'input dovrebbe essere una stringa che segue il formato indicato nell'esempio, non un elenco.
Aleksi Torhamo

@AleksiTorhamo ha ragione. Consentire un elenco separato da virgole metterebbe il tuo codice in netto vantaggio rispetto a quelli che hanno seguito il formato fornito nell'esempio. In futuro, proverò ad essere più chiaro che il formato fornito nell'esempio è il formato. Mi dispiace per quello.
Rainbolt

OK, modificato. Anche l'output deve essere unito o il formato dell'array è ok?
Michael M.

Ne ho inventato più o meno lo stesso: f=a=>{a=a.split(' ');for(x=5;--x;a[x]&=1)a[x-1]-=-a[x]/2|0;return a}68 caratteri.
MT0

6

Python - 96 personaggi

Prima volta a giocare a golf! Input da stdin.

n=map(int,raw_input().split())
x=4
while x:n[x-1]+=n[x]/2;n[x]%=2;x-=1
print' '.join(map(str,n))

1
Puoi farlo scendere a 100 se comprimi il tempo fino a una riga usando i punti e virgola invece di newline e rientri e rimuovi lo spazio direttamente dopo la stampa :)
Aleksi Torhamo

@AleksiTorhamo Grazie. Ho anche imparato che la divisione intera in qualunque versione di Python che ho usato richiede solo una singola barra, quindi l'ho
buttata

1
Ah vero! Ho anche appena capito che puoi anche omettere la ' 'divisione, portandola a 96 e battendo le altre soluzioni python2.
Aleksi Torhamo,

5

J (26 caratteri)

Ecco la mia soluzione in J: ((<.@-:@}.,0:)+{.,2|}.)^:_

   islands1 =: 3 8 6 0 2
   islands2 =: 3 8 6 3 2
   ((<.@-:@}.,0:)+{.,2|}.)^:_ islands1
8 1 0 1 0
   ((<.@-:@}.,0:)+{.,2|}.)^:_ islands2
9 0 0 0 0

Questa soluzione generale dovrebbe funzionare con qualsiasi numero di isole.


5

Rubino, 97 90 74 72

Versione online

Ho giocato ancora un po ', non invertendo più l'array ...

f=->i{i=i.split.map(&:to_i);(1..4).each{|n|i[-n-1]+=i[-n]/2;i[-n]%=2};i}

Non devi invertire la stringa prima di dividere ma dopo. In caso contrario, la soluzione potrebbe produrre risultati errati per i numeri a più cifre nell'input.
Howard

Ho anche considerato entrambe le "possibilità" - anche se non sono a conoscenza di numeri con più di una cifra ...: D Grazie!
David Herrmann,

4

C - 121 caratteri

L'input è preso dallo stdin.

a[5];main(i){b(i=0,0);while(i++<5)printf("%i ",a[i-1]);}b(i,j){scanf("%i",&i);return j<5?i+=
b(i,j+1)/2,a[j]=j?i&1:i,i:0;}

È codificato per solo 5 isole?
Geobits

4

Python2 - 98 caratteri

Input da stdin.

s=[0]
for v in raw_input().split()[::-1]:s=[int(v)+s[0]/2,s[0]%2]+s[1:4]
print' '.join(map(str,s))

Python3 - 79 caratteri

Input da stdin.

s=[0]
for v in input().split()[::-1]:s=[int(v)+s[0]//2,s[0]%2]+s[1:4]
print(*s)

4

Python 2, 85 80 byte

b=1
for x in raw_input().split():b=2*b+int(x)
print b/16-2,' '.join(bin(b)[-4:])

X persone che iniziano su qualsiasi isola equivalgono a X * 2 persone che iniziano un'isola a destra. Questo codice converte tutti nella configurazione iniziale nel loro equivalente nelle isole dell'estrema destra, quindi utilizza la rappresentazione binaria del risultato per determinare quante persone finiscono su ciascuna isola.

EDIT: abbreviato il codice inizializzando ba 1 invece di 0, consentendo l'uso di binanziché una stringa di formato.


L'uso della rappresentazione binaria è ingegnoso! Lettercount.com ti ha dato un 85. Hai superato il conto o è un cattivo strumento da usare?
Rainbolt

@Rusher: il mio strumento utilizzava i finali di riga CRLF. Contandolo con i finali di linea Unix, è 85.
user2357112 supporta Monica

3

Python (101)

l=map(int,raw_input().split())
for i in range(4):l[3-i]+=l[4-i]/2;l[4-i]%=2
print' '.join(map(str,l))

Scorriamo l'elenco da dietro in avanti e spostiamo le popolazioni in base alle specifiche, quindi stampiamo l'elenco. Ecco un breve test:

>>> l=map(int,raw_input().split())
3 8 6 0 2
>>> for i in range(4):l[3-i]+=l[4-i]/2;l[4-i]%=2
... 
>>> print' '.join(map(str,l))
8 1 0 1 0

Arresto anomalo se fornito con input che segue il formato fornito nell'esempio.
Rainbolt

@Rusher Ho aggiornato la risposta per funzionare con il formato esatto utilizzato nella domanda.
Arshajii,

Altri potrebbero essere in svantaggio se sono consentite eccezioni speciali per i programmatori Python. Siamo spiacenti e grazie per aver aggiornato la tua risposta. Proverò ad essere più chiaro in futuro che l'input di esempio è il formato richiesto.
Rainbolt

2

Mathematica 105

Questo dovrebbe funzionare con qualsiasi numero di isole.

f[w_,n_:1]:=
If[n==Length@w,w,
f[w~ReplacePart~{-n-> Mod[z=w[[-n]],2],-(n+1)->(w[[-(n+1)]]+ z~Quotient~2)},n+1]]

Esempi

5 isole

f[{3, 8, 6, 0, 2}]

{8, 1, 0, 1, 0}


25 isole

f[{145, 144, 144, 59, 35, 129, 109, 99, 200, 24, 219, 96, 12, 121, 75,20, 153, 124, 131, 178, 228, 120, 63, 207, 228}]

{270, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0 }


La mia soluzione produce 270, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0per i tuoi dati di test lunghi. Penso di aver confermato che ho ragione.
OldCurmudgeon

Strano, visto come funziona. Domani darò un'occhiata al caso.
DavidC

2

Java - 647 533 ma sperando in alcuni punti brownie per Java 8 Streams.

class I{int p;I e;I(int p,I e){this.p=p;this.e=e;}void x(){if(e!=null){int r=p&1;e.p+=(p-r)/2;p=r;}}public String toString(){return ""+p;}}Deque<I>B(String d){H<I>e=new H<>();return Arrays.stream(d.split(" ")).map(s->Integer.valueOf(s)).map(p->e.hold(new I(p,e.held()))).collect(Collectors.toCollection(LinkedList::new));}void x(Deque<I>is){is.descendingIterator().forEachRemaining((I i)->{i.x();});}void t(String s){Deque<I> a=B(s);x(a);System.out.println(a);}class H<T>{T h=null;H(){}T hold(T t){return (h=t);}T held(){return h;}}

La forma non compressa:

private static class Island {
  int population;
  final Island eastwardIsland;

  Island(int population, Island eastwardIsland) {
    this.population = population;
    this.eastwardIsland = eastwardIsland;
  }

  private void exodus() {
    if (eastwardIsland != null) {
      // How many remain.
      int remain = population & 1;
      // How many leave.
      int leave = population - remain;
      // Account for 50% death rate.
      int arrive = leave / 2;
      // Modify the eastward island population.
      eastwardIsland.population += arrive;
      // Change my population.
      population = remain;
    }
  }

  @Override
  public String toString() {
    return String.valueOf(population);
  }

}

private Deque<Island> buildIslands(String data) {
  // Holds the island to the east as we traverse.
  final Holder<Island> eastward = new Holder<>();
  // Build my list of islands - assumes order is retained.
  return Arrays.stream(data.split(" "))
          // Convert to int.
          .map(s -> Integer.valueOf(s))
          // Build the island in a chain.
          .map(p -> eastward.hold(new Island(p, eastward.held())))
          // Roll them into a linked list.
          .collect(Collectors.toCollection(LinkedList::new));
}

private void exodus(Deque<Island> islands) {
  // Walk backwards.
  islands.descendingIterator()
          // Perform all exodus.
          .forEachRemaining((Island i) -> {
            i.exodus();
          });
}

private void test(String data) {
  Deque<Island> archipelago = buildIslands(data);
  // Initiate the exodus.
  exodus(archipelago);
  // Print them.
  System.out.println(archipelago);
}

Con un aiuto di:

// Mutable final.
private static class Holder<T> {
  private T held = null;

  public Holder() {
  }

  public Holder(T it) {
    held = it;
  }

  public T hold(T it) {
    return (held = it);
  }

  public T held() {
    return held;
  }

  @Override
  public String toString() {
    return held == null ? "null" : held.toString();
  }

}

Leggermente preoccupato per il fatto che @ DavidCarraher's test:

145 144 144 59 35 129 109 99 200 24 219 96 12 121 7520 153 124 131 178 228 120 63 207 228

genera

270, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0

2

Java - 196 195

Mi sono detto che non l'avrei pubblicato se non riuscissi a ottenerlo sotto i 200 ... Onestamente non penso di potermi sbarazzare di qualsiasi altra cosa, è piuttosto sottile per Java.

class H{public static void main(String[]a){int l=a.length,p[]=new int[l],i=l;for(;i-->0;){p[i]=Integer.valueOf(a[i]);if(l-i>1){p[i]+=p[i+1]/2;p[i+1]%=2;}}for(;++i<l;System.out.print(p[i]+" "));}}

Interruzioni di riga:

class H{
    public static void main(String[]a){
        int l=a.length,p[]=new int[l],i=l;
        for(;i-->0;){
            p[i]=Integer.valueOf(a[i]);
            if(l-i>1){
                p[i]+=p[i+1]/2;
                p[i+1]%=2;
            }
        }
        for(;++i<l;System.out.print(p[i]+" "));
    }
}

Esempio di input input:

$ java H 3 8 6 0 2
8 1 0 1 0

$ java H 0 1 2 3 4 5 6 7 8 9 10
1 1 1 1 1 1 1 0 1 0 0

$java H 235 897 158 693
809 1 0 1

2

Java - 179 caratteri

compressa:

class F{public static void main(String[] a){int l=0,x,s,i=a.length-1;String z="";for(;0<=i;i--){x=Integer.valueOf(a[i])+l;s=i>0?x%2:x;l=(x-x%2)/2;z=s+" "+z;}System.out.print(z);}}

Normale:

public class FloatingHorde {

    public static void main(String[] a) {
        int leave = 0;
        String outputStr = "";
        for (int i = a.length - 1; 0 <= i ; i--) {
            int x = Integer.valueOf(a[i]) + leave;
            int stays = i > 0 ? x % 2 : x;
            leave = (x - x % 2) / 2;
            outputStr = stays + " " + outputStr;
        }
        System.out.print(outputStr);
    }
}

Uscita campione:

$ java F 3 8 6 0 2
8 1 0 1 0

$ java F 7 6 5 4 3
11 1 1 1 1

0

Emacs Lisp 144 caratteri

Non minuscolo, ma funziona

(lambda (d)
   (setq x d)(while(cdr x)
           (setcar(cdr x)(+(/(-(car x)(%(car x)2))2)(cadr x)))
           (setcar x (-(car x)(*(/(car x)2)2)))
       (pop x))
   (reverse d))

Puoi aggiungere un'intestazione come #Java - 123 Personaggi
Rainbolt

0

awk - 44 personaggi

{for(i=NF;i>1;){n=int($i/2);$i%=2;$--i+=n}}1

-2

Java - 116 personaggi

Per esempio int[] i = {2, 33, 16, 5}; (suppongo che quelli non si aggiungano al conteggio, poiché ogni numero può variare) verrebbe prodotto23 0 0 1

for(int j = i.length-1; j > 0; j--) {       
    while(i[j] > 1) {
        i[j] -= 2;
        i[j-1]++;
    }       
}
for(int j = 0; j < i.length; j++) {     
    System.out.print(i[j] + " ");
}

4
Potete fornire un compilatore che eseguirà questo codice? Inoltre, nella domanda sono stati forniti il ​​formato e le possibili fonti per l'input. Modellare l'input in un array Java ti dà un vantaggio ingiusto rispetto agli altri.
Rainbolt,
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.