数字1至7的总和


21

挑战

给定一个正整数N是28或以上,输出一个数字求和到的列表N,它使用每个数字1通过7一次。您可以给出程序或功能。

这些数字可以单独出现,也可以串联在一起,只要您一次使用它们而无重复即可。例如,[12, 34, 56, 7]是有效的,因为是[1, 27, 6, 4, 35][1234, 567],但不[123, 34567]还是[3, 2, 1476]。列出数字的顺序无关紧要。

如果N不能用1-7表示,则不返回或不输出。

其他资讯

  • 这是代码高尔夫球,因此10月15日星期四之前以字节为单位的最短代码将获胜。

  • 在评论中提出任何问题。

  • 我在挑战中未指定的任何内容都取决于您。

  • 不允许出现标准漏洞。

例子

这些可能会清除任何混淆:

输入项

28

输出量

[1, 2, 3, 4, 5, 6, 7]

输入项

100

输出量

[56, 7, 4, 31, 2]

输入项

1234567

输出量

[1234567]

输入项

29

输出量

没什么,29无效。

输入项

1891

输出量

[1234, 657]

输入项

370

输出量

[15, 342, 7, 6]

如果需要,我会做更多。

这是由这七个数字创建的所有可能数字的粘贴框,由FryAmTheEggman提供。


输出是29什么?
Geobits,2015年

4
如果您希望输出为空,请勿将其(N/A)作为输出。
mbomb007'2015-10-8

1
@LukStorms [1234566, 1]不是有效的输出,因为重复6。您不能在输出中重复数字。
The_Basset_Hound 2015年

2
也许»...由十进制数字1到7构成的数字列表(总计为N«)比当前问题中的单词更清晰。
圣保罗Ebermann

3
对于一个稍少蛮力解:这等同于分配电源的-10的系数的每一个1, ..,, 7,使得有至少一样多1的为10's,至少一样多10的作为100的,依此类推。
xnor

Answers:


9

Pyth,18个 14字节

hfqSjkTjkS7./Q

感谢@isaacg腾出2个字节并为另外2个字节铺平了道路。

如果该代码不产生任何输出,则会崩溃,从而导致不产生任何输出。

如果您有足够的耐心,这将适用于少量输入,如果有足够的时间和内存,则适用于较大的输入。

要验证代码工作打算,可以更换7一个3用于通过3位数1款项。单击此处以获取测试套件。

运行示例

$ time pyth/pyth.py -c 'hfqSjkTjkS7./Q' <<< 28
(1, 2, 3, 4, 5, 6, 7)

real    4m34.634s
user    4m34.751s
sys     0m0.101s
$ time pyth/pyth.py -c 'hfqSjkTjkS7./Q' <<< 29 2>/dev/null

real    9m5.819s
user    9m6.069s
sys     0m0.093s

怎么运行的

           ./Q    Compute all integer partitions of the input.
 f                Filter the integer partitions:
    jkT             Join the integers with empty separator.
   S                Sort the characters of the resulting string.
      jkS7          Join [1, ..., 7] with empty separator.
  q                 Check both results for equality.
                  Keep the partition of `q' returned True.
h                 Retrieve the first element of the filtered list.
                  For a non-empty list, this retrieves the solution.
                  For the empty list, it causes an error and produces no output.

2
做得好!相当创新的方法。MS7比短r\1\8。也@ .. 0与相同h
isaacg 2015年

@isaacg谢谢!我不确定我是怎么想念的h,但我不知道您可以使用S这种方式。(在线解释器中的char参考没有提及。)jkS7似乎更短了,因为我不再需要s了。
丹尼斯

5

Python 3、109

def f(n,s=set('1234567'),l='0,'):[f(n,s-{x},l+x+c)for c in(',','')for x in s]or n-sum(eval(l))or~print(l[2:])

接受数字并输出类似元组的函数123,4567,。是的,这是一个有效的元组。

我们的想法是产生像所有可能的串43,126,7,5,有数字1通过7用逗号隔开的,没有两个逗号连续的。将这个表达式评估为元组,其和等于n,打印并以错误终止。

为了构建所有这样的字符串,我们跟踪s要使用的字符集,并尝试用逗号分隔每个字符,以使数字以条目结尾,或不以逗号结尾,在这种情况下,将来的数字将串联到其上。

短路被用来检查s是空的,因为列表-COMP是空的,而且n==sum(eval(l)),在这种情况下,我们打印l,并采取一个错误终止~None通过打印返回(感谢SP3000这一点。)。

我相信在Python 3.5中,可以通过编写来保存两个字符s={*'1234567'}(感谢Sp3000)。

有一些小的烦恼会吞噬字符。一种是在l看起来1234567没有逗号的情况下,将其解析为单个数字并调用sum会产生错误。这可以l通过从元素开始0并在打印时将其剥离的技巧来解决。这需要6个字符。

c在逗号和空字符串之间进行迭代非常麻烦for c in(',',''),因为Python 3不允许该元组裸露。我希望有些?数字在数量上被忽略以减少',?'4个字符,但似乎没有这样的字符。


旧方法:

蟒蛇2,117

def f(n,s={1,2,3,4,5,6,7},l=[],p=0):
 if{n,p}|s=={0}:print l;1/0
 if p:f(n-p,s,l+[p])
 for x in s:f(n,s-{x},l,p*10+x)

定义一个接受数字并打印列表的函数。

这个想法是使用递归尝试每个分支。变量跟踪是

  • n所需的剩余金额
  • s剩余可使用的数字集
  • l到目前为止的号码清单
  • 当前部分形成的数字 p

n==0s为空时,打印l并错误终止。

如果当前部分形成的数字p不为零,请尝试将其添加到列表中,然后将其从剩余的总和中删除。

对于x我们可以使用from的每个数字s,请尝试将其附加到p和从中删除s


4

佩斯,23

#iRThfqQsiR10Ts./M.pS7q

天真的暴力行为,在线速度太慢,大约需要一分钟在我的计算机上。使用pyth golf的通用“永远循环直到异常”模式,在其中访问组合的结果过滤列表会导致不可能的数字产生错误,例如29

输出类似pythonic列表,例如

1891
[1234, 657]
100
[1, 2, 34, 56, 7]
370
[12, 345, 6, 7]

这是可以通过这种方式制作的所有10136数字的粘贴


我可以使用pastebin链接作为示例吗?
The_Basset_Hound 2015年

@The_Basset_Hound当然,继续。
FryAmTheEggman 2015年

3

Python 2.7版,178个 172 169字节

n=input()
for i in range(8**7):
 for j in len(set('%o0'%i))/8*range(128):
    s=''
    for c in'%o'%i:s+='+'[:j%2*len(s)]+c;j/=2
    if eval(s)==n:print map(int,s.split('+'));1/0

请注意,最后三行应该与制表符一起缩进,但是我不知道如何在此编辑器中这样做。

编辑:借助Sp3000展平一层嵌套


SE不幸地
剥掉

好的,仍然可以在这个网站上摸索。
xsot

3

JavaScript的(ES6),165 196

编辑缩短了一点。可以使用来缩短eval,但我喜欢快速

蛮力,比Pith版本可耻地更长,但是更快。测试在符合EcmaScript 6的浏览器中运行以下代码段的方法。

f=z=>{for(r=i=1e6;r&&++i<8e6;)for(m=/(.).*\1|[089]/.test(w=i+'')?0:64;r&&m--;t.split`+`.map(v=>r-=v,r=z))for(t=w[j=0],l=1;d=w[++j];l+=l)t+=l&m?'+'+d:d;return r?'':t}

function test() { O.innerHTML=f(+I.value) }

test()

// Less golfed

f=z=>{
  for(r=i=1e6; r&&++i<8e6;)
    for(m=/(.).*\1|[089]/.test(w=i+'')?0:64; r&&m--; t.split`+`.map(v=>r-=v,r=z))
      for(t=w[j=0],l=1;d=w[++j];l+=l)
        t+=l&m?'+'+d:d;
  return r?'':t
}
<input id=I value=28><button onclick=test()>-></button><span id=O></span>


不用再因为语言而感到羞耻,我真的很喜欢您的JS答案,+ 1
FryAmTheEggman 2015年

1

Python 2中,270个 268字节

from itertools import*;P=permutations
x,d,f=range(1,8),[],input()
r=sum([[int(''.join(str(n)for n in i))for i in list(P(x,j))]for j in x],[])
z=1
while z:
 t=sum([[list(j)for j in P(r,z)]for i in x],[])
 v=filter(lambda i:sum(i)==f,t)
 if v:print v[0];break
 else:z+=1

仍在打高尔夫球。

这将循环直到找到匹配项。


import as几乎没有必要-可以做到from itertools import*;P=permutations
Sp3000

map(str,i)比列表理解要短,并且您可以直接构造列表r,而不是通过拼合嵌套列表:r=[int(''.join(map(str,i)))for j in x for i in P(x,j)]和t的类似方法。
露丝·富兰克林

您可以使用`n`代替str(n),因为它n永远不会超过最大整数。
mbomb007

1

Haskell(145字节)

main=getLine>>=print.head.f[1..7].read
f[]0=[[]]
f b s=[n:j|(n,g)<-m b,j<-f g$s-n]
m b=[(d+10*z,g)|d<-b,(z,g)<-(0,filter(/=d)b):m(filter(/=d)b)]

使用递归。

非高尔夫(337字节):

delete d = filter (/= d)
main = getLine >>= print . (`form` [1..7]) . read

form s [] | s == 0    = [[]]
form s ds | s <= 0    = []
form s ds | otherwise = [n:ns | (n, ds') <- makeNumbers ds, ns <- form (s-n) ds']

makeNumbers [] = []
makeNumbers ds  = [(d + 10 * n',ds') | d <- ds, (n',ds') <- (0,delete d ds):makeNumbers (delete d ds)]

0

Scala,195个字节

这不是最有效的方法,它花费了15分钟以上的时间来获得29的输出,但确实有效

def g(s: Seq[Int]): Iterator[Seq[Int]]=s.combinations(2).map(c=>g(c.mkString.toInt +: s.filterNot(c.contains))).flatten ++ Seq(s)
def f(i: Int)=(1 to 7).permutations.map(g).flatten.find(_.sum==i)

这是一些输出

scala> f(100)
res2: Option[Seq[Int]] = Some(Vector(46, 35, 12, 7))

scala> f(1891)
res3: Option[Seq[Int]] = Some(Vector(567, 1324))

scala> f(370)
res4: Option[Seq[Int]] = Some(Vector(345, 12, 6, 7))

scala> f(29)
res5: Option[Seq[Int]] = None

0

Ruby,105个字节

蛮力!检查介于1到7654321之间的整数的每个介于0到7之间的长度的子集,并查看它们是否符合我们的条件。您可能不想等待此终止。

->n{8.times{|i|[*1..7654321].permutation(i){|x|return x if
x.join.chars.sort==[*?1..?7]&&eval(x*?+)==n}}}

要运行和验证算法,可以通过替换7654321为答案中知道的最大数字来缩小搜索空间。例如,对于n = 100,为56,对于n = 1891,为1234。这是后者的试用版:

$ ruby -e "p ->n{8.times{|i|[*1..1234].permutation(i){|x|return x if x.join.chars.sort==[*?1..?7]&&eval(x*?+)==n}}}[gets.to_i]" <<< 1891
[657, 1234]

0到7个整数?您应该使用7个整数:1、2、3、4、5、6、7
edc65

@ edc65您的意思是恰好7 位数字。结果是一组整数,该组的大小取决于输入。
daniero

我不会说Ruby,但我猜想程序可以运行,但是没有得到解释。如果您的整数小于1234567,您将如何获得7654321?
edc65

@ edc65您是对的,我必须更改该数字。我也会尝试更好地解释它。
daniero
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.