2 ^ n-1'e kadar çıkış numaraları, "sıralı"


38

Girdi olarak n pozitif bir tamsayı alın ve aşağıdaki şekilde sıralanan n bitleri kullanılarak oluşturulabilecek ondalık sayıları çıkarın:

Önce sadece bir taneyle yaratılabilen tüm sayıları ve ikili göstergede 1kalanı 0(sıralanmış), ardından iki ardışık 1 , geri kalan 0, sonra üç ardışık ile oluşturulabilecek tüm sayıları listeleyin 1.

Bunun n = 4 için neye benzediğini görelim :

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

Yani, n = 4 için çıktı : 1, 2, 4, 8, 3, 6, 12, 7, 14, 15 (isteğe bağlı çıkış formatı).

Test durumları:

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

Bu , yani her dilde en kısa kod kazanıyor!

“Normal dillerdeki” çözümler için de iyi açıklamalar şiddetle tavsiye edilir !



2
@zeppelin İlk başta ben de öyle düşündüm, ama bu çok farklı.
ETHproductions

1
İlgili. (Hafifçe).
Martin Ender

6
Birisi bunu herhangi bir temel dönüşüm biçimi olmadan yaparsa (düz eski matematik kullanarak) hayali ikramiye.
Stewie Griffin,

Bu ikisi arasında bir karışım olduğunu yazdım Sanırım çevrimiçi deneyin!
PrincePolka

Yanıtlar:


38

Python , 53 bayt

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

Çevrimiçi deneyin!

Özyinelemeli işlev, sıralanan listeyi, bu ağaçtan aşağıya doğru bir ön sipariş yürüyüşü olarak oluşturur (örnekle n=4):

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

1 2 4 8 3 6 12 7 14 15

Sol dallar değeri ikiye katlar ve sağ dallar i->i*2+1sadece tekler için yapar ve var olur i. Yani, olmayan yapraklar için ön sipariş yürüyüş T(i)=[i]+T(i*2)+i%2*T(i*2+1).

Ağaç girişin nolduğu yerde derinlikte sona nermektedir. Bu, nher bir adım aşağı indirildiğinde ve 0 olduğunda durdurularak gerçekleştirilir.

Alternatif bir strateji , izleme derinliği yerine , iaşan değerleri sonlandırmak olacaktır 2**n. Bunu bir bayt daha uzun buldum:

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
Vay. Sadece bu gerçekten harika / zekice bir numara değil, aynı zamanda son derece etkili. +1, gerçekten güzel cevap!
DJMcMayhem

2
[f]Eğlenceli bir dokunuş, bunu daha önce gördüm diyemeyiz.
FryAmTheEggman

18

Jöle , 6 bayt

Ḷ2*ẆS€

Bu hayali ikramiye için uygundur .

Çevrimiçi deneyin!

Nasıl çalışır

Ḷ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
bu meydan okuma için ideal bir yerleşiktir ve sonuçların bu meydan okuma için doğru sırada olması için uygulanmaktadır. Aferin :-)
ETHproductions

Bu 12 bayt değil mi (en azından UTF-8’de)?
Gareth,

1
@Gareth Evet, ancak Jelly ayrıca anladığı tek 256 simgeyi içeren tek bir baytlık karakter setini de destekliyor .
Dennis,

9

Mathematica, 40 bayt

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

İstenilen listedeki her sayı, 2 gücünün 2 gücünün farkıdır, bu nedenle Tablelisteyi kullanarak sırayla sırayla üretiyoruz . Bence bu Stewie Griffin'in hayali bonusunu kazanıyor :)

Mathematica, 35 bayt

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

Dennis'in Jelly algoritmasının limanı . Bundan Subsequencesönce haberim yoktu ! (Ayrıca millerin bu kesin cevabı gönderdiğini görmedim ... hadi oyla!)


1
Not: Bu çözüm, @ GregMartin'in düzenlemesinden 5 saat önce yayınlanan @mile Mathematica koduyla aynıdır . Bununla birlikte, meta konsensüs başına , bu cevap hala geçerlidir.
JungHwan Min,

Bunu görmedim - işaret ettiğin için teşekkürler.
Greg Martin,

8

JavaScript (ES6), 59 58 55 bayt

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

İstemi kullanarak girdi alan ve her numarayı art arda uyaran tam bir program. Bu aynı zamanda hayali ikramiye için de geçerli .

Test pasajı

(Not: console.logyerine kullanır alert)


Öneri ("pop-up'ları artık gösterme" seçeneğini işaretlemeden sonra): Test snippet'i için console.log olarak değiştirin.
Tejas Kale

@TejasKale İyi fikir, teşekkürler!
ETHproductions

7

JavaScript (ES6), 55 51 bayt

Boşlukla ayrılmış bir tamsayı listesi döndürür.

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

Hayali bonus dostu.

Biçimlendi ve yorumlandı

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

Test durumları



6

Mathematica, 35 bayt

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

5

Python 2 , 65 63 58 bayt

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

Çevrimiçi deneyin!


1
Sadece bir formülü bulmak için bir saat harcadım (2<<i)-1<<j... ve sen bunu zaten anladın. İyi iş! Ayrıca, çift aralıklardan kurtulmak için iyi bir iş
TheNumberOne


4

Haskell, 47 bayt

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

Kullanım örneği: f 4-> [1,2,4,8,3,6,12,7,14,15]. Çevrimiçi deneyin! .

Nasıl çalışır: içindeki her sayı biçin [1..n], 2^b-1değeri ile tekrar tekrar başlayın ve n-b+1bu listeden öğeleri alın.



4

Groovy, 90 89 bayt

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

İkili dönüşüm groovy çok aptalca.

-1 Gurupad Mamadapur'a teşekkürler


3
28 bayt ikili dönüşüm kazan, çok acı.
Magic Octopus Urn

1
{(1..<2**it)...bir bayt kaydeder.
Gurupad Mamadapur


3

Bash + Unix yardımcı programları, 51 bayt

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

Çevrimiçi deneyin!

N girişi bir argümanda iletilir.

Tüm sayıları n veya daha az rakamla yazdırmak için sıra kullanın. (Bunlar baz-10 sayılar, bu yüzden burada çok fazladan fazla sayılar var. Bu israf ve zaman alıcı, ancak bu kod golf!)

Grep çağrısı, yalnızca tam olarak 1s ve ardından 0'lardan oluşan sayıları tutar.

Daha sonra bunları ters sözlükte sıralamak için sort -r komutunu kullanın.

Son olarak, dc taban 2 girişine ayarlanır - bir yığındaki sıralanmış sayıları iter ve sonra yığını yukarıdan aşağıya yazdırır. (Bu, ilk basılan son öğeyi vb. Yazdırır, bu yüzden sadece sıralama yerine sort -r kullanıyorum.)

Bir hata düzeltildi: -f% .f seçeneğini 1000000'den itibaren tamsayı sayıları için gerekli olan seq seçeneğine atladım. (Bir sorun olduğunu belirttiği için @TobySpeight'a teşekkürler.)


" Zararlı ve zaman alıcı " ... ve zekice ! Bunun için teşekkürler - golf oynarken hesaplama verimliliğini bilerek yoksaymak iyi bir hatırlatıcı. Günün geri kalanını hızlı ve net kod yazarak geçirirken bu gerçekten zor ...
Toby Speight

Bazı değerler eksik: dc<<<2i`seq $[10**7-1]|grep ^1*0*$|sort -r`f | wc -sadece 12 değer bildirir. Onun grep ^1[01]*$yerine istediğini düşünüyorum .
Toby Speight

@TobySpeight Teşekkürler - düzelttiğim bir hata vardı. Sorun regex ile değildi; Mesele şu ki, seq bir seçenek gerektiriyordu. (Neden sadece 12 çıkış değeri aldığınızdan emin değilim - yanlış sürüm bile doğru 28 sonuçtan 21 çıkış değeri üretti. Bunu TIO'da kullanıyorsanız, TIO'nun 1 dakikalık zaman sınırını aşmış olabilir. .) Bunu şimdi hem Linux hem de OS X üzerinde test ettim.
Mitchell Spector

1
Aslında soruyu yanlış anladım - “ardışık” önemli sözcüğü bir şekilde dümdüz üstümden geçti!
Toby Speight


2

Perl 6 , 38 bayt

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

Nasıl çalışır

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

Yani şöyle sayıları oluşturur:

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

Kod:


Perl 6 , 44 bayt

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

Yukarıdaki (aslında daha basit) bit kaydırma çözümünü düşünmeden önce bu benim ilk yaklaşımımdı.

Nasıl çalışır

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

Yani şöyle sayıları oluşturur:

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 Bayt

İle başladım f n=[0..n]>>= \b->take(n-b).iterate(*2).sum.map(2^)$[0..b]

nimi'nin yukarıdaki cevabından sum.map(2^)$[0..x], aşağıdakilere yoğunlaşabilecek bir kavrayış kazandı2^x-1

İle biten

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

[1..n] - arasında geçiş yapmak istediğimiz ardışık bit sayısı ile liste

>> = - soldaki listedeki her öğe için iyice çevrilmiş, onu sağdaki işleve aktarın ve tüm sonuçları birleştirin

\ x -> - Bir argümanla lambda fonksiyon bildirimi

map xy - x fonksiyonunu y listesinin tüm üyelerine uygular.

Bizim durumumuzda x = (\ y-> 2 ^ y * (2 ^ x-1)) - başka bir lambda işlevi 2 ^ y * (2 ^ x-1)). Bu formül iki ile çarpma işleminden doğar ve ikili olarak sıfıra sıfır ekler (örnek 0001 ila 0010). 2 ^ x - 1 birlikte çalıştığımız bit sayısıdır. 11 için 2 ^ 0 * 3 (yani hiç kayma yok) == 0011, sonra 2 ^ 1 * 3 = 0110 sonra 2 ^ 2 * 3 - 1100.

[0..nx] Bitleri kaç kez değiştirebileceğimizin listesini oluşturur. Eğer tek bir 1 ile çalışıyorsak, o zaman 0001 'e bakıyoruz, 3 kez (4-1) geçmek istiyoruz. Eğer iki 11'de çalışıyorsak 4-2 vb. İstiyoruz.


2

Python 3, 59 bayt

Not: Bu, her ikisine de çok benzese de , ovs ve Dennis'in çözümlerinden bağımsız olarak yapıldı .

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

Nasıl çalışır:

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.

Çevrimiçi deneyin!

İpuçları (hem kodlama hem de nakit) her zaman beklerim!


2

Japt , 11 bayt

o@o!²ãXÄ mx

Çevrimiçi test edin!

açıklama

Bu hemen hemen Dennis'in yaklaşımını kullanıyor:

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 bayt

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

STDIN'den girdi alır; ile koş -R.

Yıkmak

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Çok iyi bir fikir kullanabilirsiniz . Soruyu okuduktan sonra kafamda 200'den fazla Byte ile bir çözüme
sahibim

@ JörgHülsermann STDIN'i hatırlattığın için teşekkür ederim. Sadece döngüleri birleştirmeyi seviyorum.
Titus

1

J , 19 bayt

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

Bu, @Dennis ' çözümünde aynı yöntemi kullanır .

Çevrimiçi deneyin!

açıklama

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

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

Tam program, belirtildiği gibi virgül + boşlukla ayrılmış çıktı.

Açıklama:

Yıldız gösterimi listeleri açar. Yani print(*[1,2,3])aynı print(1,2,3). Yapıcıya int()ardışık '1'ler dizesini iletin.

-~bolarak değerlendirir b+1, ancak bir dize çarparken onu parantez içine almak zorunda değilsiniz.

Bitshift, üretilen tamsayıyı defalarca arttırır. print()paketlenmemiş bir listedeki her bir öğenin arasına yerleştirilecek dizeyi belirten isteğe bağlı sep argümanına sahiptir.


2
Sadece listeyi yazdırabilirsiniz. Çıktı formatı çok katı değil.
mbomb007

1

Java 7, 108 bayt

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

Sonuç, değerden küçük olduğu sürece başlangıç ​​değerini iki katına çıkarır 2^n. Daha sonra, başlangıç ​​değerini günceller ve (initial_value * 2) + 1sonunda ulaşana kadar oradan tekrar başlar (2^n)-1.

örneğin 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

Çevrimiçi deneyin!


1

Ruby, 50 bayt

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

Bazı "akıllı" yaklaşımları denedim, ancak bu en kısa gibi görünüyor (kelimenin tam anlamıyla talimatları izleyin)

Açıklama:

Her yineleme 2 ^ n-1 ile başlar ve üst sınıra ulaşana kadar 2 ile çarpılır. Hiçbir şey fantezi, sadece temel matematik.


1

QBIC , 37 bayt - hayali bonus = hala 37 bayt ...

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

Utanç while-wendhenüz QBIC içine inşa etmedim ... Açıklama:

:       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 şimdi için destek var WHILE:

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

Bu sadece 26 bayttır! İşte 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 bayt

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

i in 1..nİkili sistemdekilere tekabül eden her ondalık sayı 2^(0..n-i), yani ikilik ilk n-i+1güçlerle çarpılır (1, 2, 4, ...).

Çevrimiçi deneyin!


1

Stax , 9 bayt

übg▓}╥é►╪

Çevrimiçi çalıştırın ve hata ayıklayın!

açıklama

Birisi bunu herhangi bir temel dönüşüm biçimi olmadan yaparsa (düz eski matematik kullanarak) hayali ikramiye.

Eh, burada temel dönüşüm yoktur.

Açıklamak için paketlenmemiş sürümünü (10 bayt) kullanır.

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

Toplu İş, 92 - 0 = 92 bayt

@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'nin hayali bonusu için 0 çıkartılması.

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.