前後にカウントしてからダブルアップ


24

数えてみましょう...

2までカウントして1に戻る
4まで
カウントして1に戻る6までカウントして1に戻る
...わかりました...

これらをすべてまとめると、次のシーケンスが得られます

 {1,2,1,2,3,4,3,2,1,2,3,4,5,6,5,4,3,2,1,2,3,4,5,6,7,8,7,6,5,4,3,2,1,2,3...}

課題 1インデックス付き(または0インデックス付き)の
整数n>0を指定しn>=0、このシーケンスのn番目の項を出力します

テストケース

Input->Output  

1->1  
68->6  
668->20  
6667->63  
10000->84

ルール

プログラムは1分以内にn = 10000までの解を計算できる必要があります

これはなので、バイト単位の最短コードが勝ちです!


2
誰が1分かかるのを決めるのですか?レゴから構築された時間最適なチューリングマシンは非常に長い時間がかかりますが、Cでシミュレートされた同じチューリングマシンは、実行するプロセッサに応じて、おそらく数秒または数分かかります。したがって、チューリングマシンの説明を送信した場合、それは有効ですか?
アーサー

2
@Arthurこの制限を行った理由を理解できると思います...膨大なリストを作成することで、アルゴリズムが「永遠に」n = 10000を見つけることを望んでいませんでした。ここにいるほとんどの人々は、すぐに。

4
@BillSteihn制限は不要だと思います。
エリックアウトゴルファー

2
@EriktheOutgolfer gode golfの回答は難しい場合があります...制限がなければ、10,000タプル[1,2 ... 2n..2,1]を生成する回答が有効になります。制限はこのような回答にのみ適用されます。問題がどこにあるかを確認します。あなたの答えが妥当な時間内にすべてのテストケースを見つけることを望みます。

3
ここでの@StraklSethの一般的なコンセンサスは、必ずしも実際に機能するとは限らず、理論的に機能する必要があるということです。
エリックアウトゴルファー

回答:


16

JavaScript(ES7)、 59 ... 44  43バイト

Titusのおかげで1バイト節約

予想される入力:1インデックス付き。

n=>(n-=(r=(~-n/2)**.5|0)*r*2)<++r*2?n:r*4-n

最初は、類似のシーケンスであるA004738の式に触発されました。しかし、私は完全に書き直しました。

テストケース

どうやって?

シーケンスは、左部分が昇順、右部分が降順の三角形として配置できます。

以下は、最初の32行を含む最初の4行です。

            1 | 2
        1 2 3 | 4 3 2
    1 2 3 4 5 | 6 5 4 3 2
1 2 3 4 5 6 7 | 8 7 6 5 4 3 2

それでは、いくつかの変数を紹介しましょう。

 row  | range   | ascending part              | descending part
 r    | x to y  | 1, 2, ..., i                | 4(r+1)-(i+1), 4(r+1)-(i+2), ...
------+---------+-----------------------------+-----------------------------------------
  0   |  1 -  2 |                           1 | 4-2
  1   |  3 -  8 |                   1   2   3 | 8-4  8-5  8-6
  2   |  9 - 18 |           1   2   3   4   5 | 12-6 12-7 12-8  12-9  12-10
  3   | 19 - 32 |   1   2   3   4   5   6   7 | 16-8 16-9 16-10 16-11 16-12 16-13 16-14

上部の2つの要素から始め、新しい行ごとに4つの要素を追加します。したがって、インデックス0の行rの要素の数は次のように表現できます。

a(r) = 4r + 2

rの1から始まる開始位置xは、この算術級数の先行するすべての項に1を加えたものであり、次のようになります。

x(r) = r * (2 + a(r - 1)) / 2 + 1
     = r * (2 + 4(r - 1) + 2) / 2 + 1
     = 2r² + 1

逆に、シーケンス内のインデックスが1の位置nを指定すると、対応する行は次のように見つかります。

r(n) = floor(sqrt((n - 1) / 2))

またはJSコードとして:

r = (~-n / 2) ** 0.5 | 0

r(n)がわかったら、開始位置x(r)から1を引いた値をnから減算します。

n -= r * r * 2

na(r)/ 2 + 1 = 2r + 2と比較して、昇順か降順かを判断します。

n < ++r * 2 ?

この式が真の場合、nを返します。そうでなければ、4(r + 1)-nを返します。しかし、rは最後のステートメントで既にインクリメントされているため、これは次のように単純化されます。

n : r * 4 - n

1
わかったと思う。各上下部分の長さは2,6,10,14 ...であるため、合計は行数の2乗、つまりsqrtとともに増加します。非常に素晴らしい!
JollyJoker

7

Haskell、37バイト

(!!)$do k<-[1,3..];[1..k]++[k+1,k..2]

オンラインでお試しください!

ゼロインデックス。リストを生成し、インデックスを作成します。2バイトを節約してくれたØrjanJohansenに感謝!


Haskell、38バイト

(!!)[min(k-r)r|k<-[0,4..],r<-[1..k-2]]

オンラインでお試しください!

ゼロインデックス。リストを生成し、インデックスを作成します。


Haskell、39バイト

n%k|n<k=1+min(k-n)n|j<-k+4=(n-k)%j
(%2)

オンラインでお試しください!

ゼロインデックス。再帰的なメソッド。



5

、8バイト

!…ṁoe1DN

1インデックス付き。 オンラインでお試しください!

説明

!…ṁoe1DN  Implicit input (an integer).
       N  Positive integers: [1,2,3,4,...
  ṁo      Map and concatenate
      D   double: [2,4,6,8,...
    e1    then pair with 1: [1,2,1,4,1,6,1,8,...
 …        Fill gaps with ranges: [1,2,1,2,3,4,3,2,1,2,3,4,5,6,...
!         Index with input.

3

Perl 6、29バイト

{({|(1...$+=2...2)}...*)[$_]}

オンラインで試す

0ベース

拡張:

{  # bare block lambda with implicit parameter 「$_」

  (
    # generate an outer sequence

    {           # bare block lambda

      |(        # flatten into outer sequence

        # generate an inner sequence

        1       # start at 1

        ...     # go (upward) towards:

        $       # an anonymous state variable (new one for each outer sequence)
          += 2  # increment by 2

        ...     # go (downward) towards:

        2       # stop at 2 (1 will come from the next inner sequence)

      )
    }

    ...         # keep generating the outer sequence until:
    *           # never stop

  )[ $_ ]       # index into outer sequence
}

内部シーケンス1...$+=2...2は以下を生成します

(1, 2).Seq
(1, 2, 3, 4, 3, 2).Seq
(1, 2, 3, 4, 5, 6, 5, 4, 3, 2).Seq
(1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2).Seq
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2).Seq
...

1から0,始まるようにするには、2番目の前に追加する{か、-1後に追加します$_


3

R、64バイト

function(n)unlist(sapply(seq(2,n,2),function(x)c(2:x-1,x:2)))[n]

引数をとる関数n。これは、ベクター作成し2:n、これらの各々について2単位とをベクトル1:(x-1)x:2作成されます。これは合計での長さより長くなりnます。私たちunlistは、ベクトルを取得してn-番目のエントリを取得します。


1:n*2代わりにできますseq(2,n,2)か?必要以上に大きくなりますが、それで問題ありません!またseq(2,n,2)n=1とにかくこれがうまくいくとは思わない!
ジュゼッペ

2

Python 2、56バイト

def f(x):n=int((x/2)**.5);print 2*n-abs(2*n*n+2*n+1-x)+2

オンラインでお試しください!

これは0インデックスです。

@JustinMarinerのおかげで-1バイト

仕組み

我々は、1インデックス付き注意n(目族1, 2, ... 2n ..., 2, 1元素から発生0インデックス番号)2(n-1)^2にします2n^2

indexの要素を見つけるxために、グループ番号nを見つけることができますx。そこから、グループの中心からの距離を計算しxます。(この距離はですabs(2*n**2+2*n+2-x))。

ただし、要素はグループの中心から離れるにつれて小さくなるため、グループの最大値から距離を引きます。


:私はこの部分をgolfedしているprint 2*n-abs(2*n*n+2*n+1-x)+2- 2*n*n+2*nことができます2*n*-~nし、+2+2*n変換することができ-~n*2、私たちは、バイト(セーブ最初に移動することを可能にする、53バイト
ミスターXcoder

2

05AB1E、8バイト

コード:

ÅÈ€1Ÿ¦¹è

05AB1Eエンコードを使用します。オンラインでお試しください!

説明:

ÅÈ           # Get all even numbers until input (0, 2, ..., input)
  €1         # Insert 1 after each element
    Ÿ        # Inclusive range (e.g. [1, 4, 1] -> [1, 2, 3, 4, 3, 2, 1])
     ¦       # Remove the first element
      ¹è     # Retrieve the element at the input index

5
of を削除ない限り正しく動作しません。これはバイトofcも保存します:)
Emigna

€1...奇妙である
マジックタコ壺

2

JavaScript、39バイト

f=(n,t=2)=>n>t?f(n-t,t+4):n>t/2?t-n+2:n

2

ゼリー10、9つのバイト

ḤŒḄṖµ€Fị@

オンラインでお試しください!

また、1がインデックス付けされ、非常に高速に終了します。

@ErikTheOutgolferのおかげで1バイト節約できました!

説明:

仮に、入力(a)が3 だとしましょう。

    µ€      # (Implicit) On each number in range(a):
            #
Ḥ           # Double
            #   [2, 4, 6]
            #
 ŒḄ         # Convert to a range, and Bounce
            #   [[1, 2, 1], [1, 2, 3, 4, 3, 2, 1], [1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1]]
            #
   Ṗ        # Pop
            #   [[1, 2], [1, 2, 3, 4, 3, 2], [1, 2, 3, 4, 5, 6, 5, 4, 3, 2]]
            #
     F      # Flatten
            #   [1, 2, 1, 2, 3, 4, 3, 2, 1, 2, 3, 4, 5, 6, 5, 4, 3, 2]
            #
      ị@    # Grab the item[a]
            #   1
            #

コードはと同等であるためḤ€ŒḄ€Ṗ€Fị@µ€-1に使用できます(開始時に3つ以上のモナド):ḤŒḄṖµ€Fị@
Erik the Outgolfer

10,000の要件に準拠するため、これは実際には12のḤŒḄṖ<改行> ½ĊÇ€Fị@である必要があります(9バイトコードをローカルで実行すると、i7で約2:20かかり、7GBを使用します)
ジョナサンアラン

1

MATL、15バイト

li:"@EZv4L)]vG)

1ベース。

オンラインでお試しください!

これはTIOの最大のテストケースではタイムアウトしますが、デスクトップコンピューター(MATLAB R2017aで実行されているコンパイラー)で時間内に終了します。経過時間を表示するにZ`は、コードの最後に追加します。

>> matl 'li:"@EZv4L)]vG)Z`'
> 10000
84
15.8235379852476

説明

コードは必要以上に多くの用語を生成します。具体的にnは、シーケンスの「ピース」を計算します。各ピースは1にカウントアップして戻ります。

l       % Push 1
i       % Push input, n
:       % Range [1 2 ...n]
"       % For each k in that range
  @E    %   Push 2*k
  Zv    %   Symmetric range: [1 2 ... 2*k-1 2*k 2*k-1 ... 2 1]
  4L)   %   Remove last entry: [1 2 ... 2*k-1 2*k 2*k-1 ... 2]
]       % End
v       % Concatenate all stack contents into a column vector
G)      % Get n-th entry. Implicitly display

いいね!TIOは...時々遅いです

1
さて、ここでの遅延の主な原因はアルゴリズムです(必要以上に多くの項を生成します)。また、MATLコンパイラは特に高速ではありません
ルイスメンドー

1

12 10バイト

!ṁ§¤+hḣṫİ0

オンラインでお試しください!

1インデックス付き、非常に高速に動作します

説明

!ṁ§¤+hḣṫİ0
 ṁ      İ0    Map the following function over the even numbers and concatenate the results together
  §   ḣṫ      Get the ranges 1-n and n-1, then... 
   ¤+h         remove the last element from both of them and concatenate them together
!             Return the element of the resulting list at the given index

8バイト使用
-Zgarb

@Zgarbそれは素晴らしいアイデアであり、おそらくあなたの答えとしてそれを投稿する必要があります:)
レオ



1

網膜、62バイト

.+
$*
^((^.|\2..)*)\1.
6$*1$2$2;1
(?=.+;(.+))\1(.+).*;\2.*
$.2

オンラインでお試しください!リンクにはテストケースが含まれます。入力は1から始まります。最初の段階は、10進数から単項への変換です。第2段階では、s厳密に半分未満の最高の平方数を見つけnます。$1is 、while $2is 2s-1です。それは、2つの値であり、現在のアップ/ダウンラン、内の数字の最初の数を算出4(s+1) = 4s+4 = 2$2+6し、そのラン、内第二の位置n-2s² = n-(2$1+1)+1 = n-$&+1だけが必要、1を補うために1、厳密な不等式を強制するために使用されます。最終段階では、その位置から実行の開始と終了までカウントし、低い結果を取得して10進数に変換します。



1

Perl 5、43 + 1(-p)= 44バイト

$_=($n=2*int sqrt$_/2)+2-abs$n/2*$n+$n+1-$_

オンラインでお試しください!

私は、n番目の要素を直接計算する式に取り組んでいました。その後、@ fireflame241がその作業を行ったことを確認し、それをPerlに入れました。

Perl 5の、50 + 1(-n)= 51バイト

push@r,1..++$",reverse 2..++$"while@r<$_;say$r[$_]

オンラインでお試しください!

結果のインデックスは0です。


1

Haskell115 81バイト

y%x=snd(span(<x)$scanl(+)y[y+1,y+3..])!!0
g 1=1
g x|1%x>2%x=1+g(x-1)|1>0=g(x-1)-1

オンラインでお試しください!

ここでいくつかの魔法が起こっています。ただし、通常のアプローチを使用した場合は、おそらく短くなる可能性があります。

説明

最初に定義します%%2つの変数を取る関数であるx、とy。リストscanl(+)y[y+1,y+3..]を作成し、そのリストの最初の要素よりも大きい値を見つけxます。 scanl(+)反復合計を実行して、実行する三角数を取得し、実行scanl(+)0[1..]する平方数を取得しますscanl(+)0[1,3..]。我々が構築される特定の2つのリストがあるscanl(+)2[3,5..]scanl(+)1[2,4..]、これらは、パターンの変曲点です。

ここで、gを取るメイン関数を定義しますx。if xが1である場合1、それが最初の値なので返されます。そうでない場合、次の2つの変曲点をチェックします。下向きの変曲が大きい場合は1%x>2x、後継g$x-1を返します。g$x-1

わかりましたが、なぜそれが機能するのですか?

まず、「頂点を見つける方法は何ですか?」。同じタイプの連続する頂点間の距離に注意することが重要です。違いは毎回2ずつ増加していることに気付くでしょう。これは、三角形のベースが毎回2ずつ広くなるため、理にかなっています。そのようにリストリテラル[2,4..]を使用scanl(+)してリスト定数を変更できます。最初の頂点の位置と最初の違いに基づいて、これらのリストを頂点リストに変換するために使用します。

これで、上下の頂点を見つける方法ができたので、その情報を使用して値を取得できます。1そうでなければ、最初の値は後継者か前任者のどちらかを取る必要があると言います。次の頂点が上向きの場合、前の頂点を取得します。それ以外の場合、後の頂点を取得します。

Haskell56 51 46バイト

これは、より少ない数学とより少ないバイトでの私のより良い解決策です。

d x|e<-[1..x-1]=e++map(x+1-)e
(([1..]>>=d)!!0)

オンラインでお試しください!




1

ルビー78 75バイト

Step Henのおかげで1バイト節約

Mr. Xcoderのおかげで1バイト節約

->n{a=0;b=2;c=1;n.times{if a==b then c=0;b+=2;end;c=1if a<2;a+=c<1?-1:1};a}

オンラインでお試しください!

バイトカウントをさらに引き下げるためのヒントが得られれば幸いです。簡単なアプローチを試みました。


PPCGへようこそ!c=1 ifゴルフすることができますc=1if
スティーブン

76バイト:->n{a=0;b=2;c=1;n.times{if a==b then c=0;b+=2;end;c=1if a==1;a+=c<1?-1:1};a}
Mr. Xcoder

1

Java(OpenJDK 8)、53バ​​イト

n->{int i=2;for(;n>i;i+=4)n-=i;return n>i/2?i-n+2:n;}

オンラインでお試しください!

Nevayのおかげで-2バイト。

1インデックス付き。

TL; DRシーケンスを便利なチャンクに分割し、チャンクnが含まれていることを確認してから、チャンク内のnth位置を見つけます。

ここで、のよう[[1,2],[1,2,3,4,3,2],[1,2,3,4,5,6,5,4,3,2],...]にシーケンスを分割でき4i-2ます。これにより、のチャンクサイズが得られます。から始めi=2、から減算iしますn。基本的に、一度にチャンクを上に移動します。を満たすn<=in、現在のチャンク内の正しい値の位置がわかります。

次に、と比較nして値を取得しますi。これは、チャンクのサイズです。各チャンクの中点はi/2+1;に等しい 場合はnこれよりも小さい、我々は単に返しますn。もしnより大きい、を返しi-n+2ます。

n = 16, i = 2

Is n > i? Yes, n = n - 2 = 14, i = i + 4 = 6
Is n > i? Yes, n = n - 6 = 8, i = i + 4 = 10
Is n > i? No, stop looping.
10 / 2 + 1 = 6
Is n > 6? Yes, return i - n + 2 = 8 - 6 + 2 = 4

あなたは必要ありません+1return n>i/2?i-n+2:n十分です。
ネベイ

ほら ありがとう、整数除算。
ザンダーホール



0

QBIC、47バイト

g=q{p=p+1~p=:|_Xg\g=g+q~g=1or g>=r|r=r+1┘q=q*-1

説明

g=q         var g is the current value of the sequence; set to 1 at the start
{           DO infinitely
p=p+1       raise the step counter (var p)
~p=:|_Xg    IF p equals the input term a (read from cmd line) THEN QUIT, printing g
\           ELSE
g=g+q       raise (or decrement) g by q (q is 1 at the start of QBIC)
~g=1        IF g is at the lower bound of a subsequence
    or g>=r OR g is at the upper bound (r start as 2 in QBIC)
|r=r+1      THEN increment r (this happens once on lower bound, and once on upper, 
            total of 2 raise per subsequence)
┘q=q*-1     and switch q from 1 to -1

0

ロダ、54バイト

f n{seq 1,n|{|i|seq 1,2*i;seq 2*i-1,2}_|head n+2|tail}

オンラインでお試しください!

で呼び出す: try f(n)

この関数はすぐに答えを返しますが、その後、いくつかの不必要な計算を行い、最終的にメモリが不足します。

関数は呼び出された直後(明らかに1分以内)に実際の回答を返すので、この回答は有効だと思います。

(Rödaでは、関数は並列処理のために終了する前に値を返すことができます。)



0

PHP、65 + 1バイト

for($x=$d=$z=1;--$argn;)$d=($x+=$d)>1?$x>$z?-1:$d:!!$z+=2;echo$x;

パイプとして実行する-R、オンラインで試してください(または他のバージョンのいずれかのコメントを外してください)。

tshの再帰JavaScriptのポートは66バイトかかります。

function f($n,$t=2){return$t<2*$n?$t<$n?f($n-$t,$t+4):$t-$n+2:$n;}

Arnauldのソリューションの移植には62 + 1が必要です。

$n=$argn;echo($n-=($r=(~-$n/2)**.5|0)*$r*2)<++$r*2?$n:$r*4-$n;

XanderhallのJavaのゴルフポートには、これまでで最短のコード(55 + 1バイト)があります。

for($n=$argn;$n+2>$i+=4;)$n-=$i-2;echo$n*2>$i?$i-$n:$n;

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