ฝูงชนที่ลอยอยู่


28

บทนำ

ฝนก็ลดลงในที่สุด ส่วนใหญ่ของมนุษยชาติจมน้ำเนื่องจากข้อผิดพลาดใน @ user12345 รหัส ผู้รอดชีวิตกระจัดกระจายไปทั่วหมู่เกาะทั่วโลก การสื่อสารทางวิทยุนั้นเริ่มขึ้นและมนุษย์ก็พร้อมที่จะเติบโตอีกครั้ง ไม่ว่าจะด้วยเหตุผลใดก็ตามโจรสลัดซอมบี้ได้รวมตัวกันที่นายกรัฐมนตรีเมริเดียนและกวาดไปทางตะวันตก ฝูงชนกลืนกินทั้งหมด

ปัญหา

สถานการณ์วันโลกาวินาศของเราสามารถอธิบายได้ด้วยจำนวนเต็ม 5 ตัวในบรรทัดเดียวซึ่งเป็นตัวแทนของชุมชนเกาะที่ให้ความร่วมมือ พวกเขาได้รับคำสั่งจากตะวันตก (จำนวนเต็มซ้ายสุด) ไปทางทิศตะวันออก (จำนวนเต็มขวาสุด)

เริ่มต้นด้วยเกาะที่ไกลออกไปทางตะวันออกสุดชาวเกาะหนีคู่ไปยังเกาะที่ใกล้ที่สุด สำหรับทุกคู่ที่เริ่มต้นมีเพียงหนึ่งคนเท่านั้นที่รอดชีวิตจากการเดินทาง เกาะเพียงเดินทางเป็นคู่ ประชากรแปลกเลือกผู้อยู่อาศัยเพียงคนเดียวที่จะอยู่ข้างหลังและให้การปรับปรุงวิทยุล่าสุดเกี่ยวกับการแสดงตลกของฝูงโจรสลัดผีดิบ ประชากรปฏิเสธที่จะเดินทางจนกว่าเกาะทั้งหมดทางตะวันออกของพวกเขาจะเสร็จสิ้นการอพยพหรือเสียชีวิต เมื่อประชากรมาถึงเกาะสุดท้ายเกาะสุดท้ายการเดินทางสิ้นสุดลง

ผู้จัดการการดำเนินงานในตอนท้ายของโลกต้องการโปรแกรมที่สามารถส่งออกจำนวนประชากรสุดท้ายของแต่ละหมู่บ้าน

ตัวอย่างการป้อนข้อมูล

3 8 6 0 2

ตัวอย่างผลลัพธ์

8 1 0 1 0

สมมติฐาน

  • อินพุตอาจถูกจัดเตรียมผ่าน stdin อ่านจากไฟล์ที่ตั้งชื่อตามอำเภอใจหรือยอมรับว่าเป็นอาร์กิวเมนต์
  • สำหรับแต่ละเกาะ 0 <= ประชากร <= 1024
  • ประชากรไม่เคยข้ามเกาะ

คำตอบที่สั้นที่สุดชนะ!


เมื่อคุณพูดอาร์กิวเมนต์คุณหมายถึงเป็นอาร์กิวเมนต์ของฟังก์ชันหรือเป็นอาร์กิวเมนต์บรรทัดคำสั่งของโปรแกรมหรือไม่
Aleksi Torhamo

@AleksiTorhamo บรรทัดคำสั่งหาเรื่องดังนั้นมันจะไม่นับรวมกับยอดรวมของคุณ
Rainbolt

29
ฉันรักเรื่องราววันโลกาวินาศที่ครอบคลุมคำถามหลายข้อ
mikhailcazi

เรื่อง: "ประชากรไม่เคยข้ามเกาะ" - ตัวอย่างของคุณแสดงให้เห็นว่าประชากรย้ายเกาะหลายเกาะในแถว มีความหมายอื่นที่ฉันหายไปหรือไม่?
อัลเลนกูล

1
@AllenGould ประชากรจริงๆย้ายข้ามหลายเกาะ แต่พวกเขาไม่เคยข้ามเลย หากมีคน 32 คนบนเกาะทางขวาสุดพวกเขาจะตายอย่าง 16, 8, 4 และในที่สุด 2 คนก็จะไปถึงเกาะซ้ายสุด
Rainbolt

คำตอบ:


26

APL, 16 ตัวอักษร

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

อินพุตมีให้เป็นสตริงของบล็อกนี้:

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

หรือหนึ่งถ่านน้อยลงหากมีการป้อนข้อมูลให้เป็นอาร์กิวเมนต์ของบล็อกนี้:

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

มันขึ้นอยู่กับความคิดของ Ilmari Karonen ในความคิดเห็นนี้

  • 2⊥⍵ ทำการแปลงฐาน 2 ของอินพุต
  • (1e9,4⍴2)⊤ดังนั้นแปลงตัวเลขนี้กลับไปเป็นฐาน 2 (สำหรับตัวเลขสี่ตัวสุดท้าย) และฐาน 1e9 สำหรับหมายเลขแรกซึ่งเพียงพอสำหรับช่วงอินพุตที่ให้ไว้ด้านบน ( 1e9,4⍴2สร้างรายการ1e9 2 2 2 2)

โปรดทราบว่าการหลบหนีไปทางตะวันตกจะกระทำโดยอัตโนมัติโดยการแปลงฐานในระหว่างกระบวนการนี้


นี่คืออัจฉริยะ
Gareth

7
APLน่าจะผิดกฎหมาย ...
กีวี

1
@ กีวี่ฉันไม่เข้าใจความคิดเห็นของคุณ ทำไม APL ถึงถูกประกาศว่าผิดกฎหมาย? อย่าลังเลที่จะส่งโซลูชัน APL ของคุณเช่นกัน
Howard

4
@ กีวี่: นี่เป็นมากกว่าแค่การใช้ APL ... มันเป็นวิธีการแก้ปัญหาที่ชาญฉลาดซึ่งเกิดขึ้นกับโปรแกรม APL นี่คือสิ่งที่เกี่ยวกับกอล์ฟ!
Claudiu

13

GolfScript, 23 22 ตัวอักษร

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

วิธีการวนซ้ำ อาร์เรย์มีการวนซ้ำหลายครั้งและแต่ละครั้งจะมีการถ่ายโอนจำนวนคู่จากขวาไปซ้าย ลองตัวอย่างออนไลน์

คำอธิบายสั้น ๆ ของรหัส:

~]       # 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 นี่สั้นกว่าสิ่งใดที่ฉันสามารถหาได้ ตอนนี้ถ้าไม่เพียงเพราะกฎ "หยุดบนเกาะทางตะวันตกสุด" ที่น่ารำคาญ~]{2base}2*' '*จะทำเคล็ดลับ ...
Ilmari Karonen

@IlmariKaronen เลือกภาษาที่เหมาะสม (ดูวิธีแก้ปัญหา APL ) และกฎที่น่ารำคาญก็ใช้ได้
Howard

8

GolfScript (25 ตัวอักษร)

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

การสาธิตออนไลน์

วิธีการแก้ปัญหาที่ตรงไปตรงมา: มีวิธีการที่น่าสนใจมากกว่าซึ่งกำหนดค่าเอาท์พุทสำหรับแต่ละเกาะให้เป็นฟังก์ชั่นของค่าอินพุต แต่ฉันไม่คิดว่ามันจะสามารถตีกอล์ฟได้ไกลเกือบเท่าจริงตามขั้นตอนวิธีการแจกจ่ายซ้ำ


7

Javascript / ES6 (69)

เล่นกับผู้ประกอบการระดับบิต:

  • x&=1 เก็บบิตที่ต่ำที่สุด (1 ถ้าแปลก, 0 ถ้าแม้)
  • x>>1 คือการหารด้วย 2 สำหรับจำนวนเต็ม
f=a=>{a=a.split(' ');for(i=5;--i;a[i]&=1)a[i-1]-=-(a[i]>>1);return a}

รุ่นที่ไม่มี ES6:

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

ตัวอย่าง:
f("3 8 6 0 2")ส่ง[8, 1, 0, 1, 0]
f("0 997 998 999 1000")คืนสินค้าส่งคืน[935, 0, 1, 1, 0]


1
ดูความคิดเห็นของ Rusher จากหนึ่งในคำตอบของ Python อินพุตควรเป็นสตริงตามรูปแบบที่กำหนดในตัวอย่างไม่ใช่รายการ
Aleksi Torhamo

@AleksiTorhamo ถูกต้อง การอนุญาตรายการที่คั่นด้วยเครื่องหมายจุลภาคจะทำให้โค้ดของคุณมีข้อได้เปรียบที่แตกต่างเหนือผู้ที่ทำตามรูปแบบที่ระบุไว้ในตัวอย่าง ในอนาคตผมจะพยายามที่จะเป็นที่ชัดเจนว่ารูปแบบที่มีให้บริการในตัวอย่างเป็นรูปแบบ ขอโทษสำหรับเรื่องนั้น.
Rainbolt

ตกลงแก้ไข ควรจะรวมเอาท์พุทหรือรูปแบบอาร์เรย์ก็โอเค?
Michael M.

ฉันคิดแบบเดียวกันมากขึ้นหรือน้อยลงf=a=>{a=a.split(' ');for(x=5;--x;a[x]&=1)a[x-1]-=-a[x]/2|0;return a}ซึ่งก็คือ 68 ตัวอักษร
MT0

6

Python - 96 ตัวอักษร

เล่นกอล์ฟเป็นครั้งแรก! ข้อมูลจาก 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
คุณสามารถทำให้มันลดลงได้ถึง 100 ถ้าคุณบีบอัด while ลงหนึ่งบรรทัดโดยใช้เครื่องหมายอัฒภาคแทนการขึ้นบรรทัดใหม่และการเยื้องและลบพื้นที่ออกหลังจากพิมพ์ :)
Aleksi Torhamo

@AleksiTorhamo ขอบคุณ ฉันยังได้เรียนรู้ว่าการแบ่งจำนวนเต็มใน Python เวอร์ชันใดก็ตามที่ฉันต้องการนั้นใช้เพียงแค่สแลชเดียวดังนั้นฉันจึงล้มลงต่ำกว่า 100
Rainbolt

1
จริงเหรอ! ฉันเพิ่งรู้ว่าคุณสามารถละเว้น' 'จากการแยกทำให้มันลดลงถึง 96 และเอาชนะโซลูชั่น python2 อื่น ๆ
Aleksi Torhamo

5

J (26 ตัวอักษร)

นี่คือทางออกของฉันใน 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

วิธีแก้ปัญหาทั่วไปนี้ควรทำงานกับเกาะจำนวนเท่าใด


5

ทับทิม, 97 90 74 72

เวอร์ชั่นออนไลน์

Golfed มันเพิ่มเติมเล็กน้อยไม่ย้อนกลับอาร์เรย์อีกต่อไป ...

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

คุณต้องไม่ย้อนกลับสตริงก่อนที่จะแยก แต่หลังจาก มิฉะนั้นโซลูชันของคุณอาจให้ผลลัพธ์ที่ไม่ถูกต้องสำหรับตัวเลขหลายหลักในอินพุต
Howard

ฉันยังถือว่าทั้ง "ความเป็นไปได้" - แม้ว่าจะไม่ได้รับรู้ตัวเลขที่มีตัวเลขมากกว่าหนึ่งหลัก ... : D ขอบคุณ!
David Herrmann

4

C - 121 ตัวอักษร

อินพุตถูกนำมาจาก 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;}

นี่เป็นรหัสที่ยากสำหรับเกาะ 5 เกาะหรือไม่?
Geobits

4

Python2 - 98 ตัวอักษร

ข้อมูลจาก 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 ตัวอักษร

ข้อมูลจาก 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 ไบต์

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

X คนที่เริ่มต้นบนเกาะใด ๆ จะเทียบเท่ากับ X * 2 คนที่เริ่มต้นหนึ่งเกาะทางด้านขวา รหัสนี้แปลงทุกคนในการกำหนดค่าเริ่มต้นให้เท่ากันในเกาะที่อยู่ทางขวาสุดจากนั้นใช้การแทนค่าฐานสองของผลลัพธ์เพื่อกำหนดจำนวนคนที่อยู่บนเกาะแต่ละเกาะ

แก้ไข: ย่อโค้ดโดยเริ่มต้นbที่ 1 แทน 0, อนุญาตให้ใช้binแทนสตริงรูปแบบ


การใช้การแทนค่าไบนารี่คือ ingenius! Lettercount.com ให้ 85 คุณคุณ overcount หรือ Lettercount เป็นเครื่องมือที่ไม่ดีที่จะใช้หรือไม่
Rainbolt

@Rusher: เครื่องมือของฉันใช้จุดสิ้นสุดของบรรทัด CRLF การนับด้วยสิ้นสุดบรรทัด Unix คือ 85.
user2357112 รองรับ 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))

เราวนรายการจากด้านหลังไปข้างหน้าและย้ายประชากรรอบ ๆ ตามข้อกำหนดจากนั้นพิมพ์รายการ นี่คือการทดสอบอย่างรวดเร็ว:

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

เกิดข้อขัดข้องเมื่อมีการป้อนข้อมูลที่ตามรูปแบบที่มีให้ในตัวอย่าง
Rainbolt

@Rusher ฉันอัปเดตคำตอบเพื่อทำงานกับรูปแบบที่แน่นอนที่ใช้ในคำถาม
arshajii

คนอื่นอาจเสียเปรียบหากอนุญาตให้มีข้อยกเว้นพิเศษสำหรับ Python coders ขออภัยและขอบคุณสำหรับการปรับปรุงคำตอบของคุณ ฉันจะพยายามให้ชัดเจนยิ่งขึ้นในอนาคตว่าตัวอย่างอินพุตเป็นรูปแบบที่ต้องการ
Rainbolt

2

Mathematica 105

สิ่งนี้น่าจะใช้ได้กับทุกเกาะ

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

ตัวอย่าง

5 เกาะ

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

{8, 1, 0, 1, 0}


25 เกาะ

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


โซลูชันของฉันสร้างขึ้น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

แปลกให้มันทำงานอย่างไร ฉันจะดูในวันพรุ่งนี้ที่กรณี
DavidC

2

ชวา - 647 533 แต่หวังว่าจะได้คะแนนบราวนี่สำหรับ 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;}}

แบบฟอร์มที่ไม่มีการบีบอัด:

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

ด้วยความช่วยเหลือของ:

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

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

สร้าง

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

ฉันบอกกับตัวเองว่าฉันจะไม่โพสต์มันถ้าฉันทำไม่ถึง 200 อันที่จริง ... ฉันไม่คิดว่าฉันจะกำจัดอะไรได้เลยมันค่อนข้างเพรียวสำหรับ 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]+" "));}}

ตัวแบ่งบรรทัด:

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

ตัวอย่างอินพุตเอาต์พุต:

$ 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 ตัวอักษร

การบีบอัด:

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

ปกติ:

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

ตัวอย่างผลลัพธ์:

$ 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 ตัวอักษร

ไม่เล็ก แต่ใช้งานได้

(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 - 123 ตัวอักษร
Rainbolt


-2

Java - 116 ตัวอักษร

ตัวอย่างเช่นint[] i = {2, 33, 16, 5};(ฉันเดาว่าสิ่งเหล่านี้จะไม่เพิ่มในการนับเนื่องจากแต่ละหมายเลขสามารถเปลี่ยนแปลงได้) จะแสดงผลลัพธ์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
คุณสามารถให้คอมไพเลอร์ที่จะเรียกใช้รหัสนี้ได้หรือไม่? นอกจากนี้ยังมีการจัดรูปแบบและแหล่งที่มาที่เป็นไปได้ของอินพุตด้วย การสร้างอินพุตให้กับอาร์เรย์ Java ให้ประโยชน์ที่ไม่เป็นธรรมแก่ผู้อื่น
Rainbolt
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.