生成斯托尔序列


12

我正在学习Ruby,并编写了我的第一个平凡的代码来解决这个问题。

面临的挑战是,以产生第一Ñ所述的元件斯托尔序列小号,其被定义如下:

S [0] = 1

S [n]是无法表示为序列中两个不同的先前元素之和的最小数字。

因此,该序列以1、2、4、7和10开头。下一个元素为13,因为11(= 1 + 10)和12(= 2 + 10)是先前元素的总和,但13不是。

我正在寻找最短的代码。我自己使用Ruby,长度为108个字符,但是也许我会等着看别人提出什么之后再发布它?


到目前为止,我喜欢答案。现在,返回并更改需求为时已晚,但是我想我应该提到我对使用序列本身的定义的解决方案特别感兴趣(即,代码事先并不知道最终数字上升3)。所以:如果可以的话,可以获得道德奖励积分。
泰奥菲尔

这就是数学序列的问题。如果您知道该模式,则通常会更短。

该序列是算术运算,没有任何用处(?)。
user75200

@ user75200序列不是算术的,从前三个元素的差异可以看出,但是从第三个元素开始的子序列确实是算术的。它用于解决邮票问题。
泰奥菲尔

Answers:


13

APL,7

在APL中,您可以选择是否要使用索引0或索引1。您可以通过设置全局变量⎕IO←0来进行此操作。

如果我们选择在索引0中工作,则有:

+\3⌊1⌈⍳

说明:

⍳    creates a sequence 0...n   (0 1 2 3 4 5)
1⌈   takes whichever is bigger, number in sequence or 1 (1 1 2 3 4 5)
3⌊   takes whichever is lower, number in sequence or 3 (1 1 2 3 3 3)
+\   partial sums for the sequence (1 2 4 7 10 13)

tryapl.org尝试


您不能使用基于1的索引,然后创建1到n的数组,然后简单地在其前面加上另一个1吗?如果可以做到,它会更短吗?
Optimizer

我得到的代码更长。这是我的索引1的代码,为10个字符:+ \3⌊1,⍳¯1+此外,index-0版本也适用于参数0,而该参数则无效。
莫里斯·祖卡

啊。是的 APL确实在这里闪耀着光芒..
Optimizer

9

哈斯克尔- 11 21

惰性无限序列

1:2:[4,7..]

返回刚刚提供的成员数(叹气)的函数

flip take$1:2:[4,7..]

必须输入并仅打印第一个n数字。
Optimizer

4
@Optimizer从技术上讲,您必须 “生成Stöhr序列的前n个元素”,这并不是说您也无法生成其余元素!它也没有说您也必须接受输入。swish的原始代码实际上确实为任何n生成了前n个项。
wchargin

1
@WChargin试图变得过聪明并不是什么新鲜事。将OP的措辞过于字面化并产生超出要求的额外输出都被视为标准漏洞。
Optimizer

2
@Optimizer实际上,懒惰意味着除非您要求,否则不会生成任何额外的输出,并且您可以要求任何条件。
2015年

1
@swish我不明白。这里有什么懒惰的?
Optimizer

7

Python 2,37 35字节

lambda n:[1,2][:n]+range(4,n*3-4,3)

利用模式...


1
您可以4将范围包括在内:lambda n:[1,2][:n]+range(4,n*3-4,3)
Jakube 2015年

好发现。现在编辑为35。
逻辑骑士

6

CJam,14个字节

1l~{_p_3e<+}*;

在这里测试。

从1开始。然后,S [n] = S [n-1] + min(S [n-1],3)

1l~{_p_3e<+}*;
1              "Push 1.";
 l~            "Read and evaluate input N.";
   {       }*  "Repeat this block N times.":
    _p         "Duplicate the last number and print it.";
      _3e<     "Duplicate it again, and take minimum with 3.";
          +    "Add to last number.";
             ; "Discard final number to prevent output.";

如果我们用2 h -1替换3,这很容易推广到h- Stöhr序列。


6

Brainfuck,13个字符

+.+.++.[+++.]

如果我们想将其限制为n个输出,则为30个字符:

,->+.<[->+.<[->++.<[->+++.<]]]

1
我认为您需要打印第一个n元素,而不是无限的元素...
Sp3000,2015年

@ Sp3000是否通常将字符代码用作数字输入和输出?在meta上找不到。这样,很容易就可以更正BF代码。
randomra 2015年

我个人不确定这是什么普遍共识,对不起。我也有这个问题。
Sp3000

对于前n个元素,我认为我可以做到-> +。<[-> +。<[-> ++。<[-> +++。<]]](29个字符),但这并不优雅。而且我不认为该语言专门限于使用ASCII码进行输入和输出。
jgosar 2015年

1
即使代码不够优雅,您的代码必须回答该问题。我建议编辑帖子并更正答案,->+.<[->+.<[->++.<[->+++.<]]]。(您一开始就错过了输入阅读逗号。)
randomra 2015年

4

Python,136个字节

def f(n):
 if n<1:return[1]
 x=f(n-1);y=set(x)|{a+b for a in x for b in x if a!=b};return x+[min([a for a in range(1,max(y)+2)if{a}-y])]

直接来自定义。我不确定我能打多少高尔夫球,这肯定比我预期的要长得多。


3

J,14个字符

这只是对[1,2, 4+3*k (k=0..n-1) ]序列进行硬编码并采用第一个N

   ({.1,2,4+3*i.) 10
1 2 4 7 10 13 16 19 22 25

J,18个字符

这个人使用的线性组合[0,1,2,3...][1,1,0,0...][0,1,1,1...]。应该更短些,但似乎不能打高尔夫球。

   ((3&*+<&2-2**)@i.) 10
1 2 4 7 10 13 16 19 22 25

3

前奏32 20

编辑: ...现在有了两倍的声音!

?(1-)
4 +3
2  ^
1 !^

假设Python解释器带有NUMERIC_OUTPUT = True。就像Brainfuck提交一样,此答案假定输入是以代码点的形式给出的。这部分是为了使该元讨论更加吸引人(部分是因为我喜欢Prelude)。因此,如果要打印前32个数字,则需要在STDIN上放置一个空格。当然,这意味着有效输入有上限,但是无论如何该答案都无法解决,因此我认为在Prelude的限制内就可以了。

说明

在Prelude中,所有行都是并行执行的,该行具有自己的堆栈,并初始化为无限数量的零。只有一个指令指针(指向列),因此,如果您在一个声音上输入一个循环,则所有其他声音都将随之循环。

在下面的代码中,我已经转置了代码,以便可以注释行而不是列:

?421  Read a character into the first stack. Push 4, 2, 1 onto the other stacks, respectively.
      Generally, the fourth stack will hold the next number to be printed, the third stack the
      one after that, and the second stack the number two steps ahead.
(     Start a loop if the input wasn't 0.
1+ !  Push a 1 onto the first stack. Add the top elements in the second stack. On the first
      iteration this will be 0 and 4, so it does nothing. On all further iterations
      this will increment the last number by 3.
-3^^  Subtract one from the first stack. Push a 3 onto the second stack for the next iteration.
      Copy the last value from the second to the third, and the third to the fourth stack.
)     If the top of the first stack is not 0, jump back to the column after the (.

2

JavaScript(ES6)92

作为基于问题定义的递归函数

S=(n,v=1,s=[],r=0)=>[for(a of s)for(b of s)r+=(a-b&&a+b==v)]|r||(s.push(v),--n)?S(n,v+1,s):s

使用模式1,2,1 + 3 * k:58

S=(n)=>(i=>{for(t=1;n>r.push(t+=i);i+=(i<3));})(0,r=[])||r

旁注:找到h-Stöhr序列(验证最多为h2个数字的总和)。该R函数尝试给定数量的列表元素的所有可能的和。

S=(n,h=2,s=[],v=1,R=(t,v,l,i=0,r=t,w)=>{
  for(;r&&l&&v[i];i++)
    w=[...v],r=!R(t-w.splice(i,1),w,l-1)
  return!r;
})=>R(v,s,h)||(s.push(v),--n)?S(n,h,s,v+1):s

Ungolfed大致相当于(和ES5兼容)

function S(n, v, s)
{
  var r=0,a,b
  v = v||1
  s = s||[]
  for(a of s)
    for(b of s)
    {
      if (a != b && a+b == v) 
        r++;
    }
  if (r == 0) 
  {
    s.push(v);
    --n;
  }
  if (n != 0)
     return S(n,v+1,s)
  else
     return s
}

在FireFox / FireBug控制台中测试。功能简单:

S(20)

[1、2、4、7、10、13、16、19、22、25、28、31、34、37、40、43、46、49、52、55]

进阶功能:

S(10,5)

[1、2、4、8、16、32、63、94、125、156]


2

> <>(鱼)72 65 49 46字符

1n1-:?!;' 'o2n1-v
v1&no' ':<4&;!?:<
>-:?!;&3+^

输入提供给解释器:

>fish.py stohr.fish -v 10
1 2 4 7 10 13 16 19 22 25

我的第一个> <>程序,建议受到赞赏。


哦,太好了!我希望有人编写一个> <>程序。
泰奥菲尔

2

> <>,​​31个字节

4i1nao:?!;2nao1-:?!;$:nao3+$d0.

读取单个字符,使用其代码点(例如space = 32),并在每行上打印数字1。


2

Perl6 22/30

我将看看Perl6是否可以为我推断出序列。

为此,我使用了Perl6内置的REPL

$ perl6
> 1,2,4,7...*
Unable to deduce arithmetic or geometric sequence from 2,4,7 (or did you really mean '..'?)
> 1,2,4,7,10...*
1 2 4 7 10 13 16 19 22 25 28 31 34 37 40 43 46 49 52 55 58 61 64 67 70 ...

嗯,我看到了Perl推论出的模式。在4之后要获得下一个值,您只需添加3。

1,2,4,*+3...*

这节省了一个字符,使代码可以获取13个字符长的Stöhr序列中的数字的无限列表。

该代码仅在REPL中做有用的事情,因为它为我们打印了结果的要旨。要使其打印,否则必须明确告诉Perl打印结果。

$ perl6 -e 'say 1,2,4,*+3...*'

(这* + 3是获取返回3的代码引用的唯一方法。其他编写方法是{ $_ + 3 },或-> $i { $i + 3 }{ $^i + 3 }sub ($i){ $i + 3 }


创建某些可调用以生成前n个元素的最短方法是获取元素的切片。

{(1,2,4,*+3...*)[^$_]} # 22

在空上下文中会生成第一个$_值,然后立即将它们丢弃。

在除void上下文之外的任何其他情况下,它都会创建一个带一个参数的匿名代码块(不带名称的基本子例程)。

# store it in a scalar variable
my $sub = {(1,2,4,*+3...*)[^$_]};
say $sub.(5);
# 1 2 4 7 10

# use it immediately
say {(1,2,4,*+3...*)[^$_]}.(5);
# 1 2 4 7 10

# pretend it always had a name
my &Stöhr-first = {(1,2,4,*+3...*)[^$_]};
say Stöhr-first 5;

如果您真的认为它必须有一个名称才有资格对此挑战有效,那么您可能会这样做:

sub s(\n){(1,2,4,*+3...*)[^n]} # 30

尽管由于s也用于替换运算符,所以调用此括号是非可选的。(我想您可能给它起了一个不同的名字)

say s(5);
# 1 2 4 7 10

除非在挑战中另有说明,否则提交高尔夫球挑战代码的提交必须是完整的程序或功能,而不仅仅是片段。
马丁·恩德

公平地说,@MartinBüttner 1,2,4,*+3...*实际上创建了一个将生成所需值的对象。我认为没有很多人会像在Perl6中那样创建可调用的对象
布拉德·吉尔伯特b2gills,2015年

2

我看到已经有一个更好的Java答案,但是我花了一段时间在这上面,我将发布它。即使很烂

Java 313字符(+4以适合屏幕显示)

import java.util.*;public class S{public static void main(String[] a){
Set<Integer> S=new HashSet<Integer>();S.add(1);int i=1,k=0;
while(S.size()<=new Integer(a[0])){if(S.contains(i)){}else{k=0;for(int j:S){
for(int l:S){if(l!=j){if((j+l)==i)k=1;}}}if(k==0)S.add(i);}i++;}for(int x:S)
{System.out.println(x);}}}

总是很高兴获得任何有关如何改进的提示或指示


1

T-SQL 204

假设输入在名为@N的变量中。我可以根据需要创建一个过程,但是在T-SQL中获取STD_IN确实不是一个好方法。

另外,是为了获得道德奖励!

DECLARE @Q INT=0,@B INT=2
DECLARE @ TABLE(A INT)WHILE @N>0
BEGIN
SET @N-=1
WHILE @B>1
BEGIN
SET @Q+=1
SELECT @B=COUNT(*)FROM @ C,@ B WHERE C.A+B.A=@Q
END
INSERT INTO @ VALUES(@Q)SET @B=2
END
SELECT*FROM @

真好!我对SQL不太了解,这里如何使用@N?我看到它设置在开始处,但是后来似乎没有引用它。
泰奥菲尔

看起来像是@N“ for循环”的“ i”。
雅各布

雅各是对的。@N是for循环的“ i”,在SQL中是while循环。本质上,它将自身与表交叉连接,并找到添加到@Q的对。如果至少有两对(即本身不只是一个数字),那么它将跳过它。否则,它将其添加到表中。@是表的名称。
bmark

1

Mathematica,27个字节

嗯,Mathematica仍然没有答案吗?这是两个:

NestList[#+3~Min~#&,1,#-1]&
Array[i=1/2;i+=3~Min~i&,#]&

两者都定义了一个未命名的纯函数,该函数接收一个整数并返回一个整数列表。这基于与我的CJam提交相同的重复关系。请注意,Array基于-的代码从开始1/2,因为递归关系始终在返回值之前应用。



1

Python-甚至没有关闭(139)

在假设这不像其他人那样容易计算的情况下采取行动,我发现的最短解决方案如下:

from itertools import combinations as C
x,i,n=[],1,input()
while len(x)<=n:
 if i not in [sum(y) for y in C(x,2)]:x.append(i)
 i+=1
print n

1

Clojure的- 130 118

(defn s[n](last(take n(iterate #(if(<(count %)3)(conj %(+ (apply + %)1))(conj %(+(last %)(second %)(first %))))[1]))))

非高尔夫版本:

(defn stohr [n]
  (last
    (take n
      (iterate #(if (< (count %) 3)
                   (conj % (+ (apply + %) 1))
                   (conj % (+ (last %) (second %) (first %)))) [1]))))

分享并享受。


1

红宝石-108 88

q=->n{*k=1;(m=k[-1];k<<([*m+1..2*m]-k.combination(2).map{|i,j|i+j})[0])while k.size<n;k}

这使用了序列的定义。

更具可读性的版本:

q=->n{
    *k=1
    (
        m = k[-1]
        k << ([*m+1..2*m] - k.combination(2).map{|i,j|i+j})[0]
    ) while k.size < n
    k
}

打印q [10]

[1、2、4、7、10、13、16、19、22、25]


Ruby高尔夫技巧:*k=1代替k=[1]foo while bar代替while bar;foo;end[*s..e]代替(s..e).to_a.map代替to_a.map{|a,b|a+b}代替{|i|i.inject(:+)}
histocrat

@histocrat谢谢,这非常有帮助!
泰奥菲尔

0

STATA 51

di 1 2 _r(a) 
loc b=3*$a-2
forv x=4(3)`b'{
di `x'
}

0

TI-BASIC,41 27 30字节

为您的计算器

Input N:For(I,1,N:I:If I>2:(I-2)3+1:Disp Ans:End

0

GML,67字节

n=argument0;for(i=1;i<=n;i++){t=i;if i>2t=(i-2)*3+1show_message(t)}
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.