ความแข็งแบบดิจิตอลของจำนวนเต็ม


26

เพื่อหาสิ่งที่มีความแข็งดิจิตอลของจำนวนเต็มใช้แทน binary ของตนและนับจำนวนครั้งทั้งชั้นนำและต่อท้ายสามารถลบออกได้จนกว่าจะมีทั้งการเริ่มต้นหรือลงท้ายด้วย1 0จำนวนบิตทั้งหมดที่ถูกลบคือความแข็งแบบดิจิตอล

นั่นเป็นคำอธิบายที่ค่อนข้างใช้คำพูด - งั้นมาลองดูตัวอย่างที่ทำงานกันดีกว่า

สำหรับตัวอย่างนี้เราจะใช้หมายเลข 3167 ในระบบเลขฐานสองนี่คือ:

110001011111

(โปรดทราบว่าในระหว่างการแปลงเป็นไบนารีคุณควรตรวจสอบให้แน่ใจว่าได้ตัดส่วนนำศูนย์)

มันไม่ได้เริ่มต้นหรือลงท้ายด้วย0ดังนั้นเราจึงลบบิต 1 คู่:

1  1000101111  1

เเละอีกอย่าง:

11  00010111  11

แต่ตอนนี้มี 0 ที่จุดเริ่มต้นดังนั้นเราจึงไม่สามารถลบ1คู่ได้อีก โดยรวมแล้ว 4 บิตที่เราลบออกและดังนั้น4คือความแข็งแบบดิจิตอลที่3167

อย่างไรก็ตามสำหรับตัวเลขที่สามารถเขียนเป็น2 n -1สำหรับบวกn (เช่นมีเฉพาะ1ในการเป็นตัวแทนไบนารี) 0 จะไม่ถึงและดังนั้นบิตทั้งหมดสามารถลบออกได้ ซึ่งหมายความว่าค่าความแข็งเป็นเพียงความยาวบิตของจำนวนเต็ม


ความท้าทาย

งานของคุณคือการเขียนโปรแกรมหรือฟังก์ชั่นซึ่งกำหนดจำนวนเต็มไม่เป็นลบn >= 0กำหนดความแข็งแบบดิจิตอล

คุณสามารถส่งโปรแกรมเต็มรูปแบบซึ่งดำเนินการ I / O หรือฟังก์ชั่นที่ส่งกลับผลลัพธ์ การส่งของคุณควรทำงานกับค่าที่nอยู่ในช่วงจำนวนเต็มมาตรฐานของภาษาของคุณ


กรณีทดสอบ

โปรดแจ้งให้ฉันทราบหากสิ่งเหล่านี้ไม่ถูกต้องหรือหากคุณต้องการแนะนำกรณีขอบที่จะเพิ่ม

0     -> 0
1     -> 1
8     -> 0
23    -> 2
31    -> 5
103   -> 4
127   -> 7
1877  -> 2
2015  -> 10

ต่อไปนี้เป็นวิธี Python ของ ungolfed ที่ฉันใช้สร้างกรณีทดสอบเหล่านี้ (ไม่รับประกันว่าจะไม่มีข้อผิดพลาด):

def hardness(num) -> int:
    binary = bin(num)[2:]

    if binary.count('0') == 0:
        return num.bit_length()

    revbin = binary[::-1]

    return min(revbin.find('0'), binary.find('0')) * 2

1
จะ1คืนค่า 1 ได้อย่างไรเมื่อไม่มี0ในนั้น? ฉันหมายความว่าคุณอาจไม่สามารถลบ 1 ออกจากสตริงเพื่อให้เริ่มต้นหรือสิ้นสุด0ได้
busukxuan

2
@busukxuan อ่านย่อหน้าก่อนส่วนหัว "The Challenge": สำหรับตัวเลขที่สามารถเขียนเป็น 2 ^ n-1 (เช่นมีเพียง 1 ในการแทนเลขฐานสอง) 0 จะไม่ถึง 0 และดังนั้นบิตทั้งหมดจะถูกลบออก . ซึ่งหมายความว่าค่าความแข็งเป็นเพียงความยาวบิตของจำนวนเต็ม
FlipTack

2
@ busukxuan คุณสามารถคิดว่ามันเป็นจำนวนของแต่ละด้านมีเบาะก่อนที่จะถึงศูนย์
FlipTack

2
สำหรับผู้ลงคะแนนเสียงที่ไม่ชอบขอบกล่อง: ความแข็งคือจำนวนของแข็ง (1) บิตที่มันเสริมด้วย - ถ้าทั้งหมดเป็นของแข็งแล้วแน่นอนว่ามันมีความแข็ง 100% ความยาวบิตทั้งหมดหรือไม่
FlipTack

1
@FlipTack ฉันไม่ต้องการมีอิทธิพลมากเกินไปมันเป็นความท้าทายของคุณ ตอนแรกฉันเข้าใจ "ความแข็ง" เป็นจำนวนคู่นอกสูงสุดที่สามารถลบออกได้หนึ่งคู่จากแต่ละด้าน แต่คุณอาจพูดถูกถ้าคนเดียวยังคงอยู่ในตอนท้ายบางทีมันควรจะนับใน
Luis Mendo

คำตอบ:


6

เยลลี่ , 11 10 ไบต์

BµQL××Ṛa\S

ลองออนไลน์!

มันทำงานอย่างไร

BµQL××Ṛa\S  Main link. Argument: n

B           Binary; convert n to base 2.
 µ          Begin a new, monadic chain. Argument: A (array of binary digits)
  Q         Unique; deduplicate the digits.
   L        Length; count the unique digits.
    ×       Multiply each digit by the result.
     ×Ṛ     Multiply the results by reversed A.
       a\   Cumulative reduce by logical AND.
            This zeroes out all elements after the first zero.
         S  Compute the sum of the result.

8

Python , 76 69 68 63 62 60 57 ไบต์

f=lambda n,k=0:n>>k&(n&n>>k>n>>k+1)and(n&n+1>0)-~f(n,k+1)

ลองออนไลน์!

มันทำงานอย่างไร

นี่เป็นโซลูชันแบบเรียกซ้ำที่ใช้อินพุตnและเพิ่มค่าk - เริ่มต้นที่0 - ในขณะที่ทั้งLSB k (n) (บิตที่ดัชนีkจากด้านขวา) และMSB k (n) (บิตที่ดัชนีkจากซ้าย) มีการตั้งค่า. เมื่อเสร็จแล้วจะส่งกลับkถ้าบิตทั้งหมดของnถูกตั้งค่าและ2kถ้าไม่

เริ่มต้น Let 's โดยการเขียนใหม่แลมบ์ดาเป็นชื่อฟังก์ชั่นFมีตัวแปรเสริมที

def F(n, k = 0):
    t = n >> k
    return t & (n & t > t >> 1) and (n & (n + 1) > 0) + 1 + F(n, k + 1)

ในการภาวนาของแต่ละFแรกเราบิตกะnรวมkหน่วยไปทางขวาและเก็บผลในเสื้อ ด้วยวิธีนี้LSB 0 (t) = LSB k (n)ดังนั้นtจึงแปลกถ้าหากตั้งค่าLSB k (n)เท่านั้น

การพิจารณาว่าMSB k (n)ถูกตั้งค่าเล็กน้อย นี่คือสิ่งที่n & t > t >> 1บรรลุ เพื่อแสดงให้เห็นวิธีการทำงานให้พิจารณาจำนวนเต็มn = 1αβγδεζη 2บิตที่มีความยาว8และวิเคราะห์การทำงานของสายF (n 3)คือk = 3

เราพยายามที่จะตรวจสอบว่าMSB 3 (n) = γถูกกำหนดโดยการตรวจสอบค่าความจริงของการเปรียบเทียบ(n & T> T >> 1) = (1αβγδεζη 2 & 1αβγδ 2 > 1αβγ 2 ) ลองตรวจสอบจำนวนเต็มที่เกี่ยวข้อง

MSB-index  012k4567

n          1αβγδεζη
t             1αβγδ

t >> 1         1αβγ

อ้างว่าเราγ = 1และถ้าหากn & T> T >> 1

  • ถ้าγ = 1แล้วn & Tมีบิตที่มีความยาว5ในขณะที่เสื้อ >> 1มีบิตที่มีความยาว4ดังนั้นn & T> T >> 1

    นี้พิสูจน์ให้เห็นว่าγ = 1หมายถึงn & T> T >> 1

  • ถ้าn & T> T >> 1มีสองตัวเลือก: ทั้งγ = 1หรือγ = 0 ในกรณีแรกไม่มีอะไรเหลือให้พิสูจน์

    ในกรณีที่สองเรามีที่αβγδ 2 ≥ n & T> T >> 1 = 1αβγ 2

    ตั้งแต่αβγδ 2 > 1αβγ 2เราจะต้องมีMSB 0 (αβγδ 2 ) ≥ MSB 0 (1αβγ 2 )มีความหมายว่าα = 1

    วิธีนี้1βγδ 2 > 11βγ 2ดังนั้นเราจึงต้องมีMSB 1 (1βγδ 2 ) ≥ MSB 1 (11βγ 2 )มีความหมายว่าβ = 1

    ในทางกลับกันนี้หมายความว่า11γδ 2 > 111γ 2 จดจำว่าγ = 0ในกรณีที่สองเราได้รับความไม่เท่าเทียมกัน110δ 2 > 1110 2ซึ่งเป็นเท็จตั้งแต่MSB 2 (110δ 2 ) = 0 <1 = MSB 2 (1110 2 )

    ดังนั้นเฉพาะกรณีแรกที่เป็นไปได้และn & T> T >> 1หมายถึงγ = 1

สรุปถ้าทั้งLSB k (n)และMSB k (n)ถูกตั้งค่าtจะแปลกและn & t> t >> 1จะเป็นจริงดังนั้นt & (n & t> t >> 1)จะ ให้ผลผลิต1 . อย่างไรก็ตามหากLSB k (n)หรือMSB k (n)ไม่มีการตั้งค่า (หรือทั้งสองอย่าง) tจะเท่ากับหรือn & t> t >> 1จะเป็นเท็จดังนั้นt & (n & t> t> > 1)จะให้ผลผลิต0

โทรFกับอาร์กิวเมนต์เดียวเริ่มต้นk = 0 ในขณะที่เงื่อนไขที่เราได้กล่าวถึงก่อนหน้านี้ถือรหัสหลังจากandถูกดำเนินการที่ (ในหมู่สิ่งอื่น ๆ ) ซ้ำเรียกFมีเพิ่มขึ้นk

เมื่อLSB k (n)หรือMSB k (n)คือไม่มีการตั้งค่าสภาพล้มเหลวและF (n, k)ผลตอบแทน0 การเรียกใช้ฟังก์ชันkก่อนหน้าแต่ละรายการเพิ่ม(n & (n + 1)> 0) + 1ถึงF (n, k) = 0ดังนั้นF (n) จึงส่งกลับ((n & (n + 1)> 0) + 1) k .

ตอนนี้ถ้าบิตทั้งหมดของnเท่ากัน (เช่นถ้าnเป็น0หรือบิตทั้งหมดถูกตั้งค่าไว้) n + 1จะไม่มีบิตใด ๆ ที่เหมือนกันกับnดังนั้นn & (n + 1) = 0และF (n)ผลตอบแทนk แต่ถ้าnมีทั้งชุดและบิตไม่มีการตั้งค่าn (n + 1)> 0และF (n)ผลตอบแทน2k


2
โซลูชันแบบเรียกซ้ำใน Python ดูเหมือนว่าจะได้คะแนนในระยะหลัง ๆ นี้
mbomb007

อย่างน้อยเมื่อเทียบกับโซลูชันซ้ำพวกเขามักจะมี input(), whileและprintมีอยู่แล้ว17ไบต์ ...
เดนนิส

ใช่ แต่ฉันพบว่าพวกเขาเขียนยากขึ้นมาก
mbomb007

1
ยุติธรรมพอสมควร การทำซ้ำอย่างตรงไปตรงมาของความคิดเดียวกันนั้นจะมีความยาวเพียง 5 ไบต์เท่านั้น tio.run/nexus/ ......สามารถบันทึกได้อีก 2 ไบต์ด้วยเทคนิคเล็กน้อย tio.run/nexus/python2#JY1BDsIgFAXX7SnepgUUI1BNm1K4jKVJQ/ …
เดนนิส

6

MATL , 13 12 ไบต์

Btv`6L&)}x@q

ลองออนไลน์! หรือตรวจสอบกรณีทดสอบทั้งหมด

คำอธิบาย

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

B        % Input number (implicit). Horizontal vector of binary digits
tv       % Duplicate and concatenate vertically
`        % Do...while
  6L&)   %   Flatten the array if needed (in column-major order), and split it
         %   into two subarrays: one with the inner entries, and another
         %   with the two outer entries. The latter will be used for deciding
         %   if the loop continues or is exited
}        % Finally (execute before exiting the loop)
  x      %   Delete last subarray of inner entries
  @q     %   Push last iteration index minus 1
         % End (implicit). The next iterarion is executed if the array at the
         % top of the stack is non-empty and only contains nonzero values. 
         % Otherwise the loop is exited, executing the "finally" block first
         % Display (implicit)

6

Python ขนาด 82 ไบต์

ฉันรู้สึกว่ามันยังคงสามารถเล่นกอล์ฟได้ แต่ฉันใช้เวลาสักครู่ในการลองวิธีการต่าง ๆ และนี่ก็สั้นที่สุด

def f(n):b=bin(n)[2:];x=min(b.find('0'),b[::-1].find('0'));print(x<0)*len(b)or x*2

ลองออนไลน์

แม้ว่าสิ่งนี้จะทำงานคล้ายกับโปรแกรม Python ของ OP แต่ฉันสร้างสิ่งนี้ก่อนที่จะโพสต์คำถามหลังจากดูคำถามใน Sandbox ซึ่งไม่มีโปรแกรมดังกล่าว


6

Python 2, 66 ไบต์

s=bin(input())[2:].split('0')
print len(min(s[-1],s[0]))<<1%len(s)

แยกการแทนค่าแบบไบนารี่ของอินพุตเป็นชิ้นจำนวน 1 นับจำนวนของ 1 ในขนาดเล็กของอันแรกและอันสุดท้าย


ฉลาด แต่ยังเข้าใจง่าย ฉันชอบมัน!
mbomb007

5
@ mbomb007 ให้ความอบอุ่นในการทำความเข้าใจกับเดนนิส :)
xnor

3

PowerShell , 109 106 ไบต์

$a=[convert]::ToString($args[0],2)-split0;(((($b=$a[0].length),$a[-1].length|sort)[0]*2),$b)[$a.count-eq1]

ลองออนไลน์!

จะเข้า$args[0]ใช้โทร .NET ไปconvertมันtoStringมีฐาน2(กล่าวคือทำให้มันไบนารี) แล้ว-splits สตริงว่า0s $aร้านค้าที่เป็น สำคัญที่ควรทราบ: โทร .NET 1ไม่ได้กลับศูนย์ชั้นนำเพื่อให้หลักแรกอยู่เสมอ

ดังนั้นจึงมีความเป็นไปได้สองอย่าง - สตริงไบนารีคือทั้งหมดหรือมีอย่างน้อยหนึ่งศูนย์ เราแยกความแตกต่างระหว่างผู้ที่มีหลอก ternary $a.count-eq1ดัชนีโดย หากไบนารีมีอย่างน้อยหนึ่งศูนย์กรณีซ้ายเราจะใช้ความยาวขั้นต่ำของ[0]สตริงแรกของ1s และ[-1]สตริงสุดท้าย(พบโดย|sortและจากนั้น[0]) 2ที่สั้นกว่านั้นคือคู่มากที่สุดที่เราสามารถลบดังนั้นเราจึงคูณว่า โปรดทราบว่าถ้าเดิมไบนารีสตริงปลายใน0เช่นสำหรับการป้อนข้อมูล8แล้ว[-1].lengthยังจะ0(เนื่องจากเป็นสตริงที่ว่างเปล่า) ซึ่งเมื่อคูณด้วยยังคงเป็น20

มิฉะนั้นด้วยสตริงไบนารีทุกคนเราจะใช้เพียงแค่$b(ซึ่งก่อนหน้านี้ถูกตั้งค่าให้เป็นความยาวของ[0]สตริงแรกในกรณีนี้คือความสมบูรณ์ของสตริงไบนารี)

ไม่ว่าจะในสถานการณ์ใดผลลัพธ์นั้นจะอยู่บนไพพ์ไลน์และเอาท์พุทก็เป็นนัย


3

JavaScript (ES6), 57 ไบต์

f=
n=>n.toString(2).replace(/^(1*)(.*(\1))?$/,'$1$3').length
<input oninput=o.value=1/this.value?f(+this.value):''><input id=o readonly>

รับไบนารีและพยายามจับคู่ทั้งหมด1sหรือล้มเหลวที่มีจำนวนนำหน้าและต่อท้าย1sเท่ากัน


2

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

.+
$*
+`(1+)\1
$1o
o1
1
m(+`^1(.*)1$
xx¶$1
x|^1$

ลองออนไลน์

คำอธิบาย:

.+              # Convert to unary
$*
+`(1+)\1        # Convert to binary (but with `o` instead of `0` -- it's shorter)
$1o
o1
1
m(+`^1(.*)1$    # Replace pairs of surrounding ones with `xx`
xx¶$1
x|^1$,          # Count x's, including the possibility of a single remaining `1`

2

C #, 133 ไบต์

ฟังก์ชั่นที่คืนความแข็ง รับจำนวนเต็มจากการโต้แย้ง

int h(int b){var n=Convert.ToString(b,2);for(b=0;;){if(n[0]+n[n.Length-1]==98)n=n.Substring(1,n.Length-2);else break;b+=2;}return b;}

ดีวันนี้ฉันพบ'1' + '1' = 98ใน C #


1
นั่นเป็นเพราะ'1'ASCII ถ่าน 49 และ 49 + 49 = 98
FlipTack

ฉันใช้เวลา 10 นาทีหาสาเหตุว่าทำไมฉัน1 + 1 = 2ไม่ทำงาน @FlipTack
devRicher

2

C, 89 88 85 ไบต์

บันทึกสองไบต์เนื่องจาก @FlipTack ชี้ให้เห็นการประกาศที่ไร้ประโยชน์

โทรf()ไปที่หมายเลขเพื่อทดสอบเอาต์พุตจะถูกส่งคืนจากฟังก์ชัน

t,h;f(l){for(t=l;t&&~t&1<<30;t*=2);for(h=0;t&1<<30&&l&1;t*=2,l/=2)++h;return h<<!!l;}

ลองบน ideone


2

JavaScript (ES6), 59 58 ไบต์

f=(n,m=1<<30)=>m>n?f(n,m/2):m>1?n&m&&n&1&&2+f(n/2,m/4):n&1

กรณีทดสอบ



2

C, 137 132 122 119 117 114 98 94 92 87 85 ไบต์

เวลาที่จะเริ่มเล่นกอล์ฟ B-)

i,j;f(n){for(i=1<<30;i&~n;i/=2);for(j=0;n&i;n/=2,i/=4)j+=~n&1?i=0:2;return j-=n<1*j;}

นี่คือข้อพิสูจน์

main()
{
  printf("%d %d\n", 0, f(0));
  printf("%d %d\n", 1, f(1));
  printf("%d %d\n", 8, f(8));
  printf("%d %d\n", 23, f(23));
  printf("%d %d\n", 31, f(31));
  printf("%d %d\n", 103, f(103));
  printf("%d %d\n", 127, f(127));
  printf("%d %d\n", 1877, f(1877));
  printf("%d %d\n", 2015, f(2015));
  printf("%d %d\n", 3167, f(3167));
} 

และผลลัพธ์

0 0
1 1
8 0
23 2
31 5
103 4
127 7
1877 2
2015 10
3167 4 


1

Mathematica, 63 56 ไบต์

(2-Min[l=#~IntegerDigits~2])Min[Tr/@Split[l][[{1,-1}]]]&

คำอธิบาย

l=#~IntegerDigits~2

สร้างฐาน-2 Listเป็นตัวแทนของใส่ห่อด้วย ร้านค้าที่ในl

(2-Min[...])

หากองค์ประกอบขั้นต่ำของl1, ผลลัพธ์ 1 ถ้าไม่ให้ผลลัพธ์ 2 คูณด้วย ...

Split[l]

แบ่งlออกเป็นวิ่ง

... [[{1,-1}]]

ใช้องค์ประกอบแรกและสุดท้าย

Tr/@ ...

รับผลรวมของทั้งคู่

Min[ ... ]

ค้นหาขนาดเล็กลงระหว่างสอง

(ทวีคูณผลลัพธ์แรก (1 หรือ 2) กับผลลัพธ์นี้)


1

อ็อกเทฟ56 56ไบต์

 @(n)cummin(d=dec2bin(n)-48)*cummin(flip(d))'*2^!all(d)

ลองออนไลน์!

คำอธิบาย:

d=dec2bin(n)-48

การเป็นตัวแทนไบนารีของ n

cumd= cummin(d);
cumfd = cummin(flip(d));

ใช้เวลาสะสมนาทีของd และจำนวนนาทีสะสมพลิกd

res = cumd * cumfd ';

ทำการคูณเมทริกซ์

out = res*2^!all(d)

คูณด้วย 2 ถ้าจำนวนทั้งหมดเป็น 1;


@FlipTack ขอบคุณลิงค์อัพเดท!
rahnema1

1

Pyth, 18 ไบต์

?*FJjQ2lJyhSxR0_BJ

โปรแกรมที่รับอินพุตของจำนวนเต็มและพิมพ์ผลลัพธ์

ชุดทดสอบ (บรรทัดแรกสำหรับการจัดรูปแบบ)

มันทำงานอย่างไร

?*FJjQ2lJyhSxR0_BJ  Program. Input: Q
?                   If
  F                 reducing
    jQ2             the binary representation of Q as a list
   J                (store in J)
 *                  by multiplication is truthy:
       lJ            Yield len(J)
                    Else:
          hS         Yield the minimum
            xR0      of the first index of zero
               _BJ   in J and its reverse
         y           * 2
                    Implicitly print

1

APL, 26 ไบต์

+/∘(∧\≢↑(∊⊢(,∧∧)¨⌽))2⊥⍣¯1⊢

กรณีทดสอบ:

      ( +/∘(∧\≢↑(∊⊢(,∧∧)¨⌽))2⊥⍣¯1⊢ ) ¨ 0 1 8 23 31 103 127 1877 2015    
0 1 0 2 5 4 7 2 10

คำอธิบาย:

+ / ∘ (∧ \ ≢↑ (ε⊢ (∧∧) ¨⌽)) 2⊥⍣¯1⊢

                         ⊢อินพุต
                    2⊥⍣¯1แปลงเป็นการแทนแบบไบนารี่
   ()
        (⊢¨⌽) สำหรับแต่ละบิตและบิตที่ตรงกันในอีกด้านหนึ่ง
            (∧) รับตรรกะและบิตทั้งสอง
             ทำรายการของบิตทั้งสอง
              take จากนั้นนำรายการและของรายการและและ
         ∊ แผ่อาร์เรย์ผลลัพธ์
      ↑↑รับเฉพาะ N บิตแรกโดยที่ N คือ
                                ความยาวของรายการบิตดั้งเดิม
    logical \ ใช้ตรรกะและ (เหลือเพียง
                                คนที่เริ่มต้น)
+ / ∘หาผลรวมเหล่านั้น

1

J, 22 ไบต์

(#<.2*(<.&(#.~)|.))@#:

สิ่งนี้ขึ้นอยู่กับเคล็ดลับเรียบร้อยที่เรียนรู้จากความท้าทายนี้

ลองออนไลน์!

คำอธิบาย

(#<.2*(<.&(#.~)|.))@#:  Input: integer n
                    #:  Binary digits of n
(                 )@    Operate on those digits D
               |.         Reverse D
       <.                 Take the minimum of
         &(#.~)           the "trailing truths" of D and reverse(D)
    2*                    Multiply by 2
 #                        The length of D
  <.                      Minimum of length and the previous result

1

PHP, 83 74 ไบต์

3 + 6 ไบต์บันทึกโดยJörg

<?=(~$s=decbin($argn))[$a=strspn($s,1)]?min($a,strspn(strrev($s),1))*2:$a;

รับอินพุตจาก STDIN; -nRทำงานด้วย

ทำให้พังถล่ม

<?=                     # print ...
(~
    $s=decbin($argn)        # $s = binary representation of input
)[
    $a=strspn($s,1)         # $a = number of leading `1`s
]                           # if $s has more than $a digits,
?   min($a,                     # 2. minimum of $a and
        strspn(strrev($s),1)    # 1. number of trailing `1`s
    )*2                         # 3. *2
:   $a                      # else $a (==strlen)

1
<?=~($s=decbin($argn))[$a=strspn($s,1)]?2*min($a,strspn(strrev($s),1)):$a;
JörgHülsermann

0

JavaScript (ES6), 83 ไบต์

f=x=>(y=x.toString(2),y.match(/^1*$/)?y:([s,e]=y.match(/^1*|1*$/g),s<e?s:e)).length

Ungolfed:

function f(n) {
    var binStr = n.toString(2);
    if(binStr.match(/^1*$/)) {
        // If binary representation is all 1s, return length of binary
        return binStr.length;
    } else {
        // Grab the starting and ending 1s in the binary representation
        var [start1s, end1s] = binStr.match(/^1*|1*$/g);
        var startHardness = start1s.length;
        var endHardness = end1s.length;
        return Math.min(startHardness, endHardness);
    }
}

0

Mathematica, 62 ไบต์

(h=0;#~IntegerDigits~2//.{{1,m___,1}:>(h+=2;{m}),{1}:>h++};h)&

ฟังก์ชั่นบริสุทธิ์ที่#แสดงถึงอาร์กิวเมนต์แรก

(h=0;...;h)&ชุดh=0ทำสิ่งต่าง ๆ...แล้วส่งคืนh(ความแข็ง) ลองดูที่พวงของสิ่งต่าง ๆ :

#~IntegerDigits~2                                     Binary representation of the input
                 //.                                  Apply the following list of rules repeatedly until there is no change
                    {                                 Start of the list of rules
                     {1,m___,1}                       If you see a list starting and ending with 1 with the sequence m (possibly empty) in between
                               :>(h+=2;{m}),            replace it with just {m} after incrementing h twice.
                                            {1}       If you see the singleton list {1}
                                               :>h++    replace it with h, then increment h.
                                                    } End of the list of rules

ขอบคุณ Greg Martin ที่แนะนำให้ฉันรู้จักกับเคล็ดลับนี้


0

Haskell , 94 92 ไบต์

b 0=[]
b n=mod n 2:b(div n 2)
h n|(c,_:_)<-span(>0)$zipWith(*)n$reverse n=c++c|1<3=n
sum.h.b

ลองออนไลน์! การใช้งาน:

Prelude> sum.h.b $ 3167
4

คำอธิบาย:
bแปลงตัวเลขเป็นเลขฐานสองและส่งกลับรายการศูนย์และรายการด้วยบิตนัยสำคัญน้อยที่สุดก่อน ในhรายการนี้จะกลับรายการและองค์ประกอบที่ชาญฉลาดคูณกับรายการเดิมจากนั้นspan(>0)แยกหลังจาก1s เริ่มต้น:

       b 3167 = [1,1,1,1,1,0,1,0,0,0,1,1] = n
    reverse n = [1,1,0,0,0,1,0,1,1,1,1,1] = m
zipWith(*)n m = [1,1,0,0,0,0,0,0,0,0,1,1] = z
   span(>0) z = ([1,1],[0,0,0,0,0,0,0,0,1,1])

tuple ที่ส่งผลให้เกิดเป็นรูปแบบการจับคู่กับ(c,_:_)ที่ตรงกับรายการที่ไม่ว่างเปล่าดังนั้น_:_ c = [1,1]เพราะไบต์จะถูกลบออกที่ด้านหน้าและด้านหลังc++c = [1,1,1,1]จะถูกส่งกลับและสรุปให้ผลผลิตในที่สุดความแข็งดิจิตอล

หากรายการที่สองของ tuple ว่างเปล่าการแสดงเลขฐานสองจะมีเฉพาะรายการและจำนวนรายการคือความแข็งแบบดิจิทัล ด้วยการจับคู่รูปแบบล้มเหลวhจะส่งคืนเพียงnซึ่งรวมอีกครั้ง


0

Perl, 61 ไบต์

sub f{$_=sprintf('%b',pop);length(/0/?/^(1+).*\1$/&&$1x2:$_)}

หัวใจของสิ่งนี้คือ regex /^(1+).*\1$/ซึ่งมีความยาว$1เป็น2 เท่า รหัสที่เหลือเป็นค่าใช้จ่ายและจัดการกับกรณีพิเศษทั้งหมด


คุณสามารถละวงเล็บรอบ ๆsprintfอาร์กิวเมนต์ได้ นอกจากนี้การใช้การ-pตั้งค่าสถานะจะช่วยให้คุณเขียนโปรแกรมเต็มรูปแบบที่จะสั้นกว่าฟังก์ชั่นของคุณในขณะที่คุณสามารถละเว้นsub f{...}(แทนคุณจะต้องจบด้วย$_=...แต่ที่ยังคงปรับปรุง 4 ไบต์) สุดท้ายแทนของคุณที่คุณสามารถทำได้length(...) /0/&&s/^(1+).*\1$/$1$1/;$_=y///cนี่น่าจะเท่ากับ 51 ไบต์
Dada


0

CJam, 14 ไบต์

ri2b_0#\W%0#e<

คำอธิบาย:

ri e# Read integer:      | 3167
2b e# Convert to binary: | [1 1 0 0 0 1 0 1 1 1 1 1]
_  e# Duplicate:         | [1 1 0 0 0 1 0 1 1 1 1 1] [1 1 0 0 0 1 0 1 1 1 1 1]
0# e# Index of first 0:  | [1 1 0 0 0 1 0 1 1 1 1 1] 2
\  e# Swap:              | 2 [1 1 0 0 0 1 0 1 1 1 1 1]
W% e# Reverse:           | 2 [1 1 1 1 1 0 1 0 0 0 1 1]
0# e# Index of first 0:  | 2 5
e< e# Minimum:           | 2
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.