浮动部落


28

介绍

雨终于平息了。由于@ user12345的代码中的错误,大多数人淹死。幸存者散布在世界各地的群岛上。无线电通信已经普及,人类有望再次蓬勃发展。僵尸海盗无缘无故聚集在本初子午线,并向西蔓延。部落吞噬了所有人。

问题

我们的世界末日场景可以用5个整数表示,这些整数代表一组协作的岛屿社区。它们从西(最左边的整数)到东(最右边的整数)排序​​。

从最东端的岛屿开始,岛民成对逃往下一个最近的岛屿。奇怪的是,对于每一对登船的人,只有其中一个能幸免于难。岛民只能成对旅行。奇怪的人群选出一个唯一的居民留下来,并提供有关僵尸海盗部落滑稽动作的最新广播更新。人口拒绝旅行,直到其东部所有岛屿完成迁徙或死亡为止。当人口到达最后一个最西端的岛屿时,旅行便停止了。

世界末日的运营经理需要一个程序,该程序可以输出每个村庄的最终人口数。

输入示例

3 8 6 0 2

示例输出

8 1 0 1 0

假设条件

  • 输入可以通过stdin提供,可以从任意命名的文件中读取,也可以作为参数接受
  • 对于每个岛屿,0 <=人口<= 1024
  • 人口从未逃过一个小岛

最短答案胜出!


当您说参数时,是指作为函数的参数还是程序的命令行参数?
Aleksi Torhamo 2014年

@AleksiTorhamo命令行参数,因此不会计入您的总数。
Rainbolt 2014年

29
喜欢这个跨多个问题的世界末日故事。
mikhailcazi14年

回复:“人口永不跳过一个岛屿”-您的示例确实显示了人口连续移动多个岛屿。还有我想念的意思吗?
艾伦·古尔德2014年

1
@AllenGould人口确实确实跨越了多个岛屿,但从未逃过一个。如果最右边的岛上有32个人,他们将像16、8、4一样死去,最后有2个人将到达最左边的岛​​。
Rainbolt 2014年

Answers:


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

7
APL应该是非法的……
Kiwy 2014年

1
@Kiwy我不明白您的评论。为什么应将APL宣布为非法?也可以随时提交您的APL解决方案。
霍华德

4
@Kiwy:这不仅仅是使用APL ...这也是解决方案的一种非常聪明的方法,恰好恰好适合APL程序。这就是高尔夫的全部内容!
2014年

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

@IlmariKaronen选择正确的语言(请参阅APL解决方案),然后使用讨厌的规则即可。
2014年

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")return [8, 1, 0, 1, 0]
f("0 997 998 999 1000")返回[935, 0, 1, 1, 0]


1
请参阅Rusher对Python答案之一的评论;输入应为示例中给出的格式的字符串,而不是列表。
Aleksi Torhamo 2014年

@AleksiTorhamo是正确的。与使用示例中提供的格式的代码相比,允许使用逗号分隔的列表将使您的代码具有明显的优势。将来,我将尝试更清楚地说明示例中提供格式是format。对于那个很抱歉。
Rainbolt 2014年

确定,已编辑。输出也应该连接还是数组格式可以吗?
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
如果通过使用分号而不是换行符和缩进的方式将while压缩为一行,则可以将其压缩为100,并在打印后直接删除空间:)
Aleksi Torhamo 2014年

@AleksiTorhamo谢谢。我也学会了在任何的Python我的版本中使用只需要一个斜杠整数除法,所以我砍价低于100
Rainbolt

1
啊,是真的!我也刚刚意识到,您也可以忽略' '拆分,将其降至96并击败其他python2解决方案。
Aleksi Torhamo 2014年

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

在线版

打得更远一点,不再扭转阵列...

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

在拆分之前,请勿在拆分后反转字符串。否则,对于输入中的多位数,您的解决方案可能会产生错误的结果。
2014年

我什至都考虑了这两种“可能性”-尽管没有意识到一个数字以上的数字...:D谢谢!
David Herrmann 2014年

4

C-121个字符

输入来自标准输入。

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

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代替格式字符串。


使用二进制表示法是天才!Lettercount.com给了您85。
Rainbolt 2014年

@Rusher:我的工具正在使用CRLF行尾。Unix行结尾的计数,它是85
user2357112支持莫妮卡

3

巨蟒(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 2014年

@Rusher我更新了答案,以使用问题中使用的确切格式。
arshajii 2014年

如果Python编码器允许特殊的异常,则其他代码可能会处于不利地位。抱歉,感谢您更新您的答案。将来,我将尝试更加清楚地说明示例输入是必需的格式。
Rainbolt 2014年

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,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 2014年

考虑到它的工作原理,很奇怪。明天我会看一下这个案子。
DavidC 2014年

2

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

0

awk-44个字符

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

-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 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.