对N-Bonacci序列进行逆向工程


15

编辑:我将在2016年2月15日星期一接受答案。愿字节永远对您有利!

@DJMcGoathem 在他的“打印N-Bonacci序列”挑战中,描述了N-bonacci序列,其中之前的N个数字相加,而不是斐波纳契序列的传统2个(称为“ nacci序列”)。然后,他要求输入两个输入X和N,然后输出第XN -nacci数。

我提出相反的建议。
给定一个序列,输出它是N -nacci序列的子集。我之所以说“子集”,是因为:

  • A)这些序列是无限的
  • B)如果给定序列的开始,则可以只计算前导1的数量

如果它可能属于多个N -nacci序列,请选择最低的序列。
如果它不属于任何N-nacci序列,则您的程序可能会执行其他操作,而不是打印可能会误输出的内容。这些行为包括(但不限于):无限循环,错误,崩溃,删除自身(*咳嗽* 保持警惕 *咳嗽*)或创建黑洞(只要该黑洞不会产生任何可能被误认为是有效输出)。
为了应对这一挑战,这些序列以1开头。这意味着任何N -nacci序列都以N开头。此外,N必须为正整数。所以没有-1 -nacci等

测试用例:

1,1,1 -> 1
49, 97 -> 7
55, 89, 144 -> 2
1 -> 1
6765 -> 2
12, 23, 45, 89 -> 12
100, 199 -> 100

1
create a black hole (as long as this black hole does not produce anything that could be mistaken for valid output).我的,黑洞的漩涡正在收敛到黄金比例!它必须是duoacci序列的有效输出!
Conor O'Brien

1
@CᴏɴᴏʀO'Bʀɪᴇɴ这可能是一个美丽的黄金比例,但不要靠近黑洞!youtube.com/watch?v=TTUQyEr-sg0
Level River St'St

1
哦,天哪,这比我原先想的要难得多
GamrCorps '16

@ mbomb007正整数和自然数有什么区别?
并不是说查尔斯

1
@ mbomb007啊。我以为1是第一个自然数。我一定想过要数数
并不是说查理

Answers:


7

露比(94)

令我惊讶的是,我能够在同一算法中打高尔夫球这么远!我从200多个开始!

->a{1.step.find{|s|x=[1]*(s+z=a.size)
x<<x[-s,s].inject(:+)while x.max<a.max&&s>1
x[-z,z]==a}}

取消高尔夫:

l=->a{
    # ooh! a built-in infinite incrementer!
    1.step.find{|s|
        # if n == 1, z is important, otherwise s.
        x=[1]*(s+z=a.size)
        ## add the next nacci number until we hit or overshot max. 
        ## if s == 1, we don't increment, so don't bother
        x<<x[-s,s].inject(:+)while x.max<g&&s>1
        # eval to true if there's a match, false if not
        x[-z,z]==a
    }
}

究竟如何x=[1]*(s+z=a.size)运作?
Cyoce

@Cyoce如果为n == 1,则我们将永远不会递增,因此无论输入多长,我们都需要一个1的数组。如果为n > 1,则n序列至少需要为1。因此s+a.size涵盖n == 1了任意长度的a,并且涵盖了任何其他序列的开头,因此我们可以开始将s数字添加到末位。那有意义吗?
并不是说查尔斯

@Cyoce,如果您要问其他问题,请在Ruby中[1]*number使用长度为1的数组number。因此x=[1]*(s+z=a.size)分配a.sizez,然后分配给x一个长度为1的数组s+z
并不是查尔斯(Charles)

3

Python 2,176字节

def r(n,x):i,f=n,[1]*n;exec"f+=sum(f[i-n:]),;i+=1;"*(x-n);return f
l=input()
m=max(l)+len(l)
for i in range(1,m):
 if any(l==r(i,m)[b:b+len(l)]for b in range(m)):print i;break;

请注意,这需要使用以下格式的输入:

[1, 1, 2, 3...]

而不是

1, 1, 2, 3...

相当简单的解决方案,只是为了使事情顺利进行。一旦其他人回答,我会继续努力。这使用了@Data 的answer中的N-Bonnaci生成器的稍微修改后的版本,因此对他很有用。然后对于输入范围内的每个N-Bonnaci,检查输入是否是其子序列。


试试我给他同样的建议:改变f.appendf+=
Cyoce

@Cooce哦,伙计。我简直不敢错过基本的东西。FP
DJMcMayhem '16

尾随是否;必要?
Cyoce's

1

Lua中,324个 323字节

当我看到其他提交内容时,我觉得我的代码有问题...但是,我记得那是Lua,而且并不是所有这些花哨的函数:

这很有趣,实际上花了我一些时间。

编辑:使用一个简单的技巧保存了1个字节:使用::label::+ goto label代替使用进行的无限循环while''

function f(l)c=2 y,z=table.remove,os.exit while(l[1]<2)do y(l,1)if(#l<1)then print(1)z()end end ::q:: a={}for i=1,c do a[i]=1 end b={}for i=1,#l do b[i]=l[i]end while(a[#a]<b[1])do x=0 for i=(#a-c+1>0 and #a-c+1 or 1),#a do x=x+a[i]end a[#a+1]=x if a[#a]==b[1]then y(b,1)end if #b<1 then print(c)z()end end c=c+1 goto q end

脱节和解释

Lua无法在不使用索引/键的情况下定义集合,子集,甚至无法检查数组/表是否包含值。这就是为什么我决定从作为参数的数组中删除元素的原因。这就是我保持记录哪些元素已经被计算以及是否匹配的方式。

  function f(l)
  c=2
  y,z=table.remove,os.exit           -- Create pointers on table.remove and os.exit
                                     -- saves a total of 9 bytes
  while(l[1]<2)                      -- loop used to remove leading 1
  do 
    y(l,1)
    if(#l<1)                         -- we also check if it was a 1-only array
    then 
      print(1)                       -- if so, we print 1 and exit
      z()
    end 
  end

  ::q::                              -- label q, start of the infinite loop
    a={}for i=1,c do a[i]=1 end      -- fill an array with c 1s
    b={}for i=1,#l do b[i]=l[i]end   -- copy the sequence array
    while(a[#a]<b[1])                -- while max(a)<min(b)
    do
      x=0 for i=(#a-c+1>0            -- iterate from index a.length-c to
                    and #a-c+1       -- to a.length
                    or 1),#a 
      do 
        x=x+a[i]                     -- summing a's elements
      end
      a[#a+1]=x                      -- append x to a
      if a[#a]==b[1]then y(b,1)end   -- if x is equal ot a member of the sequence
                                     -- remove it
      if #b<1 then print(c)z()end    -- if b is empty, it means the subset is in a
                                     -- we print c and exit
    end                              -- else we loop again
    c=c+1                            -- with c+1
  goto q                             -- return to the start of this block
end

您可以在线尝试Lua,也可以复制/粘贴以下代码示例以运行一些测试。当此函数找到答案时退出(否则无限循环),您将不得不更改test[]used 的索引(别忘了lua是1索引的:)。

function f(l)c=2 y,z=table.remove,os.exit while(l[1]<2)do y(l,1)if(#l<1)then print(1)z()end end ::q:: a={}for i=1,c do a[i]=1 end b={}for i=1,#l do b[i]=l[i]end while(a[#a]<b[1])do x=0 for i=(#a-c+1>0 and #a-c+1 or 1),#a do x=x+a[i]end a[#a+1]=x if a[#a]==b[1]then y(b,1)end if #b<1 then print(c)z()end end c=c+1 goto q end

test={{1,1,1},
{49, 97},
{55, 89, 144},
{1},
{6765},
{12, 23, 45, 89},
{100, 199}}

print(f(test[1]))
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.