Biraz, bir nibble veya bayt?


45

Bu mücadeleden ilham alındı

Aralıktaki bir tamsayı göz önüne alındığında 0 <= n < 2**64, sığabileceği minimum boyutlu kabı çıktı

  • bit: 1
  • pürüz: 4
  • bayt: 8
  • kısa: 16
  • int: 32
  • uzun: 64

testcases:

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

Bu , yani bayt cinsinden en kısa cevap kazanır.


10
Bu da 2bir çıktı olsaydı çok daha kolay olurdu ...
ETHproductions

1
@ETHproductions Ne yazık ki olurdu, öyle değil ((bunu yapan bir algoritma yazmam çok uzun sürdü)
Blue

Keşke sorunu anlayabilseydim. ... bekle, tüm istediği bir sonraki temel yapıya yuvarlanan sayıyı içermesi gereken bit miktarı mı?
z0rberg'in

2
Teşekkürler! Yorumu yazdığımda ve çok geç düzenlediğimde anladım. Sanırım konuşmak için lastik bir ördeğe ihtiyacım var ...
z0rberg

2
@ Daniel buradaki cevaplar diğer soruya tamamen farklı bir yaklaşım getiriyor. 'İlham' derken, 'kopya' anlamına gelmez. Bu soru için geçerli olacak hiçbir cevap önemsizce değiştirilemez
Blue

Yanıtlar:


3

05AB1E , 10 bayt

bg.²îD1Q+o

açıklama

bg         Push the length of the binary representation of input without leading zeros
  .²î      Push x = ceil(log2(length))
     D1Q+  Add 1 if x == 1 or add 0 otherwise
         o Push pow(2,x) and implicitly display it

Çevrimiçi deneyin!


22

Python, 39 bayt

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

İçin bir karekökünü almalıdır kaç kez Sayımlar naltında olması 162 önlemek çıkışlarına bazı özel-gövde ile.

2 dahil olsaydı yapabilirdik

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

1 için True ile.


41 bayt:

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

Üste ikadar üssü ikiye katlar 2**i>n. Den atlar i=1için i=4, ilave bir bit kaydırarak igarip.

Alt 45 bayt:

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

7
Bir problem için nasıl bu kadar çok çözüm bulabileceğimi şaşırtmaktan asla vazgeçmiyor. Temelde bir programcı olarak, bir soruna bir çözüm bulmayı ve çalışana kadar onunla çalışmayı öğrendim. Sanırım golf hakkında daha çok şey öğreneceğim var! Saygı.
ElPedro

@ xnor, 10 veya 1'in karekökü her zaman 1 olduğunda ilk yanıtınız nasıl çıktı (sonsuz özyinelemede or 2*f(n**.5))?
dfernan

2
@ ddfernan Bundan sonraki bölümün oryalnızca önceki bölümün sahte bir şeyle (sıfır) değerlendirilmesi durumunda değerlendirildiğine inanıyorum . N = 0 ve n = 1 n>1için False, sayısal ifadede sıfır olarak n<16değerlendirilen True, sayısal ifadede tek olarak değerlendirilen değerlendirilir . Yani 4**(n>1)*(n<16)1
trichoplax

1
@trichoplax, bu doğru. Açıklama için teşekkürler.
dfernan

12

J, 19 bayt

Sağdaki numarayı alarak ve konteyner boyutunu tüküren Monadic fiil. Bunu yazmanın birkaç eşdeğer yolu var, o yüzden ikisini de ekledim.

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

Patlama ile açıklanacak:

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

Asıl sorun J'de log tabanı 2'yi almanın iki farklı yolunu görmemiz. Bunlardan ilki, 2^.sayısal bir logaritma olduğu açık . İkincisi, #@#:"taban-2 gösteriminin uzunluğu" olarak okunabilir. Bu neredeyse bir artı log-base-log-base-2'ye eşdeğerdir, bunun dışında tam olarak istediğimiz #:0tek öğeli listedir 0. Bu 1+2<.@^.1&>.8 bayt atar .

REPL'de kullanımda:

   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

Eski, aşırı akıllı 20 baytlık çözüm.

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 bayt

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]bir bayt daha kısadır
Blue

Sadece benzer bir şey göndermek üzereydi. +1
ElPedro

8

Mathematica, 44 39 38 bayt

5 bayt için @orlp ve 1 bayt için @ Martininnder teşekkürler.

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

Listedeki ilk öğeyi bulur, {1, 4, 8, 16, 32, 64}öyle ki 2 ^ sayı girişten büyük.


8

Pip , 19 bayt

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

Çevrimiçi deneyin!

Nasıl çalışır

                     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 bayt

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

2
Bir özyinelemeli versiyonu f=(n,b=1)=>2**b>n&&b-2?b:f(n,b*2)biraz daha kısa olmalıdır.
Arnauld,

6

Mathematica, 46 43 38 bayt

JungHwan Min ve Martin Ender'e 3 bayt kaydettiği için teşekkürler! Büyük bir 5 baytlık tasarruf için ngenisis'e teşekkürler!

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

Adsız işlev, girdi olarak negatif olmayan bir tamsayı alarak pozitif bir tamsayı döndürür. BitLength@#Girdideki bit sayısını hesaplar ve ardından 2^⌈Log2@...⌉en az bit sayısı kadar büyük olan en küçük 2 gücünü hesaplar. Son olarak, /.{2->4,0->1}bit ve nybble arasında "niblit" bulunmadığı özel durumla ilgilenir ve aynı zamanda garip girdilerin cevabını düzeltir 0.


2
Kullanarak 3 bayt kaydet BitLength@#yerine ⌊1+Log2@#⌋. Sonra yerine değiştirme ile 1size yerini alabilir 0başka 2 bayt tasarrufu ve ilk için bağlıyız.
ngenis,

1
Bu aslında tamamen ile yapılabilir BitLength. Cevabımı
ngenisis

4

Julia, 40 bayt

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

Bu 2 hariç, 0 ile 6 2'nin kuvveti bir dizi oluşturur, anonim fonksiyonu olduğunu ve sadece bu elemanlar ile filtre x 2, öyle ki x girişinden daha büyüktür. Bu tür ilk öğe cevaptır. Ne yazık ki bu BigInt, x = 64'te taşmayı önlemek için 2'ye a'yı yükseltmeyi gerektirir .

Bu aslında orlp'in Python cevabına oldukça benzer, ancak bu yaklaşımı kabul etmeden önce görmedim.

Çevrimiçi deneyin!


4

Perl 6 , 30 bayt

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

+<Perl 6'nın birçok başka dilde aradığı sol bit kaydırma operatörü <<.


4

Haskell, 31 bayt

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

32 bayt alt:

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

2

Java, 143 bayt.

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
Bunu kısaltabileceğimi biliyorum, bilgisayardayken bunu yapıyorum.
Pavel,

2
50 bayt tasarruf edin: return a<2?1:a<5?4:a<9?8:a<17?16:a<33?32:64;
Mindwin

@Mindwin Biliyorum ama seyahat ediyorum ve bir süre bir bilgisayara erişimim olmayacak. Ben etrafına doyacağım.
Pavel,


2

Haskell, 43 bayt

f x=head$filter((>x).(2^))$[1,4,8,16,32,64]

2

Ruby, 39 36 bayt

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

Golfe yardımcı olduğunuz için teşekkürler GB


Ayrıca parantez olmadan çalışması gerekir. Ayrıca, liste 0,2,3,4,5,6 olabilir ve 1 << 2 ** p.
GB

... çünkü o zaman 0, * 2..6 kullanabilirsiniz.
GB

2

Java 8, 65 55 bayt

Bu, a'yı alan longve döndüren bir lambda ifadesidir int. Java'da daha önce hiç golf oynamamıştım, bu yüzden kolayca dövülebilir:

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

Çevrimiçi deneyin!


İçin 47 bayt biz olabilir:

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

Ancak, 1L<<i32'den büyük olan dönüş değerleri için taşma olduğundan, bu son test durumu için başarısız olur.


1
Bu döner 4ile test edildiğinde 16da 8. dönmek gerekiyordu olabileceğiniz zaman hala golf etrafında parantez kaldırarak bu çözüm i<<=1+i%2;olmadan beri {}s iken olacaktır döngü yalnızca sonraki satırını çalıştırmak
Kritixi Lithos

@KritixiLithos şimdi düzeltilmelidir - üzgünüm,
Java'm

2

Mathematica, 30 bayt

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

Açıklama:

Izin Nnegatif olmayan tamsayılar kümesi olsun. Üzerinde iki işlevi tanımlayın N, BitLengthve NextPoweraşağıdaki gibi:

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

Bu çözüm aslında NextPower(BitLength(n))verilen bir tamsayı hesaplar n >= 0. İçin n > 0, bunu görebilirsiniz NextPower(n) = 2^BitLength(n-1)böylece NextPower(BitLength(n)) = 2^BitLength(BitLength(n)-1).

Şimdi Mathematica BitLengthyerleşik olarak verdiğim tanımı kabul ediyor n >= 0. İçin n < 0, BitLength[n] == BitLength[BitNot[n]] == BitLength[-1-n]yani BitLength[-1] == BitLength[0] == 0. Böylece istenen cevap almak 1için n==0.

Biz bit'ten yarım bayt düz atlamak yana, cevaplarını değiştirmek zorunda 2olan 4.


1
Güzel inşa edilmiş! (Boşluğun gerekli olduğu konusunda utanç verin.)
Greg Martin,

2

bash, 49 bayt 48 bayt

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

veya

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

Bir betiğe kaydedin ve argüman olarak test edilecek sayıyı iletin.

Düzenleme: Değiştirildi || | ile çalışır, çünkü argümanlar her zaman 0 veya 1 olur.

Not: Bu, bash sürümünüzün kaldırabileceği en büyük pozitif tamsayıya kadar olan tam sayılar için çalışır. Zamanım varsa, 32-bit imzalı aritmetik kullanan bash sürümlerinde 2 ^ 64-1'e kadar çalışacak şekilde değiştireceğim.

Bu arada, rasgele büyük sayılar için çalışan 64 baytlık bir çözüm: (herhangi bir bash sürümünde):

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

2

Yığılmış, 34 30 bayt

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

veya

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

Birincisi TOS'ta girdi alır ve TOS'ta çıktıyı bırakır; ikincisi bir fonksiyondur. Burada dene!

açıklama

@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

İşte repl üzerinde çalışan bir örnek :

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

Test durumları

> {!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))
> 

Veya, tam bir program olarak:

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

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

out

2

Raket 45 bayt

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

Ungolfed:

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

Diğer sürümler:

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

ve dize uzunluğu kullanarak:

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

Test yapmak:

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

Çıktı:

1
1
4
4
8
8
16
32
64

1

Octave, 40 36 31 29 bayt

Basit anonim işlev. Giriş değerinin bir tamsayı olduğu varsayılır - sondaki uyarıya bakın.

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

Kod aşağıdaki gibi çalışır:

  • İlk önce izin verilen bit uzunluklarının bir dizisi (1,4,8,16,32,64) oluşturulur ve kaydedilir b.

  • Daha sonra, hangisinin yeterince büyük olduğunu görmek için aher bir konteynırın maksimum büyüklüğü ile karşılaştırarak giriş numarasını depolamak için gereken bit sayısını buluyoruz b.

  • Daha sonra, konteynır boyutunu btekrardan çıkarmak için elde edilen indeks vektörünü kullanırız .

  • Sonunda, ilk diziyi elde edilen dizideki mümkün olan en küçük konteyner olacak şekilde alıyoruz.

Burada çevrimiçi deneyebilirsiniz .

Basitçe aşağıdaki kodu çalıştırın ve yapın ans(x).


Bununla ilgili tek uyarı, varsayılan olarak sabitler için çift duyarlık kullanılmasıdır, yani yalnızca 2 ^ 64'ten küçük çift duyarlıklı bir şamandıra ile gösterilen en yüksek değere kadar sayılarla çalışır.

Bu, işleve verilen sayının çift değil bir tam sayı olmasını sağlayarak sabitlenebilir. Bu örneğin fonksiyonunu çağırarak elde edilebilir: ans(uint64(x)).


1

PHP, 49 46 44 bayt

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

Bu şekilde koş:

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

açıklama

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.

Düzenlemeler

  • Kurtularak 3 bayt Kaydedilen $r=atama
  • Kullanılabilir -Rhale getirmek için $argnkullanılarak 2 bayt kaydedildi

1

CJam , 18 bayt

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

Çevrimiçi deneyin!

açıklama

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 bayt

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

Bir girişi (1<<15)+1veya daha fazlası, imzalı davranışı nedeniyle bunu bozmaz long longmıydı? Gerçekten istediğiniz tip uint64_thangisidir #include <stdint.h>ki hangisi hala kaybeden ise unsigned long long! Başlıklar, c.
dmckee

@dmckee Sanırım bozabilir, ama en azından bilgisayarımda çalışıyor gibi görünüyor. İşe yaramayacak bir örnek bulamadım. Kullanmayı unsigned long longya da düşündüm uint64_t, ama onunla iş göründüğü için long longonunla gittim.
Steadybox

0

QBIC , 27 bayt

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

açıklama

:        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

Pyke, 13 bayt

7Zm@2-#2R^<)h

Burada dene!

7Zm@          -   [set_bit(0, i) for i in range(7)] <- create powers of 2
    2-        -  ^.remove(2)
      #    )h - filter(^, V)[0]
       2R^    -   2 ** i
          <   -  input < ^

0

PHP, 43 bayt

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

İle koş echo <number> | php -R '<code>'.

girişden daha büyük $iolana kadar döngüler 2**(2**$i). (Tweak: parensi ortadan kaldırmak <<yerine **) Döngüden
sonra, $ i çok yüksek; bu nedenle çıktıyı hesaplamadan önce bir azalma olur
- ancak için değil $i==2.

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.