Die schwimmende Horde

28

Einführung

Der Regen ließ endlich nach. Der größte Teil der Menschheit ist aufgrund eines Fehlers im Code von @ user12345 ertrunken . Überlebende sind auf einem weltweiten Archipel verstreut. Die Funkkommunikation ist unterbrochen, und die Menschheit ist bereit, sich wieder zu entfalten. Ohne jeden Grund haben sich Zombie-Piraten am Nullmeridian versammelt und ziehen nach Westen. Die Horde verschlingt alles.

Problem

Unser Weltuntergangsszenario kann durch 5 ganze Zahlen in einer einzigen Zeile beschrieben werden, die eine Reihe von kooperierenden Inselgemeinschaften darstellen. Sie sind von West (ganz links) nach Ost (ganz rechts) angeordnet.

Beginnend mit der östlichsten Insel fliehen die Inselbewohner paarweise zur nächstgelegenen Insel. Seltsamerweise überlebt für jedes Paar, das sich einschifft, nur eines die Reise. Inselbewohner reisen nur zu zweit. Seltsame Bevölkerungsgruppen wählen einen einzigen Bewohner, der zurückbleibt und die neuesten Radio-Updates zu den Possen der Zombie-Piratenhorde liefert. Die Bevölkerung weigert sich zu reisen, bis alle Inseln im Osten ihre Wanderungen abgeschlossen haben oder gestorben sind. Wenn die Bevölkerung die letzte, westlichste Insel erreicht, hört die Reise auf.

Der Betriebsleiter am Ende der Welt benötigt ein Programm, das die endgültigen Bevölkerungszahlen jedes Dorfes ausgibt.

Beispiel Eingabe

3 8 6 0 2

Beispielausgabe

8 1 0 1 0

Annahmen

  • Die Eingabe kann über stdin erfolgen, aus einer Datei mit willkürlichem Namen gelesen oder als Argument akzeptiert werden
  • Für jede Insel gilt 0 <= Bevölkerung <= 1024
  • Die Bevölkerung überspringt niemals eine Insel

Kürzeste Antwort gewinnt!

Regenblitz
quelle
Wenn Sie argumentieren, meinen Sie das als Argument für eine Funktion oder als Befehlszeilenargument für das Programm?
Aleksi Torhamo
@AleksiTorhamo Befehlszeilenargument, sodass es nicht zu Ihrer Gesamtsumme zählt.
Rainbolt
29
Ich liebe diese mehrfragenübergreifende Weltuntergangsgeschichte.
mikhailcazi
Betreff: "Populationen überspringen niemals eine Insel" - Ihr Beispiel zeigt eine Population, die mehrere Inseln in einer Reihe bewegt. Gibt es eine andere Bedeutung, die mir fehlt?
Allen Gould
1
@AllenGould Die Populationen haben zwar mehrere Inseln überquert, aber nie eine übersprungen. Wenn es 32 Menschen auf der ganz rechten Insel gäbe, würden sie wie 16, 8, 4 sterben und schließlich würden 2 die ganz linke Insel erreichen.
Rainbolt

Antworten:

26

APL, 16 Zeichen

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

Die Eingabe wird als Zeichenfolge für diesen Block bereitgestellt:

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

oder ein Zeichen weniger, wenn die Eingabe als Argument für diesen Block bereitgestellt wird:

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

Es basiert auf der Idee von Ilmari Karonen in diesem Kommentar .

  • 2⊥⍵ Führt eine Basis-2-Konvertierung der Eingabe durch.
  • (1e9,4⍴2)⊤wandelt diese Zahl also wieder in Basis 2 (für die vier letzten Stellen) und Basis 1e9 für die erste um, was für die oben angegebenen Eingabebereiche ausreicht. ( 1e9,4⍴2Erstellt die Liste 1e9 2 2 2 2.)

Beachten Sie, dass die Flucht nach Westen während dieses Vorgangs automatisch durch die Basisumwandlung erfolgt.

Howard
quelle
Das ist Genie.
Gareth
7
APL
Sollte
1
@ Kiwy Ich verstehe deinen Kommentar nicht. Warum sollte APL für illegal erklärt werden? Sie können auch Ihre APL-Lösung einreichen.
Howard
4
@Kiwy: Dies ist mehr als nur die Verwendung von APL ... es ist auch ein sehr kluger Lösungsansatz, der sich sehr gut in ein APL-Programm einfügt. Darum geht es beim Golf!
Claudiu
13

GolfScript, 23 22 Zeichen

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

Ein iterativer Ansatz. Das Array wird mehrmals iteriert und jedes Mal wird eine Anzahl von Paaren von rechts nach links übertragen. Probieren Sie das Beispiel online aus .

Kurze Erklärung des Codes:

~]       # 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
Howard
quelle
1
+1, das ist kürzer als alles, was ich finden konnte. Wäre da nicht die lästige Regel "Stopp auf der westlichsten Insel", ~]{2base}2*' '*wäre das der Fall ...
Ilmari Karonen
@IlmariKaronen Wählen Sie die richtige Sprache (siehe APL-Lösung ) und die lästige Regel wird in Ordnung.
Howard
8

GolfScript (25 Zeichen)

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

Online-Demo

Ziemlich einfache Lösung: Es gibt einen interessanteren Ansatz, bei dem der Ausgabewert für jede Insel in Abhängigkeit von den Eingabewerten definiert wird. Ich denke jedoch, er kann nicht annähernd so weit golfen werden, wie es tatsächlich mit dem in der Frage beschriebenen Umverteilungsalgorithmus möglich ist.

Peter Taylor
quelle
7

Javascript / ES6 (69)

Spielen mit bitweisen Operatoren:

  • x&=1 behält das niedrigste Bit (1 wenn ungerade, 0 wenn gerade)
  • x>>1 ist eine Division durch 2 für ganze Zahlen
f=a=>{a=a.split(' ');for(i=5;--i;a[i]&=1)a[i-1]-=-(a[i]>>1);return a}

Version ohne ES6:

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

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

Michael M.
quelle
1
Siehe Rushers Kommentare zu einer der Python-Antworten; Die Eingabe sollte eine Zeichenfolge sein, die dem im Beispiel angegebenen Format folgt, keine Liste.
Aleksi Torhamo
@ AleksiTorhamo ist richtig. Wenn Sie eine durch Kommas getrennte Liste zulassen, hat Ihr Code einen deutlichen Vorteil gegenüber denen, die dem im Beispiel angegebenen Format folgen. In Zukunft werde ich versuchen, klarer zu machen, dass es sich bei dem im Beispiel angegebenen Format um das Format handelt. Das tut mir leid.
Rainbolt
OK, bearbeitet. Soll die Ausgabe auch verknüpft werden oder ist das Array-Format in Ordnung?
Michael M.
Ich habe mir ungefähr das Gleiche ausgedacht: f=a=>{a=a.split(' ');for(x=5;--x;a[x]&=1)a[x-1]-=-a[x]/2|0;return a}das sind 68 Zeichen.
MT0
6

Python - 96 Zeichen

Zum ersten Mal Golf spielen! Eingabe von 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))
Regenblitz
quelle
1
Sie können den Wert auf 100 reduzieren, indem Sie den Wert auf eine Zeile reduzieren, indem Sie Semikolons anstelle von Zeilenumbrüchen und Einrückungen verwenden und das Leerzeichen direkt nach dem Druck entfernen :)
Aleksi Torhamo
@ AleksiTorhamo Vielen Dank. Ich habe auch erfahren, dass die Ganzzahldivision in jeder Version von Python, die ich verwendet habe, nur einen einzigen Schrägstrich erfordert, sodass ich sie unter 100 gesetzt habe.
Rainbolt
1
Ah, stimmt! Mir ist auch gerade klar geworden, dass Sie das auch weglassen können ' ', indem Sie es auf 96 reduzieren und die anderen Python2-Lösungen übertreffen.
Aleksi Torhamo
5

J (26 Zeichen)

Hier ist meine Lösung 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

Diese allgemeine Lösung sollte mit einer beliebigen Anzahl von Inseln funktionieren.

Thomas Baruchel
quelle
5

Rubin, 97 90 74 72

Online Version

Golf es ein bisschen weiter, nicht mehr das Array umkehren ...

f=->i{i=i.split.map(&:to_i);(1..4).each{|n|i[-n-1]+=i[-n]/2;i[-n]%=2};i}
David Herrmann
quelle
Sie dürfen die Zeichenfolge vor dem Teilen nicht umkehren, sondern erst danach. Andernfalls liefert Ihre Lösung möglicherweise falsche Ergebnisse für mehrstellige Zahlen in der Eingabe.
Howard
Ich habe sogar beide "Möglichkeiten" in Betracht gezogen - obwohl ich keine Zahlen mit mehr als einer Ziffer kenne ...: D Danke!
David Herrmann
4

C - 121 Zeichen

Die Eingabe erfolgt aus 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;}
Oberon
quelle
Ist das nur für 5 Inseln fest programmiert?
Geobits
4

Python2 - 98 Zeichen

Eingabe von 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 Zeichen

Eingabe von stdin.

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

Python 2, 85-80 Bytes

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

X Personen, die auf einer beliebigen Insel beginnen, entsprechen X * 2 Personen, die eine Insel auf der rechten Seite beginnen. Dieser Code konvertiert alle Benutzer in der Startkonfiguration in ihre Entsprechung in Insulanern ganz rechts und verwendet dann die binäre Darstellung des Ergebnisses, um zu bestimmen, wie viele Benutzer auf jeder Insel landen.

BEARBEITEN: Verkürzung des Codes durch Initialisierung bauf 1 anstelle von 0, wodurch binanstelle einer Formatzeichenfolge die Verwendung gestattet wird .

user2357112 unterstützt Monica
quelle
Die Verwendung der Binärdarstellung ist genial! Lettercount.com hat Ihnen eine 85 gegeben. Haben Sie überzählt oder ist Lettercount ein schlechtes Werkzeug?
Rainbolt
@ Rusher: Mein Tool verwendete CRLF-Zeilenenden. Mit Unix-Zeilenenden sind es 85.
user2357112 unterstützt Monica am
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))

Wir durchlaufen die Liste von hinten nach vorne und verschieben die Populationen entsprechend der Spezifikation. Anschließend drucken wir die Liste aus. Hier ist ein kurzer 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
arshajii
quelle
Absturz bei Eingabe, die dem im Beispiel angegebenen Format entspricht.
Rainbolt
@ Rusher Ich habe die Antwort aktualisiert, um mit dem genauen Format zu arbeiten, das in der Frage verwendet wurde.
Arshajii
Andere können benachteiligt sein, wenn für Python-Codierer spezielle Ausnahmen zulässig sind. Entschuldigung und vielen Dank für die Aktualisierung Ihrer Antwort. Ich werde versuchen, in Zukunft klarer zu machen, dass die Beispieleingabe das erforderliche Format ist.
Rainbolt
2

Mathematica 105

Dies sollte mit einer beliebigen Anzahl von Inseln funktionieren.

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]]

Beispiele

5 Inseln

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

{8, 1, 0, 1, 0}


25 Inseln

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, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0 }

DavidC
quelle
Meine Lösung produziert 270, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0für Sie lange Testdaten. Ich glaube, ich habe bestätigt, dass ich richtig bin.
OldCurmudgeon
Seltsam, wenn man bedenkt, wie es funktioniert. Ich werde morgen einen Blick auf den Fall werfen.
DavidC
2

Java - 647 533, aber in der Hoffnung auf ein paar Brownie-Punkte für 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;}}

Die unkomprimierte Form:

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);
}

Mit Unterstützung von:

// 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();
  }

}

Etwas besorgt darüber, dass @ 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

erzeugt

270, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0
OldCurmudgeon
quelle
2

Java - 196 195

Ich sagte mir, ich würde es nicht posten, wenn ich es nicht unter 200 kriegen könnte ... Ich glaube ehrlich gesagt nicht, dass ich irgendetwas anderes loswerden kann, es ist ziemlich schlank für 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]+" "));}}

Zeilenumbrüche:

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]+" "));
    }
}

Beispiel Input Output:

$ 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
Geobits
quelle
2

Java - 179 Zeichen

Komprimiert:

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);}}

Normal:

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);
    }
}

Beispielausgabe:

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

$ java F 7 6 5 4 3
11 1 1 1 1
Hopper Hunter
quelle
0

Emacs Lisp 144 Zeichen

Nicht winzig, aber es funktioniert

(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))
Jordon Biondo
quelle
Sie könnten einen Header wie #Java - 123 Characters
Rainbolt
0

awk - 44 Zeichen

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

Java - 116 Zeichen

Zum Beispiel int[] i = {2, 33, 16, 5};(ich denke, diese addieren sich nicht zur Zählung, da jede Zahl variieren kann) würde ausgegeben23 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] + " ");
}
Jochen Reinschlüssel
quelle
4
Können Sie einen Compiler bereitstellen, der diesen Code ausführt? Auch das Format und die möglichen Quellen für die Eingabe wurden in der Frage angegeben. Durch das Formen der Eingabe in ein Java-Array erhalten Sie einen unfairen Vorteil gegenüber anderen.
Rainbolt