总和为15


36

编写一个程序或函数,该程序或函数将非负整数数组作为输入,并按顺序输出带有输入数组元素的一组向量/数组,并进行拆分,以使每个向量的总和为15。 N个元素不会“命中15个”,那么必须使通过15个元素的数字被截断,其余元素将成为下一个向量的第一个元素。直到您到达输入数组的末尾为止。如果最终向量的总和小于15,则必须在末尾添加一个数字以使总和增加。

通过查看示例,我认为规则更容易理解:

Input: 3 7 5 10
Output:
3 7 5           <- Sum is 15
10 5            <- 5 is added to make the sum 15

Input: 2 4 5 9 2 3 5 0 2 4 5 0 3
Output:
2 4 5 4          <- Sum 15. 9 is split in two. 
5 2 3 5          <- The first 5 is the remainder of 9
0 2 4 5 0 3 1    <- The last number is added to make the sum 15

Input: 1 1 1            
Output:
1 1 1 12         <- The number 12 is added to make the sum 15

Input: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Output:
1 2 3 4 5
6 7 2           <- 2 is the first part of 8
6 9             <- 6 is the remainder of 8
10 5            <- 5 is first part of 11
6 9             <- 6 is remainder of 11. 9 is first part of 12
3 12            <- 3 is remainder of 12. 12 is first part of 13
1 14            <- 1 is remainder of 13. 14 is 14
15
15              <- 15 is first part of 16
1 14            <- 1 is remainder of 16. 14 is first part of 17
3 12            <- 3 is remainder of 17. 12 is added to make the sum 15

Input: 20 20
Output:
15
5 10           <- 5 is remainder from the first 20
10 5           <- 10 is remainder from second 20. 5 is added to make the sum = 15.

输入和输出格式都是可选的。以您的语言为准。

以字节为单位的最短代码获胜。


排行榜

这篇文章底部的Stack Snippet从答案a)生成目录,答案是每种语言的最短解决方案列表,b)则是总体排行榜。

为确保您的答案显示出来,请使用以下Markdown模板以标题开头。

## Language Name, N bytes

N您提交的文件大小在哪里。如果您提高了分数,则可以通过打败旧分数保持标题。例如:

## Ruby, <s>104</s> <s>101</s> 96 bytes

如果要在标头中包含多个数字(例如,因为您的分数是两个文件的总和,或者您想单独列出解释器标志罚分),请确保实际分数是标头中的最后一个数字:

## Perl, 43 + 2 (-p flag) = 45 bytes

您还可以将语言名称设置为链接,然后该链接将显示在代码段中:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes


“输出格式是可选的”。这是否意味着[[3, 7, 5], [10, 5]]第一个测试用例的有效输出?
Morgan Thrapp 2015年

@MorganThrapp,是的。没错
Stewie Griffin

1
@FlagAsSpam,我在您要询问的示例中添加了更多说明。
Stewie Griffin

3
好测试案例:Input: 100 Output: 15; 15; 15; 15; 15; 15; 10 5
randomra 2015年

3
这绝对应该更换FizzBu​​zz测试
CSᵠ

Answers:


8

Pyth,37个字节

K15VQ=+ZNIgZK=-ZK-NZbIZZ)).?N;I>KZ-KZ

讲解

K15              Store 15 in K (the max) (K is Autoinitializing, no = needed here)
VQ              For N in the evaluated input
  =+ZN           Set Z(Which in pyth defaults to 0) to Z+N
  IgZK           If Z(row total) is greater than or equal to K (row max)
    =-ZK         Set Z to Z-K (How much the max was exceeded)
    -NZ          Implicitly print N-Z
    b            Implicitly print b (in pyth defaults to a newline)
    IZ         If Z > 0 (There was excess to carry to the next row)
      Z          Implicitly print Z (the excess)
  .?N            Else(the current row count is < the max(15)) output the current number
;                Use infinite )'s in place of )) (to save 1 character)
I>KZ             If K > Z (The max is greater than the current row count)
  -KZ           Implicitly print K-Z (The amount needed for the row to equal 15)

这是我的第一讲,请随时提出改进建议。

例:

输入值

[1, 3, 4, 5, 9, 8]

输出量

1
3
4
5
2


7
8

注意:非常感谢Isaacg提供了几个字节的大小缩减建议并首先创建了pyth!请在下面评论他的评论:)


2
其他最近更改为,.?而不是E,但我忘了更新文档。对于那个很抱歉。
isaacg 2015年

@isaacg谢谢isaacg!我现在应该工作了。尽管它只保存1个字节,因为else现在是2个字符。
csga5000

1
在我们讲话时修复它。
isaacg 2015年

3
其他一些建议:=Z+ZN=+ZN相同。有点像Python的+=。Likewiese,=Z-ZK-> =-ZK。另外,您不需要)结尾-它是自动填写的。最后,FNQVQ都是一样的。
isaacg 2015年

1
您可以通过替换I>Z0为来保存另外2个字节IZ- Z不能为负,因此您实际上只是在检查是否Z不为零,并且零为假,而所有其他数字为真。
isaacg 2015年

16

爪哇- 229 200 192 181 172 170 168字节

已经开始了,不是为了胜利而是为了乐趣:)
任何建议都欢迎。

感谢@ThomasKwa保存了8个字节感谢@corsiKa
保存了20个
字节感谢@Ypnypn
保存了2个字节感谢@ user902383保存了2个字节

String p(int[]a){int c=0,j;String s="";f:for(int i:a){for(j=i;j-->0;)if(++c>14){s+=(i-j)+"\n";c=0;if(j<15){if(j>0)s+=j+" ";c+=j;continue f;}}s+=i+" ";}return s+(15-c);}

170字节

String p(int[]a){int c=0,j;String s="";f:for(int i:a){for(j=i;j-->0;){if(++c>14){s+=(i-j)+"\n";c=0;if(j<15){if(j>0)s+=j+" ";c+=j;continue f;}}}s+=i+" ";}return s+(15-c);}

172字节

String p(int[]a){int c=0,j;String s="";f:for(int i:a){for(j=i;j>0;){j--;if(++c>14){s+=(i-j)+"\n";c=0;if(j<15){if(j>0)s+=j+" ";c+=j;continue f;}}}s+=i+" ";}return s+(15-c);}

181字节

void p(int[]a){int c=0,j;String s="";f:for(int i:a){for(j=i;j>0;){j--;if(++c>14){s+=(i-j)+"\n";c=0;if(j<15){if(j>0)s+=j+" ";c+=j;continue f;}}}s+=i+" ";}System.out.print(s+(15-c));}

192字节

void p(int[]a){int c=0,j;String s="";f:for(int i:a){for(j=i;j>0;){j--;c++;if(c==15){s+=(i-j)+"\n";c=0;if(j>=15)continue;if(j>0)s+=j+" ";c+=j;continue f;}}s+=i+" ";}System.out.print(s+(15-c));}

200字节

void p(int[]a){int c=0,j;String s="";f:for(int i:a){j=i;while(j>0){j--;c++;if(c==15){s+=(i-j)+"\n";c=0;if(j>=15)continue;else{if(j!=0)s+=j+" ";c+=j;continue f;}}}s+=i+" ";}System.out.print(s+(15-c));}

229字节

void p(int[]a){int c=0,j;f:for(int i:a){j=i;while(j>0){j--;c++;if(c==15){System.out.print(i-j+"\n");c=0;if(j>=15){continue;}else{if(j!=0)System.out.print(j+" ");c+=j;continue f;}}}System.out.print(i+" ");}System.out.print(15-c);}

String p(int[] a) {
    int c = 0, j;
    String s = "";
    f: for (int i: a) {
        for (j = i; j-- > 0;)
            if (++c > 14) {
                s += (i - j) + "\n";
                c = 0;
                if (j < 15) {
                    if (j > 0) s += j + " ";
                    c += j;
                    continue f;
                }
            }
        s += i + " ";
    }
    return s + (15 - c);
}

1
哇,直到现在,Java程序还没有真正继续使用它。
魔术章鱼缸

7

蟒蛇3-1̶7̶7̶1̶3̶8̶1̶6̶6̶1̶3̶3̶113

s=0
i=15
p=print
for e in eval(input()):
 if s>=i:p()
 s=s%i+e
 if s>i:s-=i;p(e-s);p();e=s
 p(e)
if s!=i:p(i-s%i)

编辑5由于@poke而真正打高尔夫球*去除了换行符等

编辑4 Aliased打印,并用-=替换a =以保存字节。感谢@poke和@elzell。还将输入eval移入for循环以节省分配的2个字节

编辑3如果第二秒内在不同的OO中发现了节省

编辑2修正的错误

编辑1将输入更改为'[1,2,3,4,5 ...]'的形式,并实现了前两个注释,这要感谢@Morgan Thrapp

第一次海报在这里。输入是命令行,条目之间用空格分隔,输出是每行条目,分组之间有换行符。


3
通过将15分配给变量,并且仅使用一个空格进行缩进,可以将其降低到122。
Morgan Thrapp 2015年

此外,你失败了第二次测试时,我得到2 3 5,但它应该是5 2 3 5
摩根Thrapp

1
@AdamMartin您可能对我的代码的Pyth版本感兴趣
csga5000

1
由于您print经常使用,因此应将其保存为变量:p=print。再为您节省14个字符。

2
当前计数为132,但是如果您删除了一些换行符,则可以将其降低到113。您可以将每个if合并为一行,例如if s>i:s-=i;p(e-s);p();e=s第二行。这样可以节省换行符和缩进字符。

7

Haskell中,126个 107 102 100字节

[]#c=[]
(h:t)#c|s<0=t#u|s<1=u:t#[]|1<2=(c++[h-s]):(s:t)#[]where s=sum c+h-15;u=c++[h]
(#[]).(++[14])

用法示例:(#[]).(++[14]) $ [1..17]->[[1,2,3,4,5],[6,7,2],[6,9],[10,5],[6,9],[3,12],[1,14],[15],[15],[1,14],[3,12]]

编辑:@Stewie Griffin帮助我节省了19个字节。谢谢!


4

CJam,39个字节

q~0af*Sf*N*30/{S-N/:,F1$:+-+0+e`W<e~p}/

在这里测试。

这感觉不是很理想,但是到目前为止,我对较短解决方案的所有尝试都被输入中零的存在​​所挫败。


4

Python2 搭载正则表达式158个 155字节

用爱和几乎没有数学的python制成。
如果愿意,也可以使用Regex Math,一元数学。
“实数”数学仅用于“修复”最后一个要求:

如果最终向量的总和小于15,则必须在末尾添加一个数字以使总和增加。

编码:

import re
def f(i):o=[map(len,p.split())for p in re.findall('((?:x *){15}|.+)',' '.join(['x'*c for c in i]))];l=sum(o[-1]);o[-1]+=([],[15-l])[l<15];print o

这种工作方式是将每个数字N转换为长度为N的字符串(将x选为char以填充该字符串),并将它们全部连接到一个空格中string。结果字符串通过RegEx BLACK MAGIC拆分为类似以下内容的字符串:

['x xx xxx xxxx xxxxx ', 'xxxxxx xxxxxxx xx', 'xxxxxx xxxxxxxxx', 'x']

对于类似f([1, 2, 3, 4, 5, 6, 7, 8, 10])
这样的输入:然后将其再次拆分,并x使用连续es 的长度再次创建数字,所有内容都很好地打包在列表推导中。

取消高尔夫:

import re
o = [map(len, p.split()) for p in re.findall('((?:x *){15}|.+)', ' '.join(['x'*c for c in i]))]
l = sum(o[-1])
o[-1] += ([], [15-l])[l<15]
print o

输出:

>>> f([30, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16])
[[15], [15], [1, 2, 3, 4, 5], [6, 7, 2], [6, 9], [15], [1, 14]]

注意:0的魔力不足,因此该条目不符合资格

必须包含零。参见第二个例子


所有这些函数名称都很昂贵。使得在代码高尔夫中几乎不可能使用正则表达式之类的东西。不过,考虑到您的字节大小也不错
csga5000

4

严重的是88个字节

,`'!*'0`M' j0╗`;;;'|ε35*('!=╜+;╗%(' =|('0=|I)`Mεj'|@s`ôl`╝`ö'0@s╛M`Md;Σ35*-;`X``@q`Iƒ@q.

在线尝试

这是我的第一个认真回答!现在,我已经非常熟悉该语言的所有缺点!

十六进制转储:

2c6027212a2730604d27206a30bb603b3b3b277cee33352a2827213dbd2b3bbb252827203d7c2827303d7c49
29604dee6a277c407360936c60bc609427304073be4d604d643be433352a2d3b60586060407160499f40712e

说明:

,`'!*'0`M' j         Replace all the numbers by "0"+"!"*n, separated by " "
0╗                   Initialize an accumulator in register 0
` ... `M             Map the string with the following function:
   ;;;'|ε                Put three extra copies of the character, a pipe, an empty string
   35*                   and a 15 on the stack.
   ('!=                  Move one copy of the character to the top and push 1 if it's a !
   ╜+                    Load the accumulator, add the 1 or 0 from the preceding test
   ;╗                    Make a copy, and save it back to register 0
   %                     Modulo the sum by 15
   (' =|                 Or the result with whether the dug-up character is " "
   ('0=|                 Or the result with whether the dug-up character is "0"
   I                     If we're at " " or "0" or the current sum is not divisible by 15,
                         push empty string, else push "|"
   )                     Bury the new character under the original character.
εj                   Join the list that resulted from the map into a single string.
'|@s                 Resplit the string on occurrences of "|" (after every 15 "!"s)
`ôl`╝                Store a function in register 1 which trims whitespace
                     and returns the length of the remaining string
` ... `M             Map the list with the following function:
   ö                     Trim leading spaces.
   '0@s                  Split the string on occurrence of "0"
   ╛M                    Map the resulting list with the function stored in register 1
d;                   Push the last sublist from the resulting list and make a copy.
Σ                    Find the sum of the list.
35*-                 Subtract it from 15
;`X``@q`Iƒ           Duplicate it, drop it if it's zero, put it in the list otherwise.
@q.                  Put the list back in the big list and print it.

如果使用Unicode代码点,那么这些字符是否每个都算作2个字节?:P

我在所示的源代码中使用了unicode,以便可以按其预期的方式进行读取。否则,它将看起来像是充满不可打印内容的随机垃圾。官方来源是十六进​​制转储。
quintopia,2015年

这本来是个幽默的问题

1
这也是另一个读者可能会想知道的合理问题,因此我很幽默地回答了这个问题。
quintopia,2015年

@quintopia +1尝试一种新的高尔夫语言!新语言很有趣;)我也第一次在这个问题上尝试过pyth。
csga5000

3

Javascript,138128字节

i=>eval("for(o=z=n='',m=15,t=q=0;q<i.length;q++)(t+=c=+i[q])>=m?(t-=m,z+=c-t,o+=z+`\n`,z=t>0?t+' ':n):z+=c+' ';t<m?o+z+(m-t):o")

带空格:

i => eval("
  for(o=z=n='', m=15, t=q=0; q < i.length; q++)
    (t+=c=+i[q])>=m
      ?(
        t-=m,
        z+=c-t,
        o+=z+`\n`,
        z=t>0?t+' ':n)
      :
        z+=c+' '
    ;
  t<m ? o+z+(m-t) : o
")

例:

将函数分配给变量

sumFifteen=i=>eval("for(o=z=n='',m=15,t=q=0;q<i.length;q++)(t+=c=+i[q])>=m?(t-=m,z+=c-t,o+=z+`\n`,z=t>0?t+' ':n):z+=c+' ';t<m?o+z+(m-t):o")

然后像这样评估:

console.log(sumFifteen([1,4,11,4,5]))

1 4 10
1 4 5 5

修订记录:

2015/12/3 00:02-感谢user81655(在评论中+1他)改进了10个字节

2015年12月2日21:44-切换为使用功能样式以减小尺寸。


3
你可以改善这个与这些:f=根据网站规则是不需要的,从删除括号(i),环绕有eval,所以你不需要return或括号,并更换if了三元使o返回和变化'\n'`\n`,合并t+=...t>=m以删除循环括号。以下是所有这些改进的127个字节的解决方案:i=>eval("for(o=z=n='',m=15,t=q=0;q<i.length;q++)(t+=c=+i[q])>=m?(t-=m,z+=c-t,o+=z+`\n`,z=t>0?t+' ':n):z+=c+' ';t<m?o+z+(m-t):o")
user81655

@ user81655我将实现其中的一些更改!当我尝试使用SytaxError时,会收到SytaxError:意外令牌ILLEGAL(...)。注意,为了测试功能,我
2015年

1
SO o+在行尾添加了一些符号。删除o+=z并重新写入即可使用。:P
user81655

@ user81655我看不出\n有什么区别
csga5000

1
你的意思是`\n`?如果没有它,它将无法工作,因为代码位于"..."其中eval
user81655 2015年

2

Python 3:139字节

与其他答案略有不同。从问题产生实际输出,因为我最初认为这是一个要求。

def f(l):
 m=15;r,s=sum(l)%m,0
 if r:l+=[m-r]
 while l:
  x=l.pop(0)
  if s+x>m:y=m-s;l[0:0]=[x-y];x=y
  s+=x;print(x,end=' \n'[s==m]);s%=m

用法示例:

>>> f([2, 4, 5, 9, 2, 3, 5, 0, 2, 4, 5, 0, 3])
2 4 5 4
5 2 3 5
0 2 4 5 0 3 1

2

Perl,86个字节

#!perl -p
s|\d+( ?)|($i+=$&)<15?$&:($a=$&-($i%=15)).$/.($&>$a&&$&-$a.$1)|ge;$\=$".(15-$i)if$i

将shebang数为三,则输入取自标准输入,空格分隔。


样品用量

$ echo -n 2 4 5 9 2 3 5 0 2 4 5 0 3 | perl sum15.pl
2 4 5 4
5 2 3 5
0 2 4 5 0 3 1

2

R,155个字节

n=scan();while(S<-sum(n)){C=cumsum(n);if(S>14){w=which(C>14)[1];N=n[1:w];n=n[-(1:w)];r=C[w]-15;N[w]=N[w]-r;if(r)n=c(r,n);cat(N,"\n")}else{cat(n,15-S);n=0}}

缩进和换行符:

n=scan()
while(S<-sum(n)){
     C=cumsum(n)
     if(S>14){
         w=which(C>14)[1]
         N=n[1:w]
         n=n[-(1:w)]
         r=C[w]-15
         N[w]=N[w]-r
         if(r) n=c(r,n)
         cat(N,"\n")
         }else{
            cat(n,15-S)
             n=0
             }
      }

用法:

> n=scan();while(S<-sum(n)){C=cumsum(n);if(S>14){w=which(C>14)[1];N=n[1:w];n=n[-(1:w)];r=C[w]-15;N[w]=N[w]-r;if(r)n=c(r,n);cat(N,"\n")}else{cat(n,15-S);n=0}}
1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
18: 
Read 17 items
1 2 3 4 5 
6 7 2 
6 9 
10 5 
6 9 
3 12 
1 14 
15 
15 
1 14 
3 12
> n=scan();while(S<-sum(n)){C=cumsum(n);if(S>14){w=which(C>14)[1];N=n[1:w];n=n[-(1:w)];r=C[w]-15;N[w]=N[w]-r;if(r)n=c(r,n);cat(N,"\n")}else{cat(n,15-S);n=0}}
1: 20 20
3: 
Read 2 items
15 
5 10 
10 5
> n=scan();while(S<-sum(n)){C=cumsum(n);if(S>14){w=which(C>14)[1];N=n[1:w];n=n[-(1:w)];r=C[w]-15;N[w]=N[w]-r;if(r)n=c(r,n);cat(N,"\n")}else{cat(n,15-S);n=0}}
1: 10 5
3: 
Read 2 items
10 5 
> n=scan();while(S<-sum(n)){C=cumsum(n);if(S>14){w=which(C>14)[1];N=n[1:w];n=n[-(1:w)];r=C[w]-15;N[w]=N[w]-r;if(r)n=c(r,n);cat(N,"\n")}else{cat(n,15-S);n=0}}
1: 2 4 5 9 2 3 5 0 2 4 5 0 3
14: 
Read 13 items
2 4 5 4 
5 2 3 5 
0 2 4 5 0 3 1

2

Python 2,117字节

i=input()
while i:
 s=15;r=[]
 while s>0:n=i.pop(0)if i else s;s-=n;r+=[n]if s>=0 else[n+s]
 if s<0:i=[-s]+i
 print r

将输入作为列表:

>>[2,4,5,9,2,3,5,0,2,4,5,0,3]
[2, 4, 5, 4]
[5, 2, 3, 5]
[0, 2, 4, 5, 0, 3, 1]

1

Perl,76个字节

包括+3 -p(通常为+1,但+3与其他perl解决方案公平竞争)

在STDIN上使用输入运行(输入上的最后换行符是可选的,但对于空输入,必须不存在)

sum15.pl <<< "1 2 3"

sum15.pl

#!/usr/bin/perl -p
s/$/ 15/;s/\d+/1x$&/eg;s/( *1){15}\K ?/
/g;s/
1*
*$//;s/1+|\B/length$&/eg

看,没有任何计算...


迟到总比不到好!很好的解决方案:)
达达

0s在此解决方案中非常棘手(用多余的空格表示),我必须非常小心地正确处理空格以保持0s 的数量正确。特别要考虑部分和正好为15的输入,例如1 14 2 13。尝试使用没有`?`的
字符

是的,我尝试了一下,发现在某些行的开头添加了0(如您所说)(这就是为什么我在发布评论30秒后删除了我的评论)。谢谢
达达

0

Java- 158155字节

yassin-hajajhttps://codegolf.stackexchange.com/a/65590/46866的Lambda版本,不确定提交的内容是否有效,但没有足够的代表对链接的答案添加评论。使用http://meta.codegolf.stackexchange.com/questions/4944/byte-counter-snippet进行计数

a->{int c=0,j;String s="";f:for(int i:a){for(j=i;j-->0;)if(++c>14){s+=(i-j)+"\n";c=0;if(j<15){if(j>0)s+=j+" ";c+=j;continue f;}}s+=i+" ";}return s+(15-c);}

158字节

a->{int c=0,j;String s="";f:for(int i:a){for (j=i;j-->0;)if(++c>14){s+=(i-j)+ "\n";c=0;if(j<15){if(j>0)s+=j+" ";c+=j;continue f;}}s+=i+ " ";}return s+(15-c);}

不打高尔夫球

a ->
    {
        int c=0, j;
        String s = "";
        f:
        for (int i : a) {
            for (j = i; j-- > 0; )
                if (++c > 14) {
                    s += (i - j) + "\n";
                    c = 0;
                    if (j < 15) {
                        if (j > 0) s += j + " ";
                        c += j;
                        continue f;
                    }
                }
            s += i + " ";
        }
        return s + (15 - c);
    }

可以像

Function<int[], String> func =a->{int c=0,j;String s="";f:for(int i:a){for (j=i;j-->0;)if(++c>14){s+=(i-j)+ "\n";c=0;if(j<15){if(j>0)s+=j+" ";c+=j;continue f;}}s+=i+ " ";}return s+(15-c);};
System.out.println(func.apply(new int[]{2, 4, 5, 9, 2, 3, 5, 0, 2, 4, 5 ,0 ,3}));
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.