まだ迷っていますか?


31

あなたの仕事は整数シーケンスA130826を実装することです

a nは最小の正の整数で、a n -n3の倍数であり、(a n -n)/ 3の約数の2倍はフラビウスによって生成されたシーケンスの最初の差のn 番目の項を与えますジョセフスふるい。

まだ失った?まあ、実際には非常に簡単です。

フラウィウスヨセフス篩は次のように整数のシーケンスを定義します。

  1. 正の整数のシーケンスから始めて、k = 2に設定します。

  2. すべての削除のk 番目から始まる、一連の整数をk個

  3. kをインクリメントし、ステップ2に戻ります。

f nは、削除されないn 番目の整数(1から始まる)です。

いつものように- -場合σ 0(k)が整数の正の約数の数示しkは、我々が定義することができ、N最小の正の整数であり、その結果として0((N = F - N)/ 3)N + 1を - F N

チャレンジ

正の整数かかるプログラムや関数書き込みNを入力し、印刷物として、または返しNを

標準の規則が適用されます。最短のコードが勝つように!

実施例

正の整数の2番目の要素をすべて削除すると、次のようになります。

 1  3  5  7  9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 ...

残りの3つごとの要素を削除すると、次のようになります

 1  3  7  9 13 15 19 21 25 27 31 33 37 39 ...

ここで、4番目ごと、5番目、6番目の要素を削除すると、

 1  3  7 13 15 19 25 27 31 37 39 ...
 1  3  7 13 19 25 27 31 39 ...
 1  3  7 13 19 27 31 39 ...
 1  3  7 13 19 27 39 ...

最後の行は、条件を示し、F 1F 7

これらの用語の連続した要素の違いは

 2  4  6  6  8 12

これらの前方差分を2で除算すると、

 1  2  3  3  4  6 

これらは、ターゲットの除数です。

  • 図4は、最初の整数であり、kのようにσ 0 = 1 - (1)/ 3(K) 。実際には、σ 0(1)= 1
  • 図8は、第一整数であるKようσ 0 = 2 - (2)/ 3(K) 。実際には、σ 0(2)= 2
  • 図15は、第一整数であるKようσ 0( - 3)/ 3(K)= 3。実際には、σ 0(4)= 3
  • 図16は、第一整数であるKようσ 0( - 4)/ 3(K)= 3。実際には、σ 0(4)= 3
  • 図23は、第一整数であるKようσ 0( - 5)/ 3(K)= 4。実際には、σ 0(6)= 4
  • 42は第一整数であるKようσ 0( - 6)/ 3(K)6 =。実際には、σ 0(12)= 6

テストケース

   n     a(n)

   1        4
   2        8
   3       15
   4       16
   5       23
   6       42
   7       55
   8      200
   9       81
  10       46
  11      119
  12      192
  13      205
  14   196622
  15    12303
  16       88
  17      449
  18      558
  19      127
  20     1748
  21   786453
  22       58
  23     2183
  24     3096
  25     1105
  26   786458
  27 12582939
  28      568
  29     2189
  30     2730

14
OEISのキーワード:ダム(「重要でないシーケンス」)。
orlp 16

15
ダム?それは世界を救うことができます!
デニス

3
...しかしそれしゃれ
MEGO

回答:


7

ゼリー、30 29 27 25バイト

@Dennisから通知されたおかげでÆd2バイト、2つのチェーンを結合するためにさらに2バイト節約されました。

RUð÷‘Ċ×µ/
‘Ç_ÇH0Æd=¥1#×3+

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

これはおそらく、私がこれまでJellyで行った中で最も楽しいものでした。f nを計算する2行目から始めましたからn個 OEIS上の式を使用して、そして非常に美しいです。

説明

RUð÷ 'Ċ×µ / Fを計算するためのヘルパーリンク n。引数:n
R数字を取得[1..n]
 Uリバース
        /「次の2の倍数まで切り上げ」:
   ÷次の数で割る
    '倍数をスキップするための増分
     ĊCeil(切り上げ)
      ×次の数で乗算

'Ç_ÇH0Æd=¥1#×3 +メインリンク。引数:n
'nをインクリメント
 F F n + 1の 
   計算ÇF nの計算
  _減算
    H 2で割る
     0 1#0から始まり、(a n -n)/ 3の最初の候補を見つける
                   それは満足します...
      AEDσ 0((n個 -n)/ 3)
        = =(F n + 1 -F n)/ 2
            ×3 3倍して(a n -n)/ 3をn -nに変換
              +オンにするn個の追加のnに-nをn個

3

パイソン2121の 119 118バイト

n=input();r=range(1,4**n);d=s,=r*1,
for k in r:del s[k::k+1];d+=sum(k%j<1for j in r)*2,
print d.index(s[n]-s[n-1])*3+n

実行時間はおおよそO(16 n)でO(4 n)のメモリ使用量です。交換4**nして5<<n-私はこれを考えることは十分です-劇的これを改善するだろうが、私はそれが任意の大きさの値のために働くことを確信していないn個

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

漸近的挙動とnの上限

定義BをNとしてN - N)/ 3、すなわち、最小の正の整数kのようにσ 0(K)=½(F N + 1 - F Nを

OEISページ、上に述べたように、F N〜¼πn 2に、F N + 1 - F N〜¼π(N + 1)2 - ¼πn 2 =¼π(2N + 1)〜½πn

このようにして、½(f n + 1 -f n)〜¼πn。実際の数が素数である場合、pは、と最小の正の整数、Pの約数である2 P-1に、BがNで近似することができる2 、C NC N〜¼πn

したがって、B N <4 N十分に大きいために保持するN、及びその所与2 ¼πn <2 N <<(2 N2 = 4 N、私は反例がない確信しています。

使い方

n=input();r=range(1,4**n);d=s,=r*1,

これにより、反復プロセスの参照がいくつか設定されます。

  • nはユーザー入力:正の整数です。

  • rはリスト[1、...、4 n -1]です。

  • srのコピーです。

    リストを1回繰り返すとr*1浅いコピーが作成されるため、sを変更してもrは変更されません。

  • dはタプル(s)として初期化されます。

    この最初の値は重要ではありません。他のすべては正の整数の除数カウントを保持します。

for k in r:del s[k::k+1];d+=sum(k%j<1for j in r)*2,

各整数のためにKから14 N - 1、我々は次のことを行います。

  • del s[k::k+1]すべてのかかる(K + 1)番目の整数で始まる- (K + 1)番目の -および削除からスライスそのS

    これは、sのフラビウスジョセフスふるいの初期間隔を格納する簡単な方法です。必要なn + 1の初期項よりもはるかに多くを計算しますが、1つのforループを使用してsdの両方を更新すると、いくつかのバイトが節約されます。

  • d+=sum(k%j<1for j in r)*2,カウント何の要素Rの分割K均一と付加0(k)を、D

    以来、Dはシングルトンタプルとして初期化し、0(k)は、インデックスに格納されるK

print d.index(s[n]-s[n-1])*3+n

この発見最初の指標F N + 1 - F NにおいてD、最小となるKのようにその0(K)= F N + 1 F - N、次に計算します Nをとして+ 1 3K及び結果を印刷します。


2

Javaの8、 336305303 287283の 279バイト

Kritixi Lithosのおかげで57バイトが削除されました

ゴルフ

class f{static int g(int s,int N){return s<1?N+1:g(s-1,N+N/s);}static int h(int k){int u=0,t=1,i;for(;u!=(g(k,k)-g(k,k-1))/2;t++)for(i=1,u=0;i<=t;)if(t%i++<1)u++;return 3*t-3+k;}public static void main(String[]a){System.out.print(h(new java.util.Scanner(System.in).nextInt()));}}

非ゴルフ

class f {
    static int g(int s,int N){return s < 1 ? N + 1 : g(s - 1, N + N / s);}

    static int h(int k) {
        int u = 0, t = 1, i;
        // get the first number with v divisors
        while(u != (g(k, k) - g(k, k - 1))/2){
            u = 0;
            for (i = 1; i <= t; i++)
                if (t % i < 1) u++;
            t++;
        }
        // 3*(t-1)+k = 3*t+k-3
        return 3 * t + k - 3;
    }

    public static void main(String[] a) {
        System.out.print(h(new java.util.Scanner(System.in).nextInt()));
    }
}

コマンドライン引数をとして解析するint方がを使用するよりも短いと思いますjava.util.Scanner。あなたがスキャナを使用している場合でも、しかし、あなたが行うことができますSystem.out.print(h(new java.util.Scanner().nextInt()))し、前の行削除
KritixiのLithos

@KritixiLithos thx、今すぐ修正...
Bobas_Pett

内部ではint h()、に変更できますint v = (g(k,k)-g(k,k-1))/2,u = 0,t = 1;。あなたはから(forループ、あなたの中にある)あなたのif文に変更することができますif(t%i==0)if(t%i<1)
KritixiのLithos

また、あなたはあなたの関数を変更することができますg三項演算子を使用してのようなものを返すためにreturn s==0?N+1:g(s-1,N+N/2)-ish
KritixiのLithosを

2
笑@KritixiLithosこの時点で、uがちょうどウル自身の独立したソリューションとしてこれを投稿する必要があります
Bobas_Pett

1

Mathematicaの、130の 116 106 103バイト

3Catch@Do[f=#2⌈#/#2+1⌉&~Fold~Reverse@Range@#&;If[Tr[2+0Divisors@k]==f[#+1]-f@#,Throw@k],{k,∞}]+#&

または

3Catch@Do[f=#2⌈#/#2+1⌉&~Fold~Reverse@Range@#&;If[2DivisorSum[k,1&]==f[#+1]-f@#,Throw@k],{k,∞}]+#&

@ Pietu1998のJellyコードとほとんど同じになりました...

説明

Catch@

CatchThrow-ed(スロー)は何でも。

Do[ ... ,{k,∞}]

無限ループ; kから始まり、1反復ごとに増分します。

f= ...

割り当てるf

Reverse@Range@#

を見つけます{1, 2, ... , n}。逆に。

#2⌈#/#2+1⌉&

ceil(n1 / n2 + 1)* n2を出力する関数

f= ... ~Fold~ ... &

f上記の関数を再帰的に上記の2つのステップのリストに適用する関数を割り当てます。各出力を最初の入力として使用し、リストの各要素を2番目の入力として使用します。最初の「出力」(最初の入力)は、リストの最初の要素です。

Tr[2+0Divisors@k]==f[#+1]-f@#

の約数の2倍がkf(n + 1)-f(n)に等しいかどうかを確認します。

If[ ... ,Throw@k]

条件がの場合TrueThrowの値k。そうでない場合は、ループを続行します。

3 ... +#&

出力に3を掛けて、nを追加します。

130バイトバージョン

Catch@Do[s=#+1;a=k-#;If[3∣a&&2DivisorSigma[0,a/3]==Differences[Nest[i=1;Drop[#,++i;;;;i]&,Range[s^2],s]][[#]],Throw@k],{k,∞}]&

1

Perl 6の154の 149 136 107バイト

->\n{n+3*first ->\o{([-] ->\m{m??&?BLOCK(m-1).rotor(m+0=>1).flat!!1..*}(n)[n,n-1])/2==grep o%%*,1..o},^Inf}

ゴルフをしていない:

-> \n {                    # Anonymous sub taking argument n
  n + 3 * first -> \o {    # n plus thrice the first integer satisfying:
    (                      #
      [-]                  #
      -> \m {              # Compute nth sieve iteration:
        m                  # If m is nonzero,
          ?? &?BLOCK(m-1).rotor(m+0=>1).flat # then recurse and remove every (m+1)-th element;
          !! 1..*          # the base case is all of the positive integers
      }                    #
      (n)                  # Get the nth sieve
      [n,n-1]              # Get the difference between the nth and (n-1)th elements (via the [-] reduction operator above)
    ) / 2                  # and divide by 2;
    ==                     # We want the number that equals
    grep o %% *, 1..o      # the number of divisors of o.
  }
  ,^Inf
}

1

05AB1E35 34 39バイト

1Qi4ë[N3*¹+NÑg·¹D>‚vyy<LRvy/>îy*}}‚Æ(Q#

ひどいように見えるので、実行時のパフォーマンスもそうです。小さい値を生成する入力には数秒かかります。14のような数字を試さないでください。最終的に結果を見つけますが、時間がかかります。

説明

これは、連続して呼び出される2つのプログラムとして機能します。最初のものはF n + 1 -F nを計算し、2番目のものはブルートフォースアプローチを使用して、その定義に基づいてnを決定ます。

F n + 1 -F nは、ループが不変であっても、反復ごとに評価されます。コードの時間は非効率になりますが、コードは短くなります。

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


私は上手く理解できていない気がします。65,536を超えるふるいを計算できないのはなぜですか?
デニス

これは、0〜65536(žHL)のすべての整数を生成し、ふるいの制約を満たさない値を除外するという事実に基づいています。このプログラムの最初の部分は、ゴルフができるように完全に異なるアプローチで完全に書き直されるべきだと思います。
2016

そうすることを妨げる制限(固定幅整数など)がない限り、十分な時間とメモリがあれば、すべての入力に対して回答が機能することが期待されます。
デニス

それが私が別のふるいアルゴリズムを思いついた理由です。ゴルフはできるかもしれませんが、私は05AB1Eでこれ以上見つけられませんでした。しかし、反例がありますgiven enough time and memoryます。他の質問についてはすでにいくつかの回答があり、それらの回答が非常に遅いため、適切な出力を生成したかどうかを判断することはほぼ不可能でした。このため、ループ以外のふるい計算を行ったため、2バイトかかりました。
オスブル

コードを効率的にする必要はありません。ゴルフ/スローの実装を提出し、サイドノートとしてより速い/長いものを含めることができます。ただし、1バイトかかる場合でも、動的な制限を主張する必要があります。
デニス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.