ビット、ニブルまたはバイト?


45

この挑戦に触発された

範囲内の整数を指定すると、範囲0 <= n < 2**64外に収まる最小サイズのコンテナを出力します

  • ビット:1
  • ニブル:4
  • バイト:8
  • 短い:16
  • int:32
  • 長い:64

テストケース:

0 -> 1
1 -> 1
2 -> 4
15 -> 4
16 -> 8
123 -> 8
260 -> 16
131313 -> 32
34359750709 -> 64

これはであるため、バイト単位の最短回答が優先されます。


10
場合、これはかなり容易になり2、出力があまりにもだった...
ETHproductions

1
@ETHproductions悲しいかな、そうではありません(それを行うアルゴリズムを書くのに長い時間がかかりました)
Blue

私は問題を理解したいです。...待ってください。必要なのは、次の基本構造に丸められた、数値を含めるために必要なビットの量だけですか?
z0rbergの

2
ありがとう!コメントを書いて編集するのが遅すぎたときに気づきました。私は、私が話にゴム製のアヒルを必要と推測する...
z0rbergの

2
@Danielの回答は、他の質問に対してまったく異なるアプローチを取ります。「触発された」と言うとき、それは「重複」を意味するものではありません。この質問に有効となるように回答を簡単に変更することはできませんでした
Blue

回答:



22

Python、39バイト

f=lambda n:4**(n>1)*(n<16)or 2*f(n**.5)

2の出力を回避するための特別なケースを使用して、n以下になるために平方根を取る必要がある回数をカウントします16

2が含まれていれば、できます

f=lambda n:n<2or 2*f(n**.5)

1の場合はTrue


41バイト:

f=lambda n,i=1:i*(2**i>n)or f(n,i<<1+i%2)

iまで繰り返し指数を2倍にし2**i>nます。が奇数の場合、追加のビットをシフトするi=1ことi=4により、からをスキップしiます。

Alt 45バイト:

f=lambda n,i=4:4**(n>1)*(2**i>n)or 2*f(n,i*2)

7
問題に対する非常に多くの解決策を思い付くことができる方法を私を驚かせることは決してありません。基本的にプログラマーとして、私は問題の解決策を見つけ、それが機能するまでそれを扱うことを学びました。ゴルフについて学ぶべきことがまだたくさんあると思います!尊敬。
エルペドロ16

@ xnor、10または1の平方根が常に1(無限再帰性or 2*f(n**.5))の場合、最初の回答はどのように出力されますか?
dfernan 16

2
@dfernan or前の部分が偽(ゼロ)に評価された場合にのみ、後の部分が評価されると思います。n = 0の場合、およびn = 1の場合、でn>1評価されますFalse。これは、数値式ではゼロとして扱われ、でn<16評価されますTrue。これは、数値式で1として扱われます。だから、4**(n>1)*(n<16)1です
センモウヒラムシは

1
@trichoplax、そうです。説明ありがとう。
dfernan

12

J、19バイト

右側の数字を取得し、コンテナサイズを吐き出すモナド動詞。同等の書き方がいくつかあるので、両方を含めました。

2^2(>.+1=>.)@^.#@#:
2^s+1=s=.2>.@^.#@#:

爆発の説明:

2^2(>.+1=>.)@^.#@#: NB. takes one argument on the right...
                 #: NB. write it in binary
               #@   NB. length (i.e. how many bits did that take?)
  2          ^.     NB. log base 2 of that
   (>.     )@       NB. ceiling
      +1=>.         NB. +1 if needed (since no container is two bits wide)
2^                  NB. base 2 exponential

クールなのは、Jで2を2^.底とする対数をとる2つの異なる方法があることです。1つ目は、数値対数である明らかなものです。2番目は#@#:、「base-2表現の長さ」として読み取ることができます。これは、one-plus-floor-of-log-base-2とほぼ同じです#:0が、1要素のlist 0である点が異なります。これは1+2<.@^.1&>.8バイトのビートです。

REPLで使用中:

   f =: 2^2(>.+1=>.)@^.#@#:
   f 131313
32
   f 34359750709
64
   (,.f"0) 0 1 2 15 16 123 260
  0  1
  1  1
  2  4
 15  4
 16  8
123  8
260 16

古い、非常に巧妙な20バイトのソリューション。

2&^.(>.+1=>.&.)@#@#: NB. takes one argument on the right...
                #@#: NB. how many bits
2&^.                 NB. log base 2 of that
     >.              NB. ceiling
       +1=>.         NB. +1 if needed (since no container is two bits wide)
    (       &.)      NB. undo log base 2

9

Python、53 50 49バイト

lambda n:[w for w in[1,4,8,16,32,64]if n<2**w][0]

1
lambda n:[w for w in[1,4,8,16,32,64]if n<2**w][0]1バイト短い
ブルー

似たようなものを投稿しようとしていた。+1
ElPedro 16

8

Mathematica、44 39 38バイト

5バイトの@orlpと1バイトの@MartinEnderに感謝します。

FirstCase[{1,4,8,16,32,64},x_/;2^x>#]&

{1, 4, 8, 16, 32, 64}2 ^ numberが入力よりも大きいリスト内の最初の要素を検索します。


8

ピップ、19バイト

(a<2**_FI2**,7RM2i)

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

使い方

                     a is 1st cmdline arg, i is 0 (implicit)
         2**,7       Construct powers of 2 from 0 to 6 [1 2 4 8 16 32 64]
              RM2    Remove 2
       FI            Filter for elements for which:
 a<2**_                a is less than 2 to that element
(                i)  Get 0th item of resulting list and autoprint

7

JavaScript(ES7)、35バイト

n=>[1,4,8,16,32,64].find(b=>2**b>n)

2
などの再帰バージョンf=(n,b=1)=>2**b>n&&b-2?b:f(n,b*2)は、少し短くする必要があります。
アーナルド

6

Mathematica、46 43 38バイト

3バイトを節約してくれたJungHwan MinとMartin Enderに感謝します! ngenisisに5バイトの大きな節約をありがとう!

2^⌈Log2@BitLength@#⌉/.{2->4,0->1}&

入力として非負の整数を取り、正の整数を返す名前のない関数。BitLength@#入力のビット数を計算してから、2^⌈Log2@...⌉少なくともビット数と同じ大きさの最小の2のべき乗を計算します。最後に、/.{2->4,0->1}bitとnybbleの間に「ニブリ」がないという特殊なケースを処理し、奇妙なinputに対する答えも修正します0


2
BitLength@#代わりにを使用して3バイトを節約します⌊1+Log2@#⌋。そして、代わりに置き換えること1、あなた置き換えることができ0、別の2つのバイトを保存し、あなたが最初のために結ばれています。
ngenisis

1
これは実際には完全にで行うことができBitLengthます。参照してください私の答えを
ngenisis

4

ジュリア、40バイト

n->filter(x->n<big(2)^x,[1;2.^(2:6)])[1]

これは、2を除く0から6までの2のべき乗の配列を生成し、2 xが入力よりも大きくなるような要素xのみにフィルタリングする無名関数です。最初のそのような要素が答えです。残念ながら、x = 64でのオーバーフローを避けるために2をa にプロモートする必要があります。BigInt

これは、実際にはorlpのPythonの回答に非常に似ていますが、このアプローチを作成する前にそれを見ませんでした。

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


4

Perl 6、30バイト

{first 1+<*>$_,1,4,8,16,32,64}

+<は、Perl 6の左ビットシフト演算子であり、他の多くの言語で呼び出されます<<


4

Haskell、31バイト

f n=[2^i|i<-0:[2..],2^2^i>n]!!0

32バイトの代替:

f n|n<2=1|n<16=4|1>0=2*f(sqrt n)

2

Java、143バイト。

int f(long a){a=Long.toBinaryString(a).length();if(a<2)return 1;if(a<5)return 4;if(a<9)return 8;if(a<17)return 16;if(a<33)return 32;return 64;}

1
私はこれを短くすることができることを知っています、私はコンピューターにいるときにそれをします
パベル

2
50バイト節約: return a<2?1:a<5?4:a<9?8:a<17?16:a<33?32:64;
Mindwin

@Mindwin私は知っていますが、私は旅行中で、しばらくの間コンピューターにアクセスできません。私はそれに近づきます。
パベル

スコアはそれを... 愛のバイトにしますか?
エンジニアトースト


2

ルビー、39 36バイト

->n{2**[0,*2..6].find{|p|2**2**p>n}}

ゴルフを手伝ってくれたGBに感謝


括弧なしでも動作するはずです。また、リストは0,2,3,4,5,6で、1 << 2 ** pを使用できます。
GB

... 0、* 2..6を使用できるためです。
GB

2

Java 8、65 55バイト

これはを受け取り、longを返すラムダ式intです。これまでにJavaでゴルフをしたことがないため、これは簡単に解決できるはずです。

x->{int i=1;while(Math.pow(2,i)<=x)i<<=1+i%2;return i;}

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


以下のために47バイト、我々は持っている可能性があり:

x->{int i=1;while(1L<<i<=x)i<<=1+i%2;return i;}

ただし、1L<<i32より大きい戻り値ではオーバーフローが発生するため、最終テストケースでは失敗します。


1
このリターン4でテストしたときに16、また8を返すことになっている時にすることができますまだゴルフの周りにブラケットを除去することにより、このソリューションi<<=1+i%2;のないことから{}S、しばらくますループだけ次の行を実行
KritixiのLithos

申し訳ありませんが、私のJavaのなくなっさび... - @KritixiLithosは修正されなければならない
FlipTack

2

Mathematica、30バイト

2^(f=BitLength)[f@#-1]/. 2->4&

説明:

してみましょうN非負整数の集合とします。上の2つの関数を定義しNBitLengthそしてNextPower次のように:

BitLength(n) := min {x in N : 2^x - 1 >= n}
NextPower(n) := 2^(min {x in N : 2^x >= n})

このソリューションではNextPower(BitLength(n))、整数を指定して計算しn >= 0ます。ためにn > 0、我々はそれを見ることができますNextPower(n) = 2^BitLength(n-1)ので、NextPower(BitLength(n)) = 2^BitLength(BitLength(n)-1)

Mathematica BitLengthビルトインはのために与えた定義に同意しn >= 0ます。のためn < 0BitLength[n] == BitLength[BitNot[n]] == BitLength[-1-n]、そうBitLength[-1] == BitLength[0] == 0。したがって、の望ましい答えが得1られn==0ます。

我々はビットからニブルにまっすぐ進みますので、我々は答え交換する必要2とします4


1
うまく構築されました!(スペースが必要なのは残念です。)
グレッグマーティン

2

bash、49バイト 48バイト

for((y=1;$[y==2|$1>=1<<y];$[y*=2])){ :;};echo $y

または

for((y=1;$[y==2|$1>=1<<y];)){ y=$[y*2];};echo $y

スクリプトに保存し、テストする数値を引数として渡します。

編集:置換|| |では、引数が常に0または1であるため機能します。

注:これは、bashのバージョンが処理できる最大の正の整数までの整数で機能します。時間があれば、32ビットの符号付き算術を使用するbashのバージョンで最大2 ^ 64-1まで動作するように修正します。

それまでの間、任意の大きな数値(任意のbashバージョン)で機能する64バイトのソリューションを次に示します。

for((x=`dc<<<2o$1n|wc -c`;$[x==2||x&(x-1)];$[x++])){ :;};echo $x

2

スタック、34 30バイト

@n 1 2 6|>2\^,:n 2 log>keep 0#

または

{!1 2 6|>2\^,:n 2 log>keep 0#}

最初は、TOSで入力を受け取り、TOSで出力を残します。2番目は関数です。ここで試してみてください!

説明

@n 1 2 6|>2\^,:n 2 log>keep 0#
@n                               set TOS to `n`
   1 2 6|>2\^,                   equiv. [1, ...2 ** range(2, 6)]
              :                  duplicate it
               n                 push `n`
                 2 log           log base-2
                      >          element-wise `>`
                       keep      keep only truthy values
                            0#   yield the first element

replで動作する例を次に示します

> 8    (* input *)
(8)
> @n 1 2 6|>2\^,:n 2 log>keep 0#    (* function *)
(4)
>    (* output *)
(4)

テストケース

> {!1 2 6|>2\^,:n 2 log>keep 0#} @:f
()
> (0 1 2 15 16 123 260 131313 34359750709) $f map
((1 1 4 4 8 8 16 32 64))
> 

または、完全なプログラムとして:

{!1 2 6|>2\^,:n 2 log>keep 0#} @:f

(0 1 2 15 16 123 260 131313 34359750709) $f map

out

2

ラケット45バイト

(findf(λ(x)(>(expt 2 x)m))'(1 4 8 16 32 64))

ゴルフをしていない:

(define (f m)
  (findf (λ (x) (> (expt 2 x) m))          ; find first function
         '(1 4 8 16 32 64)))

他のバージョン:

(define (f1 m)
  (for/last ((i '(1 4 8 16 32 64))         ; using for loop, taking last item
             #:final (> (expt 2 i) m))     ; no further loops if this is true
    i))

そして、文字列の長さを使用して:

(define (f2 m)
  (for/last
      ((i '(1 4 8 16 32 64))
       #:final (<= (string-length
                    (number->string m 2))  ; convert number to binary string
                   i))
    i))

テスト:

(f 0)
(f 1)
(f 2)
(f 15)
(f 16)
(f 123)
(f 260)
(f 131313)
(f 34359750709)

出力:

1
1
4
4
8
8
16
32
64

1

オクターブ、40 36 31 29バイト

シンプルな匿名関数。入力値は整数であると想定されています-最後の警告を参照してください。

@(a)(b=2.^[0 2:6])(a<2.^b)(1)

コードは次のように機能します。

  • 最初に、許可されたビット長(1,4,8,16,32,64)の配列が作成され、に保存されbます。

  • 次にa、各コンテナの最大サイズと比較して、入力数を保存するのに必要なビット数を見つけますbどれが十分に大きいかを確認すること。

  • 次に、結果のインデックスベクトルを使用して、コンテナサイズをb再度抽出します。

  • 最後に、結果の配列の最初の要素を取得します。これは、可能な限り最小のコンテナになります。

こちらからオンライン試すことができます

次のコードを実行してから、実行しますans(x)


これに関する唯一の注意点は、定数にデフォルトで倍精度が使用されることです。つまり、2 ^ 64未満の倍精度浮動小数点数で表現可能な最大値までの数値でのみ動作します。

これは、関数に提供される数値がdoubleではなく整数であることを確認することで修正できます。これは、たとえば次の関数を呼び出すことで実現できますans(uint64(x))


1

PHP、49 46 44バイト

echo(2**ceil(log(log(1+$argn,2),2))-2?:2)+2;

次のように実行します:

echo 16 | php -R 'echo(2**ceil(log(log(1+$argv[1],2),2))-2?:2)+2;';echo

説明

echo                       # Output the result of the expression
  (
    2**                    # 2 to the power
      ceil(log(            # The ceiling of the power of 2 of bitsize
        log(1+$argn,2),    # Number of bits needed
        2
      ))
      - 2 ?:               # Subtract 2 (will be added back again)
      2;                   # If that results in 0, result in 2 (+2=4).
  ) + 2                    # Add 2.

微調整

  • を取り除くことで3バイトを節約しました $r=割り当てました
  • 使用して2つのバイトを保存-Rするために$argn利用可能

1

CJam、18バイト

2ri2b,2mLm]_({)}|#

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

説明

2                   Push 2
 ri                 Read an integer from input
   2b,              Get the length of its binary representation
      2mLm]         Take the ceiling of the base-2 log of the length
           _(       Duplicate it and decrement it
             {)}|   Pop the top element, if it's 0, increment the next element
                     Effectively, if ceil(log2(input)) was 1, it's incremented to 2,
                     otherwise it stays the same.
                 #  Raise 2 to that power

0

C、71 52バイト

i;f(long long n){for(i=1;n>>i;i*=2);return i-2?i:4;}

(1<<15)+1の署名された動作のために、これ以上の入力がこれを壊さないでしょうlong longか?あなたが本当に望むタイプは、それがまだ敗者でuint64_tある必要が#include <stdint.h>あるものです!ヘッダーはcのゴルフの悩みの種です。unsigned long long
dmckee 16

@dmckeeそれが壊れる可能性があると思いますが、少なくとも私のコンピューターでは動作するようです。動作しない例を見つけていません。unsigned long longまたはを使用することを考えましたuint64_tが、うまくいくように見えるので、一緒long longに行きました。
Steadybox 16

0

QBIC、27バイト

:~a<2|_Xq]{~a<2^t|_Xt\t=t*2

説明

:        Get cmd line parameter N, call it 'a'
~a<2     IF 'a' is 0 or 1 (edge case)
|_Xq]    THEN quit, printing 1 ('q' is auto-initialised to 1). ']' is END-IF
{        DO - infinite loop
    2^t  't' is our current number of bits, QBIC sets t=4 at the start of the program.
         2^t gives the maximum number storable in t bytes.
 ~a<     IF the input fits within that number,
|_Xt     THEN quit printing this 't'
\t=t*2   ELSE jump to the next bracket (which are spaced a factor 2 apart, from 4 up)
         DO-loop is auto-closed by QBIC.


0

PHP、43バイト

for(;1<<2**$i++<=$argn;);echo 2**$i-=$i!=2;

で実行しecho <number> | php -R '<code>'ます。

入力よりも大きくなる$iまでループし2**(2**$i)ます。(微調整:括弧を削除する<<代わりに**
ループの後、$ iは高すぎます。それは、出力を計算する前にデクリメントを取得します
が、ないために- $i==2

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.