울람 수 생성


19

입력으로 정수 n(where n < 10001)가 주어지면 첫 번째 n Ulam 숫자를 출력하는 프로그램을 작성하십시오 . 울람 숫자는 다음과 같이 정의됩니다.

  1. U 1 = 1, U 2 = 2.
  2. 의 경우 n > 2U n 은 정확히 하나의 방식으로 두 개의 서로 다른 이전 항의 합계 인 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

이것은 코드 골프이므로 가장 짧은 참가작이 승리합니다.


출력이 표시된 것과 같아야합니까 (쉼표와 공백으로 구분 된 목록) 아니면 배열을 출력 할 수 있습니까?
Dennis

n우리가 처리해야하는 최소값은 얼마입니까?
Dennis

1
@Dennis Space 또는 쉼표 또는 둘 다 괜찮습니다. N의 최소값은 1입니다
압생트

그대로 내 목록 주위에 대괄호가 있습니다. 이것도 괜찮습니까? 아니면 제거해야합니까?
Dennis

1
@Dennis Brackets는 괜찮습니다.
absinthe

답변:


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 숫자는 두 개의 작은 숫자의 합과 0과 그 자체의 합 모두이므로 Ulam 숫자를 버립니다 U₃, U₄, ... Uₖ.

  4. 나머지 배열은입니다 [ U₁ U₂ Uₖ₊₁ ... ]. 따라서 다음 Ulam 숫자는 세 번째로 작은 요소입니다. 추가하고 A1 단계로 돌아가십시오.

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를 계산하는 데 시간이 걸릴 것이라고 생각합니까?
Martin Ender

@ MartinBüttner : Java 인터프리터는 훨씬 빠르지 만 여전히 느립니다. 모든 무차별 알고리즘은 O (n²) 이상입니다. 배열에 스택 지향 언어를 사용하는 것은 결코 예쁘지 않습니다 (예를 들어, 배열 길이를 계산하려면 전체 배열을 복사해야 함). 실제 실행 시간은 아마도 O (n³)입니다.
Dennis

1
@ MartinBüttner : WolframAlpha 이므로 1e4 (감사하지만 1e5 아님)는 3 주 미만이 소요됩니다.
Dennis

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"은 결국 종료 될 것입니다. 이 항목의 문자 수는 한 자리 숫자 입력을위한 것입니다. 결과는 쿼리 결과 형식입니다.



5

GolfScript ( 41 37 바이트)

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

온라인 데모

GolfScript의 데카르트 제품은 상당히 길기 때문에 다른 접근 방식이 필요합니다. Ulam 수의 장기 성장은 nUlam 수는 약 13.5n이지만 처음 10000 용어에서 nUlam 수 사이의 가장 큰 비율 n이며 바로 아래에 13.3있습니다. 따라서 n첫 번째 14n숫자를 필터링 하여 시퀀스에 속하는 숫자를 찾을 수 있습니다.

41-> 37의 Dennis 에게 감사합니다 .


1
이것은 매우 빠릅니다. n = 1000GolfScript를 사용하면 1 분 미만이 소요됩니다. CJam으로 향하는 항구 n = 1000는 8 초, n = 100001 시간 20 분 안에 완료 됩니다 . -접근 방식을 광산과 결합하여 배열에 0을 포함시키고 나중에 버림으로써 4 바이트를 절약 할 수 있습니다. 이를 통해 블록 대신 set union을 사용할 수 있으며 변수가 필요하지 않습니다.~.14*,4,\{1$.{2$1$-.@<*}%&,2=*|}/1><`
Dennis

@Dennis, CJam은 얼마나 짧은 문자입니까? 나는 어떤 연산도 더 이상 길지 않다고 가정하고에 대한 하나의 문자 별칭이 있다고 확신합니다 14.
피터 테일러

네, 14그냥 E. 그러나 STDIN에서 읽고 set union을 수행하기 전에 정수를 싱글 톤으로 변환해야하며 (그에 대한 버그 보고서를 제출 할 것입니다) 2$CJam은 각 반복 후에 스택을 수정하기 때문에 내부 루프에서 작동하지 않습니다 ... 몇 가지 다른 트릭을 시도했지만 가장 짧은 트릭은 정확히 37 바이트였습니다.li4,1$E*{__{I1$-_@<*}%&,2=I*a|}fI1><`
Dennis

5

JavaScript ES6, 100 ... 93 90 자

최신 Firefox (Nightly 또는 Release)의 웹 콘솔 또는 Scratchpad에서이를 실행하십시오.

편집 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

웹 페이지의 스크립트 태그 내에서 이것을 실행할 때의 숫자는 다음과 같습니다.

n 시간
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를 부러워해야한다고 말해야합니다.


하스켈에 대해서는, 기능적인 스타일과 구문 메이크업 (예를 들어, 어떤 무시 무시한 거대한 루프) 함수의 양이 차이 :-) 항상 좋은입니다 가장하지만 생각
자랑 haskeller

1
더 빠른 골프는 확실히 더 많은 골프를 즐길 수 있습니다 : (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. 나는 여전히 당신이 이중 루프를 피하는 방법을 거의 이해하지 못합니다. Kudos 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

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

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

펄-71 바이트

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

온라인으로 사용해보십시오!

shebang을 하나로 계산합니다.
두 번째 배열을 사용하여 합계를 저장하면 해시보다 훨씬 빠릅니다. 메모리 사용량도 적어 예상하지 못했습니다.

샘플 사용법 :

$ 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은 정확하지 않습니다. 단일 번호를 인쇄해야합니다.
Dennis

@Dennis가 수정되었습니다.
primo

4

자바, 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은 단일 숫자 여야합니다.
Dennis

1
이것은 10k의 입력을 처리합니까?
Martin Ender

j 및 k for 루프에는 중괄호가 필요하지 않습니다.
Michael Easter

Martin이 암시하는 것처럼 N = 10K에 대해이 프로그램을 시간에 맞춰 실행하고 싶습니다.
Michael Easter

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.

xxx2a+baxbxa=12a+b{2,3}

* (ngn / APL에서 상수는을 사용하지 않고 열차를 끝낼 수 있습니다 . 그러나 ngn / APL에는 카운트 인이 없으므로 어딘가에 ⍨가 필요합니다.)


{(2 3∊⍨⍵⍧⍵)/⍵}(∊⊢⊆⍨⍧⍨∊2 3⍨)
Adám

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

최근에 Golfing JavaScript를 향상시키기 위해 CoffeeScript를 연습하고 있으므로 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의 루프와 이해력을 잘 이해하지 못 하므로 이것이 더 골프를 칠 수 있지만 지금은 내가 가지고있는 것입니다. 줄 바꿈은 하나의 문자로 계산됩니다 (Unix 스타일).


2

자바 스크립트, 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의 출력은 싱글 톤이어야합니다.
Dennis

@Dennis 감사합니다.
rink.attendant.6

1. z=0루프 내부 로 이동 하면 루프가 한 번만 필요합니다. 2. 접근 방식 for(j in l)for(k in l)z+=l[j]<l[k]&l[j]+l[k]==i;보다 훨씬 짧습니다 l.forEach.
Dennis

2

매스 매 티카, 107 91 바이트

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

스펙을 직접 구현 한 것입니다.

  • 모든 쌍을 찾으십시오.
  • 모든 중복을 삭제하십시오.
  • 마지막 Ulam 숫자보다 작은 모든 숫자를 삭제하십시오.
  • 목록에 최소값을 추가하십시오.

나는 또한으로 합계를 포함하는 데니스의 트릭을 적용 0하고 있지만 캐치는 이것이 목록의 세 번째 요소가된다는 것입니다.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

파이썬, 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
jwpat7 - 제임스 Waldby

제안 해 주셔서 감사합니다! 또한 while 루프를 색인으로 변경했지만 예상보다 많은 문자를 저장하지 않았습니다.
QuadmasterXLII

문자 2 개 더 : U를 [1]에 초기화하고 7 행을 다음 행으로 이동for
James Waldby-jwpat7

당신은 여전히 변경하여이 개 문자를 제거 할 수 있습니다 U,i=[1,2],2U,i=[1],2input()-2input()-1t=_*3*it=_*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));}}

테스트 하네스와 함께 언 골프

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 일이 소요될 것으로 생각합니다.
Richard II

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

골프 프로그래밍에 문제는 없지만 모든 것이 아니라고
말합니다


이진 검색 (bs () 함수 또는 B () 함수)이 인수 범위로 원하는 것처럼 보이기 때문에 @ceilingcat "z = k"가 잘못되었습니다 (나도 올바른지 모르겠습니다 ...) bin 검색을 호출하는 함수는 z = k-1
이어야합니다.

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의 번역 일 것입니다. ∇ 대신 ∇∇를 사용하는시기를 이해할 수없는 것 같습니다 ... 가능한 ∇∇는 하나의 인수가 하나의 함수 (다른 유형이 아닌) 일 때 사용됩니다. "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에서 연산자 자체 는 피연산자와 연산자로 구성된 파생 함수 를 나타냅니다. 따라서 monadic 연산자 (⍺⍺∇∇)dyadic 연산자 와 같은 의미 (⍺⍺∇∇⍵⍵)입니다.
Adám
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.