最大2 ^ n-1の出力番号、「ソート済み」


38

入力として正の整数nを取り、nビットを使用して作成できる10進数(一部)を出力し、次の順序で並べます。

最初に1つだけで作成できるすべての番号をリストし、1残り0をバイナリ表現(ソート済み)でリストし、次に2つの連続 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
何らかの形式の基本変換なしでこれを行うと、想像上のボーナスが得られます(単純な古い数学を使用)。
スティーヴィーグリフィン

これを書きました。これは2つをミックスしたものです。オンラインで試してみてください。
PrincePolka

回答:


38

Python、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

左の分岐は値を2倍にし、右の分岐は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では)。
ガレス

1
@Garethはい。ただし、Jellyは、1バイト文字セットもサポートしています。これには、理解できる256個のシンボルのみが含まれています。
デニス

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

DennisのJellyアルゴリズムの移植版。Subsequencesこの前は知りませんでした!(マイルがこの正確な答えを投稿したことも知りませんでした...それを支持してください!)


1
注:この解決策は@GregMartinの編集の5時間前に投稿された@mileのMathematicaコードと同じです。ただし、メタコンセンサスごとに、この答えはまだ有効です。
ジョンファンミン

うーん、私はそれを見なかった-それを指摘してくれてありがとう。
グレッグマーティン

8

JavaScript(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に変更します。
テハスケール

@TejasKale良いアイデア、ありがとう!
ETHproductions

7

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

テストケース






4

Haskell、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

Groovy、90 89バイト

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

バイナリ変換は、グルーヴィーにとても馬鹿です。

-1 Gurupad Mamadapurに感謝


3
28バイトのバイナリ変換ボイラープレート、とても痛い。
魔法のタコ

1
{(1..<2**it)...バイトを保存します。
グルパッドママダプール


3

Bash + Unixユーティリティ、51バイト

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

オンラインでお試しください!

入力nは引数に渡されます。

seqを使用して、すべての数字をn桁以下で印刷します。(これらは10を基数とするため、ここには余分な番号がたくさんあります。無駄で時間がかかりますが、これはコードゴルフです!)

grepの呼び出しは、1の後に0が続く数字のみを保持します。

次に、sort -rを使用して、これらを逆の辞書式順序でソートします。

最後に、dcは基数2の入力に設定されます。ソートされた数値をスタックにプッシュし、スタックを上から下に印刷します。(これは最初にプッシュされた最後のアイテムなどを出力します。そのため、単にsortではなくsort -rを使用しています。)

バグを修正しました。1000000以降の整数カウントに必要な-f%.fオプションをseqに省略していました。(問題があったことを指摘してくれた@TobySpeightに感謝します。)


無駄で時間がかかる」...そして賢い!これに感謝します-ゴルフをするとき、計算効率を故意に無視することは良い思い出です。あなたが迅速かつ明確なコードを書いて、あなたの日の残りの部分を過ごすときには...本当に難しい
トビースパイツ

一部の値が欠落しています:dc<<<2i`seq $[10**7-1]|grep ^1*0*$|sort -r`f | wc -12の値のみを報告します。grep ^1[01]*$代わりに欲しいと思います。
トビー・スペイト

@TobySpeightありがとう。バグがありましたが、修正しました。問題は正規表現にありませんでした。問題は、seqにオプションが必要だったことです。(しかし、なぜ12の出力値しか得られなかったのかはわかりません-間違ったバージョンでも正しい28の21の出力値が生成されました。これをTIOで実行している場合、TIOの1分の制限時間を超えている可能性があります。)LinuxとOS Xの両方でこれをテストしました。
ミッチェルスペクター

1
実際、私はこの質問を誤解しました-そこにある「連続する」という重要な言葉は、どういうわけか私を通り過ぎました!
トビースパイト


2

Perl 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

コード:


Perl 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

Haskell 59 46バイト

私はで始めました f n=[0..n]>>= \b->take(n-b).iterate(*2).sum.map(2^)$[0..b]

上記のnimiの回答から、次の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-> -1つの引数を持つラムダ関数宣言

マップxy-関数xをリストyのすべてのメンバーに適用します

この場合、x = (\ y-> 2 ^ y *(2 ^ x-1)) -別のラムダ関数2 ^ y *(2 ^ x-1))。この式は、2で右にゼロを追加する2の乗算(例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)。2つの11を使用している場合、4-2などが必要です。


2

Python 3、59バイト

注:これはovsおよびDennisのソリューションとは無関係に作成されましたが、両方に非常に似ています。

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ülsermannSTDINを思い出させてくれてありがとう。ループのマージが大好きです。
タイタス

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

Python 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

Java 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倍にし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-wendQBICにまだ組み込まれていない...

:       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

スタックス、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.