비트 반전 순열


28

당신의 목표는 정수 n 주어진 정수의 범위에서 비트를 반전시키는 함수 또는 프로그램을 만드는 것입니다 . 다시 말해 , 0 n 인덱스 의 2 n 항목 범위의 비트 반전 순열 을 찾고자합니다 . 이것은 또한 OEIS 시퀀스 A030109 입니다. 이 프로세스는 종종 FFT에 대한 내부 Cooley-Tukey 알고리즘과 같은 고속 푸리에 변환을 계산하는 데 사용됩니다. 길이가 2의 거듭 제곱 인 시퀀스에 대해 FFT를 계산 하는 데 어려움 이 있습니다 .

이 프로세스를 수행하려면 [0, 2 n -1] 범위를 반복하고 각 값을 이진수로 변환하고 해당 값의 비트를 반전 시켜야합니다 . 밑수 2에서 각 값을 n 자리 숫자 로 취급 하므로 마지막 n 비트 사이에서만 반전이 발생합니다 .

예를 들어, n = 3 인 경우 정수 범위는입니다 [0, 1, 2, 3, 4, 5, 6, 7]. 이것들은

i  Regular  Bit-Reversed  j
0    000        000       0
1    001        100       4
2    010        010       2
3    011        110       6
4    100        001       1
5    101        101       5
6    110        011       3
7    111        111       7

여기서 각 인덱스 i 는 비트 리버설을 사용하여 인덱스 j 로 변환됩니다 . 이는 출력이 [0, 4, 2, 6, 1, 5, 3, 7]입니다.

0에서 4까지의 n에 대한 출력 은

n    Bit-Reversed Permutation
0    [0]
1    [0, 1]
2    [0, 2, 1, 3]
3    [0, 4, 2, 6, 1, 5, 3, 7]

패턴이 형성되었음을 알 수 있습니다. 주어 N , 당신은 이전 순서를 취할 수 N -1을 두 배로. 그런 다음 해당 이중 목록을 동일한 이중 목록에 연결하지만 1 씩 증가시킵니다. 보여주기 위해

[0, 2, 1, 3] * 2 = [0, 4, 2, 6]
[0, 4, 2, 6] + 1 = [1, 5, 3, 7]
[0, 4, 2, 6] ⊕ [1, 5, 3, 7] = [0, 4, 2, 6, 1, 5, 3, 7]

어디는 연결을 나타냅니다.

솔루션을 구성하기 위해 위의 두 가지 방법 중 하나를 사용할 수 있습니다. 더 나은 방법을 알고 있다면 그 방법도 자유롭게 사용할 수 있습니다. 올바른 결과를 출력하는 한 모든 방법이 좋습니다.

규칙

  • 이것은 이므로 가장 짧은 솔루션이 승리합니다.
  • 이 문제를 전체적으로 해결하는 기본 및 값의 비트 반전을 계산하는 기본은 허용되지 않습니다. 이진 변환이나 다른 비트 단위 연산을 수행하는 내장은 포함되지 않습니다.
  • 귀하의 솔루션은 최소한 0에서 31까지의 n에 유효해야합니다 .

3
"이 문제를 전체적으로 해결하고 값의 비트 반전을 계산하는 내장은 허용되지 않습니다." Awww IntegerReverse[Range[2^#]-1,2,#]&. (나도 몰라 이유 는보다 많은 괴상 아니다 티카가 내장 된 것을 필요로하지만, 그런 것 같아요 Sunset...)
마틴 청산을

@MartinEnder 좋은 발견. 언젠가, 임의의 코드 골프 챌린지를 생성하는 것을 포함하여 Mathematica에 모든 것이 내장되어있을 수 있습니다.
마일

0대신 인쇄 [0]해야합니까 아니면 목록이어야합니까?
Dennis

@ 데니스 좋은 지적. 형식에 관계없이 출력이 유효한 순열을 나타내는 것이 중요하기 때문에 허용합니다.
마일

0 대신 false 반환 해도 괜찮습니까?
Dennis

답변:


2

젤리 , 7 6 바이트

Ḥ;‘$$¡

1 바이트를 골라내는 @EriktheOutgolfer에게 감사합니다!

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

작동 원리

Ḥ;‘$$¡  Main link. No arguments.
        Implicit argument / initial return value: 0

     ¡  Read an integer n from STDIN and call the link to the left n times.
    $   Combine the two links to the left into a monadic chain, to be called
        with argument A (initially 0, later an array).
Ḥ         Unhalve; yield 2A.
   $      Combine the two links to the left into a monadic chain, to be called
          with argument 2A.
  ‘         Increment; yield 2A + 1
 ;          Concatenate 2A and 2A + 1.

4

05AB1E , 8 바이트

암호:

¾)IF·D>«

설명:

¾         # Constant for 0.
 )        # Wrap it up into an array.
  IF      # Do the following input times.
    ·     # Double every element.
     D    # Duplicate it.
      >   # Increment by 1.
       «  # Concatenate the first array.

CP-1252 인코딩을 사용합니다 . 온라인으로 사용해보십시오! .


좋은 것! 내가 가진 것을
이겼다

@Emigna 감사합니다! 당신의 버전은 무엇입니까?
Adnan

0)ïsF·D>«그래도 가까이 있었다. '0'에 문제가있었습니다.
Emigna 2016 년

1
의 좋은 사용법 ¾. 그 트릭을 기억해야합니다.
Emigna 2016 년

1
@KevinCruijssen 입력 0의 경우 , 문자열 표현이 아닌 int 표현이 0 인 것이 더 예쁘게 보입니다. :). 그 외에는 차이가 없습니다.
Adnan

4

MATL, 13 12 10 9 8 바이트

0i:"EtQh

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

설명

0       % Push number literal 0 to the stack
i:"     % Loop n times
    E   % Multiply by two
    t   % Duplicate
    Q   % Add one
    h   % Horizontally concatenate the result
        % Implicit end of loop, and implicitly display the result

완전성을 기하기 위해 비 재귀 접근법 (9 바이트)을 사용하는 이전 답변이 있습니다.

W:qB2&PXB

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

설명

W       % Compute 2 to the power% ofImplicitly thegrab input (n) and compute 2^n
:       % Create an array from [1...2^n]
q       % Subtract 1 to get [0...(2^n - 1)]
B       % Convert to binary where each row is the binary representation of a number
2&P     % Flip this 2D array of binary numbers along the second dimension
XB      % Convert binary back to decimal
        % Implicitly display the result

4

J, 15 11 바이트

2&(*,1+*)0:

간단한 이진 변환 및 반전을 사용 하는 15 바이트에 대한 대안이 있습니다 .

2|."1&.#:@i.@^]

용법

   f =: 2&(*,1+*)0:
   f 0
0
   f 1
0 1
   f 2
0 2 1 3
   f 3
0 4 2 6 1 5 3 7
   f 4
0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15

설명

2&(*,1+*)0:  Input: n
         0:  The constant 0
2&(     )    Repeat n times starting with x = [0]
2      *       Multiply each in x by 2
     1+        Add 1 to each
    ,          Append that to
2  *           The list formed by multiplying each in x by 2
               Return that as the next value of x
             Return the final value of x



3

옥타브, 37 바이트

@(n)bin2dec(fliplr(dec2bin(0:2^n-1)))

ans간단히 호출 할 수 있는 익명의 함수를 만듭니다 ans(n).

온라인 데모


3

파이썬 2, 56 55 54 바이트

f=lambda n:[0][n:]or[i+j*2for i in 0,1for j in f(n-1)]

Ideone에서 테스트하십시오 .

1 바이트를 골라내는 @xnor에게 감사드립니다!


할 수 있습니다 [0][n:]or.
xnor

3

자바, (422) 419 바이트 :

import java.util.*;class A{static int[]P(int n){int[]U=new int[(int)Math.pow(2,n)];for(int i=0;i<U.length;i++){String Q=new String(Integer.toBinaryString(i));if(Q.length()<n){Q=new String(new char[n-Q.length()]).replace("\0","0")+Q;}U[i]=Integer.parseInt(new StringBuilder(Q).reverse().toString(),2);}return U;}public static void main(String[]a){System.out.print(Arrays.toString(P(new Scanner(System.in).nextInt())));}}

글쎄, 마침내 두 번째 프로그래밍 언어로 Java를 배웠기 때문에 새로운 기술을 사용하여 간단한 도전을 완수하고 싶었지만 매우 오래 되었지만 실망하지 않았습니다. Java로 간단한 도전을 완료 할 수있어서 기쁩니다.

온라인으로 사용해보십시오! (아이디어)


StdIn에서 읽지 않고 args에서 int를 파싱하는 몇 바이트를 절약 할 수 있습니다
Pavel

3

매스 매 티카, 56 33 바이트

바이트 수는 ISO 8859-1 인코딩 소스를 가정합니다.

±0={0};±x_:=Join[y=±(x-1)2,y+1]

이것은 재귀 적 정의를 사용하여 단항 연산자를 정의합니다 ±.


3

펄, 46 45 바이트

에 +1 포함 -p

STDIN에 입력 번호를 줘

#!/usr/bin/perl -p
map$F[@F]=($_*=2)+1,@F for(@F=0)..$_;$_="@F"


2

자바 스크립트 ES6, 65 53 51 바이트

f=(n,m=1)=>n?[...n=f(n-1,m+m),...n.map(i=>i+m)]:[0]

재귀 이중 증가 연결 알고리즘을 사용합니다.

예제 실행 :

f(0) => [0]
f(1) => [0, 1]
f(2) => [0, 2, 1, 3]
f(4) => [0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15]

어때요 f=n=>n>0?(r=f(n-1).map(i=>i*2)).concat(r.map(i=>i+1)):[0]?
마일

@miles Whoops,에 대한 기본 사례가 필요하지 않다는 것을 몰랐습니다 n==1.
Dendrobium 2016 년

2
나는 곱셈을 2 씩 움직여서 2 바이트를 줄 였다고 생각한다.f=(n,m=1)=>n?[...n=f(n-1,m+m),...n.map(i=>i+m)]:[0]
Neil

2

파이썬 3, 67 59 바이트

-8 바이트의 @Dennis 덕분에

lambda n:[int(bin(i+2**n)[:1:-1],2)//2for i in range(2**n)]

꽤 긴 경우에도 파이썬에서 (수정 된) 간단한 구현을 가질 수도 있습니다.

인수로 입력하고 비트 반전 순열을 목록으로 반환하는 익명 함수입니다.

작동 원리

lambda n                 Anonymous function with input n
...for i in range(2**n)  Range from 0 to 2**n-1
bin(i+2**n)[:1:-1]       Convert i+2**n to binary string, giving 1 more digit than needed,
                         remove '0b' from start, and reverse
int(...,2)               Convert back to decimal
...//2                   The binary representation of the decimal value has one trailing
                         bit that is not required. This is removed by integer division by 2
:[...]                   Return as list

Ideone에서 사용해보십시오


2
이것은 내 접근 방식과 관련이 있지만 골프는 파이썬 3 포트에서 살아남지 못합니다.
Dennis

2

Dyalog APL , 12 바이트

⎕IO←0많은 시스템에서 기본값이 필요합니다 .

2⊥⊖2⊥⍣¯12*⎕

2⊥ ~의 기초 -2

뒤집힌

2⊥⍣¯1 에서베이스 2의 역수

첫 번째 n 정수 (여기서 n

2* 2의 힘

숫자 입력

TryAPL 온라인!


비교를 위해 다른 방법은 다음과 같습니다.

(2∘×,1+2∘×)⍣⎕⊢0

( 기능 기차 ...

2∘× 두 번 (논쟁)

, 에 연결

1+ 하나 더하기

2∘× 두 번 (논쟁)

)⍣ 에 의해 지정된 횟수만큼 적용

숫자 입력

0 제로


(⍋,⍨)⍣⎕⊢0( ⎕io←0)
ngn

@ngn 그것은 내 알고리즘과 관련이 없습니다.
Adám

나는 그것이 당신의 "다른 방법"과 비슷하다고 생각했지만 알았어요, 나는 별도의 답변을 쓸 것입니다
ngn

2

K (ngn / k) , 11 8 바이트

2/|!2|&:

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

 x:3  / just for testing
 &x   / that many zeroes
0 0 0
 2|&x / max with 2
2 2 2
 !x#2 / binary words of length x, as a transposed matrix
(0 0 0 0 1 1 1 1
 0 0 1 1 0 0 1 1
 0 1 0 1 0 1 0 1)
 |!x#2 / reverse
(0 1 0 1 0 1 0 1
 0 0 1 1 0 0 1 1
 0 0 0 0 1 1 1 1)
 2/|!x#2 / base-2 decode the columns
0 4 2 6 1 5 3 7

&컴포지션의 마지막 동사이므로 :강제로 모나 딕해야합니다.



1

Pyth, 8 바이트

iR2_M^U2

온라인으로 사용해보십시오 : 데모 또는 테스트 스위트

설명:

iR2_M^U2Q   implicit Q (=input number) at the end
     ^U2Q   generate all lists of zeros and ones of length Q in order
   _M       reverse each list
iR2         convert each list to a number

1

클로저, 78 바이트

사양을 따르기 만하면 ...

(defn f[n](if(= n 0)[0](let[F(map #(* 2 %)(f(dec n)))](concat F(map inc F)))))

1

루비, 57 바이트 :

->n{(0...a=2**n).map{|x|("%b"%x+=a).reverse[0,n].to_i 2}}

1

PHP, 57 바이트

while($i<1<<$argv[1])echo bindec(strrev(decbin($i++))),_;

명령 줄 매개 변수에서 입력을 받고 밑줄로 구분 된 값을 인쇄합니다. 로 실행하십시오 -nr.

재귀 솔루션, 72 바이트

function p($n){$r=[$n];if($n)foreach($r=p($n-1)as$q)$r[]=$q+1;return$r;}

함수는 정수를 취하고 배열을 반환



1

펄 6 , 42 바이트

{0,{$^p+^($_-$_/2+>lsb ++$)}...$_}o 1+<*-1

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

정수를 증가 시키면 단순히 최하위 비트 시퀀스를 뒤집습니다 (예 :에서 xxxx0111~로) xxxx1000. 따라서 다음 비트 반전 인덱스는 가장 중요한 비트 시퀀스를 뒤집어 이전 인덱스로부터 얻을 수 있습니다. XOR 마스크는 m - (m >> (ctz(i) + 1))for m = 2**n또는 로 계산할 수 있습니다 m = 2**n-1.

펄 6 , 30 바이트

my&f={$_&&(^2 X+(f($_-1)X*2))}

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

재귀 적 접근.


1

자바 스크립트 (Firefox 30-57), 48 바이트

f=n=>n?[for(x of[0,1])for(y of f(n-1))x+y+y]:[0]

@ Dennis ♦의 Python 2 솔루션 포트.


ReferenceError : f is not defined
l4m2

1

apt , 14 13 바이트

2pU Ǥw ú0U Í

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

포장 풀기 및 작동 방식

2pU o_s2 w ú0U n2

2pU    2**n
o_     range(2**n).map(...)
s2       convert to binary string
w        reverse
ú0U      right-pad to length n, filling with '0'
n2       convert binary string to number

간단한 구현.


실제로 문서화되지 않은 바로 가기가 있습니다 n2.Í
Oliver


0

x86, 31 바이트

충분히 큰 int[] bufferin eaxn in을 취하고 ecx에서 버퍼를 반환합니다 eax.

challenge 문에 제공된 연결 알고리즘을 구현합니다. 배열 액세스를 직접 사용하는 대신 포인터를 4 씩 증가시켜 바이트를 절약 할 수 있지만 lea/ mov는 이미 매우 짧습니다 (3 개의 레지 스토리 및 3 배의 경우 3 바이트).

.section .text
.globl main
main:
        mov     $buf, %eax          # buf addr
        mov     $3, %ecx            # n 

start:
        xor     %ebx, %ebx
        mov     %ebx, (%eax)        # init buf[0] = 0 
        inc     %ebx                # x = 1

l1:
        mov     %ebx, %edi          
        dec     %edi                # i = x-1
        lea     (%eax,%ebx,4), %edx # buf+x 

l2:
        mov     (%eax,%edi,4), %esi # z = buf[i]
        sal     %esi                # z *= 2
        mov     %esi, (%eax,%edi,4) # buf[i] = z
        inc     %esi                # z += 1
        mov     %esi, (%edx,%edi,4) # buf[x+i] = z

        dec     %edi                # --i 
        jns     l2                  # do while (i >= 0)

        sal     %ebx                # x *= 2
        loop    l1                  # do while (--n)

        ret

.data
buf:    .space 256, -1

16 진 덤프 :

00000507  31 db 89 18 43 89 df 4f  8d 14 98 8b 34 b8 d1 e6  |1...C..O....4...|
00000517  89 34 b8 46 89 34 ba 4f  79 f1 d1 e3 e2 e7 c3     |.4.F.4.Oy......|
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.