Yüzen Orda


28

Giriş

Yağmur nihayet azaldı. İnsanlığın çoğu @ user12345 kodundaki bir hata nedeniyle boğuldu . Hayatta kalanlar dünya çapında bir takımadaya dağılmış durumda. Radyo iletişimi arttı ve insanlık bir kez daha gelişmeye hazırlanıyor. Sebepsiz yere, zombi korsanları Başbakan Meridyeninde toplandı ve batıya doğru yürüyorlar. Bu ordu herkesi mahvediyor.

Sorun

Kıyamet günü senaryomuz, işbirliği yapan bir ada topluluğu kümesini temsil eden tek bir hatta 5 tamsayı ile tanımlanabilir. Batıdan (en soldaki tamsayı) doğuya (en sağdaki tamsayı) sipariş edilir.

En doğulu adadan başlayarak, adalılar çiftler halinde en yakın adaya kaçarlar. İlginç bir şekilde, patlayan her çift için, bunlardan sadece biri yolculuktan kurtuldu. Sadece adalılar çiftler halinde seyahat ederler. Tek nüfus, geride kalmak ve zombi korsan ordularının antikleri hakkında en son radyo güncellemelerini sağlamak için tek bir kişi seçer. Nüfuslar, doğusundaki bütün adalar göçlerini tamamlayana ya da ölene kadar seyahat etmeyi reddediyor. Nüfus finale ulaştığında, en batıdaki ada, seyahat sona erer.

Dünyanın sonundaki operasyon müdürünün, her köyün son nüfus sayımını verebilecek bir programa ihtiyacı var.

Örnek Giriş

3 8 6 0 2

Örnek çıktı

8 1 0 1 0

Varsayımlar

  • Girdi, stdin yoluyla sağlanabilir, isteğe bağlı olarak adlandırılmış bir dosyadan okunabilir veya bir argüman olarak kabul edilebilir.
  • Her ada için 0 <= nüfus <= 1024
  • Nüfuslar asla bir ada atlamıyor

En kısa cevap kazanır!


Argüman derken, bir işlevin argümanı mı yoksa programın komut satırı argümanı mı demek istiyorsun?
Aleksi Torhamo,

@AleksiTorhamo Komut satırı arg, bu nedenle toplamınıza sayılmaz.
Rainbolt

29
Ben seviyorum bu çok soru kapsayan kıyamet hikaye.
mikhailcazi

re: "popülasyonlar asla bir ada atlamıyor" - örneğin, arka arkaya birden fazla ada hareket eden popülasyonu gösteriyor. Kaybettiğim başka bir anlamı var mı?
Allen Gould

1
@AllenGould Nüfuslar gerçekten de birden fazla adadan geçtiler, fakat hiçbir zaman geçmediler. En sağdaki adada 32 kişi olsaydı, 16, 8, 4 gibi ölürlerdi ve sonunda 2 en soldaki adaya ulaşırdı.
Rainbolt

Yanıtlar:


26

APL, 16 karakter

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

Giriş, bu bloğa dize olarak sağlanır:

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

ya da giriş bu bloğa bağımsız değişken olarak sağlanmışsa, bir karakter daha az:

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

Bu yorumda Ilmari Karonen fikrine dayanmaktadır .

  • 2⊥⍵ Girişin temel 2 dönüşümünü yapar.
  • (1e9,4⍴2)⊤bu nedenle, bu sayıyı tekrar temel 2'ye (son dört hane için) ve ilke için temel 1e9'a dönüştürür; bu, yukarıda verilen giriş aralıkları için yeterlidir. ( 1e9,4⍴2listeyi oluşturur 1e9 2 2 2 2.)

Kaçan batıya, bu işlem sırasında baz dönüşümüyle otomatik olarak yapıldığına dikkat edin.


Bu bir dahi.
Gareth

7
APLyasadışı olmalı ...
Kiwy

1
@Kiwy Yorumunuzu anlamıyorum. APL neden yasadışı ilan edilmeli? APL çözümünüzü de göndermekten çekinmeyin.
Howard,

4
@Kiwy: Bu sadece APL kullanmaktan öte bir şey ... aynı zamanda APL programına çok düzgün bir şekilde uyan çözümü için çok akıllıca bir yaklaşım. İşte golf bu işte!
Claudiu

13

GolfScript, 23 22 karakter

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

Yinelemeli bir yaklaşım. Dizi birkaç kez tekrarlanır ve her seferinde bir çift çifti sağdan sola aktarılır. Örneği çevrimiçi deneyin .

Kodun kısa açıklaması:

~]       # 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, bu bulabildiğim her şeyden daha kısa. Şimdi, sadece bu sinir bozucu "en batıdaki adada dur" kuralı ~]{2base}2*' '*olmasaydı, hile yapardı ...
Ilmari Karonen

@IlmariKaronen Doğru dili seçin ( APL çözümüne bakın ) ve sinir bozucu kuralı iyi olur.
Howard,

8

GolfScript (25 karakter)

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

Çevrimiçi demo

Oldukça basit bir çözüm: Her ada için çıktı değerini girdi değerlerinin bir fonksiyonu olarak tanımlayan daha ilginç bir yaklaşım var, ancak soruda açıklanan yeniden dağıtım algoritmasını takip ederek neredeyse golf oynayabileceğini sanmıyorum.


7

Javascript / ES6 (69)

Bitsel operatörlerle oynamak:

  • x&=1 en düşük biti tutar (tek ise 1, çift ise 0)
  • x>>1 tamsayılar için 2'ye bölünür
f=a=>{a=a.split(' ');for(i=5;--i;a[i]&=1)a[i-1]-=-(a[i]>>1);return a}

ES6'sız sürüm:

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

Örnekler:
f("3 8 6 0 2")döner [8, 1, 0, 1, 0]
f("0 997 998 999 1000")döndürür[935, 0, 1, 1, 0]


1
Rusher'in Python cevaplarından biri hakkındaki yorumlarını görün; giriş örnekte verilen formatı izleyerek bir liste olmalı.
Aleksi Torhamo

@AleksiTorhamo haklı. Virgülle ayrılmış bir listeye izin vermek, kodunuzu örnekte verilen formatı izleyenlere göre belirgin bir avantaja getirir. Gelecekte, örnekte verilen biçimde olduğunu daha net olmaya çalışacağım biçimi. Bunun için üzgünüm.
Rainbolt

Tamam, düzenlendi. Çıktı da birleştirilmeli mi yoksa dizi formatı tamam mı?
Michael M.

Daha az ya da çok aynı buldum: f=a=>{a=a.split(' ');for(x=5;--x;a[x]&=1)a[x-1]-=-a[x]/2|0;return a}68 karakter.
MT0

6

Python - 96 Karakterler

İlk kez golf! Stdin'den giriş.

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
Yeni satırlar ve girintiler yerine noktalı virgül kullanarak, bir satırdan aşağıya doğru bir çizgiyi sıkıştırarak 100'e
indirgeyebilir ve baskıdan

@AleksiTorhamo Teşekkürler. Ayrıca, kullandığım Python sürümündeki tamsayı bölümünün sadece tek bir eğik çizgi gerektirdiğini öğrendim, bu yüzden 100'ün altına
düşürdüm.

1
Ah, doğru! Ayrıca ' 'bölmeden çıkarmayı, 96'ya düşürmeyi ve diğer python2 çözümlerini yenmeyi de anladım.
Aleksi Torhamo

5

J (26 karakter)

İşte J'deki çözümüm: ((<.@-:@}.,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

Bu genel çözüm, herhangi bir sayıda adayla çalışmalıdır.


5

Yakut, 97 90 74 72

Çevrimiçi sürüm

Biraz daha ileri sürdüm, artık diziyi geri çevirmedim

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

Dizeyi bölmeden önce fakat sonra tersine çevirmelisiniz. Aksi halde, çözümünüz girişteki çok basamaklı sayılar için yanlış sonuçlara neden olabilir.
Howard,

Her iki "olasılık" ı bile düşündüm - birden fazla rakamdan oluşan rakamların farkında olmasam da ...: D Teşekkürler!
David Herrmann

4

C - 121 karakter

Girdi stdin'den alınmıştır.

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

Bu sadece 5 ada için kodlanmış mı?
Geobits

4

Python2 - 98 karakter

Stdin'den giriş.

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 karakter

Stdin'den giriş.

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 bayt

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

Herhangi bir adadan başlayan X kişi, bir adadan sağa başlayan X * 2 kişi ile eşdeğerdir. Bu kod, başlangıç ​​konfigürasyonundaki herkesi en sağdaki adalılarda eşdeğerlerine dönüştürür, daha sonra her adada kaç kişinin sonuçlanacağını belirlemek için sonucun ikili gösterimini kullanır.

EDIT: başlayarak kodu kısalttı b 0 yerine 1 yerinebin biçim dizesi yerine kullanılmasına izin verildi .


İkili gösterimi kullanmak ingenius! Lettercount.com size 85 verdi. Saymak ya da kullanmak için kötü bir araç mu?
Rainbolt

@Rusher: Aracım CRLF satır sonları kullanıyordu. Unix satır sonları ile
sayılıyor,

3

Piton (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))

Listeyi arkadan öne doğru döndürüyoruz ve popülasyonları spesifikasyona göre hareket ettiriyoruz, ardından listeyi yazdırıyoruz. İşte hızlı bir 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

Örnekte verilen formatı takip eden giriş sağlandığında çöktü.
Rainbolt

@Rusher Soruyu kullanılan formatla çalışmak için cevabı güncelledim.
arshajii

Python kodlayıcıları için özel istisnalara izin veriliyorsa diğerleri dezavantajlı olabilir. Üzgünüz ve cevabınızı güncellediğiniz için teşekkür ederiz. Gelecekte, örnek girdinin gereken biçim olduğu konusunda daha net olmaya çalışacağım.
Rainbolt

2

Mathematica 105

Bu, herhangi bir sayıda adayla çalışmalıdır.

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

Örnekler

5 adalar

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

{8, 1, 0, 1, 0}


25 adalar

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


Benim çözümüm 270, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0uzun test verileriniz için üretiyor . Sanırım doğru olduğumu onayladım.
OldCurmudgeon

Garip, nasıl çalıştığı göz önüne alındığında. Yarın davaya bir göz atacağım.
DavidC

2

Java - 647 533 ama Java 8 Streams için bazı brownie noktaları umuyor.

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

Sıkıştırılmamış 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);
}

Bir yardımı ile:

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

}

DavidCarraher'ın testi @ @ biraz endişeli:

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

üretir

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

Kendime 200'ün altında alamazsam gönderemeyeceğimi söyledim ... Açıkçası başka bir şeyden kurtulabileceğimi sanmıyorum, Java için oldukça zayıf.

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

Satır sonları:

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

Örnek giriş çıkışı:

$ 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 karakter

Sıkıştırılmış:

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

Örnek çıktı:

$ 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 karakter

Küçük değil, ama işe yarıyor

(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))

#Java gibi bir başlık ekleyebilirsiniz - 123 Karakterler
Rainbolt

0

awk - 44 Karakterler

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

-2

Java - 116 Karakterler

Örneğin int[] i = {2, 33, 16, 5};(her sayı değişebileceğinden sayımlara eklemediğini sanıyorum) çıktı23 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
Bu kodu çalıştıracak bir derleyici sağlayabilir misiniz? Ayrıca soru için girdi formatı ve girdi için olası kaynaklar verilmiştir. Girişi bir Java dizisine biçimlendirmek size diğerlerine göre haksız bir avantaj sağlar.
Rainbolt
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.