生成SUDSI序列


15

所述SUDSI序列(米,d。差分,s ^ WAP, ncrement)是一个奇怪的整数序列,似乎表现出相当混乱行为。可以如下生成:

S为自然数的无限列表:1 2 3 4 5 6 ...。让小号表示一个索引的的第i个元素小号。因此,最初, S 1为1,S 2为2,依此类推(没有S 0)。

S 1S 2开始 ...

  • 计算它们的总和: sum = S1 + S2
  • 计算它们的绝对差(较大的值减去较小的值): diff = |S1 - S2|
  • 交换S中两个值的总和和差值:swap(Ssum, Sdiff)

  • 递增您正在使用的S的索引。因此,下一次您将计算S 2S 3的和与差,之后的时间将是S 3S 4,依此类推。

  • 无限重复此过程。

这是应用此过程时S的前几个阶段。方括号[]包围将要求和和求差的两个值。

原始S

[1 2] 3 4 5 6 7 8 9 10 11 12 ...

小号33 = 1 + 2)和小号11 = |1 - 2|)被交换:

3 [2 1] 4 5 6 7 8 9 10 11 12 ...

交换S 3S 1之后:

1 2 [3 4] 5 6 7 8 9 10 11 12 ...

交换S 7S 1之后:

7 2 3 [4 5] 6 1 8 9 10 11 12 ...

交换S 9S 1之后:

9 2 3 4 [5 6] 1 8 7 10 11 12 ...

交换S 11S 1之后:

11 2 3 4 5 [6 1] 8 7 10 9 12 ...

交换S 7S 5之后:

11 2 3 4 1 6 [5 8] 7 10 9 12 ...

等等

SUDSI序列定义为这些列表中每个列表中的第一元素的序列。因此SUDSI序列的前几项是1 3 1 7 9 11 11

这是SUDSI序列的前200个术语(每行20个):

1 3 1 7 9 11 11 11 15 15 19 19 19 19 19 19 19 19 19 19 
19 19 19 19 19 19 19 19 57 59 59 59 59 59 59 59 59 59 77 79 
81 83 85 87 89 91 91 91 91 91 91 91 91 91 91 91 91 91 115 115 
121 123 125 127 127 127 127 127 137 139 141 143 145 147 147 147 147 147 147 147 
147 147 147 147 167 167 167 167 167 167 167 167 167 167 167 167 167 167 167 167 
167 167 167 167 209 211 211 211 211 211 221 223 223 223 223 223 223 223 223 223 
223 223 243 243 243 243 243 243 257 259 261 263 263 263 263 263 263 263 263 263 
263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 263 
263 263 325 327 329 331 331 331 331 331 331 331 331 331 349 351 351 351 351 351 
361 363 363 363 363 363 363 363 363 363 363 363 363 363 363 363 363 363 363 363

(至少对我而言)尚不清楚如何预测未来的期限。可以肯定地说,这些术语始终是奇数,不递减(在第二个术语之后),并且某些数字重复了很多次。

挑战

编写一个接受正整数n并打印或返回SUDSI序列的第n个项的程序或函数。例如,如果n为1,则输出为1,如果n为2,则输出为3,如果n为200,则输出为363

以任何常用方式(stdin /命令行/功能arg)进行输入。以字节为单位
的最短答案将获胜。
(该站点以UTF-8编码,但是您可以使用任何想要的现有编码。)

数学奖金:(可能有资格获得赏金)

  • 告诉我更多有关SUDSI序列的信息。什么是数字的基本模式是什么?数字有多少(以及类似的东西)?(顺便说一下,我在OEIS上找不到SUDSI 。)

再次。最好不要链接,而要给编码造成混乱。
Optimizer

@Optimizer我一直使用相同的短语链接到该字节计数器,并且使用了ages。为什么突然引起比以往更多的混乱?
卡尔文的爱好

1
@orlp我想这将是一个不错的附加功能,但是我个人依赖能够复制粘贴,因为我很少有提交的源文件。
马丁·恩德

1
@orlp但是谁仍然需要它呢?如果他们有文件,他们可以直接看到大小。最后,在某些操作系统中删除换行符并不容易。
jimmy23013 2015年

Answers:


5

Pyth,45 41 40 38字节

MXGH_HhugGm@Gtd,s<>GH2.a-@GH@GhHtQr1yQ

我注意到(与MartinBüttner一样),置换步骤的最大受影响数目k2k + 1。但是,由于只有n - 1步数,因此只需要一个数字列表即可2n - 1

在线试用:演示

M                       define a function g(G, H): return
                        (G is the list of numbers, H is a tuple)
 XGH_H                     a translation of G
                           (replaces the elements in H with the elements in reversed H)
                           in this application it swaps two values in the list G


                        implicit: Q = input()
 u     tQr1yQ           reduce, G = [1, 2, ..., 2*Q-1]
                        for each H in [0, 1, ..., Q - 2]:
                           G = 
  gG...                        g(G, ...)
h                       print the first element of the resulting list

And the second argument ... of the function call g is:

     ,                  create the tuple (
      s<>GH2               sum(G[H:][:2]), 
            .a-@GH@GhH     abs(G[H],G[H+1])
                        )
m@Gtd                   and map each value d to G[d - 1]

在库外使用Pyth可以吗?
Alex A.

1
@Alex A.哈哈,不。但是有一个不退书的地方。
2015年

18

Mathematica,88个字节

Last[f@n_:=n;(r=f@1;{f@a,f@b}={f[b=+##],f[a=Abs[#-#2]]};r)&@@f/@{#,#+1}&/@Range@Input[]]

这是一个完整的程序,从提示中读取输入。这是定义的非常直接的实现,在其中我跟踪当前序列f(其值f[n]默认为n)。

这是一个更具可读性的版本:

Last[
  f@n_ := n;
  (
    r = f@1;
    {f@a,f@b} = {f[b=+##],f[a=Abs[#-#2]]};
    r
  ) & @@ f /@ {#,#+1} & /@ Range @ Input[]
]

一些分析

我已经绘制了序列的前2000个元素(事后并没有变得更加有趣):

在此处输入图片说明

因此,该序列基本上与斜率2呈线性关系,并且始终包含其中一些步骤。似乎步长是亚线性增长的(如果它们甚至没有边界),因为随着您增加绘制点的数量,这些步变得几乎不明显。

我们可以很容易地证明线性增长的合理性(这有点麻烦,但是我认为通过归纳法可以得到严格的证明):最初,最大置换步数nn + (n+1) = 2n + 1。还要注意的是,这些数字将始终被移动到1,因为|n - (n+1)| = 1。因此,我们获得大约2n在序列中的数字也就不足为奇了。但是,我们还可以注意到,对于直到n的步长,S n + 1始终受n + 1限制,这意味着没有交换步骤可以交换两个都大于n的数字。因此,仍需要处理的数字将小于或等于其初始值。因此,2n + 1 也是序列本身的界限。

我认为找到有关步骤长度的论点会比较棘手。


3
+1是一个很好的解决方案,但主要是用于非常有趣和有益的分析!
Alex A.

4

CJam,45 40 39字节

只是一个幼稚的方法。可以进一步打高尔夫球。太多缺少数组交换功能。

ri_K*,\{\:L>2<L1$:+:S@:-z:DL=tDSL=t}/1=

怎么运行的:

ri_                             "Read the input, convert to integer and copy it";
   K*,                          "Multiply the copy by 20 and get 0 to 20*input-1 array";
      \{ ... }/1=               "Swap and put input on stack and run the loop that many";
                                "times. After the loop, take the second element as";
                                "we have a 0 based array while series is 1 based";
{\:L>2<L1$:+:S@:-z:DL=tDSL=t}
 \:L                            "Swap to put iteration index behind the array";
                                "and store array in L";
    >2<                         "In each loop, the iteration index will be on stack";
                                "Get the two elements from the array starting at that";
       L1$                      "Put the array on stack and copy the tuple";
          :+:S                  "Get the sum and store it in S";
              @:-z:D            "Get the absolute difference of the tuple and store in D";
                    L=t         "Put the element at S diff at sum index";
                       DSL=t    "Put the element at S sum at diff index";

在这里在线尝试


4

Haskell,95个字节

f#n=let b=f$n+1;l=f n+b;r=abs$f n-b;y x|x==l=f r|x==r=f l|1<2=f x in y
p n=foldl(#)id[1..n-1]$1

用例:p 70- >139

我不将序列存储在列表或数组中。我反复将标识函数更新为交换了当前步骤的两个元素的函数。在执行n步骤之后,我使用参数调用结果函数1


2

J,63个字节

3 :'{.>((1-~{(+,|@-)]{~1+[)|.@:{`[`]}])&.>/(<"*i.1-y),<>:i.3*y'

用法和测试:

   f=.3 :'{.>((1-~{(+,|@-)]{~1+[)|.@:{`[`]}])&.>/(<"*i.1-y),<>:i.3*y'

   f 5
9
   f every 1+i.20
1 3 1 7 9 11 11 11 15 15 19 19 19 19 19 19 19 19 19 19

在这里在线尝试。


1

Pyth, 55 53 51

可以进一步打高尔夫球。 可能会变得很慢,n因为我懒得弄清楚我需要多长时间,而只使用了n^n一个。

感谢VolatilityMartinBüttner指出我最多可以使用3n

KU*3QFNr1QJ@KN=G@tKNAJG,+JG.a-JG=Y@KJ XXKJ@KGGY)@K1

说明

                   Q = input (implicit)
KU*3Q              K = range(3 * Q)
FNr1Q              for N in range(1, Q):
 J@KN               J = K[N]
 =G@tKN             G = K[1:][N]
 AJG,+JG.a-JG       J, G = J + G, abs(J - G)
 =Y@KJ              Y = K[J]
 XXKJ@KGGY          K[J], K[G] = K[G], Y
)
@K1                print K[1]

我进行了一些测试,看来所需的列表长度收敛2*n为大n,最大3*nn=1
波动率

@Volatility本质上,最大值为2n+1,正如您所说的,最大值为3n=1并且(以某种方式)收敛到2n。这并不奇怪,因为这是未置换序列的最大值,并且该过程中的任何步骤都不能增加仍然领先的数字。我可以将其添加到我的答案中。
马丁·恩德

我看到您已经将我的.a扩展程序做好了!路上还有更多好吃的东西,但是isaac现在正在睡觉:github.com/isaacg1/pyth/pull/32
orlp

@orlp,我实际上在编写代码时偶然阅读了文档(我通常doc.txt在GitHub上使用手册)并看到了更新。幸运的是,我可以跳过它并编写一个自定义实现...
PurkkaKoodari 2015年

1

Python 2 117 106 101

j=input();a=range(3*j)
for i in range(1,j):b,c=a[i:i+2];d=abs(b-c);a[b+c],a[d]=a[d],a[b+c]
print a[1]

使用dict(映射)保存值以使用任意索引。g(n)是返回n第一个项目的函数。然后只是迭代input-1时间并输出第一项。

事实证明,使用我的Pyth回答中的方法,它更短。

感谢xnor节省了5个字节。


您可以使用列表解压缩:b,c=a[i:i+2]。而且,b+c它足够短,以至于将其保存到变量中s会浪费字符,而不仅仅是将其写入两次。
xnor

1

转到150

func f(j int){a:=make([]int,j*2);for i:=range a{a[i]=i};for i:=1;i<j;i++{b,c:=a[i],a[i+1];v:=b-c;if v<0{v*=-1};a[b+c],a[v]=a[v],a[b+c]};println(a[1])}

松散的,没什么棘手的,主要是从@ Pietu1998偷来的

func f(j int) {
    a := make([]int, j*2) // Build the array we will be working on
    for i := range a {
        a[i] = i
    }
    for i := 1; i < j; i++ {
        b, c := a[i], a[i+1]
        v := b - c
        if v < 0 {
            v *= -1
        }
        a[b+c], a[v] = a[v], a[b+c]
    }
    println(a[1])
}

http://play.golang.org/p/IWkT0c4Ev5


1

爪哇162

int f(int n){int a[]=new int[2*n],s,d,x,t;for(x=0;x<2*n;)a[x]=++x;for(x=0;++x<n;){s=a[x]+a[x-1]-1;d=Math.abs(a[x]-a[x-1])-1;t=a[s];a[s]=a[d];a[d]=t;}return a[0];}

说明

int f(int n) {
    int a[] = new int[2 * n], sum, diff, x, temp;
    for (x = 0; x < 2 * n;) {
        a[x] = ++x;  // set initial array
    }
    for (x = 0; ++x < n;) {
        sum = a[x] + a[x - 1] - 1;
        diff = Math.abs(a[x] - a[x - 1]) - 1;
        temp = a[sum];
        a[sum] = a[diff];
        a[diff] = temp;
    }
    return a[0];
}

您可以通过将第二个循环主体移到for语句的递增子句中来节省两个字节。(用逗号而不是Semicola分隔语句。)
AJMansfield,2015年

1

直流电 134 132 131字节

[_1*]sOdsn2*ddslsSsa[ladd:S1-dsa0<P]dsPx1d0rsN:N[la1+dsad;SdS@r1+;SdS@rL@L@r+Ss-d0>Od;SrLsdSsrLs;Sr:S:S1;SladsN:Nlaln>G]dsGxln1-;Nf

使用echo $n $code | dc,其中n$nn$code是...代码(gasp)。引用品尝。

编辑:除非您让我讨厌一个解释,否则我永远也不会解决。


我需要为-e添加三个字节吗?

@先生,事实证明你没有![ codegolf.stackexchange.com/questions/25670/…–

那是和你自己的谈话吗?
NoOneIsHere

@NoOneIsHere:是的,肯定是。这是一个对任何人都开放的问题,但我找到了答案。

0

Perl 5,131

天真的解决方案(即定义的直接实现)。子例程,将输入作为1所需长度的s 列表。

{map$a[$_]=$_,1..3*@_;($a[$a[$_-1]+$a[$_]],$a[abs($a[$_-1]-$a[$_])])=($a[abs($a[$_-1]-$a[$_])],$a[$a[$_-1]+$a[$_]])for 2..@_;$a[1]}

通过例如可视化其输出print sub...->(1,1,1,1,1)

说明:

map$a[$_]=$_,1..3*@_构建数组@a,将每个整数本身从@_(输入)大小的1到3倍进行索引。

($a[$a[$_-1]+$a[$_]],$a[abs($a[$_-1]-$a[$_])])=($a[abs($a[$_-1]-$a[$_])],$a[$a[$_-1]+$a[$_]])for 2..@_重复多次的switcheroo(一个比的大小更少倍@_)时,切换$a[$a[$_-1]+$a[$_]]$a[abs($a[$_-1]-$a[$_])]作为$_范围从2到的大小@_

然后,子例程返回$a[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.