최대 2 ^ n-1까지의 출력 번호, "정렬"


38

양의 정수 n 을 입력으로 사용 하고 다음과 같은 순서로 n 비트를 사용하여 만들 수있는 10 진수를 출력합니다 (일부) .

먼저 하나만으로 생성 할 수있는 모든 숫자를 나열 1하고 나머지 0는 이진 표현 (정렬)으로 나열한 다음 두 개의 연속 1 , 나머지 0는 3 연속 으로 생성 할 수있는 모든 숫자를 나열 하십시오 1.

n = 4의 모습을 봅시다 :

0001  -  1
0010  -  2
0100  -  4
1000  -  8
0011  -  3
0110  -  6
1100  -  12
0111  -  7
1110  -  14
1111  -  15

따라서 n = 4 의 출력 은 1, 2, 4, 8, 3, 6, 12, 7, 14, 15입니다 (선택적 출력 형식).

테스트 사례 :

n = 1
1

n = 2
1 2 3

n = 3
1, 2, 4, 3, 6, 7

n = 8
1, 2, 4, 8, 16, 32, 64, 128, 3, 6, 12, 24, 48, 96, 192, 7, 14, 28, 56, 112, 224, 15, 30, 60, 120, 240, 31, 62, 124, 248, 63, 126, 252, 127, 254, 255

n = 17
1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 3, 6, 12, 24, 48, 96, 192, 384, 768, 1536, 3072, 6144, 12288, 24576, 49152, 98304, 7, 14, 28, 56, 112, 224, 448, 896, 1792, 3584, 7168, 14336, 28672, 57344, 114688, 15, 30, 60, 120, 240, 480, 960, 1920, 3840, 7680, 15360, 30720, 61440, 122880, 31, 62, 124, 248, 496, 992, 1984, 3968, 7936, 15872, 31744, 63488, 126976, 63, 126, 252, 504, 1008, 2016, 4032, 8064, 16128, 32256, 64512, 129024, 127, 254, 508, 1016, 2032, 4064, 8128, 16256, 32512, 65024, 130048, 255, 510, 1020, 2040, 4080, 8160, 16320, 32640, 65280, 130560, 511, 1022, 2044, 4088, 8176, 16352, 32704, 65408, 130816, 1023, 2046, 4092, 8184, 16368, 32736, 65472, 130944, 2047, 4094, 8188, 16376, 32752, 65504, 131008, 4095, 8190, 16380, 32760, 65520, 131040, 8191, 16382, 32764, 65528, 131056,16383, 32766, 65532, 131064, 32767, 65534, 131068, 65535, 131070, 131071

이것은 이므로 각 언어 에서 가장 짧은 코드가 승리합니다!

"일반 언어"의 솔루션에 대해서도 좋은 설명을 적극 권장합니다 !



2
@ zeppelin 처음에는 그렇게 생각했지만 이것은 매우 다릅니다.
ETHproductions


6
누군가가 어떤 형태의 기본 변환없이 (일반적인 오래된 수학 사용)이 작업을 수행하면 상상의 보너스.
Stewie Griffin

답변:


38

파이썬 , 53 바이트

f=lambda n,i=1:n*[f]and[i]+f(n-1,2*i)+i%2*f(n-1,i-~i)

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

재귀 함수는 정렬 된 목록을이 트리 아래의 사전 주문으로 생성합니다 (예 :) n=4.

      1
     / \
    2   3
   /   / \
  4   6   7
 /   /   / \
8   12  14  15

1 2 4 8 3 6 12 7 14 15

왼쪽 분기는 값을 두 배로 늘리고 오른쪽 분기는 i->i*2+1odd 만 수행 하고 존재합니다 i. 따라서 잎이없는 곳의 선주문 순서는 T(i)=[i]+T(i*2)+i%2*T(i*2+1)입니다.

트리는 depth n위치 에서 종료되며 여기 n에서 입력이 있습니다. 이는 n각 스텝 다운이 감소 할 때마다 감소 하고 0 일 때 정지하여 달성됩니다 .

다른 방법 은 추적 깊이가 아닌 을 (를) i초과 하는 값에서 종료 2**n하는 것입니다. 나는 이것이 1 바이트 더 길다는 것을 발견했다.

f=lambda n,i=1:2**n/i*[f]and[i]+f(n,2*i)+i%2*f(n,i-~i)
f=lambda n,i=1:[f][i>>n:]and[i]+f(n,2*i)+i%2*f(n,i-~i)

4
와. 그것은 정말 멋진 / 영리한 트릭 일뿐만 아니라 매우 효과적입니다. +1, 정말 좋은 답변입니다!
DJMcMayhem

2
(가) [f]재미있는 터치입니다, 내가 그 전에 본 적이 말할 수 없습니다.
FryAmTheEggman

18

젤리 , 6 바이트

Ḷ2*ẆS€

이것은 가상의 보너스를 받을 자격이 있습니다.

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

작동 원리

Ḷ2*ẆS€  Main link. Argument: n

Ḷ       Unlength; yield [0, ..., n-1].
 2*     Yield [2**0, ..., 2**(n-1)].
   Ẇ    Sliding window; yield all subarrays of consecutive elements.
        The subarrays are sorted by length, then from left to right.
    S€  Map the sum atom over the substrings.

1
이 과제에 이상적인 기본 제공 도구이며 결과가이 과제에 적합한 순서로 구현되도록 구현되었습니다. 잘 했어요 :-)
ETHproductions

이 12 바이트 (최소한 UTF-8)가 아닙니까?
Gareth

1
@Gareth 예. 그러나 Jelly는 단일 바이트 문자 세트를 지원하며 여기에는 이해하는 256 개의 기호 만 포함됩니다.
Dennis

9

Mathematica, 40 바이트

Join@@Table[2^j(2^i-1),{i,#},{j,0,#-i}]&

원하는 목록의 모든 숫자는 2의 거듭 제곱의 차이이므로 2를 사용하여 순서대로 생성 Table한 다음 목록을 병합합니다. 나는 이것이 Stewie Griffin의 가상 보너스를 얻는다고 생각합니다 :)

Mathematica, 35 바이트

Tr/@Rest@Subsequences[2^Range@#/2]&

의 포트 데니스 젤리 알고리즘이다 . 나는 Subsequences전에 이것 에 대해 몰랐다 ! (또한 마일 이이 정확한 답변을 게시 한 것을 보지 못했습니다 ... upvote it!)


1
참고 :이 솔루션은 @GregMartin이 편집하기 5 시간 전에 게시 된 @mile의 Mathematica 코드 와 동일합니다 . 그러나 메타 합의에 따라이 답변은 여전히 ​​유효합니다.
JungHwan Min

나는 그것을 보지 못해서 그것을 보지 못했다.
Greg Martin

8

자바 스크립트 (ES6), 59 58 55 바이트

for(q=prompt(n=1);p=q--;n-=~n)for(m=n;p--;m*=2)alert(m)

프롬프트를 통해 입력을 받고 각 번호를 연속적으로 경고하는 전체 프로그램입니다. 이것은 또한 가상 보너스를 받을 자격이 있습니다 .

테스트 스 니펫

(참고 : console.log대신 사용 alert)


제안 ( "더 이상 팝업 표시 안 함"을 확인한 후) : 테스트 스 니펫을 위해 console.log로 변경하십시오.
Tejas Kale

@TejasKale 좋은 생각이야, 고마워!
ETHproductions

7

자바 스크립트 (ES6), 55 51 바이트

공백으로 구분 된 정수 목록을 리턴합니다.

n=>(F=k=>k>>n?--j?F(k>>j|1):'':k+' '+F(k*2))(1,j=n)

상상의 보너스 친화적.

형식화 및 의견

n => (                    // main function, takes n as input
  F = k =>                // recursive function, takes k as input
    k >> n ?              // if k is greater or equal to 1 << n:
      --j ?               //   decrement j ; if j is > 0:
        F(k >> j | 1)     //     do a recursive call with an additional bit set
      :                   //   else
        ''                //     stop recursion
    :                     // else
      k + ' ' + F(k * 2)  //   append k to output and do a recursive call with k * 2
  )(1, j = n)             // start the recursion with k = 1 and j = n

테스트 사례



6

Mathematica, 35 바이트

Tr/@Rest@Subsequences[2^Range@#/2]&



4

하스켈, 47 바이트

f n=[1..n]>>= \b->take(n-b+1)$iterate(2*)$2^b-1

사용 예 : f 4-> [1,2,4,8,3,6,12,7,14,15]. 온라인으로 사용해보십시오! .

작동 방식 :의 각 숫자 b에 대해 값을 [1..n]시작하여 2^b-1반복적으로 두 배로 늘리고이 n-b+1목록에서 요소를 가져 옵니다.



4

그루비, 90 89 바이트

{(0..<2**it).collect{0.toBinaryString(it)}.sort{it.count("1")}.collect{0.parseInt(it,2)}}

이진 변환은 그루비에서 너무 바보입니다.

Gurupad Mamadapur에게 -1 감사


3
28 바이트 이진 변환 상용구이므로 고통 스럽습니다.
Magic Octopus Urn

1
{(1..<2**it)...바이트를 저장합니다.
Gurupad Mamadapur


3

Bash + Unix 유틸리티, 51 바이트

dc<<<2i`seq -f%.f $[10**$1-1]|grep ^1*0*$|sort -r`f

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

입력 n은 인수로 전달됩니다.

n 이하의 숫자로 모든 숫자를 인쇄하려면 seq를 사용하십시오. (이것은 10 자리 숫자이므로 여기에 많은 추가 숫자가 있습니다. 낭비적이고 시간이 많이 걸리지 만 코드 골프입니다!)

grep 호출은 정확히 1과 그 뒤에 0으로 구성된 숫자 만 유지합니다.

그런 다음 sort -r을 사용하여 사전 사전 순으로 정렬하십시오.

마지막으로 dc는 기본 2 입력으로 설정됩니다. 정렬 된 숫자를 스택에 푸시 한 다음 스택을 위에서 아래로 인쇄합니다. (이것은 마지막으로 밀린 마지막 항목 등을 인쇄하므로 sort 대신 sort -r을 사용하는 이유입니다.)

버그 수정 : -f % .f 옵션을 seq로 생략했는데, 정수 카운트는 1000000부터 필요합니다. (문제가 있음을 지적 해 주신 @TobySpeight에게 감사합니다.)


" 낭비하고 시간 소모적 인 "... 그리고 영리한 ! 고마워요-골프를 칠 때 계산 효율을 고의로 무시한다는 것은 좋은 생각입니다. 빠르고 명확한 코드를 작성하면서 하루의 나머지 시간을 보내면 정말 어려워요.
Toby Speight

누락 된 일부 값 : dc<<<2i`seq $[10**7-1]|grep ^1*0*$|sort -r`f | wc -12 개의 값만보고합니다. 나는 당신이 grep ^1[01]*$대신 원한다고 생각합니다 .
Toby Speight

@TobySpeight 감사합니다-버그가 수정되었습니다. 문제는 정규 표현식이 아니 었습니다. 문제는 seq에 옵션이 필요하다는 것입니다. (왜 12 개의 출력 값만 가져 왔는지 잘 모르겠습니다. 잘못된 버전이라도 올바른 28 개의 출력 값으로 21 개의 출력 값을 생성했습니다. TIO에서이 값을 실행하는 경우 TIO의 1 분 시간 제한을 초과했을 수 있습니다. .) 나는 이것을 Linux와 OS X에서 지금 테스트했다.
Mitchell Spector 2019

1
사실, 나는 그 질문을 오해했다. 중요한 단어 "연속적"은 어떻게 든 나를지나 갔다!
Toby Speight


2

펄 6 , 38 바이트

->\n{map {|(2**$_-1 X+<0..n-$_)},1..n}

작동 원리

->\n{                                }  # A lambda with argument n.
                                 1..n   # Numbers from 1 to n.
     map {                     },       # Replace each one with a list:
            2**$_-1                     #   2 to that power minus 1,
                    X+<                 #   bit-shifted to the left by each element of
                       0..n-$_          #   the range from 0 to n minus the number.
          |(                  )         #   Slip the list into the outer list.

즉, 다음과 같이 숫자를 구성합니다.

1 2 4 8 = (2^1)-1 bit-shifted to the left by 0 1 2 3 places
3 6 12  = (2^2)-1 bit-shifted to the left by 0 1 2   places
7 14    = (2^3)-1 bit-shifted to the left by 0 1     places
15      = (2^4)-1 bit-shifted to the left by 0       places      n rows
                                                  
             n                                     n-1

코드:


펄 6 , 44 바이트

->\n{map {|(2**$_-1,* *2...^*>2**n-1)},1..n}

위의 (실제로는 더 간단한) 비트 시프트 솔루션을 생각하기 전에 이것이 첫 번째 접근법이었습니다.

작동 원리

->\n{                                      }  # A lambda with argument n.
                                       1..n   # Numbers from 1 to n.
     map {                           }        # Replace each one with:
            2**$_-1                              # 2 to that power minus 1,
                   ,* *2                         # followed by the result of doubling it,
                        ...^                     # repeated until (but not including)
                            *>2**n-1             # it's larger than 2^n-1.
          |(                        )            # Slip the list into the outer list.

즉, 다음과 같이 숫자를 구성합니다.

1 2 4 8 = (2^1)-1, times 2, times 2, times 2
3 6 12  = (2^2)-1, times 2, times 2
7 14    = (2^3)-1, times 2
15      = (2^4)-1                                 n rows
                                    
             n                       as many columns as possible in
                                     each row without exceeding (2^n)-1

2

하스켈 59 46 바이트

나는 시작했다 f n=[0..n]>>= \b->take(n-b).iterate(*2).sum.map(2^)$[0..b]

위의 니미의 대답에서 sum.map(2^)$[0..x]응축 될 수있는 통찰력을 얻었습니다.2^x-1

끝나는

e n=[1..n]>>= \x->map(\y->2^y*(2^x-1))[0..n-x]

[1..n] -순환하고자하는 연속적인 비트 수를 가진리스트

>> =- 왼쪽에있는 각 요소에 대해 거의 번역되어 오른쪽에있는 함수에 전달하고 모든 결과를 연결합니다.

\ x-> -하나의 인수로 람다 함수 선언

맵 xy- 함수 x를리스트의 모든 멤버에 적용합니다. y

우리의 경우 x = (\ y-> 2 ^ y * (2 ^ x-1)) -다른 람다 함수 2 ^ y * (2 ^ x-1)). 이 공식은 이진수로 오른쪽에 0을 더한 두 곱셈 (예 : 0001 ~ 0010)으로 발생합니다. 2 ^ x-1은 우리가 작업하는 비트 수입니다. 11의 경우 2 ^ 0 * 3 (즉, 전혀 이동하지 않습니다) == 0011, 2 ^ 1 * 3 = 0110, 2 ^ 2 * 3-1100입니다.

[0..nx] 비트를 몇 번이나 이동할 수 있는지 목록을 작성합니다. 단일 1로 작업하고 0001을보고 있다면 3 번 (4-1) 이동하고 싶습니다. 우리가 두 11을 일하고 있다면 우리는 4-2 등을 원합니다.


2

파이썬 3, 59 바이트

참고 : 이것은 ovsDennis 솔루션 과 독립적으로 이루어 졌지만 둘 다와 매우 유사합니다.

lambda n:[(2<<i)-1<<j for i in range(n)for j in range(n-i)]

작동 방식 :

for i in range(n)for j in range(n-i)  # Iterate over number of ones, then number of places
                                      # shifted over. i = ones, j = shifts

(2<<i)                                # Create a one followed by i zeroes
      -1                              # Subtract one from above to get i ones.
        <<j                           # Shift j places.

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

팁 (코딩과 현금 모두)은 언제나 환영합니다!


2

Japt , 11 바이트

o@o!²ãXÄ mx

온라인으로 테스트하십시오!

설명

이것은 @Dennis의 접근법을 거의 사용합니다.

o@ o!²  ãXÄ  mx
oX{o!p2 ãX+1 mx}
                  // Implicit: U = input integer
oX{            }  // Create the range [0...U) and map each item X by this function:
   o              //   Create the range [0...U)
    !p2           //     and map each item Z to 2.p(Z); that is, 2**Z.
                  //     (p2 would map each item Z to Z.p(2); ! reverses the arguments.)
        ãX+1      //   Get all overlapping slices of length X + 1.
             mx   //   Map each of these slices Z through Z.x(); that is, sum each slice.
                  // Implicit: output result of last expression


2

PHP, 59 56 53 바이트

for(;$p>($k*=2)?:($p=1<<$argn)>$k=$i+=$i+1;)echo$k,_;

STDIN에서 입력을받습니다. 로 실행하십시오 -R.

고장

for(;$p>($k*=2)         // 3. inner loop: shift-0 $k while $k<$p (false in first iteration)
    ?:
    ($p=1<<$argvn)      // 1. init $p=2^N, outer loop:
    >$k=$i+=$i+1        // 2. shift-1 $i while $i<$p, init $k to new $i
;)
    echo$k,_;           // 4. print $k

$argn아주 좋은 생각을 사용할 수 있습니다 . 나는 내 머리 200 바이트와 용액에이 질문을 읽은 후
요 르그 Hülsermann

@ JörgHülsermann STDIN을 상기시켜 주셔서 감사합니다. 루프 병합을 좋아합니다.
Titus

1

J , 19 바이트

(0-.~&,>:+/\2&^)@i.

이것은 @Dennis ' solution 과 동일한 방법을 사용합니다 .

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

설명

(0-.~&,>:+/\2&^)@i.  Input: integer n
                 i.  Range [0, 1, ..., n-1]
(              )@    Operate on that range
            2&^        Compute 2^x for each x in that range
       >:              Increment each in that range
           \           For each overlapping sublist of size (previous) in powers of 2
         +/              Reduce by addition
 0                     The constant 0
     &,                Flatten each
  -.~                  Remove zeroes

1

파이썬 3, 91 바이트

a=int(input())
print(*[int('1'*-~b,2)<<c for b in range(a)for c in range(a-b)],sep=', ')

지정된대로 쉼표 + 공백으로 구분 된 출력을 포함한 전체 프로그램.

설명:

별표 표기법은 목록의 압축을 풉니 다. 그래서 print(*[1,2,3])동일하다 print(1,2,3). 패스 int()생성자에게 연속 '1 개의 문자열을.

-~b로 평가 b+1되지만 문자열을 곱할 때 대괄호로 묶을 필요는 없습니다.

생성 된 정수를 비트 수만큼 비트 시프트합니다. print()압축 해제 된 목록의 각 항목 사이에 넣을 문자열을 지정하는 선택적 sep 인수가 있습니다.


2
목록을 인쇄하면됩니다. 출력 형식이 엄격하지 않습니다.
mbomb007

1

자바 7, 108 바이트

static void x(int i){int a=0,t=1<<i,b;while((a=(a<<1)+1)<t){b=a;do System.out.println(b);while((b<<=1)<t);}}

결과가보다 작 으면 초기 값이 두 배가 2^n됩니다. 그런 다음 초기 값을로 업데이트하고 (initial_value * 2) + 1결국에 도달 할 때까지 다시 시작합니다 (2^n)-1.

예를위한 n=4:

0001 -> init
0010
0100
1000
return, double init and add one
0011 -> init
0110
1100
return, double init and add one
0111 -> init
1110
return, double init and add one
1111 -> init
done

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


1

루비, 50 바이트

->r{1.upto(r){|x|p a=2**x-1;p a while(a*=2)<2**r}}

나는 "영리한"접근 방식을 시도했지만 이것이 가장 짧은 것 같습니다

설명:

각 반복은 2 ^ n-1로 시작하여 상한에 도달 할 때까지 2를 곱합니다. 멋진 것도없고 단지 기본 수학입니다.


1

QBIC , 37 바이트-허수 보너스 = 여전히 37 바이트 ...

:[a|e=2^b-1┘while e<2^a┘?e┘e=e*2┘wend

부끄러움 while-wend아직 QBIC에 내장 되어 있지 않습니다 ... 설명 :

:       Get N from the command line
[a|     For b = 1 to N; The sequence is reset N times
e=2^b-1 Set the first number of this sub-sequence (yields 1, 3, 7, 15 ...)
┘       Line-break - syntactic separation of commands because there's no command for WHILE yet.
while   Pure QBasic code - lower-case is not (really) interpreted by QBIC
e<2^a   Continue as long as we don't exceed the maximum value
┘?e     Print the number in the sequence
┘e=e*2  Double the number
┘wend   And loop as long as we're not exceeding maximum, reset the sequence otherwise.
        FOR loop auto-closed by QBIC

편집 : QBIC은 이제 다음을 지원합니다 WHILE.

:[a|e=2^b-1≈e<2^a|?e┘e=e*2

이것은 단지 26 바이트입니다! 여기에 WHILE:

≈e<2^a|          ≈ = WHILE, and the TRUE condition is everything up to the |
       ...       Loop code goes here
          ]      Close construct: adds a WEND instruction
                 In the program above, this is done implicitly because of EOF.



1

Stax , 9 바이트

übg▓}╥é►╪

온라인으로 실행하고 디버그하십시오!

설명

누군가가 어떤 형태의 기본 변환없이 (일반적인 오래된 수학 사용)이 작업을 수행하면 상상의 보너스.

여기에는 기본 변환이 없습니다.

압축을 푼 버전 (10 바이트)을 사용하여 설명합니다.

m|2vx_-DQH
m             For input=`n`, loop over `1..n`
 |2v          Power of two minus one
    x_-D      Do `n-j` times, where `j` is the current 1-based loop index
        Q     Output the current value
         H    And double it

0

배치, 92-0 = 92 바이트

@for /l %%i in (1,1,%1)do @for /l %%j in (%%i,1,%1)do @cmd/cset/a"(1<<%%i)-1<<%%j-%%i"&echo(

@StewieGriffin의 가상 보너스에 대해 0을 뺍니다.

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