Ulam番号を生成する


19

整数n(where n < 10001)を入力として、最初のn Ulam番号を出力するプログラムを作成します。Ulam番号は次のように定義されます。

  1. U 1 = 1、U 2 = 2
  2. の場合n > 2、U nは、正確に1つの方法で2つの異なる以前の用語の合計であるU n-1よりも大きい最小の整数です。

たとえば、U 33(2 + 1)、U 44(3 + 1)(用語は区別されないため(2 + 2)はカウントされない)、U 56(U 55ではないことに注意してください)5は2 + 3または4 + 1として表現できるためです。最初のいくつかのウラム番号は次のとおりです。

1, 2, 3, 4, 6, 8, 11, 13, 16, 18, 26, 28, 36, 38, 47, 48, 53, 57, 62, 69, 72, 77, 82, 87, 97, 99

これはコードゴルフなので、最短のエントリーが勝ちです。


出力は示されているとおりでなければなりませんか(コンマとスペースで区切られたリスト)、または配列などを出力できますか?
デニス14

n処理しなければならない最小値は何ですか?
デニス14

1
@Dennisスペースまたはコンマ、あるいはその両方で問題ありません。Nの最小値は1である
アブサン

現状では、リストを括弧で囲んでいます。それも大丈夫ですか、それらを削除する必要がありますか?
デニス14

1
@Dennis Bracketsは大丈夫です。
アブサン14

回答:


10

CJam、47 41 37バイト

li4,1${__m*{_~<\:+*}%$2/z:^$2=+}*1><`

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

実行例

$ cjam <(echo 'li4,1${__m*{_~<\:+*}%$2/z:^$2=+}*1><`') <<< 26
[1 2 3 4 6 8 11 13 16 18 26 28 36 38 47 48 53 57 62 69 72 77 82 87 97 99]

使い方

この基本的な考え方は次のとおりです。

  1. 配列から始めA := [ 0 U₁ U₂ ... Uₖ ]ます。

  2. Compute S、およびx + yなどのすべての合計の配列。x,y ∊ Ax < y

  3. からすべての一意でない合計を破棄しSます。2より大きいすべてのUlam数は、2つの小さいものの合計であり、ゼロとそれ自体の合計であるため、これはUlam数を破棄しますU₃, U₄, ... Uₖ

  4. 残りの配列は[ U₁ U₂ Uₖ₊₁ ... ]なので、次のUlam番号は3番目に小さい要素です。それを追加してA、ステップ1に戻ります。

li                                    " Read one integer (I) from STDIN.                  ";
  4,                                  " Push the array A = [ 0 1 2 3 ].                   ";
    1${                        }*     " Do the following I times:                         ";
       __m*                           " Push the Cartesian product A × A.                 ";
           {       }%                 " For each pair (x,y) in A × A:                     ";
            _~<\:+*                   " Compute (x + y) * (x < y).                        ";
                     $2               " Sort the resulting array.                         ";
                       /              " Split it into chunks of length 2.                 ";
                        z             " Transpose the resulting two-dimensional array.    ";
                         :^           " Compute the symmetric difference of its rows.     ";
                           $          " Sort the resulting array.                         ";
                            2=        " Extract its third element.                        ";
                              +       " Push it on the array A.                           ";
                                 1>   " Discard the first element of A (0).               ";
                                   <  " Discard all but the first I elements of A.        ";
                                    ` " Push a string representation of A.                ";

の入力には100すでに数秒かかります。最大入力1e5の計算には時間がかかると思いますか?
マーティンエンダー14

@MartinBüttner:Javaインタープリターは非常に高速ですが、それでもまだ低速です。すべてのブルートフォースアルゴリズムはO(n²)以下です。配列にスタック指向言語を使用することは決してきれいではありません(たとえば、配列の長さを計算するには配列全体をコピーする必要があります)。したがって、実際の実行時間はおそらくO(n³)です。
デニス14

1
@MartinBüttner:WolframAlphaなので、1e4(ありがたいことに、1e5ではなく)は3週間未満で済むはずです。
デニス14

6

J-46文字

n引数として受け取る関数。

_2}.(,]<./@-.~</~({.+_*1<#)/.~@#&,+/~)@[&0&1 2

爆発の説明:

    (                                )          NB. procedure for a list:
                                  +/~           NB.   take an addition table
              </~              #&,              NB.   select the top right half (no diag)
                 (        )/.~@                 NB.   for each unique value:
                       1<#                      NB.     if more than one present
                  {.+_*                         NB.     add infinity to it
      ]    -.~                                  NB.   remove existing Ulam numbers
       <./@                                     NB.   take the smallest
     ,                                          NB.   append to Ulam numbers
                                      @[&0      NB. repeat this procedure:
                                          &1 2  NB.   n times starting with [1, 2]
_2}.                                            NB. drop the last two numbers

あります+_*...
tomsmeding

6

T-SQL、301 300 288 287

私は少し軽いSQLの乱用を犯しました。

DECLARE @N INT=100,@T INT=1DECLARE @ TABLE(I INT,U INT)INSERT @ VALUES(1,1),(2,2)#:IF @T>2INSERT @ SELECT TOP 1@T,A.U+B.U FROM @ A,@ B WHERE A.U>B.U GROUP BY A.U+B.U HAVING COUNT(*)=1AND A.U+B.U>ALL(SELECT U FROM @)ORDER BY 2SET @T+=1IF @T<=@N GOTO # SELECT U FROM @ WHERE I<=@N ORDER BY I

こちらの SQL Server 2008 試してください。

@Nは入力整数を保持します。例「100」をnに変更します。「10000」はおそらく最終的に終了するでしょうが、私はそれを最後まで実行させていません。このエントリの文字数は、1桁の入力用です。出力はクエリ結果形式です。



5

GolfScript(41 37バイト)

~.14*,3,\{1$.{2$1$-.@<*}%&,2=*|}/0-<`

オンラインデモ

GolfScriptのデカルト製品は非常に長いため、これは異なるアプローチを取ります。ウラムの数字の長期的な成長は、n番目のウラムの数字が約13.5nであるということですが、最初の10000の用語では、n番目のウラムの数字とのn直下の最大の比率13.3です。したがってn、最初の14n数値をフィルター処理して、シーケンスに属する数値を見つけることができます。

41-> 37のDennisに感謝します。


1
これは非常に高速です。n = 1000GolfScriptで1分未満かかります。CJamへのポートn = 1000は8秒n = 10000で1時間20分で完了します。-アプローチを私のものと組み合わせることで、つまり、配列に0を含めてから破棄することで、4バイトを節約できます。それはセット組合の代わりに、ブロックを使用して可能にし、変数の必要性を排除します~.14*,4,\{1$.{2$1$-.@<*}%&,2=*|}/1><`
デニス・

@ Dennis、CJamはどれだけ短い文字ですか?いずれの操作も長くなることはないと想定しており、の1文字のエイリアスがあると確信してい14ます。
ピーターテイラー14

はい、14ただEです。しかし、あなたはSTDINから読み込み、整数をシングルトンに変換してからセットユニオンを実行する必要があります(それに関するバグレポートを提出します)2$。CJamは各反復後にスタックを変更するため、内側のループでは動作しません... 'いくつかの異なるトリックを試してみましたが、最短の1つは正確に37バイトでした:li4,1$E*{__{I1$-_@<*}%&,2=I*a|}fI1><`
デニス14

5

JavaScript ES6、100 ... 93 90文字

これを最新のFirefox(Nightlyまたはリリース)のWebコンソールまたはスクラッチパッドで実行します。

EDIT 8たくさんゴルフをしました!!! とにそれを作っ94文字 93 90文字(@openorcloseに感謝)。(私の最初のサブ100)

これは私のバージョンですが、はるかに高速ですが、3文字(107文字)長く 、上記まったく同じ文字数であり、以下のブルートフォースメソッドよりもはるかに小さくなっています!、(edc65のおかげです):

u=n=>(s=>{for(r=[i=l=1];c=l<n;i+=c&&i-2?1:s[r[l++]=i]=1)r.map(j=>c-=j<i/2&s[i-j])})([])||r

さらにゴルフをしようとしています。しかし、私たちはJSの範囲外でそれを絞っています:P

これをWebページのスクリプトタグ内で実行した場合の数値を次に示します。

n時間(s)
10 0.001
100 0.005
1000 2.021
10000 236.983
100000       保留中の tldr; あまりにも長い間実行されませんでした:P

これは、JavaScriptでの@ rink.attendant.6の回答に大きな影響を受けた最初の投稿です。

u=n=>{for(l=[1,g=2],i=3;g<n;++i){z=1;for(j of l)for(k of l)z-=j<k&j+k==i;!z?l[g++]=i:0}return n>1?l:[1]}

これはさらにゴルフができることを知っています。非ブルートフォースソリューションも投稿しますが、これはさらに短くなる可能性があります。

編集1:もう少しゴルフをし、n = 1に修正

私はHaskellとJがあらゆる種類の要件に対するこのような非常に便利なショートカットをvy望していると言わなければなりません-_-


機能の量は常にいいですが、ハスケルについて、私は、機能的なスタイルおよび構文のメイクに(例えば、無恐ろしい巨大なループ)ほとんど違いを考える:-)
誇りhaskeller

1
速い1を確実に、よりgolfedすることができます:(104)u=n=>{for(s=[,1,1],r=[i=1,l=2];c=l<n;!c?s[r[l++]=i]=1:0,i++)for(j of r)c-=j<i/2&s[i-j];return n>1?r:[1]}と、多分もっと
edc65

1
1.二重ループをどのように回避したのか、まだほとんどわかりません。賞賛2.ゴルフのヒント:E6では、常に回避しようとしていreturnます。100:u=n=>(s=>{for(r=[i=1,l=2];c=l<n;i+=!c?s[r[l++]=i]=1:1)for(j of r)c-=j<i/2&s[i-j]})([,1,1])|n>1?r:[1]
edc65 14

1
文字が1つ少ない:u=n=>(s=>{for(r=[i=l=1];c=l<n;i+=c&&i-2?1:s[r[l++]=i]=1)for(j of r)c-=j<i/2&s[i-j]})([,1])||r
openorclose 14

1
90の文字:u=n=>(s=>{for(r=[i=l=1];c=l<n;i+=c&&i-2?1:s[r[l++]=i]=1)r.map(j=>c-=j<i/2&s[i-j])})([])||r [1]が必要とされているどこかにいない限り
openorclose

5

Perl-71バイト

#!perl -p
@a=$b[2]=1;1while$b[++$a]^1||$_>map(++$b[$_+$a],@a)&&push@a,$a;$_="@a"

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

シバンを1つとして数えます。
2番目の配列を使用して合計を格納することは、ハッシュよりも大幅に速いようです。メモリ使用量も少なくなりますが、これは予想していなかったでしょう。

サンプル使用法:

$ echo 30 | perl ulam.pl

サンプル出力:

1 2 3 4 6 8 11 13 16 18 26 28 36 38 47 48 53 57 62 69 72 77 82 87 97 99 102 106 114 126

おおよそのランタイム:

n = 100     0.015s
n = 1000    0.062s
n = 10000   4.828s

2
8.6秒のためn == 1e4。すごい!n == 1ただし、の出力は正しくありません。単一の数字を印刷する必要があります。
デニス14

@Dennisが修正されました。
primo 14

4

Java、259

import java.util.*;class C{public static void main(String[]a){List<Integer>l=new ArrayList<>();l.add(1);l.add(2);for(int i=3,z=0;l.size()<new Long(a[0]);i++,z=0){for(int j:l){for(int k:l){if(j<k&j+k==i)z++;}}if(z==1)l.add(i);}l.forEach(System.out::println);}}

ブルートフォースはこれに適しています。

import java.util.*;
class C {
    public static void main(String[] a) {
        List<Integer>l = new ArrayList<>();
        l.add(1);
        l.add(2);
        for (int i = 3, z = 0; l.size() < new Long(a[0]); i++, z = 0) {
            for (int j : l) {
                for (int k : l) {
                    if (j < k & j + k == i)
                        z++;
                }
            }
            if (z == 1)
                l.add(i);
        }
        l.forEach(System.out::println);
    }
}

1.結果を印刷するにはJava 8が必要なようです。これは言及する価値があるかもしれません。2.の出力1は単一の数字でなければなりません。
デニス14

1
これは10kの入力を処理しますか?
マーティンエンダー14

jとk forループには中括弧は必要ないと思います。
マイケルイースター

Martinが示唆しているように、私もN = 10Kでこのプログラムを時限的に実行したいと思っています。
マイケルイースター14

4

APL(Dyalog Extended)36 35バイト

Adámによる-1バイト

{⍵↑{⍵,⊃∧(∊⊢⊆⍨⍧⍨∊2 3⍨)⍵~⍨,+⍀⍨⍵}⍣⍵⍳2}

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

{⍵↑{⍵,⊃∧(∊⊢⊆⍨⍧⍨∊2 3⍨)⍵~⍨,+⍀⍨⍵}⍣⍵⍳2}      Monadic function taking an argument n:

{⍵,⊃∧(∊⊢⊆⍨⍧⍨∊2 3⍨)⍵~⍨,+⍀⍨⍵}   Helper function to compute the next Ulam number
                                    given  (the first few Ulam numbers)
                        +⍀⍨⍵      Make an addition table from ⍵.
                       ,          Flatten into a list.
                   ⍵~⍨            Remove all entries already in ⍵.

     (∊⊢⊆⍨2 3∊⍨⍧⍨)               Helper function taking an argument x:
                ⍧⍨                  The count of elts of x in itself                 
           2 3∊⍨                    1s where those counts are in (2 3), else 0s.*
       ⊢⊆⍨                          Partition x, removing values corresponding to 0s.
                                   Join the partitions into a single list.

    (∊⊢⊆⍨⍧⍨∊2 3⍨)                Keep all elements that occur exactly 2 or 3 times.
                                  (i.e. that occur once as a
                                  sum of distinct elements of ⍵).
                             Sort ascending.
                             Take the first value (the next Ulam #).
 ⍵,                           Append that value to ⍵.

{⍵↑{...}⍣⍵⍳2}
{  {...}⍣⍵  }                 Call the helper function n times
           2                 starting with (1 2). First n+2 Ulam numbers.
 ⍵↑                           Keep the first n elements.

バツバツバツ2a+baバツbバツa=12a+b{23}

*(ngn / APLでは、定数を使用せずにトレインを終了できますが、ngn / APLにはカウントインがないため、どこかにneedが必要です。)


{(2 3∊⍨⍵⍧⍵)/⍵}(∊⊢⊆⍨⍧⍨∊2 3⍨)
アダム

3

PHP 5.4 +、164

私の答えと同じアプローチ:

<?function u($n){for($l=[1,2],$i=3;count($l)<$n;++$i){$z=0;foreach($l as $j){foreach($l as $k){$z+=$j<$k&$j+$k==$i;}}if($z==1)$l[]=$i;}return array_slice($l,0,$n);}

3

ゼリー、20バイト

Œc§ḟµḟœ-Q$Ṃɓ;
2RÇ⁸¡ḣ

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

Œc§ḟµḟœ-Q$Ṃɓ;    Helper link that appends the next number to x, a list of Ulam numbers:
Œc                  All unordered pairs of x
  §                 Sum each pair
   ḟ                Filter out the numbers already present in x.
    µ               Let this list be y. Then apply the following chain:

     œ-Q$Ṃ          Find the minimum of all unique elements.
     ḟ                Take y and filter out the elements in
      œ-Q$            the multiset difference between y and its unique elements.
          Ṃ           Then find the Ṃinimum of the result.

           ɓ;    Append (ɓ reverses argument order) the result to 


2RÇ⁸¡ḣ           Main link:
2R               Start with [1,2].
  Ç⁸¡            Apply the helper link (Ç) n (⁸) times to generate n+2 Ulam #s.
     ḣ           Keep the first n values.

2

CoffeeScript、119 114

最近、私は、CoffeeScriptを練習してJavaScriptのゴルフを改善しています。CoffeeScriptにコンパイルされたJavaScriptの回答は次のとおりです。

u=(n)->l=[1,2];i=3;z=0;(for j in l
 for k in l
  z+=j<k&j+k==i
l.push(i) if z==1;++i;z=0)while l.length<n;l[..n-1]

私はCoffeeScriptのループと理解をあまりよく理解していないので、おそらくこれをさらに進めることができますが、今のところそれは私が持っているものです。改行は1文字としてカウントされます(Unixスタイル)。


2

JavaScriptを、147 154 150(136)

以前に投稿された@YpnypnのブルートフォースJavaソリューションに大きく影響されました。

function u(n){for(l=[1,2],i=3;l.length<n;++i){z=0;l.forEach(function(j){l.forEach(function(k){z+=j<k&j+k==i})});if(z==1)l.push(i)}return l.slice(0,n)}

元のバージョンから4〜18バイト削った@Dennisに感謝します。

危険なバージョン(for..inループを使用)

ループを使用しているオブジェクトをループ処理すると、マシンが炎上したり、怒っている殺人マシンに変化したりする可能性があるため、これを実行することはお勧めしませんが、次のとおりです。instanceof Arrayfor..in

function u(n){for(l=[1,2],i=3;l.length<n;++i){z=0;for(j in l)for(k in l)z+=l[j]<l[k]&l[j]+l[k]==i;if(z==1)l.push(i)}return l.slice(0,n)}

非ゴルフ

function u(n) {
    var l = [1, 2],
        i = 3,
        j, k, z;

    for (; l.length < n; ++i) {
        z = 0; 
        l.forEach(function (j) {
            l.forEach(function (k) {
                if (j < k & j + k === i) {
                    z++;
                }
            });
        });
        if (z === 1) {
            l.push(i);
        }
    }

    return l.slice(0, n);
}

1の出力はシングルトンでなければなりません。
デニス14

@Dennisありがとう、修正しました。
rink.attendant.6 14

1. z=0ループ内を移動する場合、必要なのは1回だけです。2. アプローチfor(j in l)for(k in l)z+=l[j]<l[k]&l[j]+l[k]==i;よりもずっと短いl.forEach
デニス14

2

Mathematica、107 91バイト

Nest[#~Append~Min@Cases[Tally[Tr/@#~Subsets~2],{n_,1}:>n]&,{1,2},i=Input[]]~Drop~{3}~Take~i

これは、仕様の非常に直接的な実装です。

  • すべてのペアを見つけます。
  • すべての重複を削除します。
  • 最後のウラム番号より小さい番号をすべて削除します。
  • リストに最小値を追加します。

デニスの合計を含むトリックも適用して0いますが、キャッチは、リストの3番目の要素を作成して0から再開することです。

1000数秒で入力を処理しますが、妥当な時間で10kの結果が得られるとは思いません。しかし、私は他のどれもその上でうまくいくとは思わない。


2

OCaml-254文字

コードはハッシュテーブルを使用してリストの現在の要素の合計を保存し、新しい要素が計算されるたびに更新します。

open Hashtbl let h=create 7 let()=add h 3 1 let rec r n i l=if n=0then List.rev l else if mem h i&&find h i=1then(List.iter(fun x->if mem h(x+i)then replace h(x+i)2else add h(x+i)1)l;r(n-1)(i+1)(i::l))else r n(i+1)l let u n=if n=1then[1]else r(n-2)3[2;1]

使用法:

OCamlインタープリター内:

# u 26;;
- : int list =
[1; 2; 3; 4; 6; 8; 11; 13; 16; 18; 26; 28; 36; 38; 47; 48; 53; 57; 62; 69;
 72; 77; 82; 87; 97; 99]

非ゴルフ

open Hashtbl
let h = create 7
let() = add h 3 1
let rec r n i l =
  if n=0 then List.rev l
  else if mem h i && find h i=1 then
    begin
      List.iter
        (fun x-> if mem h(x+i) then replace h (x+i) 2 else add h (x+i) 1)
        l;
      r (n-1) (i+1) (i::l)
    end
  else r n (i+1) l

let u n = if n=1 then [1] else r (n-2) 3 [2;1]

2

Python、137 128 126文字。

U,i=[1,2],2
for _ in [[0]]*(input()-2):
 t=_*3*i
 for a in U:
  for b in U:t[a+b]+=a!=b
 i=t[i+1:].index(2)+i+1;U+=[i]
print U

これは私の最初のゴルフであり、私はそれを約250文字から下げました、私はかなり幸せですが、改善する方法についての提案が欲しいです!


マイナー、しかしやりがいのある:線5&6の組み合わせfor b in U:t[a+b]+=a!=bにし、ライン8&9while t[i]-2:i+=1
ジェームズWaldby - jwpat7

提案をありがとう!また、whileループをインデックスに変更しましたが、予想したほど多くの文字が保存されませんでした。
QuadmasterXLII

さらに2文字:Uを[1]に初期化し、7行目を後に移動するfor
ジェームズウォルドビー-jwpat7 14年

あなたはまだ変更することで、2つの文字を取り除くことが可能U,i=[1,2],2U,i=[1],2してinput()-2までinput()-1t=_*3*iするt=_*3*i;U+=[i]と、削除;U+=[i]のための終わりに
ジェームズWaldby - jwpat7

0

C#、257

LINQを使用したブルートフォースアプローチ:

using System.Linq;class U{void F(int n){var u=n<2?new int[]{1}:new int[]{1,2};for(int i=3;u.Length<n;++i)if(u.SelectMany(x=>u,(a,b)=>new{A=a,B=b}).Count(x=>x.A>x.B&&x.A==i-x.B)==1)u=u.Union(new int[]{i}).ToArray();System.Console.Write(string.Join("",u));}}

Ungolfed、テストハーネス付き

using System.Linq;
class Ulam
{
    void F(int n)
    {
        //handle special case where n = 1 (ugh)
        var u = n < 2 ? new int[] { 1 } : new int[] { 1, 2 };
        for (int i=3; u.Length<n; ++i)
            if (u.SelectMany(x => u, (a, b) => new { A = a, B = b })
                     .Count(x => x.A > x.B && x.A == i - x.B) == 1)
                u = u.Union(new int[] { i }).ToArray();
        System.Console.Write(string.Join(" ",u));
    }
    public static void Main(string[] args)
    {
        new Ulam().F(1);
        System.Console.WriteLine();
        new Ulam().F(2);
        System.Console.WriteLine();
        new Ulam().F(3);
        System.Console.WriteLine();
        new Ulam().F(26);
        System.Console.WriteLine();
    }
}

非常に遅い:n = 500で46秒、n = 1000で6m、n = 2000で50m。その指数関数的なレートでは、n = 10Kを処理するのに5または6日かかると思います。
リチャードII 14

0

Pyth、27 25バイト

<uaGh-sfq1lT.gksM.cG2GQS2

こちらからオンラインでお試しください。

<uaGh-sfq1lT.gksM.cG2GQS2Q   Implicit: Q=eval(input())
                             Trailing Q inferred
 u                    Q      Perform the following Q times...
                       S2    ... with G initialised to [1,2]:
                 .cG2          Get all 2-element combinations of G
               sM              Sum each pair
            .gk                Group them by value
                                 The groups are sorted by the result of the sum
       f                       Filter the groups, as T, keeping those where:
          lT                     Length of T
        q1                       Equal to 1
      s                        Flatten list
     -               G         Remove elements of the above which are already in G
    h                          Take the first of the remaining elements
                                 This is the smallest, as the grouping also sorted them
  aG                           Append this to G
<                        Q   Take the first Q elements, implicit print

編集:グループ化する前に合計を実行して2バイトをゴルフしました。前のバージョン:<uaGh-mssdfq1lT.gsk.cG2GQS2


0

C、478バイト

#define R return
bs(x,v,l,h,r)unsigned x,*v,l,h,*r;{unsigned m;for(;l<=h;){m=(l+h)/2;if(x<v[m])h=m-1;else if(x>v[m])l=m+1;else{*r=m;R 1;}}*r=m;R 0;}
#include<stdlib.h>
unsigned*f(unsigned w){unsigned*u=0,i,k,m,y,z;if(w>1E6||w==0)R u;u=malloc(w*sizeof*u);if(!u)R u;k=0;u[k++]=1;if(w==1)R u;m=u[k++]=2;if(w==2)R u;l:for(i=0,y=0,z=k-1,++m;i<k;y+=bs(m-u[i],u,i+1,z,&z),++i)if(y>1||u[i]+(i+1!=k?u[i+1]:0)>m)break;if(m==0){free(u);u=0;R u;}if(y!=1)goto l;u[k++]=m;if(k< w)goto l;R u;}

Tioでは9秒で10000個の値が見つかります(そして最初の100個の値が印刷されます)。トリックは、内側のループで線形検索ではなく、バイナリ検索を使用することです...これらは、インデントが十分で完全に読み取り可能な関数です(最後に私にとって)。

bsCopy(x,v,l,h,r)unsigned x,*v,l,h,*r;
{unsigned m;
 for(;l<=h;){m=(l+h)/2;if(x<v[m])h=m-1;else if(x>v[m])l=m+1;else{*r=m;R 1;}}
 *r=m;R 0;// in *r if return 0 the min index that fail else the index of find x
}

unsigned*fCopy(unsigned w)
{unsigned*u=0,i,k,m,y,z;
 if(w>1E6||w==0)R u;
 u=malloc(w*sizeof*u);
 if(!u)R u;
 k=0;u[k++]=1;if(w==1)R u;
   m=u[k++]=2;if(w==2)R u;//below I suppose m-u[i] is in the range (if exist in u) (i+1)..z 
 l: for(i=0,y=0,z=k-1,++m;i<k;y+=bsCopy(m-u[i],u,i+1,z,&z),++i)
          if(y>1||u[i]+(i+1!=k?u[i+1]:0)>m)break;
   if(m==0){free(u);u=0;R u;}
          if(y!=1)goto l;
   u[k++]=m;if(k< w)goto l;
 R u;
}

何かを減らすことができるかどうかを確認してください...
RosLuP

何か...ゴルフをプログラミングでOKですが、それがすべてではないことを私に言う
RosLuP


@ceilingcat "z = k"は私にとっては間違っていますビン検索を呼び出す関数は、z = k-1でなければなりません
RosLuP

0

APL(NARS)、278文字、556バイト

∇u←p w;m;y;i;k;z;r;bs
bs←{(x l h)←⍵⋄l>h:0,h⋄x<⍺[t←⌊2÷⍨l+h]:⍺∇x,l,t-1⋄x>⍺[t]:⍺∇x,(t+1),h⋄1,t}
u←⍬  ⋄→0×⍳(w>1E6)∨w≤0
u←u,1⋄→0×⍳w=1
u←u,2⋄→0×⍳w=2⋄k←m←2
i←1⋄y←0⋄m+←1⋄z←k
→7×⍳(y>1)∨i>k⋄→7×⍳m<u[i]+{i=k:0⋄u[i+1]}⋄r←u bs(m-u[i]),(i+1),z⋄y+←↑r⋄z←2⊃r⋄i+←1⋄→6
→5×⍳y≠1⋄u←u,m⋄k+←1⋄→5×⍳k<w
∇

それは私が送ったCのAPLでの翻訳でしょう。whenの代わりにuseを使用するタイミングがわからないようです... 1つの引数が1つの関数(他の型ではない)である場合に、possibleが使用される可能性があります。「u bs x、a、b」は、範囲a..bの値「x」に対する「u」配列のビン検索である必要があります。1、indexWhereFindまたは0、indexWhereEndOfsearchを返します。引数200 pの関数では、ここで+-1分かかります...

  p 100
1 2 3 4 6 8 11 13 16 18 26 28 36 38 47 48 53 57 62 69 72 77 82 87 97 99 102 106 114 126 
  131 138 145 148 155 175 177 180 182 189 197 206 209 219 221 236 238 241 243 253 
  258 260 273 282 309 316 319 324 339 341 356 358 363 370 382 390 400 402 409 412 
  414 429 431 434 441 451 456 483 485 497 502 522 524 544 546 566 568 585 602 605 
  607 612 624 627 646 668 673 685 688 690 
  p¨1 2 3 4
1  1 2  1 2 3  1 2 3 4 

1
∇∇dopでは、演算子自体を参照し、演算子とそのオペランドで構成される派生関数を参照します。したがって、単項演算子では、(⍺⍺∇∇)二項演算子での意味と同じ(⍺⍺∇∇⍵⍵)です。
アダム
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.