Hofstadter의 Figure-Figure Sequence 생성


16

에서는 괴델, 에셔 바흐 더글러스 호프스 태터 일반적 도면 자형 시퀀스로 지칭되는 정수 시퀀스를 도입

2, 4, 5, 6, 8, 9, 10, 11, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, ...

챌린지의 일부로 시퀀스 정의를 직접 연습 할 수도 있지만 OEIS에서 시퀀스 A030124로 , Wikipedia 에서 약간 더 명확하게 정의 할 수 없거나 알아 내고 싶지 않은 경우 OEIS에서 찾을 수 있습니다 .

nSTDIN, ARGV 또는 함수 인수를 통해 주어진 n시퀀스 의 첫 번째 숫자 목록을 합리적인 목록 형식으로 STDOUT에 인쇄 하는 프로그램 또는 함수를 작성하십시오 .

이것은 바이트 골프에서 가장 짧은 솔루션 인 코드 골프입니다.

답변:


6

CJam, 38 30 29 21 바이트

li_3*,2>\{(_pX+:X-}*;

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

작동 원리

li                     " Read an integer N from STDIN.              ";
  _3*,2>               " Push S := [ 2 3 ... (N * 3 - 1) ].         ";
        \{        }*   " Do the following N times:                  ";
          (            " Shift an integer I from S.                 ";
           _p          " Print a copy of I, followed by a linefeed. ";
             X+:X      " Execute X += I. (X is initialized to 1.)   ";
                 -     " Remove X from S.                           ";
                    ;  " Discard S from the stack.                  ";

예제 실행

$ cjam <(echo 'li_3*,2>\{(_pX+:X-}*;') <<< 20
2
4
5
6
8
9
10
11
13
14
15
16
17
19
20
21
22
23
24
25

인터프리터의 URL을 입력 할 때 aditsu에서 빠진 부분을 놓쳤습니다
Beta Decay

하지 편집을 수정하는 이유를 다음 @BetaDecay)
마틴 청산을

@Martin 나는 충분한 담당자가 있다고 생각하지 않았다 ...
Beta Decay

2
@BetaDecay 당신은하지 않지만, 당신은 여전히 ​​그들을 제안 할 수 있습니다 (심지어 그들이 받아 들여지면 2 담당자를 제공합니다).
Martin Ender

8 바이트의 코드를 추가로 골라내는 것이 영리하다고 생각했습니다. 그때 나는 그것이 지금 histocrat, matsjoyce와 Peter Taylor의 대답과 정확히 똑같다는 것을 깨달았습니다 ...
Dennis

6

하스켈, 67 61 60 56 55 53 자

g n=take n$2:4:h
a#(x:s)=[a..x-2]++x#s
h=5#scanl(+)8h

첫 번째 알고리즘으로 돌아갑니다.

이 솔루션은 시퀀스의 시작 요소를 합산하여 보수 시퀀스를 계산합니다. 그런 다음 보수의 시퀀스 번호 사이의 모든 숫자로 시퀀스를 계산합니다.

(#)보수 시퀀스 사이의 숫자를 계산하는 함수입니다.
h시퀀스 자체입니다.
g질문에 답하는 함수입니다.

g 함수는 필요한 양의 요소를 h에서 가져 오도록 정의됩니다.

미묘함 :

h실제로 처음 두 요소를 제외하고 그림 숫자 순서입니다.
보수 시퀀스는 계산되지 않지만 각 요소에 대해 1이 추가 된 보수 시퀀스.
이 두 가지 미묘한 이유는 scanl(+)8h(1이 추가 된 보수 시퀀스 (처음 2 요소 제외) 코드) 가 그 이유 8입니다. 그것은 1이 추가 된 보수 시퀀스의 세 번째 요소를위한 것입니다.
계산에 처음 두 요소가 누락되지 않은 이유는에 추가 되었기 때문 g입니다 2:4:h.

예:

>g 50
[2,4,5,6,8,9,10,11,13,14,15,16,17,19,20,21,22,23,24,25,27,28,29,30,31,32,33,34,36,37,38,39,40,41,42,43,44,46,47,48,49,50,51,52,53,54,55,57,58,59]

5

루비, 54 48

f=->n{x=1
b=*2..n*n
n.times{b-=[x+=p(b.shift)]}}

데모

편집 : 메모리에 전체 보완 시퀀스를 유지할 필요가 없다는 것을 깨달았을 때 이것을 조금 더 골랐습니다. 작동 방식은 다음과 같습니다 x. 보완 시퀀스에서 가장 큰 계산 된 숫자를 추적 하는 데 사용 되며 시퀀스 b후보 풀입니다. n시간, 우리는 가장 작은 나머지 요소를 출력 하고 보완 시퀀스의 다음 숫자를 계산하기 위해 b추가합니다 x. 그런 다음 후보 풀에서 두 숫자를 모두 제거하므로 항상 두 시퀀스에 추가되지 않은 가장 작은 숫자를 출력합니다.

Ruby 골프 트릭 : Stabby lambda 구문이 메소드 정의보다 짧습니다. 출력이 STDOUT 대신의 반환 값으로 제공되는 요구 사항은의 반환 값은 사실 사용하는 나에게 영감을 p(x)것입니다 x그것은 무질서 골프에 사용되는 루비 버전의 경우 아니기 때문에 내가 일반적으로 기억하지 않는을.


1
어떻게 작동합니까?
자랑스런 Haskeller

1
다음을 사용할 수 있습니다 2..2*n. 나는 n*n효과적으로하고 있기 때문에 사용해야 하므로 b = [x]^b가장 큰 요소는 b의 가장 큰 값보다 커야 x하지만 출력 시퀀스의 가능한 가장 큰 값 b -= [x]b포함 해야합니다 .
피터 테일러

4

GolfScript ( 24 21 바이트)

~.3*,1>\{(\(.p@+\|}*;

온라인 데모

이것은 상당히 다르게 시작되었지만 데니스 가 약간 다른 방향으로 제안 하기 전에 histocrat 루비 솔루션 의 GolfScript 포트에 수렴되었습니다 . 특히, 우리가 식별 할 때 숫자를 인쇄하면 마지막에 인쇄하기 위해 배열에 숫자를 모으는 것이 상당히 절약됩니다. 그 이유는 스택에서 3 개 이상의 항목에 대해 걱정할 필요가 없다는 것을 의미하기 때문입니다.

해부

~.3*,           # Eval input n, dup, multiply by 3, make list [0 1 ... 3n-1]
1>              # Discard 0, which is part of neither sequence
\{              # Execute n times: stack contains pool of numbers not yet seen
                # in either sequence and the first element of it is the next element of the
                # complement sequence
  (\(           #   Pop two numbers from the start of the pool: stack is
                #     pool[0] pool[2..max] pool[1]
  .p            #   Print pool[1]
  @+            #   Rotate pool[0] to top and add to pool[1]
  \|            #   Place pool[0]+pool[1] at the start of the pool and
                #   (this is the clever bit) remove it from later in the pool
}*
;               # Discard the unused remainder of the pool

당신이 교체하는 경우 ^\-, 당신은 대체 할 수 ).*와 함께 3*. 이렇게하면 바이트가 절약되지 않지만 런타임 및 메모리 사용량이 크게 줄어 듭니다. -배열 위에 정수를 유지하여 1 바이트를 절약 할 수 있어야합니다. 루프는 동일한 바이트 수를 갖지만 초기화는 1 바이트 더 짧습니다.
Dennis

2
노동 조합은 차이보다 훨씬 더 효과적이다 :~.3*,1>\{(\(.p@+\|}*;
Dennis

3

J-28 자

n인수로 사용되는 기능 .

($+/\(-.~2+i.)&:>:+/)^:_&2 4

우리는 n왼쪽 인수로 함수를 변경하지 않을 때까지 오른쪽 인수에 반복적으로 실행합니다. 시작할 인수는 list 2 4입니다.

함수 자체에서 부분 합 +/\과 전체 합 +/을 취한 다음로 모두 증가시킵니다 &:>:. 그런 다음 모든 정수를 2에서 전체 합계 ( 2+i.) 보다 하나 이상으로 생성 -.하고 부분 합계를 빼기 ( )로 설정 하여 정의에 따라 더 긴 숫자 그림 시퀀스를 남깁니다. 마지막으로,리스트를 length로 짧게 또는 주기적으로 확장합니다 n.

결과 즉 2 4하게 3 7, 이는 제거되어 2..8이탈 2 4 5 6 8. 또 다른 라운드 후에 2 4 5 6 8하게 3 7 12 18 26된다

2 4 5 6 8 9 10 11 13 14 15 16 17 19 20 21 22 23 24 25 27

이런 식으로, 우리는 그림 그림 순서를 반복적으로 확장합니다. $길이 동작은 순서가 길이로 성장하기를 기다리는 단지가 아닌 사소한 문자 절약 방법입니다 n이상, 그리고 출력 n그들이 변경을 정지 할 때 첫번째 값을. 우리는 매우 오래 기다릴 필요도 없습니다. 내부 동사의 네 가지 응용 프로그램에서 최대 46336 개의 용어를 얻을 수 있습니다.

k의 동일한 기능 :

  • k2, 37 자 : {{x#y@&~_lin[y:1+!1+/y;1+\y]}[x]/2 4}
  • k4, 36 자 : {{x#y@&~(y:2+!1+/y)in\:1+\y}[x]/2 4}

2

자바 - 183 (158)

이것은 내가 골프를 해 본 것 중 가장 큰 것이었고, 그것을 자랑스럽게 생각합니다! (Java이기 때문에 차트의 상단 근처에는 없지만)

Peter Taylor에게 제안 해 주셔서 감사합니다.

class f{public static void main(String[]a){int q=1,m=Byte.valueOf(a[0]),w=2,n[]=new int[m*m*2];for(n[q+=w]=1;m-->0;){System.out.println(w);for(;n[++w]>0;);}}}

더 큰-

public class f {
    public static void main(String[] a) {
        int q = 1, m = Byte.valueOf(a[0]), w = 2, n[] = new int[m * m * 2];
        for (n[q += w] = 1; m-- > 0;) {
            System.out.println(w);
            for (; n[++w] > 0;)
                ;
        }
    }
}

그 내부 for 루프는 상당히 난독 화되지만 몇 바이트를 절약 할 수 있다고 생각합니다. Byte.valueOf세 가지를 저장하고 질문에 입력 범위를 지정하지 않으므로 수용 가능해야한다고 생각합니다. 루프 외부에서는 m초기화에만 사용 n되므로 완전히 제거 k++<m할 수 있습니다 . 이전 이니셜 라이저로 초기화 하여 병합 할 수 있습니다 . 결코 이외의 값을 보유하지 , 그렇게 될 수있다 . 그러면 이니셜 라이저가 첫 번째 루프 의 이니셜 라이저 부분이 될 수 있습니다 . m-->0kint[] nint n[]n1n[...]!=0n[...]>0for
피터 테일러

그리고을 제거 u하고 사용 ++w하면 n[q]또는 을 설정할 필요가 없습니다 n[w]. nwhen 의 끝을 벗어나는 버그 m==2가 있습니다. 초기화로 가장 잘 수정 된 것처럼 보이지만 n=new int[2*m*m]157 바이트로 떨어졌습니다.
피터 테일러

첫 번째 for 루프의 초기자가 된 초기자가 의미 for(int q=1,w=2,m=...,n[]=...;m-->0;){...하는 것은 세미콜론 을 절약하는 것이 었습니다 .
피터 테일러

1

파이썬 2-77 바이트


암호:

n=input();x=1;b=range(2,n*n)
while n:v=b.pop(0);x+=v;print v;b.remove(x);n-=1

입력은 stdin에서 오는 것을 제외하고 @histocrat의 솔루션과 동일하게 작동합니다.


1

파이썬 2-68

R=[1]
s=0
n=input()
while n:s+=1+(s+1in R);R+=[R[-1]+s];print s;n-=1

0

젤리 , 15 바이트

SƤŻ‘µṀ‘Rḟ
2dz¡ḣ

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

6의 입력에서 메모리 오류.

작동 원리

SƤŻ‘µṀ‘Rḟ  Aux. link (monad). Input: part of the desired sequence
SƤŻ‘       Sum of prefixes, then prepend a zero and increment
           This is a list of numbers to exclude from the next iteration
    µ      Re-focus on the above
     Ṁ‘Rḟ  Create range 1..Max + 1, then remove all elements of the above
           +1 is needed to progress from [2] to [2,4]

2dz¡ḣ  Main link (monad). Input: n, number of terms
2dz¡   Starting from 2, apply aux. link n times
    ḣ  Take n elements from the beginning

보다 효율적인 버전, 16 바이트

SƤŻ‘µṀ‘Rḟḣ³
2ÇÐL

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

이 J 답변 의 아이디어를 사용합니다 . 반복 할 때마다 원하는 길이로 자르고 고정 점을 사용하십시오. (max + 1 S) 대신 (sum)을 사용한다고 생각 Ṁ‘했지만 정확성을 보장 할 수는 없습니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.