Số lượng đầu ra lên tới 2 ^ n-1, Sắp xếp


38

Lấy số nguyên dương n làm đầu vào và đầu ra (một số) số thập phân có thể được tạo bằng n bit, được sắp xếp theo cách sau:

Đầu tiên liệt kê tất cả các số có thể được tạo chỉ bằng một 1và phần còn lại 0trong biểu diễn nhị phân (được sắp xếp), sau đó tất cả các số có thể được tạo bằng hai liên tiếp 1 , phần còn lại 0, sau đó ba liên tiếp 1 , v.v.

Chúng ta hãy xem điều này trông như thế nào cho n = 4 :

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

Vì vậy, đầu ra cho n = 4 là: 1, 2, 4, 8, 3, 6, 12, 7, 14, 15 (định dạng đầu ra tùy chọn).

Các trường hợp thử nghiệm:

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

Đây là , vì vậy mã ngắn nhất trong mỗi ngôn ngữ sẽ thắng!

Giải thích tốt rất được khuyến khích , cũng cho các giải pháp trong "ngôn ngữ thông thường"!



2
@zeppelin Lúc đầu tôi cũng nghĩ vậy, nhưng cái này thì khác.
Sản phẩm ETH

1
Liên quan. (Hơi một chút.)
Martin Ender

6
Phần thưởng tưởng tượng nếu ai đó thực hiện việc này mà không cần bất kỳ hình thức chuyển đổi cơ sở nào (sử dụng toán học cũ đơn giản).
Stewie Griffin

Đã viết điều này là một sự pha trộn giữa hai tôi đoán Hãy thử trực tuyến!
PrincePolka

Câu trả lời:


38

Python , 53 byte

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

Hãy thử trực tuyến!

Hàm đệ quy tạo danh sách được sắp xếp dưới dạng đặt hàng trước đi xuống cây này (ví dụ với n=4):

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

1 2 4 8 3 6 12 7 14 15

Các nhánh trái tăng gấp đôi giá trị, và các nhánh phải làm i->i*2+1và chỉ tồn tại cho số lẻ i. Vì vậy, đi bộ đặt hàng trước cho không lá là T(i)=[i]+T(i*2)+i%2*T(i*2+1).

Cây chấm dứt ở độ sâu n, nơi nlà đầu vào. Điều này đạt được bằng cách giảm dần nvới mỗi bước xuống và dừng lại khi nó bằng 0.

Một chiến lược thay thế sẽ là chấm dứt các giá trị ivượt quá 2**n, thay vì theo dõi độ sâu. Tôi thấy điều này dài hơn một byte:

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
Ồ Không chỉ là một mẹo thực sự hay / thông minh, mà nó còn cực kỳ hiệu quả. +1, câu trả lời thực sự tốt đẹp!
DJMcMayhem

2
Đây [f]là một liên lạc thú vị, không thể nói rằng tôi đã thấy điều đó trước đây.
FryAmTheEggman

18

Thạch , 6 byte

Ḷ2*ẆS€

Điều này đủ điều kiện cho phần thưởng tưởng tượng .

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

Ḷ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
là một lý tưởng tích hợp sẵn cho thử thách này và nó được triển khai sao cho kết quả theo đúng thứ tự cho thử thách này.
Hoàn

Đây không phải là 12 byte (ít nhất là trong UTF-8) sao?
Gareth

1
@Gareth Có, nhưng Jelly cũng hỗ trợ một bộ ký tự byte đơn , chỉ chứa 256 ký hiệu mà nó hiểu.
Dennis

9

Toán học, 40 byte

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

Mỗi số trong danh sách mong muốn là sự khác biệt của hai lũy thừa 2, vì vậy chúng tôi chỉ cần tạo chúng theo thứ tự bằng cách sử dụng Tablevà sau đó làm phẳng danh sách. Tôi nghĩ rằng điều này kiếm được tiền thưởng tưởng tượng Stewie Griffin :)

Toán học, 35 byte

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

Một cổng của thuật toán Jelly của Dennis . Tôi không biết về Subsequencesđiều này trước đây! (Tôi cũng không thấy rằng dặm đã đăng câu trả lời này chính xác ... đi upvote nó!)


1
Lưu ý: Giải pháp này giống hệt với mã Mathicala của @mile , được đăng 5 giờ trước khi chỉnh sửa của @GregMartin. Tuy nhiên, trên mỗi sự đồng thuận meta , câu trả lời này vẫn còn hiệu lực.
JungHwan Min

Ugh, tôi đã không thấy rằng cảm ơn vì đã chỉ ra nó.
Greg Martin

8

JavaScript (ES6), 59 58 55 byte

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

Một chương trình đầy đủ đưa đầu vào thông qua một dấu nhắc và cảnh báo từng số liên tiếp. Điều này cũng đủ điều kiện cho phần thưởng tưởng tượng .

Kiểm tra đoạn

(Lưu ý: sử dụng console.logthay vì alert)


Đề xuất (sau khi phải kiểm tra "không hiển thị cửa sổ bật lên nữa"): Thay đổi thành console.log cho đoạn kiểm tra.
Tejas Kale

@TejasKale Ý kiến ​​hay, cảm ơn!
Sản xuất ETH

7

JavaScript (ES6), 55 51 byte

Trả về một danh sách các số nguyên được phân tách bằng dấu cách.

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

Tưởng tượng thân thiện.

Định dạng và nhận xét

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

Các trường hợp thử nghiệm



6

Toán học, 35 byte

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

5

Python 2 , 65 63 58 byte

lambda n:[(2<<k/n)-1<<k%n for k in range(n*n)if k/n+k%n<n]

Hãy thử trực tuyến!


1
Tôi mới dành một giờ để tìm ra công thức đó (2<<i)-1<<j... và bạn đã tìm ra nó. Lam tôt lăm! Ngoài ra, công việc tốt trong việc thoát khỏi phạm vi gấp đôi
TheNumberOne


4

Haskell, 47 byte

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

Ví dụ sử dụng: f 4-> [1,2,4,8,3,6,12,7,14,15]. Hãy thử trực tuyến! .

Cách thức hoạt động: đối với mỗi số btrong [1..n], hãy bắt đầu 2^b-1và liên tục nhân đôi giá trị và lấy n-b+1các phần tử từ danh sách này.





3

Tiện ích Bash + Unix, 51 byte

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

Hãy thử trực tuyến!

Đầu vào n được truyền trong một đối số.

Sử dụng seq để in tất cả các số có n hoặc ít hơn chữ số. (Đây là những số cơ bản 10, vì vậy có rất nhiều số phụ ở đây. Thật lãng phí và tốn thời gian, nhưng đây là mã golf!)

Cuộc gọi đến grep chỉ giữ những số đó bao gồm chính xác 1 số theo sau là 0.

Sau đó sử dụng sort -r để sắp xếp chúng theo thứ tự từ điển đảo ngược.

Cuối cùng, dc được đặt thành đầu vào cơ sở 2 - nó đẩy các số được sắp xếp trên một ngăn xếp và sau đó in ngăn xếp từ trên xuống dưới. (Điều này in mục cuối cùng được đẩy trước, v.v., đó là lý do tại sao tôi sử dụng sort -r thay vì chỉ sắp xếp.)

Đã sửa một lỗi: Tôi đã bỏ tùy chọn -f% .f thành seq, cần thiết cho số nguyên từ 1000000 trở đi. (Cảm ơn @TobySpeight đã chỉ ra rằng có một vấn đề.)


" Lãng phí và tốn thời gian " ... và thông minh ! Cảm ơn vì điều này - đó là một lời nhắc tốt để cố tình bỏ qua hiệu quả tính toán khi chơi golf. Điều đó thực sự khó khăn khi bạn dành phần còn lại của ngày để viết mã nhanh và rõ ràng ...
Toby Speight

Một số giá trị bị thiếu: dc<<<2i`seq $[10**7-1]|grep ^1*0*$|sort -r`f | wc -chỉ báo cáo 12 giá trị. Tôi nghĩ rằng bạn muốn grep ^1[01]*$thay thế.
Toby Speight

@TobySpeight Cảm ơn - có một lỗi mà tôi đã sửa. Vấn đề không nằm ở regex; vấn đề là seq yêu cầu một tùy chọn. (Tôi không chắc tại sao bạn chỉ nhận được 12 giá trị đầu ra - ngay cả phiên bản không chính xác đã tạo ra 21 giá trị đầu ra đúng với 28. Nếu bạn đang chạy nó trên TIO, nó có thể đã vượt quá giới hạn thời gian 1 phút của TIO .) Tôi đã thử nghiệm điều này trên cả Linux và OS X ngay bây giờ.
Spector Mitchell

1
Thật ra, tôi đã hiểu nhầm câu hỏi - từ quan trọng "liên tiếp" bằng cách nào đó đã đi thẳng qua tôi!
Toby Speight


2

Perl 6 , 38 byte

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

Làm thế nào nó hoạt động

->\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.

Tức là nó xây dựng các số như thế này:

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

Mật mã:


Perl 6 , 44 byte

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

Đây là cách tiếp cận đầu tiên của tôi trước khi tôi nghĩ đến giải pháp thay đổi bit (thực sự đơn giản hơn) ở trên.

Làm thế nào nó hoạt động

->\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.

Tức là nó xây dựng các số như thế này:

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

Haskell 59 46 byte

Tôi bắt đầu với f n=[0..n]>>= \b->take(n-b).iterate(*2).sum.map(2^)$[0..b]

từ câu trả lời của nimi ở trên đã đạt được cái nhìn sâu sắc sum.map(2^)$[0..x]có thể được cô đọng xuống2^x-1

Kết thúc với

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

[1..n] - danh sách với số bit liên tiếp chúng tôi muốn chuyển qua `

>> = - Được dịch hoàn toàn cho từng thành phần trong danh sách bên trái, chuyển nó vào hàm bên phải và nối tất cả các kết quả

\ x -> - Khai báo hàm lambda với một đối số

map xy - áp dụng hàm x cho tất cả các thành viên trong danh sách y

Trong trường hợp của chúng tôi x = (\ y-> 2 ^ y * (2 ^ x-1)) - một hàm lambda khác 2 ^ y * (2 ^ x-1)). Công thức này phát sinh từ phép nhân bằng cách thêm hai số 0 sang phải trong hệ nhị phân (ví dụ 0001 đến 0010). 2 ^ x - 1 là số bit chúng ta đang làm việc. vì vậy với 11 ta có 2 ^ 0 * 3 (tức là không dịch chuyển chút nào) == 0011, sau đó 2 ^ 1 * 3 = 0110 rồi 2 ^ 2 * 3 - 1100.

[0..nx] Xây dựng danh sách số lần chúng ta có thể dịch chuyển các bit. Nếu chúng tôi đang làm việc với một số 1 thì nhìn vào 0001, chúng tôi muốn thay đổi 3 lần (4-1). Nếu chúng tôi đang làm việc hai 11, chúng tôi muốn 4-2 và như vậy.


2

Python 3, 59 byte

Lưu ý: điều này được thực hiện độc lập với các giải pháp của ovsDennis , mặc dù nó rất giống với cả hai.

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

Làm thế nào nó hoạt động:

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.

Hãy thử trực tuyến!

Lời khuyên (cả mã hóa và tiền mặt) luôn được chào đón!


2

Japt , 11 byte

o@o!²ãXÄ mx

Kiểm tra nó trực tuyến!

Giải trình

Điều này sử dụng khá nhiều cách tiếp cận của @ 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 byte

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

lấy đầu vào từ STDIN; chạy với -R.

phá vỡ

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

Bạn có thể sử dụng $argný tưởng rất tốt. Sau khi đọc câu hỏi, tôi có một giải pháp với hơn 200 Byte
Jörg Hülsermann

@ JörgHülsermann Cảm ơn bạn đã nhắc nhở tôi về STDIN. Tôi chỉ thích hợp nhất các vòng lặp.
Tít

1

J , 19 byte

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

Điều này sử dụng cùng một phương pháp trong giải pháp của @Dennis .

Hãy thử trực tuyến!

Giải trình

(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

Python 3, 91 byte

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

Chương trình đầy đủ, với đầu ra được phân tách bằng dấu phẩy + dấu cách, như được chỉ định.

Giải trình:

Ký hiệu sao giải nén danh sách. Như vậy print(*[1,2,3])là giống như print(1,2,3). Truyền cho hàm int()tạo một chuỗi liên tiếp '1'.

-~bước tính b+1, nhưng bạn không phải bao quanh nó bằng dấu ngoặc khi nhân chuỗi.

Bitshift số nguyên được sản xuất tăng số lần. print()có đối số sep tùy chọn, chỉ định chuỗi cần đặt giữa mỗi mục trong danh sách chưa giải nén.


2
Bạn chỉ có thể in danh sách. Các định dạng đầu ra không quá nghiêm ngặt.
mbomb007

1

Java 7, 108 byte

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

Nhân đôi giá trị ban đầu miễn là kết quả nhỏ hơn 2^n. Sau đó, cập nhật giá trị ban đầu (initial_value * 2) + 1và bắt đầu lại từ đó cho đến khi cuối cùng nó đạt được (2^n)-1.

ví dụ 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

Hãy thử trực tuyến!


1

Ruby, 50 byte

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

Tôi đã thử một số cách tiếp cận "thông minh", nhưng dường như đây là cách ngắn nhất (theo đúng nghĩa đen)

Giải trình:

Mỗi lần lặp lại bắt đầu bằng 2 ^ n-1 và nhân với 2 cho đến khi đạt đến giới hạn trên. Không có gì lạ mắt, chỉ là toán cơ bản.


1

QBIC , 37 byte - tiền thưởng tưởng tượng = vẫn là 37 byte ...

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

Thật xấu hổ khi tôi chưa tích hợp while-wendvào QBIC ... Giải thích:

:       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

EDIT: QBIC hiện có hỗ trợ cho WHILE:

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

Đây chỉ là 26 byte! Đây là 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

R , 69 48 46 byte

n=scan();for(i in 1:n)print((2^i-1)*2^(i:n-i))

Mỗi số thập phân tương ứng với các i in 1..nsố trong hệ nhị phân được nhân với 2^(0..n-i), tức là n-i+1lũy thừa thứ nhất của hai (1, 2, 4, ...).

Hãy thử trực tuyến!


1

Stax , 9 byte

übg▓}╥é►╪

Chạy và gỡ lỗi trực tuyến!

Giải trình

Phần thưởng tưởng tượng nếu ai đó thực hiện việc này mà không cần bất kỳ hình thức chuyển đổi cơ sở nào (sử dụng toán học cũ đơn giản).

Vâng, không có chuyển đổi cơ sở ở đây.

Sử dụng phiên bản đã giải nén (10 byte) để giải thích.

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

Mẻ, 92 - 0 = 92 byte

@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(

Trừ 0 cho phần thưởng tưởng tượng của @ StewieGriffin.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.