La horde flottante

28

introduction

La pluie s'est finalement calmée. La plupart de l'humanité s'est noyée en raison d'un bogue dans le code de @ user12345 . Les survivants sont dispersés dans un archipel mondial. La communication radio est en hausse, et l'humanité est prête à prospérer une fois de plus. Pour aucune raison que ce soit, des pirates zombies se sont rassemblés au premier méridien et se dirigent vers l'ouest. La horde dévore tout.

Problème

Notre scénario apocalyptique peut être décrit par 5 entiers sur une seule ligne qui représentent un ensemble de communautés insulaires coopérantes. Ils sont classés de l'ouest (entier le plus à gauche) à l'est (entier le plus à droite).

En commençant par l'île la plus à l'est, les insulaires s'enfuient par paires jusqu'à la prochaine île la plus proche. Curieusement, pour chaque paire qui s'embarque, un seul d'entre eux survit au voyage. Les insulaires voyagent uniquement par paires. Les populations étranges élisent un habitant unique pour rester derrière et fournir les dernières mises à jour radio sur les pitreries de la horde de pirates zombies. Les populations refusent de voyager jusqu'à ce que toutes les îles à l'est d'entre elles aient achevé leurs migrations ou soient mortes. Lorsque la population atteint la dernière île la plus à l'ouest, les voyages cessent.

Le directeur des opérations à la fin du monde a besoin d'un programme capable de produire les chiffres de population finaux de chaque village.

Exemple d'entrée

3 8 6 0 2

Exemple de sortie

8 1 0 1 0

Hypothèses

  • L'entrée peut être fournie via stdin, lue à partir d'un fichier nommé arbitrairement ou acceptée comme argument
  • Pour chaque île, 0 <= population <= 1024
  • Les populations ne sautent jamais une île

La réponse la plus courte gagne!

Rainbolt
la source
Lorsque vous dites argument, voulez-vous dire comme argument d'une fonction ou comme argument de ligne de commande du programme?
Aleksi Torhamo
@AleksiTorhamo Argument de ligne de commande, donc il ne comptera pas dans votre total.
Rainbolt
29
J'adore cette histoire de Doomsday multi-question transmembranaires.
mikhailcazi
re: "les populations ne sautent jamais une île" - votre exemple montre une population se déplaçant sur plusieurs îles d'affilée. Y a-t-il un autre sens qui me manque?
Allen Gould
1
@AllenGould Les populations ont effectivement traversé plusieurs îles, mais elles n'en ont jamais sauté une. S'il y avait 32 personnes sur l'île la plus à droite, elles mourraient comme 16, 8, 4, et finalement 2 atteindraient l'île la plus à gauche.
Rainbolt

Réponses:

26

APL, 16 caractères

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

L'entrée est fournie sous forme de chaîne à ce bloc:

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

ou un caractère de moins si l'entrée est fournie en argument à ce bloc:

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

Il est basé sur l'idée d'Ilmari Karonen dans ce commentaire .

  • 2⊥⍵ effectue une conversion en base 2 de l'entrée.
  • (1e9,4⍴2)⊤convertit ainsi ce nombre en base 2 (pour les quatre derniers chiffres) et en base 1e9 pour le premier, ce qui est suffisant pour les plages d'entrée données ci-dessus. ( 1e9,4⍴2construit la liste 1e9 2 2 2 2.)

Notez que la fuite vers l'ouest se fait automatiquement par la conversion de base au cours de ce processus.

Howard
la source
C'est génial.
Gareth
7
APLdevrait être illégal ...
Kiwy
1
@Kiwy Je ne comprends pas votre commentaire. Pourquoi APL devrait-il être déclaré illégal? N'hésitez pas à soumettre également votre solution APL.
Howard
4
@Kiwy: C'est plus qu'une simple utilisation d'APL ... c'est aussi une approche très intelligente de la solution, qui se trouve très bien s'intégrer dans un programme APL. C'est ça le golf!
Claudiu
13

GolfScript, 23 22 caractères

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

Une approche itérative. Le tableau est itéré plusieurs fois et à chaque fois un nombre de paires est transféré de droite à gauche. Essayez l'exemple en ligne .

Brève explication du code:

~]       # 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
la source
1
+1, c'est plus court que tout ce que j'ai pu trouver. Maintenant, si ce n'était pas pour cette règle embêtante "arrêt sur l'île la plus à l'ouest", ~]{2base}2*' '*ferait l'affaire ...
Ilmari Karonen
@IlmariKaronen Choisissez la bonne langue (voir la solution APL ) et la règle embêtante devient fine.
Howard
8

GolfScript (25 caractères)

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

Démo en ligne

Solution assez simple: il existe une approche plus intéressante qui définit la valeur de sortie pour chaque îlot en fonction des valeurs d'entrée, mais je ne pense pas qu'il soit possible de jouer autant que de suivre l'algorithme de redistribution décrit dans la question.

Peter Taylor
la source
7

Javascript / ES6 (69)

Jouer avec des opérateurs au niveau du bit:

  • x&=1 conserve le bit le plus bas (1 si impair, 0 si pair)
  • x>>1 est la division par 2 pour les entiers
f=a=>{a=a.split(' ');for(i=5;--i;a[i]&=1)a[i-1]-=-(a[i]>>1);return a}

Version sans ES6:

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

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

Michael M.
la source
1
Voir les commentaires de Rusher sur l'une des réponses Python; l'entrée doit être une chaîne suivant le format donné dans l'exemple, pas une liste.
Aleksi Torhamo
@AleksiTorhamo a raison. Autoriser une liste séparée par des virgules donnerait à votre code un avantage distinct sur ceux qui ont suivi le format fourni dans l'exemple. À l'avenir, j'essaierai d'être plus clair que le format fourni dans l'exemple est le format. Désolé pour ça.
Rainbolt
OK, modifié. La sortie doit-elle également être jointe ou le format du tableau est correct?
Michael M.
Je suis venu avec plus ou moins le même: f=a=>{a=a.split(' ');for(x=5;--x;a[x]&=1)a[x-1]-=-a[x]/2|0;return a}qui est de 68 caractères.
MT0
6

Python - 96 caractères

Golf pour la première fois! Entrée de 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))
Rainbolt
la source
1
Vous pouvez le réduire à 100 si vous compressez le tout sur une seule ligne en utilisant des points-virgules au lieu des sauts de ligne et de l'indentation, et supprimez l'espace directement après l'impression :)
Aleksi Torhamo
@AleksiTorhamo Merci. J'ai également appris que la division entière dans n'importe quelle version de Python que j'utilisais ne nécessite qu'une seule barre oblique, alors je l'ai fait tomber en dessous de 100.
Rainbolt
1
Ah, c'est vrai! Je viens également de réaliser que vous pouvez également omettre le ' 'fractionnement, le ramenant à 96 et battant les autres solutions python2.
Aleksi Torhamo
5

J (26 caractères)

Voici ma solution en 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

Cette solution générale devrait fonctionner avec n'importe quel nombre d'îles.

Thomas Baruchel
la source
5

Rubis, 97 90 74 72

Version en ligne

Je l'ai joué un peu plus loin, sans inverser le tableau ...

f=->i{i=i.split.map(&:to_i);(1..4).each{|n|i[-n-1]+=i[-n]/2;i[-n]%=2};i}
David Herrmann
la source
Vous ne devez pas inverser la chaîne avant le fractionnement mais après. Sinon, votre solution peut donner des résultats incorrects pour les nombres à plusieurs chiffres dans l'entrée.
Howard
J'ai même considéré les deux "possibilités" - bien que je ne sois pas au courant des nombres à plus d'un chiffre ...: D Merci!
David Herrmann
4

C - 121 caractères

L'entrée provient de 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
la source
Est-ce codé en dur pour seulement 5 îles?
Geobits
4

Python2 - 98 caractères

Entrée de 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 caractères

Entrée de 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
la source
4

Python 2, 85 80 octets

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

X personnes commençant sur une île équivalent à X * 2 personnes commençant une île à droite. Ce code convertit tout le monde dans la configuration de départ en son équivalent dans les insulaires d'extrême droite, puis utilise la représentation binaire du résultat pour déterminer combien de personnes se retrouvent sur chaque île.

EDIT: raccourci le code en initialisant bà 1 au lieu de 0, permettant l'utilisation de binau lieu d'une chaîne de format.

user2357112 prend en charge Monica
la source
Utiliser la représentation binaire est ingénieux! Lettercount.com vous a donné un 85. Avez-vous sur-compté, ou est-ce un mauvais outil à utiliser?
Rainbolt
@Rusher: Mon outil utilisait des fins de ligne CRLF. En comptant avec les fins de ligne Unix, c'est 85.
user2357112 prend en charge 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))

Nous parcourons la liste de l'arrière vers l'avant et déplaçons les populations selon les spécifications, puis imprimons la liste. Voici un test rapide:

>>> 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
la source
Crashed lorsque fourni avec une entrée qui suit le format fourni dans l'exemple.
Rainbolt
@Rusher J'ai mis à jour la réponse pour travailler avec le format exact utilisé dans la question.
arshajii
D'autres peuvent être désavantagés si des exceptions spéciales sont autorisées pour les codeurs Python. Désolé et merci d'avoir mis à jour votre réponse. Je vais essayer d'être plus clair à l'avenir que l'exemple d'entrée est le format requis.
Rainbolt
2

Mathematica 105

Cela devrait fonctionner avec n'importe quel nombre d'îles.

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

Exemples

5 îles

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

{8, 1, 0, 1, 0}


25 îles

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 }

DavidC
la source
Ma solution produit 270, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0pour vos longues données de test. Je pense avoir confirmé que j'ai raison.
OldCurmudgeon
Étrange, vu son fonctionnement. Je vais jeter un œil demain à l'affaire.
DavidC
2

Java - 647 533 mais en espérant quelques points brownie pour 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 forme non compressée:

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

Avec l'aide de:

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

}

Légèrement préoccupé par le test de @ DavidCarraher:

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

génère

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
la source
2

Java - 196 195

Je me suis dit que je ne le publierais pas si je ne pouvais pas le faire sous 200 ... Honnêtement, je ne pense pas pouvoir me débarrasser de quoi que ce soit d'autre, c'est assez mince pour 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]+" "));}}

Sauts de ligne:

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

Exemple de sortie d'entrée:

$ 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
Géobits
la source
2

Java - 179 caractères

Comprimé:

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

Ordinaire:

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

Exemple de sortie:

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

$ java F 7 6 5 4 3
11 1 1 1 1
Chasseur de trémie
la source
0

Emacs Lisp 144 caractères

Pas minuscule, mais ça marche

(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
la source
Vous pouvez ajouter un en-tête comme #Java - 123 caractères
Rainbolt
0

awk - 44 caractères

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

Java - 116 caractères

Par exemple int[] i = {2, 33, 16, 5};(je suppose que ceux-ci ne s'ajoutent pas au nombre, car chaque nombre peut varier) produirait23 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
la source
4
Pouvez-vous fournir un compilateur qui exécutera ce code? De plus, le format et les sources possibles pour l'entrée ont été fournis dans la question. Le moulage de l'entrée dans un tableau Java vous donne un avantage injuste sur les autres.
Rainbolt