SUDSIシーケンスを生成する


15

SUDSI配列(SUの M、D ifference、S WAP、I ncrement)が表示されますではなくカオス的挙動を示すために、その好奇心整数配列です。次のように生成できます。

してみましょうSは、自然数の無限リストであります:1 2 3 4 5 6 ...。してみましょうSを、私は 1インデックス表すの番目の要素S。したがって、最初は、 S 1は1、S 2は2などです(S 0はありません)。

S 1およびS 2から開始...

  • それらの合計を計算します。 sum = S1 + S2
  • それらの絶対差を計算します(大きい方から小さい方を引いたもの): diff = |S1 - S2|
  • Sの2つの値を和と差のインデックスで交換します。swap(Ssum, Sdiff)

  • 作業しているSのインデックスを増やします。したがって、次回はS 2S 3の合計と差を計算し、その後の時間はS 3S 4などになります。

  • このプロセスを無期限に繰り返します。

このプロセスが適用されるSの最初のいくつかの段階を以下に示します。括弧[]は、合計および差分される2つの値を囲みます。

オリジナルS

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

S 33 = 1 + 2)とS 11 = |1 - 2|)交換されます。

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

S 3及びS 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 9およびS 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の用語を次に示します(1行あたり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

(少なくとも私には)将来の用語を予測する方法は不明です。用語は常に奇数であり、減少しない(2番目の用語の後)であり、いくつかの数字は何度も繰り返されると言っても安全です。

チャレンジ

正の整数nを取り込んで、SUDSIシーケンスのn番目の項を出力または返すプログラムまたは関数を作成します。たとえば、nが1の場合、出力は1です。nが2の場合、出力は3です。nが200の場合、出力は363です。

通常の方法で入力を行います(stdin / command line / function arg)。バイト単位
の最短回答が優先されます
(そのサイトは物事をUTF-8でエンコードしますが、必要な既存のエンコードを使用できます。)

Mathyボーナス:(賞金の対象になる可能性があります)

  • SUDSIシーケンスについて詳しく教えてください。どの数字がその一部であり、いくつあるか(そしてそのようなもの)の基本パターンは何ですか?(ところで、OEISで SUDSIが見つかりませんでした。)

再び。エンコードに関する混乱を作成するよりもリンクしない方が良い。
オプティマイザー

@Optimizer私は年齢のために同じフレージングでそのバイトカウンターにリンクしてきました。なぜそれが突然、これまでよりも多くの混乱を引き起こすのでしょうか?
カルビンの趣味

1
@orlpこれは素晴らしい追加機能になると思いますが、提出物のソースファイルがめったにないので、個人的にコピーアンドペーストできることに依存しています。
マーティンエンダー

1
@orlpしかし、とにかく誰がそれを必要としますか?ファイルがあれば、サイズを直接確認できます。また、一部のオペレーティングシステムでは、最終的に改行を削除するのはそれほど簡単ではありません。
jimmy23013

2
:MartinBüttner私は退屈していた@ meta.codegolf.stackexchange.com/questions/4944/...
orlp

回答:


5

Pyth、45 41 40 38バイト

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

(マーティンBüttnerを行ったように)私は、順列のステップの最大影響を受けた数がでていること、気づいkています2k + 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を使用するのに罰金はありますか?
アレックスA.

1
@アレックスA.ハハ、いや。しかし、本を返さないためのものがあります。
ジャクベ

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は良い解決策ですが、ほとんどが非常に興味深い有益な分析のためです!
アレックス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

シーケンスをリストまたは配列に保存しません。現在のステップの2つの要素が入れ替わった関数に恒等関数を繰り返し更新します。nステップの後、結果の関数をparameterで呼び出します1



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*nfor large nに収束し、最大3*nforになっているようn=1です。
ボラティリティ

@Volatility基本的に、最大値は2n+1であり、あなたが言うように3for n=1で最大であり、ある意味でに収束し2nます。これは、並べ替えられていないシーケンスの最大値であり、プロセスのどのステップもまだ先の数字を増やすことができないため、これは驚くべきことではありません。これを答えに追加するかもしれません。
マーティンエンダー

私の.a拡張機能はすでに有効に使用されているようです!まだまだたくさんの機能
orlp

@orlp、実際にコードを書いているときにドキュメントを読んで(通常、doc.txtGitHubのマニュアルを使用しています)、更新を見ました。幸いなことに、私はそれをスキップしてカスタム実装を作成できたので
...-PurkkaKoodari

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の回答からの方法を使用すると、より短いことがわかります。

5バイトを節約してくれたxnorに感謝します。


リストのアンパックを使用できますb,c=a[i:i+2]。また、b+c変数に保存すると、s2回書き込むだけで文字が失われるほど短いです。
-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])}

Ungolfed、トリッキーなことはほとんどなく、主に@ 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

Java、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];
}

2番目のループ本体をforステートメントのincrement句に移動すると、2バイトを節約できます。(セミコーラではなく、コンマでステートメントを区切ります。)
AJMansfield

1

dc、 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であるN$codeある...コード(GASP)。味に引用します。

編集:説明を求められない限り、私は決してそれに近づかないでしょう。


`-e`に3バイトを追加する必要がありますか?
ジョー

@サー、あなたはしないことがわかります![ 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(のサイズよりも1つの少ない回繰り返し@_切り替え)$a[$a[$_-1]+$a[$_]]$a[abs($a[$_-1]-$a[$_])]のような$_範囲で2からの大きさ@_

そして、サブルーチンはを返します$a[1]


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.