Horde nổi


28

Giới thiệu

Mưa cuối cùng cũng nguôi. Hầu hết nhân loại bị chết đuối do lỗi trong mã của @ user12345 . Những người sống sót nằm rải rác trên một quần đảo trên toàn thế giới. Truyền thông vô tuyến được đưa lên, và nhân loại đã sẵn sàng để phát triển một lần nữa. Không có lý do gì, những tên cướp biển zombie đã tập trung tại Prime Meridian và đang càn quét về phía tây. Đám người nuốt chửng tất cả.

Vấn đề

Kịch bản ngày tận thế của chúng ta có thể được mô tả bởi 5 số nguyên trên một dòng duy nhất đại diện cho một tập hợp các cộng đồng đảo hợp tác. Chúng được sắp xếp từ tây (số nguyên ngoài cùng bên trái) sang phía đông (số nguyên ngoài cùng bên phải).

Bắt đầu với hòn đảo xa nhất về phía đông, người dân đảo chạy trốn theo cặp đến hòn đảo gần nhất tiếp theo. Thật kỳ lạ, đối với mỗi cặp bắt đầu, chỉ một trong số họ sống sót sau chuyến đi. Người dân đảo chỉ đi du lịch theo cặp. Dân số kỳ lạ bầu một cư dân duy nhất ở lại phía sau và cung cấp các bản cập nhật radio mới nhất về những trò hề của đám cướp biển zombie. Dân cư từ chối đi du lịch cho đến khi tất cả các hòn đảo ở phía đông của họ đã hoàn thành việc di cư hoặc chết. Khi dân số đến cuối cùng, hòn đảo cực tây, du lịch chấm dứt.

Người quản lý hoạt động ở cuối thế giới cần một chương trình có thể tạo ra số lượng dân số cuối cùng của mỗi làng.

Ví dụ đầu vào

3 8 6 0 2

Ví dụ đầu ra

8 1 0 1 0

Giả định

  • Đầu vào có thể được cung cấp qua stdin, đọc từ tệp có tên tùy ý hoặc được chấp nhận làm đối số
  • Đối với mỗi đảo, 0 <= dân số <= 1024
  • Quần thể không bao giờ bỏ qua một hòn đảo

Câu trả lời ngắn nhất sẽ thắng!


Khi bạn nói đối số, bạn có nghĩa là một đối số cho một chức năng hoặc như là một đối số dòng lệnh cho chương trình?
Aleksi Torhamo

@AleksiTorhamo Dòng lệnh arg, vì vậy nó sẽ không được tính vào tổng số của bạn.
Rainbolt

29
Tôi thích câu chuyện ngày tận thế đa câu hỏi này.
mikhailcazi

re: "quần thể không bao giờ bỏ qua một hòn đảo" - ví dụ của bạn cho thấy dân số di chuyển nhiều đảo liên tiếp. Có một ý nghĩa khác tôi đang thiếu?
Allen Gould

1
@ ALLenGould Quần thể thực sự đã di chuyển qua nhiều hòn đảo, nhưng họ không bao giờ bỏ qua một hòn đảo. Nếu có 32 người trên hòn đảo ngoài cùng bên phải, họ sẽ chết như 16, 8, 4 và cuối cùng 2 người sẽ đến hòn đảo ngoài cùng bên trái.
Rainbolt

Câu trả lời:


26

APL, 16 ký tự

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

Đầu vào được cung cấp dưới dạng chuỗi cho khối này:

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

hoặc ít hơn một char nếu đầu vào được cung cấp làm đối số cho khối này:

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

Nó dựa trên ý tưởng của Ilmari Karonen trong bình luận này .

  • 2⊥⍵ thực hiện chuyển đổi cơ sở 2 của đầu vào.
  • (1e9,4⍴2)⊤do đó chuyển đổi số này trở lại cơ sở 2 (cho bốn chữ số cuối) và cơ sở 1e9 cho số đầu tiên, đủ cho các phạm vi đầu vào được đưa ra ở trên. ( 1e9,4⍴2xây dựng danh sách 1e9 2 2 2 2.)

Lưu ý rằng việc chạy trốn về phía tây được thực hiện tự động bằng cách chuyển đổi cơ sở trong quá trình này.


Đây là thiên tài.
Gareth

7
APLnên là bất hợp pháp ...
Kiwy

1
@Kiwy Tôi không hiểu bình luận của bạn. Tại sao APL nên được tuyên bố là bất hợp pháp? Vui lòng gửi giải pháp APL của bạn là tốt.
Howard

4
@Kiwy: Đây không chỉ là sử dụng APL ... đây còn là một cách tiếp cận rất thông minh đối với giải pháp, điều này rất phù hợp với chương trình APL. Đây là những gì golf là tất cả về!
Claudiu

13

GolfScript, 23 22 ký tự

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

Một cách tiếp cận lặp đi lặp lại. Mảng được lặp đi lặp lại nhiều lần và mỗi lần một số cặp được chuyển từ phải sang trái. Hãy thử ví dụ trực tuyến .

Giải thích ngắn về mã:

~]       # 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, điều này rút ngắn hơn bất cứ điều gì tôi có thể tìm thấy. Bây giờ, nếu chỉ không tuân theo quy tắc "dừng lại ở hòn đảo cực tây" ~]{2base}2*' '*
phiền phức đó

@IlmariKaronen Chọn ngôn ngữ phù hợp (xem giải pháp APL ) và quy tắc pesky trở nên tốt.
Howard

8

GolfScript (25 ký tự)

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

Bản demo trực tuyến

Giải pháp khá đơn giản: có một cách tiếp cận thú vị hơn, xác định giá trị đầu ra cho mỗi đảo là một hàm của các giá trị đầu vào, nhưng tôi không nghĩ rằng nó có thể được chơi gần như thực sự theo thuật toán phân phối lại được mô tả trong câu hỏi.


7

Javascript / ES6 (69)

Chơi với các toán tử bitwise:

  • x&=1 giữ bit thấp nhất (1 nếu lẻ, 0 nếu chẵn)
  • x>>1 được chia cho 2 cho số nguyên
f=a=>{a=a.split(' ');for(i=5;--i;a[i]&=1)a[i-1]-=-(a[i]>>1);return a}

Phiên bản không có ES6:

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

Ví dụ:
f("3 8 6 0 2")trả [8, 1, 0, 1, 0]
f("0 997 998 999 1000")về[935, 0, 1, 1, 0]


1
Xem bình luận của Rizer về một trong những câu trả lời của Python; đầu vào phải là một chuỗi theo định dạng được đưa ra trong ví dụ, không phải là một danh sách.
Aleksi Torhamo

@AleksiTorhamo đã đúng. Việc cho phép một danh sách được phân tách bằng dấu phẩy sẽ đặt mã của bạn ở một lợi thế khác biệt so với những người theo định dạng được cung cấp trong ví dụ. Trong tương lai, tôi sẽ cố gắng để được rõ ràng hơn rằng các định dạng được cung cấp trong ví dụ này là các định dạng. Xin lỗi vì điều đó.
Rainbolt

OK, chỉnh sửa. Đầu ra cũng nên được tham gia hoặc định dạng mảng là ok?
Michael M.

Tôi đã đưa ra ít nhiều giống nhau: f=a=>{a=a.split(' ');for(x=5;--x;a[x]&=1)a[x-1]-=-a[x]/2|0;return a}đó là 68 ký tự.
MT0

6

Python - 96 ký tự

Lần đầu chơi golf! Đầu vào từ 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
Bạn có thể giảm xuống 100 nếu bạn nén xuống một dòng bằng cách sử dụng dấu chấm phẩy thay vì dòng mới và thụt lề, và xóa khoảng
trắng

@AleksiTorhamo Cảm ơn. Tôi cũng đã học được rằng phép chia số nguyên trong bất kỳ phiên bản Python nào tôi sử dụng chỉ cần một dấu gạch chéo, vì vậy tôi đã hạ nó xuống dưới 100.
Rainbolt

1
À, đúng rồi! Tôi cũng chỉ nhận ra rằng bạn cũng có thể bỏ qua phần ' 'tách, đưa nó xuống 96 và đánh bại các giải pháp python2 khác.
Aleksi Torhamo

5

J (26 ký tự)

Đây là giải pháp của tôi trong 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

Giải pháp chung này sẽ làm việc với bất kỳ số lượng đảo.


5

Hồng ngọc 97 90 74 72

Phiên bản trực tuyến

Đánh gôn thêm một chút nữa, không đảo ngược mảng nữa ...

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

Bạn không được đảo ngược chuỗi trước khi tách nhưng sau. Nếu không, giải pháp của bạn có thể mang lại kết quả sai cho các số có nhiều chữ số trong đầu vào.
Howard

Tôi thậm chí đã xem xét cả hai "khả năng" - mặc dù không nhận thức được các số có nhiều hơn một chữ số ...: D Cảm ơn!
David Herrmann

4

C - 121 ký tự

Đầu vào được lấy từ 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;}

Đây có phải là mã hóa cứng chỉ cho 5 hòn đảo?
Geobits

4

Python2 - 98 ký tự

Đầu vào từ 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 ký tự

Đầu vào từ 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:])

Người X bắt đầu trên bất kỳ hòn đảo nào tương đương với X * 2 người bắt đầu từ một hòn đảo bên phải. Mã này chuyển đổi tất cả mọi người trong cấu hình bắt đầu thành tương đương của họ ở những người cực hữu, sau đó sử dụng biểu diễn nhị phân của kết quả để xác định có bao nhiêu người kết thúc trên mỗi đảo.

EDIT: Rút ngắn mã bằng cách khởi tạo bthành 1 thay vì 0, cho phép sử dụng binthay vì chuỗi định dạng.


Sử dụng biểu diễn nhị phân là ingenius! Lettercount.com đã cho bạn một 85. Bạn đã vượt qua, hoặc lettercount là một công cụ xấu để sử dụng?
Rainbolt

@Rizer: Công cụ của tôi đã sử dụng kết thúc dòng CRLF. Đếm nó với các kết thúc dòng Unix, nó là 85.
user2357112 hỗ trợ Monica

3

Con trăn (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))

Chúng tôi lặp qua danh sách từ sau ra trước và di chuyển các quần thể xung quanh theo đặc điểm kỹ thuật, sau đó in danh sách. Đây là một bài kiểm tra nhanh:

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

Sự cố khi được cung cấp với đầu vào tuân theo định dạng được cung cấp trong ví dụ.
Rainbolt

@Rizer Tôi đã cập nhật câu trả lời để làm việc với định dạng chính xác được sử dụng trong câu hỏi.
arshajii

Những người khác có thể gặp bất lợi nếu ngoại lệ đặc biệt được phép cho các lập trình viên Python. Xin lỗi, và cảm ơn vì đã cập nhật câu trả lời của bạn. Tôi sẽ cố gắng rõ ràng hơn trong tương lai rằng đầu vào ví dụ là định dạng bắt buộc.
Rainbolt

2

Toán học 105

Điều này sẽ làm việc với bất kỳ số lượng đảo.

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

Ví dụ

5 hòn đảo

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

{8, 1, 0, 1, 0}


25 hòn đảo

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 }


Giải pháp của tôi tạo ra 270, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0cho dữ liệu thử nghiệm dài của bạn. Tôi nghĩ rằng tôi đã xác nhận rằng tôi đúng.
OldCurmudgeon

Lạ, đưa ra cách nó hoạt động. Tôi sẽ xem xét trường hợp vào ngày mai.
DavidC

2

Java - 647 533 nhưng hy vọng cho một số điểm brownie cho Luồng Java 8.

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

Các hình thức không nén:

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

Với sự hỗ trợ của:

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

}

Hơi lo ngại rằng bài kiểm tra của @ 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

tạo ra

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

Tôi đã nói với bản thân mình rằng tôi sẽ không đăng nó nếu tôi không thể nhận được nó dưới 200 ... Tôi thực sự không nghĩ rằng tôi có thể thoát khỏi bất cứ điều gì khác, nó khá mỏng cho 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]+" "));}}

Ngắt dòng:

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

Đầu ra mẫu:

$ 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 ký tự

Nén:

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

Bình thường:

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

Đầu ra mẫu:

$ 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 ký tự

Không nhỏ, nhưng nó hoạt động

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

Bạn có thể thêm một tiêu đề như #Java - 123 Nhân vật
Rainbolt

0

awk - 44 ký tự

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

-2

Java - 116 ký tự

Ví dụ: int[] i = {2, 33, 16, 5};(tôi đoán những người không thêm vào số đếm, vì mỗi số có thể thay đổi) sẽ xuất ra23 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
Bạn có thể cung cấp một trình biên dịch sẽ chạy mã này? Ngoài ra, định dạng và các nguồn có thể cho đầu vào được cung cấp trong câu hỏi. Việc tạo đầu vào cho một mảng Java mang lại cho bạn một lợi thế không công bằng so với các mảng khác.
Rainbolt
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.