ในจำนวนที่ฉันพอดี


52

สำหรับจำนวนเต็มบวก 32- บิตใด ๆ ( 1 ≤ n ≤ 0xFFFFFFFF) เอาท์พุทจำนวนบิตที่จำเป็นในการแสดงจำนวนเต็มนั้น

กรณีทดสอบ

| n    | n in binary | bits needed |
|----------------------------------|
| 1    | 1           | 1           |
| 2    | 10          | 2           |
| 3    | 11          | 2           |
| 4    | 100         | 3           |
| 7    | 111         | 3           |
| 8    | 1000        | 4           |
| 15   | 1111        | 4           |
| 16   | 10000       | 5           |
| 128  | 10000000    | 8           |
| 341  | 101010101   | 9           |

4294967295 => 11111111111111111111111111111111 => 32

ดังนั้นf(16)จะพิมพ์หรือส่งคืน5

นี่คือรหัสกอล์ฟรหัสที่สั้นที่สุดในหน่วยไบต์ชนะ


2
นี่คือเพดานของลอการิทึมฐาน 2
orlp

23
@ orlp จริง ๆ แล้วคือfloor(log2(num))+1
Kritixi Lithos

2
@KritixiLithos ถูกต้อง
orlp

3
ไม่เป็นไรเพียงตระหนักว่าความแตกต่างนั้นสำคัญเมื่อnumอำนาจของทั้งสอง
Brian J

11
นี่เป็นความท้าทายเล็กน้อยที่มีวิธีแก้ปัญหาเล็กน้อยมากมาย อย่างไรก็ตามยังมีวิธีแก้ปัญหาที่ไม่สำคัญเช่นกัน วิธีการลงคะแนน: โปรดอ่านประโยคแรกของการโพสต์เมตานี้ก่อนที่จะ upvoting ฟังก์ชัน builtin (นำมาอย่างนอบน้อมจากความคิดเห็นนี้)
Kritixi Lithos

คำตอบ:


30

16
ภาษาลึกลับได้รับรางวัลอีกครั้ง ...bg
devRicher

20
@devRicher ฉันคาดว่าจะถูกตีด้วยโซลูชั่น 1 ไบต์ยังคงซื่อสัตย์
Magic Octopus Urn

9
อย่างน้อยคำตอบนี้ทำให้ได้ upvotes bgมันไม่ได้อยู่ใน
NoOneIsHere

3
bgในการเล่นเกมหมายถึงbad game:)
YoYoYonnY

1
@ yoyoyonny หรือสมรภูมิฮ่าฮ่า
Magic Octopus Urn

35

JavaScript (ES6), 18 ไบต์

f=n=>n&&1+f(n>>>1)
<input type=number min=0 step=1 value=8 oninput="O.value=f(this.value)">
<input id=O value=4 disabled>


นี่เป็นหนึ่งในวิธีการแก้ปัญหาเล็กน้อยที่นี่ ชั้นเชิงดี!
Kritixi Lithos

1
ควรn>>>1ให้การสนับสนุนn > 0x7FFFFFFF?
Arnauld

@Arnauld อืมไม่รู้ว่า>>ล้มเหลวในnที่สูง ขอบคุณ
ETHproductions

ดีความพยายามครั้งแรกของฉันคือf=(a,b=1)=>a>1?f(a>>1,++b):b
Bassdrop Cumberwubwubwub

28

x86 ชุดประกอบ 4 ไบต์

สมมติว่าค่าคงที่ในEBX:

bsr eax,ebx
inc eax

EAX มีจำนวนบิตที่จำเป็นสำหรับค่าคงที่

ไบต์: ☼¢├@

เลขฐานสิบหก: ['0xf', '0xbd', '0xc3', '0x40']


2
คุณช่วยรวม hexdump ของรหัสประกอบ 86 ตัว x86 ที่คอมไพล์แล้วด้วยหรือไม่?
Loovjo

ทำเช่นนั้น และขอบคุณเพราะฉันรู้ว่าฉันทำผิด ฉันเพิ่ม "inc eax" เพื่อให้พอดีกับกฎ ฉันทำไบต์หาย :(
z0rberg ใน

โอ้ว้าวคุณเปลี่ยนโพสต์ของฉันเป็นรูปแบบที่เหมาะสม ขอบคุณสำหรับการแก้ไข!
z0rberg ใน


1
เป็นเรื่องปกติไหมที่จะนับการส่งชุดประกอบเป็นจำนวนไบต์ของรหัสเครื่องที่คอมไพล์แทนที่จะเป็นรหัสภาษาชุดประกอบ?
smls

18

Pythonขนาด 14 ไบต์

int.bit_length

ลองออนไลน์!


มันทำงานได้ใน Python 2 ด้วย
vaultah

1
มันไม่แน่นอน ลืมหลาม 2 intเป็น 64 บิตกว้างไม่ 32 บิต
เดนนิส

งูหลาม 3 คือbit_length bit_length()
dfernan

2
@dfernan นี่ไม่ใช่การเรียกใช้ฟังก์ชัน มันเป็นฟังก์ชั่น ถ้าnเป็นint , int.bit_length(n)และn.bit_length()ทำตรงเดียวกัน
เดนนิส

2
@dfernan int.bit_length(n)เป็นการเรียกใช้ฟังก์ชันและทำให้ข้อมูลโค้ดที่สมมติว่าอินพุตถูกเก็บไว้ในตัวแปร กฎนี้ไม่ได้รับอนุญาตดังนั้นการผนวก(n)จะทำให้คำตอบนี้ไม่ถูกต้อง อย่างไรก็ตามint.bit_lengthประเมินเป็นฟังก์ชันและสามารถบันทึกในตัวแปรเพื่อใช้ในภายหลัง สิ่งนี้ได้รับอนุญาตโดยค่าเริ่มต้น
เดนนิส

15

เขาวงกต , 13 12 ไบต์

 ?
_:
2/#(!@

ลองออนไลน์!

คำอธิบาย

โปรแกรมแบ่งการป้อนข้อมูล 2 ครั้งซ้ำ ๆ จนกระทั่งมันเป็นศูนย์ จำนวนขั้นตอนจะถูกติดตามโดยการทำซ้ำค่าในแต่ละขั้นตอน เมื่อมันลดลงเหลือศูนย์เราจะพิมพ์ความลึกของสแต็ก (ลบ 1)

โปรแกรมเริ่มต้นที่?อ่านอินพุต ลูปหลักคือบล็อก 2x2 ด้านล่าง, ทวนเข็มนาฬิกา:

:   Duplicate current value.
_2  Push 2.
/   Divide.

เมื่อค่าเป็นศูนย์หลังจากการวนซ้ำเต็มบิตเชิงเส้นที่ท้ายจะถูกดำเนินการ:

#   Push stack depth.
(   Decrement.
!   Print.
@   Terminate.

5
โซลูชันนี้เสร็จสมบูรณ์ - ใช้อินพุตและให้คำตอบและไม่ใช้ฟังก์ชันที่มีอยู่เพื่อวัตถุประสงค์เฉพาะ - คำนวณคำตอบด้วยตนเอง สำหรับฉันนี่เป็นจิตวิญญาณของเกมมากกว่าคำตอบอื่น ๆ
Johan

15

C, 31 ไบต์

f(long n){return n?1+f(n/2):0;}

... จากนั้นฉันก็คิดถึงการสอบถามซ้ำ จากที่คลุมเครือถึงชัดเจนและหนึ่งในสี่ของความยาวหลุดออกไป

ดูมันสดบน Coliru


C, 43 ไบต์

c;
#define f(v)({for(c=0;v>=1l<<c;++c);c;})

การโทรfด้วยค่าที่ไม่ได้ลงชื่อ (เช่นf(42u)) จะ "คืน" ความยาวบิตของมัน แม้ใช้งานได้0u!

Ungolfed และอธิบาย: (ไม่ใส่เครื่องหมายแบ็กสแลช)

c;
#define f(v)
    ({ // GCC statement-expression

        // Increment c until (1 << c) >= v, i.e
        // that's enough bits to contain v.
        // Note the `l` to force long
        // arithmetic that won't overflow.
        for(c = 0; v >= 1l << c; ++c)
            ; // Empty for body

        c; // Return value
    })

ดูมันสดบน Coliru


OP รับประกัน n> = 1 ดังนั้นจึงn?...:0ไม่จำเป็น
นักฟิสิกส์บ้า

1
@MadPhysicist ดีฉันจะต้องหยุดการเรียกซ้ำบางไม่ฉัน;)
เควนติน

OIC ไม่ได้อ่านอย่างละเอียดรู้สึกเหมือนเป็นคนโง่ ตอบอย่างเรียบร้อยทั้งสองทาง
นักฟิสิกส์บ้า

@MadPhysicist ไม่ต้องกังวลขอบคุณมาก :)
เควนติน

สำหรับโซลูชันที่ไม่เรียกซ้ำโดยสมมติว่าสำนวนคำสั่ง gcc ฉันคิดว่าคุณอาจมีแนวโน้มที่จะใช้#define f(n) ({64-__builtin_clzl(n);})วิธีนี้เช่นกัน
Moreaki


14

Perl 6 , 7 ไบต์

*.msb+1

ลองมัน

คำอธิบาย:

* ทำให้มันกลายเป็นสิ่งที่แลมบ์ดารหัสและระบุตำแหน่งที่จะนำเข้า

.msb บน Int จะส่งคืนดัชนีของบิตที่สำคัญที่สุด (ตาม 0)

+1.msbจะรวมกันเป็นแลมบ์ดาและเพิ่มหนึ่งไปยังผลที่สุดของการโทร


13

มาโครตัวประมวลผลล่วงหน้า C (ที่มีนามสกุล gcc), 26

#define f 32-__builtin_clz

ใช้ GCC's นับชั้นนำศูนย์ builtin

เรียกสิ่งนี้ว่าเป็นฟังก์ชั่นเช่น f(100)เรียกสิ่งนี้เป็นฟังก์ชั่นเช่น

ลองมันออนไลน์


โอ้ว้าวฉันคิดเกี่ยวกับการใช้ builtin แต่ลดความคิดเพราะฉันคิดว่ามันจะนานเกินไป ... เล่นได้ดี
Quentin

โชคดีที่ OP ระบุไว้ n> = 1: D
Matthieu M.

12

เรติน่า , 56 37 ไบต์

วิธีนี้ใช้ได้กับค่าอินพุตที่จำเป็นทั้งหมด

ปัญหาที่ใหญ่ที่สุดของหน้าจอ Retina ในการท้าทายนี้คือความจริงที่ว่าสตริงมีความยาวสูงสุด 2 ^ 30 ตัวอักษรดังนั้นวิธีปกติในการจัดการกับตัวเลข (การแสดงแบบเอก) ไม่ทำงานกับค่าที่มากกว่า 2 ^ 30

เพื่อที่จะแก้ปัญหานี้ฉันได้นำวิธีการที่แตกต่างกันไปใช้การจัดเรียงตัวเลขทศนิยมแทนตัวเลข แต่ที่แต่ละหลักจะเขียนด้วยภาษาเดียว (ฉันจะเรียกวิธีนี้ว่าการเป็นตัวแทนดิจิทัล ) ยกตัวอย่างเช่นตัวเลข341จะถูกเขียน111#1111#1#ในรูปแบบดิจิทัล ด้วยการเป็นตัวแทนนี้เราสามารถทำงานกับตัวเลขสูงสุด2^30/10(~ ร้อยล้านหลัก) มันใช้งานได้น้อยกว่า unary มาตรฐานสำหรับเลขคณิตโดยพลการ แต่ด้วยความพยายามเล็กน้อยเราสามารถดำเนินการใด ๆ ได้

หมายเหตุ: ดิจิทัลในทางทฤษฎีสามารถใช้ฐานอื่น ๆ (เช่นไบนารี110จะอยู่1#1##ในฐานที่ 2 ดิจิตัล) แต่เนื่องจาก Retina มี builtins ในการแปลงระหว่างทศนิยมและไม่เป็นเอกภาพและไม่มีวิธีโดยตรงที่จะจัดการกับฐานอื่น ๆ

อัลกอริทึมที่ฉันใช้คือทำให้การหารจำนวนเต็มต่อเนื่องสองจนกว่าเราจะถึงศูนย์จำนวนหน่วยงานที่เราทำคือจำนวนบิตที่จำเป็นในการเป็นตัวแทนของจำนวนนี้

ดังนั้นเราจะแบ่งสองหลักเป็นหน่วยหลักได้อย่างไร นี่เป็นตัวอย่างของ Retina ที่ทำ:

(1*)(1?)\1#        We divide one digit, the first group captures the result, the second group captures the remainder
$1#$2$2$2$2$2      The result is put in place of the old number, the remainder passes to the next digit (so it is multiplied by 10) and is divided by two there -> 5 times the remainder goes to the next digit

การแทนที่นี้เพียงพอที่จะหารจำนวนหลักด้วย 2 เราเพียงแค่ต้องลบ. 5s ที่เป็นไปได้ออกจากท้ายหากหมายเลขเดิมเป็นเลขคี่

ดังนั้นนี่คือรหัสเต็มเราจะหารด้วยสองจนกว่าจะมีตัวเลขยังคงอยู่ในตัวเลขและใส่ตัวอักษรที่nด้านหน้าของสตริงที่การวนซ้ำแต่ละครั้ง: จำนวนnท้ายที่เป็นผลลัพธ์

.                  |
$*1#               Convert to digitunary
{`^(.*1)           Loop:|
n$1                    add an 'n'
(1*)(1?)\1#            |
$1#$2$2$2$2$2          divide by 2
)`#1*$                 |
#                      erase leftovers
n                  Return the number of 'n's in the string

ลองออนไลน์!


โซลูชันที่อัปเดตแล้ว 37 ไบต์

การปรับโครงสร้างครั้งยิ่งใหญ่ด้วยแนวคิดที่ดีมากมายที่เล่นกอล์ฟได้ประมาณหนึ่งในสามของความยาวทั้งหมดขอบคุณ Martin Ender!

แนวคิดหลักคือใช้_เป็นสัญลักษณ์ของเรา: ด้วยวิธีนี้เราสามารถใช้ตัวเลขปกติในสายอักขระของเราตราบใดที่เราแปลงกลับเป็น_ s เมื่อต้องการ: สิ่งนี้ช่วยให้เราประหยัดหลายไบต์ในการหารและการแทรกหลาย ตัวเลข

นี่คือรหัส:

<empty line>    |
#               put a # before each digit and at the end of the string 
{`\d            Loop:|
$*_                 Replace each digit with the corrisponding number of _
1`_                 |
n_                  Add an 'n' before the first _
__                  |
1                   Division by 2 (two _s become a 1)
_#                  |
#5                  Wherever there is a remainder, add 5 to the next digit
}`5$                |
                    Remove the final 5 you get when you divide odd numbers
n               Return the number of 'n's in the string

ลองออนไลน์!


1
ฉันใช้รูปแบบตัวเลขที่คล้ายกัน (แต่เรียกว่าUnary-Coded Decimal ) ซึ่งค่อนข้างมีประโยชน์สำหรับเลขคณิตกับ Sed
Toby Speight




10

JavaScript ES6, 19 ไบต์

a=>32-Math.clz32(a)

Math.clz32ส่งคืนจำนวนบิตศูนย์นำในการแทนเลขฐานสองแบบ 32 บิตของตัวเลข ดังนั้นเพื่อให้ได้จำนวนบิตที่ต้องการสิ่งที่เราต้องทำก็คือ substract นั้นจาก 32

f=
  a=>32-Math.clz32(a)
  
pre {
    display: inline;
}
<input id=x type="number" oninput="y.innerHTML = f(x.value)" value=128><br>
<pre>Bits needed: <pre id=y>8</pre></pre>


2
ทางเลือกa=>1+Math.log2(a)|0คือ 19 ไบต์
Neil

5
@Neil 1+...|0กรีดร้องลบเครื่องหมายตัวหนอน ! a=>-~Math.log2(a)คือวันที่ 18
edc65

@ edc65 ฉันนับ 17 ... แต่ใช่ฉันแน่ใจว่าฉันพลาดบางสิ่งบางอย่างขอบคุณที่ชี้ให้เห็น
Neil

@Neil รู้สึกอิสระที่จะโพสต์มันเป็นคำตอบที่แยกจากกัน มันใช้วิธีการอื่นที่แตกต่างจากคำตอบของฉันดังนั้นมันจะไม่ยุติธรรมที่จะใช้ของคุณสำหรับจำนวนไบต์ที่ลดลง
Bassdrop Cumberwubwubwub

10

เครื่องมือทุบตี / Unix ขนาด 16 ไบต์

dc<<<2o$1n|wc -c

บันทึกสิ่งนี้ในสคริปต์และส่งผ่านอินพุตเป็นอาร์กิวเมนต์ จำนวนบิตที่ต้องใช้เพื่อแสดงจำนวนนั้นในไบนารีจะถูกพิมพ์

นี่คือคำอธิบาย:

dc เป็นเครื่องคิดเลขตามสแต็ก อินพุตแยกเป็นโทเค็นคือ:

2 - กด 2 บนสแต็ก

o - ป๊อปอัพค่าออกจากสแต็ก (ซึ่งคือ 2) และทำให้มันเป็นฐานเอาท์พุท

ค่าของการโต้แย้งไปยังโปรแกรมทุบตี ($ 1) - ผลักดันอาร์กิวเมนต์นั้นในสแต็ก

n - ป๊อปอัพค่าออกจากสแต็ก (ซึ่งเป็นหมายเลขอินพุต) และพิมพ์ (เป็นไบนารีเพราะนั่นคือฐานเอาต์พุต) โดยไม่มีการขึ้นบรรทัดใหม่

ดังนั้นคำสั่ง dc จะพิมพ์ตัวเลขเป็นเลขฐานสอง

เอาต์พุตของ dc ถูกไพพ์ไปที่คำสั่ง wc พร้อมกับอ็อพชัน -c ซึ่งพิมพ์จำนวนอักขระในอินพุต

ผลลัพธ์ที่ได้คือการพิมพ์จำนวนของตัวเลขในการเป็นตัวแทนไบนารีของการโต้แย้ง


ทางเลือกที่ดีของภาษา แต่มันก็จะยิ่งเย็นลงถ้าคุณรวมคำอธิบาย
นิวแฮมป์เชียร์

@NH ขอบคุณ ฉันได้เพิ่มคำอธิบายแล้ว
Mitchell Spector

9

Google ชีตขนาด 15 ไบต์

รับอินพุตจากเซลล์A1และเอาต์พุตไปยังเซลล์ที่เก็บสูตร

=Len(Dec2Bin(A1

หรือ

=Int(1+Log(A1,2

หรือ

=Int(Log(2*A1,2

Excel, 17 ไบต์

เหมือนกับด้านบน แต่ได้รับการจัดรูปแบบสำหรับ MS Excel

=Len(Dec2Bin(A1))

หรือ

=Int(1+Log(A1,2))

หรือ

=Int(Log(2*A1,2))



8

C #, 63 45 31 ไบต์

บันทึกแล้ว 18 ไบต์ขอบคุณ Loovjo และ TuukkaX

บันทึกแล้ว 14 ไบต์ขอบคุณ Grax

 b=>1+(int)System.Math.Log(b,2);

มันใช้ว่าตัวเลขทศนิยม n มี⌊log2 (n) ⌋ + 1 บิตซึ่งอธิบายไว้ในหน้านี้ :

จำนวนบิตในจำนวนเต็มทศนิยมแบบเฉพาะ

จำนวนเต็มบวก n มี b บิตเมื่อ 2 ^ (b-1) ≤ n ≤ 2 ^ b - 1 ตัวอย่างเช่น:

  • 29 มี 5 บิตเพราะ 16 ≤ 29 ≤ 31 หรือ 2 ^ 4 ≤ 29 ≤ 2 ^ 5 - 1
  • 123 มี 7 บิตเพราะ 64 ≤ 123 ≤ 127 หรือ 2 ^ 6 ≤ 123 ≤ 2 ^ 7 - 1
  • 967 มี 10 บิตเพราะ 512 ≤ 967 ≤ 1023 หรือ 2 ^ 9 ≤ 967 ≤ 2 ^ 10 - 1

สำหรับตัวเลขที่มากขึ้นคุณสามารถดูตารางพลังสองเพื่อค้นหาพลังที่ต่อเนื่องกันที่มีหมายเลขของคุณ

หากต้องการดูว่าทำไมการทำงานนี้ให้ลองนึกถึงการแทนเลขฐานสองของจำนวนเต็ม 2 ^ 4 ถึง 2 ^ 5 - 1 เป็นต้น ค่าเหล่านี้คือ 10,000 ถึง 11111 ค่า 5 บิตที่เป็นไปได้ทั้งหมด

ใช้ลอการิทึม

วิธีการข้างต้นสามารถระบุได้อีกวิธีหนึ่ง: จำนวนบิตคือเลขชี้กำลังของกำลังไฟฟ้าที่เล็กที่สุดที่สองของคุณมากกว่าจำนวนของคุณ คุณสามารถระบุได้ว่าทางคณิตศาสตร์เป็น:

bspec = ⌊log2 (n) ⌋ + 1

สูตรนั้นมีสามส่วน:

  • log2 (n) หมายถึงลอการิทึมในฐาน 2 ของ n ซึ่งเป็นเลขยกกำลังที่ยก 2 เพื่อรับ n ตัวอย่างเช่น log2 (123) ≈ 6.9425145 การมีอยู่ของส่วนที่เป็นเศษส่วนหมายความว่า n อยู่ระหว่างกำลังสอง

  • ⌊x⌋เป็นพื้นของ x ซึ่งเป็นส่วนจำนวนเต็มของ x ตัวอย่างเช่น⌊6.9425145⌋ = 6. คุณสามารถคิดถึง⌊log2 (n) ⌋เป็นเลขชี้กำลังของกำลังสูงสุดของสองในการแทนเลขฐานสองของ n

  • +1 จะยกกำลังเป็นเลขยกกำลังสองถัดไป คุณสามารถคิดว่าขั้นตอนนี้เป็นการบัญชีสำหรับเลขที่ 2 ^ 0 ของเลขฐานสองของคุณซึ่งจะให้จำนวนบิตทั้งหมด สำหรับตัวอย่างของเรานั่นคือ 6 + 1 = 7 คุณอาจถูกล่อลวงให้ใช้ฟังก์ชันเพดาน - ceilingx⌉ซึ่งเป็นจำนวนเต็มที่น้อยที่สุดที่มากกว่าหรือเท่ากับ x - เพื่อคำนวณจำนวนบิตเช่น:

bspec = ⌈log2 (n) ⌉

อย่างไรก็ตามสิ่งนี้ล้มเหลวเมื่อ n คือพลังของสอง


คุณมีพื้นที่พิเศษในการมี->...)+ 1)... ...)+1...นอกจากนี้ฉันคิดว่าคุณสามารถคืนค่าได้โดยตรงแทนที่จะพิมพ์
Loovjo

คุณสามารถวางมันลงไปที่ 31 ได้โดยการใช้b=>1+(int)System.Math.Log(b,2); การแปลง int ให้ผลลัพธ์เช่นเดียวกับ Math.Floor และคุณไม่จำเป็นต้องใช้คำสั่งถ้าคุณอ้างอิงระบบเพียงครั้งเดียว
Grax32

6

C #, 32 ไบต์

n=>Convert.ToString(n,2).Length;

แปลงพารามิเตอร์เป็นสตริงไบนารีและส่งคืนความยาวของสตริง



4

Befunge-93 , 23 21 Bytes

&>2# /# :_1>+#<\#1_.@

Befunge เป็นภาษาที่ใช้กริด 2 มิติ (แม้ว่าฉันจะใช้เพียงบรรทัดเดียวเท่านั้น)

&                      take integer input
 >2# /# :_             until the top of the stack is zero, halve and duplicate it
          1>+#<\#1_    find the length of the stack
                   .@  output that length as an integer and terminate the program

ลองออนไลน์!


@ JamesHolderness ขอบคุณฉันคิดว่ามันจะสั้นลงเพราะมีแฮช / ช่องว่างมากมาย แต่ฉันไม่สามารถรับมันได้
JayDepp





3

QBICขนาด 18 ไบต์

:{~2^q>a|_Xq\q=q+1

นั่นคือไมค์ที่เหลือเชื่อ! แต่มันทำงานอย่างไร

:        Read input as integer 'a'
{        Start an infinite DO-LOOP
~2^q>a   If 2 to the power of q (which is 1 by default) is greater than a
|_Xq     Then quit, printing q
\q=q+1   Else, increment q
[LOOP is closed implicitly by QBIC]

3

Java 8, 34 27 ไบต์

ครั้งหนึ่ง Java มี builtins ที่มีประโยชน์! ตอนนี้เราต้องการชื่อที่สั้นกว่านี้ ...

x->x.toString(x,2).length()

ลองออนไลน์!

แน่นอนคุณสามารถทำสิ่งนี้ได้โดยไม่ต้อง buildins ( ดูคำตอบของ Snowman ) แต่สำหรับจำนวนไบต์ที่สูงขึ้น


3

อ็อกเทฟ, 19 ไบต์

@(x)nnz(dec2bin(x))    % or
@(x)nnz(de2bi(x)+1)    % or
@(x)nnz(de2bi(x)<2)    % or
@(x)numel(de2bi(x))    % or
@(x)rows(de2bi(x'))

ระดับแปดเสียงมีสองฟังก์ชั่นสำหรับการแปลงเลขทศนิยมให้เป็นเลขฐานสอง

dec2binแปลงตัวเลขให้เป็นสตริงของอักขระ1และ0(ค่า ASCII 48และ49) ความยาวของสตริงจะเท่ากับจำนวนบิตที่จำเป็นเว้นแต่จะระบุไว้เป็นอย่างอื่น ตั้งแต่ตัวละคร1และ0เป็นที่ไม่ใช่ศูนย์ที่เราสามารถใช้เพื่อหาจำนวนขององค์ประกอบเช่นนี้:nnz @(x)nnz(dec2bin(x))นี่คือ 19 ไบต์ดังนั้นจึงเชื่อมโยงกับคำตอบ Octave อื่น ๆ ของ Luis Mendoคำตอบของคู่อื่น

เราสามารถทำได้ดีกว่าโดยใช้de2bi?

de2biเป็นฟังก์ชันที่คืนค่าตัวเลขไบนารีเป็นเวกเตอร์ที่มีตัวเลข1และ0เป็นจำนวนเต็มไม่ใช่อักขระ de2biจะเห็นได้ชัดไบต์ที่สองสั้นกว่าแต่เราไม่สามารถใช้dec2bin nnzเราสามารถใช้nnzถ้าเราเพิ่ม1องค์ประกอบทั้งหมดหรือทำให้เป็นเวกเตอร์เชิงตรรกะที่มีเฉพาะtrueค่า @(x)nnz(de2bi(x)+1)และ@(x)nnz(de2bi(x)<2)มีทั้ง 19 ไบต์ การใช้numelจะให้ 19 ไบต์กับเราด้วย, @(x)numel(de2bi(x)).

rowsสั้นกว่าหนึ่งไบต์numelแต่de2biส่งคืนเวกเตอร์แนวนอนดังนั้นจึงต้องทำการเปลี่ยน @(x)rows(de2bi(x)')เพียงแค่เกิดขึ้นเป็น 19 ไบต์เช่นกัน



2

เรติน่า 44 ไบต์

ต้องใช้หน่วยความจำมากเกินไปในการทำงานสำหรับค่าอินพุตที่มีขนาดใหญ่ แปลงเป็นเอกภาพจากนั้นหารด้วย 2 ซ้ำ ๆ นับจำนวนครั้งจนกว่าจะถึงศูนย์ จำนวนไบต์ถือว่าการเข้ารหัส ISO 8859-1

.*
$*
+`^(1+)1?\1
$1_
.

ลองออนไลน์


1
ฉันไม่แน่ใจว่าถูกต้อง นี่ไม่ใช่กรณีของ "มันต้องมีหน่วยความจำมากกว่าที่คุณอาจจะมี" แต่ "มันต้องใช้หน่วยความจำมากกว่าที่ Retina สามารถจัดการได้" โดยเฉพาะอย่างยิ่งการแปลงเริ่มต้นเป็นเอกจะล้มเหลวสำหรับอินพุตของคำสั่งที่ 2 ^ 30 ขึ้นไปเนื่องจากข้อ จำกัด ในการใช้งานของ Retina
Martin Ender

หากถูกต้องก็สามารถย่อให้สั้นลงได้มาก: tio.run/nexus/retina#@6@nxaWixaWdEKdhqK1paB9jyKViGM@l9/@/saUhAA
Martin Ender
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.