做一个序列


12

如果此序列中任何两个连续数字之间的差为-1或1并且其第一个元素为0,则整数序列为一个序列。

更精确地说:a1,a2,...,an是一个单序列,如果:

For any k (1 ≤  k < n): |a[k] - a[k+1]|=1, 
a[1]=0

输入值

  • n -序列中的元素数
  • s -序列中元素的总和

输出量

  • 如果可能的话,一个单序列集/列表/数组/等的长度n加上元素的总和s
  • 空集/列表/数组/等(如果不可能)

例子

对于输入8 4,输出可以是[0 1 2 1 0 -1 0 1][0 -1 0 1 0 1 2 1]。可能还有其他可能性。

对于input 3 5,输出为空[],因为无法完成。

规则

这是一个代码高尔夫,最短答案以字节为单位。提交的内容应为程序或功能。输入/输出可以以任何标准方式给出


顺便说一下,我有一个证明,可以表示为长度为1的一个序列的所有数字都是之间的所有数字,(l-1)*l/2并且-(l-1)*l/2具有与相同的奇偶校验(l-1)*l/2
骄傲的haskeller 2014年

这可用于制定有效的算法(O(n))来生成所需的一个序列
骄傲的haskeller 2014年

Answers:


7

CJam,56 47 44 34字节

这里有很多改进的余地,但是这里是第一次尝试:

L0aa{{[~_(]_)2++}%}l~:N;(*{:+N=}=p

归功于Dennis所做的有效工作{ ... }%

如果可能,打印数组表示形式,否则 ""

在这里在线尝试


我很困惑:{}%您的代码部分看上去与我的代码完全不同(这只是@PeterTaylor的代码,用下划线替换了点)。如果我为您的代码贡献了什么,那就是{}=操作员……
丹尼斯

我最初_{_W=)+}%\{_W=(+}%+使用的是第一份制作两份,然后在第一份上加1,再减去另一份。您的示例使我弄清楚了如何{ ... }%一步完成。关于{ ... }=,尽管实验还没有发布,但我已经在实验中做了很多减少。
Optimizer

我从这个问题中了解到,给定输入3 5应该是输出[]而不是""
Peter Taylor

1
@PeterTaylor“如果可能的话,请提供一个空的set / list / array / etc”-所以我认为我只需要澄清一下...
Optimizer

另外,[]p在CJam中,仅输出到""。因此,该语言如何表示空数组。
Optimizer

6

JavaScript(E6)79 82

F=(n,t,
  d=n+n*~-n/4-t/2,
  l=1,
  q=[for(x of Array(n))d<n--?++l:(d+=~n,--l)]
)=>d?[]:q

无需蛮力或枚举所有元组。

见长度的序列ñ作为Ñ -1步,每步为递增或递减。
请注意,您只能将一个增量换为一个减量,其总和为2,因此对于任何给定的长度,总和始终为偶数或始终为奇数。
具有所有增量,序列为0、1、2、3,...,n-1,我们知道总和为(n-1)* n / 2
更改最后一步,总和改变2,因此最后一步的权重为2。
更改最后一步的权重为4,因此最后一步的权重为4。这是因为后续步骤基于到目前为止的部分总和。
更改上一步,总和更改为6,因此最后一步的权重为6(不是8,这不是二进制数字)。
...
更改第一步的重量为(n-1)* 2

算法

Find the max sum (all increments)  
Find the difference with the target sum (if it's not even, no solution)  
Seq[0] is 0  
For each step  
  Compare current difference with the step weight
  if is less 
     we have an increment here, seq[i] = seq[i-1]+1 
  else 
     we have a decrement here, seq[i] = seq[i-1]-1.  
     Subtract we current weight from the current diff.
If remaining diff == 0, solution is Seq[]. Else no solution

非高尔夫代码

F=(len,target)=>{
  max=(len-1)*len/2
  delta = max-target
  seq = [last=0]
  sum = 0
  weight=(len-1)*2
  while (--len > 0)
  {
    if (delta >= weight)
    {
      --last
      delta -= weight;
    }
    else
    {
      ++last
    }  
    sum += last
    seq.push(last);
    weight -= 2;
  }  
  if (delta) return [];
  console.log(sum) // to verify

  return seq
}

在Firefox / FireBug控制台中测试

F(8,4)

输出量

[0, -1, 0, -1, 0, 1, 2, 3]

5

GolfScript(41 39字节)

[][1,]@~:^;({{.-1=(+.)))+}%}*{{+}*^=}?`

在线演示

感谢Dennis提供41-> 39。


您可以缩短,0=?。通往CJam的直接端口要短5个字节:L1,al~:S;({{_W=(+_)))+}%}*{:+S=}=p
Dennis

@Dennis oooh,这是获得两个{}%街区的便捷方法。介意我用吗?
Optimizer

@Optimizer:我没有,但这不是我的工作。
丹尼斯

我说的是{ ... }%街区。在我的代码中,我有两个尝试将其减少到1。正如真正的算法一样,我认为Peter和我几乎同时发布了相同的算法。
Optimizer

3

Mathematica,73个字节

f=FirstCase[{0}~Join~Accumulate@#&/@Tuples[{-1,1},#-1],l_/;Tr@l==#2,{}]&;

简单的暴力解决方案。

我正在生成所有选择的步骤。然后,我将它们变成累积的列表以得到一个序列。然后,我正在寻找第一个参数,其总和等于第二个参数。如果不存在,则默认值为{}


Mathematica只是针对与数学/组合相关的问题,不是吗?;)
Optimizer

@Optimizer我确信CJam还是会击败它。;)实际上,在CJam中不难实现相同的算法。
2014年

1
它肯定会击败它,但仅仅是因为方法名短。该算法不会那么简单。
Optimizer

@Optimizer,是吗?我认为使用简单的循环和过滤器比使用此函数组合更为直接。
彼得·泰勒

3

Haskell,56个字节

n%s=[x|x<-scanl(+)0`map`mapM(\_->[1,-1])[2..n],s==sum x]

说明:

  • 1,-1长度为n-1 的排列构建一个列表:replicateM n-1[-1,1]
    示例:replicateM 2 [-1,1]==[[-1,-1],[-1,1],[1,-1],[1,1]]
  • 从中构建一个序列。scanl性能不佳,但在这里却做得很好。
  • 过滤长度n等于和的所有可能的一序列s

1
一个简单的改进就是将a更改为infix函数。这暗示了更不直观的改进:Control.Monad仅为使用replicateM而导入已经太长了。您还可以使用什么其他单子函数进行模拟replicateM
自豪的haskeller 2014年

顺便说一句,您应该只返回一个解决方案,所以您应该添加head$到您的解决方案中。
骄傲的haskeller 2014年

head不返回[][] :: [[a]]-我讨厌错误。
约翰内斯·库恩

1
因为已经过去了一段时间,我会告诉你我的意思。您可以使用mapM(\x->[1,-1])[2..n]代替sequencereplicate
骄傲的haskeller 2014年

有趣。:P
Johannes Kuhn 2014年

2

Python,138

from itertools import*
def f(n,s):
 for i in[list(accumulate(x))for x in product([-1,1],repeat=n-1)]:
  if sum(i)==s:return[0]+i
 return[]

0

CJam,65 58 54字节

几乎比我的Mathematica解决方案短,但这主要是我仍然没有正确使用CJam的错误:

0]]l~:S;({{_1+\W+}%}*{0\{+_}%);}%_{:+S=}#_@\i=\0>\[]?p

从字面上讲,它是相同的算法:获取的所有n-1元组{1, -1}。找到第一个累加与相同的累加s,加一个0。如果未找到,则打印一个空数组。


0

果酱40岁

CJam中的另一种方法。

ri,W%)\_:+ri-\{2*:T1$>1{T-W}?2$+\}/])!*p

0

红宝石(136)

def one_sequences(n)
  n.to_s.chars.map(&:to_i).each_cons(2).to_a.select{|x|x[0] == 0 && (x[1] == 1 || x[1]
  == -1)}.count
end

0

J,47个字符

像许多其他答案一样检查每个序列。将尝试制作更短的O(n)解决方案。

   f=.4 :'(<:@#}.])(|:#~y=+/)+/\0,|:<:2*#:i.2^<:x'

   8 f 4
0 1 2 1 0 1 0 _1

   3 f 5
[nothing]

0

APL 38

{⊃(↓a⌿⍨⍺=+/a←+\0,⍉1↓¯1*(⍵⍴2)⊤⍳2*⍵),⊂⍬}

例:

     4 {⊃(↓a⌿⍨⍺=+/a←+\0,⍉1↓¯1*(⍵⍴2)⊤⍳2*⍵),⊂⍬}8
0 1 2 1 0 1 0 ¯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.