Bit-Ters Permattasyonlar


28

Amacınız bir işlev veya bir tamsayı verilen tamsayılar bir dizi bit tersine çevirmek için bir program oluşturmaktır n . Başka bir deyişle, bulmak istediğiniz bit ters permütasyon 2 bir dizi n öğeleri, sıfır endekslendi. Bu aynı zamanda OEIS dizisi A030109'dur . Bu işlem genellikle FFT için yerinde Cooley-Tukey algoritması gibi Hızlı Fourier Dönüşümlerini hesaplamada kullanılır. Uzunluğun 2 bir güç olduğu sekanslar için FFT'yi hesaplamak için bir zorluk da vardır .

Bu işlem, [0, 2 n -1] aralığı üzerinde yineleme yapmanızı ve her değeri ikili değere dönüştürmenizi ve bu değerdeki bitleri ters çevirmenizi gerektirir. Her değeri temel 2'de bir n- dijit sayısı olarak ele alacaksınız, bu durumda tersine çevirme yalnızca son n bit arasında gerçekleşecektir .

Örneğin, n = 3 ise, tam sayı aralığı [0, 1, 2, 3, 4, 5, 6, 7]. Bunlar

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

Burada her bir i indeksi , bit-ters çevirme kullanarak bir j indisine dönüştürülür . Bu, çıktı olduğu anlamına gelir [0, 4, 2, 6, 1, 5, 3, 7].

0 dan 4 e kadar olan n sayısı

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

Bir desen oluşumu fark etmiş olabilirsiniz. N verildiğinde , önceki diziyi n -1 için alabilir ve iki katına çıkarabilirsiniz . Ardından, iki katına çıkan listeyi aynı çift listeyle birleştirin, ancak bir tarafından artırın. Göstermek için,

[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]

burada birleştirme temsil eder.

Çözümünüzü oluşturmak için yukarıdaki iki yöntemden birini kullanabilirsiniz. Daha iyi bir yol biliyorsanız, onu kullanmakta özgürsünüz. Doğru sonuçlar çıktığı sürece herhangi bir yöntem iyidir.

kurallar

  • Bu yani en kısa çözüm kazanır.
  • Bu sorunu bir bütün olarak çözen yerleşiklere ve bir değerin bit tersini hesaplayan yerleşiklere izin verilmez. Bu, ikili dönüşüm veya diğer bitsel işlemleri gerçekleştiren yerleşikleri içermez.
  • Çözümünüz, en azından, 0 ile 31 arasında n için geçerli olmalıdır .

3
“Bu sorunu bir bütün olarak çözen yerleşiklere ve bir değerin bit tersine çevrilmesini hesaplayan yerleşiklere izin verilmez.” Awww IntegerReverse[Range[2^#]-1,2,#]&,. ( Mathematica'nın neden bu kadar dahili bir sisteme ihtiyacı olduğunu bilmiyorum ama sanırım bundan daha tuhaf değil Sunset...)
Martin Ender

@ Martininder Nice bulmak. Bir gün, Mathematica'da rastgele kod-golf mücadelesi oluşturmak da dahil her şey için bir yerleşik olabilir.
mil

0Bunun yerine yazdırabilir miyiz [0]yoksa liste mi olmalı?
Dennis,

@Dennis İyi nokta. Buna izin vereceğim, çünkü çıktının formattan bağımsız olarak geçerli bir permütasyonu temsil etmesi önemlidir.
mil,

0 yerine false döndürmek kabul edilebilir mi?
Dennis

Yanıtlar:


2

Jöle , 7 6 bayt

Ḥ;‘$$¡

1 byte kapalı golf için @EriktheOutgolfer için teşekkürler!

Çevrimiçi deneyin!

Nasıl çalışır

Ḥ;‘$$¡  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 bayt

Kod:

¾)IF·D>«

Açıklama:

¾         # 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 kodlamasını kullanır . Çevrimiçi deneyin! .


Güzel bir! Sahip olduğum birini
yendi

@Emigna Teşekkürler! O zaman sürümün neydi?
Adnan

0)ïsF·D>«olsa yakındı. '0' ile ilgili bazı sorunlar vardı.
Emigna

1
Güzel kullanımı ¾. Bu numarayı hatırlamak zorunda kalacağım.
Emigna

1
@KevinCruijssen 0 girişi için, 0 karakterinin gösterilişine sahip olması daha güzel görünmektedir :). Bunun dışında hiçbir fark yoktur.
Adnan

4

MATL, 13 12 10 9 8 bayt

0i:"EtQh

Çevrimiçi Deneyin

açıklama

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

Tamamlanma uğruna, işte özyinelemesiz yaklaşım (9 bayt) kullanarak eski cevabım.

W:qB2&PXB

Çevrimiçi Deneyin

açıklama

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 bayt

2&(*,1+*)0:

İleriye doğru ikili dönüşüm ve ters çevirme kullanan 15 baytlık alternatif vardır .

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

kullanım

   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

açıklama

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

Octave, 37 bayt

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

Adında anonim bir işlev oluşturur ans çağrılabilenans(n) .

Çevrimiçi Demo


3

Python 2, 56 55 54 bayt

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

İdeone üzerinde test et .

1 byte kapalı golf için @xnor için teşekkürler!


Yapabilirsin [0][n:]or.
xnor

3

Java, 422 419 bayt:

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())));}}

Eh, basit bir meydan tamamlamak için benim yeni beceriler kullanmak istedim bu yüzden son olarak, benim ikinci programlama dili için Java öğrenilen ve rağmen çıktı çok uzun sürmesine hayal kırıklığına uğramam. Java ile basit bir mücadeleyi tamamlayabildiğim için mutluyum.

Çevrimiçi Deneyin! (Ideone)


StdIn
Pavel

3

Mathematica, 56 33 bayt

Bayt sayısı, bir ISO 8859-1 kodlu kaynağı varsayar.

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

Bu, tek bir işleci tanımlamak için özyinelemeli tanımı kullanır ±.


3

Perl, 46 45 bayt

İçin +1 içerir -p

STDIN'e giriş numarası verin

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


2

Javascript ES6, 65 53 51 bayt

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

Özyinelemeli çift-artımlı-concat algoritmasını kullanır.

Örnek çalışır:

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]

Ne dersiniz f=n=>n>0?(r=f(n-1).map(i=>i*2)).concat(r.map(i=>i+1)):[0]?
mil

@miles Whoops, temel bir davaya ihtiyacım olmadığının farkında değildim n==1, teşekkürler.
Dendrobium

2
Sanırım çarpımı iki ile değiştirerek 2 byte'ı tıraş etmeyi başardım:f=(n,m=1)=>n?[...n=f(n-1,m+m),...n.map(i=>i+m)]:[0]
Neil

2

Python 3, 67 59 bayt

-8 baytlık @Dennis'e teşekkürler

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

Python'da oldukça uzun olsa bile (değiştirilmiş) basit bir uygulama yapabiliriz.

Argümanla girdi alan ve bit tersine çevrilmiş permütasyonu bir liste olarak döndüren adsız bir işlev.

Nasıl çalışır

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'da dene


2
Bu benim yaklaşımımla bağlantılı, ancak golf sahası Python 3'e bir limandan sağ çıkmayacak.
Dennis

2

Dyalog APL , 12 bayt

⎕IO←0Birçok sistemde varsayılan olanı gerektirir .

2⊥⊖2⊥⍣¯12*⎕

2⊥ taban-2’den

saygısız

2⊥⍣¯1 taban-2 tersi

İlk n tamsayıları, n ise

2* 2 gücüne

sayısal giriş

TryAPL çevrimiçi!


Karşılaştırma için, işte diğer yöntem:

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

( fonksiyon treni ...

2∘× iki kez (argüman)

, birleştirilmiş

1+ bir artı

2∘× iki kez (argüman)

)⍣ tarafından belirtilen sayıda uygulandı.

sayısal giriş

üzerinde

0 sıfır


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

@ ngn Bunun algoritmamla ilgisi yok.
Adám

"diğer yönteminize" benzer olduğunu düşündüm ama tamam, ayrı bir cevap yazacağım
ngn

2

K (ngn / k) , 11 8 bayt

2/|!2|&:

Çevrimiçi deneyin!

 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

&bileşimdeki son fiil, bu yüzden :onu monadik olmaya zorlamak için bir ihtiyacımız var



1

Pyth, 8 bayt

iR2_M^U2

Çevrimiçi deneyin: Gösteri veya Test Paketi

Açıklama:

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

Clojure, 78 bayt

Sadece teknik özelliklere uyuyorum ...

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

1

Ruby, 57 bayt:

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

1

PHP, 57 bayt

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

komut satırı parametresinden girdi alır, alt çizgi ile sınırlanmış değerleri yazdırır. İle koş -nr.

özyinelemeli çözüm, 72 bayt

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

işlev tamsayı alır, diziyi döndürür



1

Perl 6 , 42 bayt

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

Çevrimiçi deneyin!

Bir tamsayıyı artırmak, örneğin 'den' xxxx0111ye kadar olan en az anlamlı bitlerin bir sırasını çevirir xxxx1000. Böylece, bir sonraki bit-ters endeksi, en anlamlı bitlerin bir dizisini çevirerek bir öncekinden elde edilebilir. XOR maskesi ile hesaplanabilir m - (m >> (ctz(i) + 1))için m = 2**nya m = 2**n-1.

Perl 6 , 30 bayt

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

Çevrimiçi deneyin!

Özyinelemeli yaklaşım.


1

JavaScript (Firefox 30-57), 48 bayt

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

Limanın @ Dennis Py 'nin Python 2 çözümü.


ReferenceError: f tanımlanmadı
l4m2

1

Japt , 14 13 bayt

2pU Ǥw ú0U Í

Çevrimiçi deneyin!

Ambalajsız ve Nasıl Çalışır?

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

Basit uygulama.


Aslında belgelenmemiş bir kısayol var n2:Í
Oliver

1

APL (Dyalog Klasik) , 9 bayt

(⍋,⍨)⍣⎕⊢0

Çevrimiçi deneyin!

değerlendirilmiş girdi

( )⍣⎕⊢0içinde şeyi uygulamak ( )ile başlayan birçok kez0

,⍨ mevcut sonucu kendisiyle birleştirir

sıralama artan bir permütasyon indeksleri


0

x86, 31 bayt

Yeterince büyük bir alır int[] bufferiçinde eaxve n de ecx, ve de tampon döndürüreax .

Challenge ifadesinde verilen birleştirme algoritmasını uygular. Doğrudan dizi erişimini kullanmak yerine işaretçileri 4 artırarak baytları kurtarmak mümkün olabilir, ancak lea/ movzaten oldukça kısadır (3 kayıt ve bir çarpan için 3 bayt).

.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

HexDump:

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......|
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.