คำนวณชุดที่ยาวที่สุดของ 1 ในค่าเลขฐานสองของจำนวนเต็ม


32

เป้าหมาย

กำหนดจำนวนเต็มแบบไม่ลบสร้างฟังก์ชันที่ส่งคืนตำแหน่งเริ่มต้นของจำนวน 1 ที่ใหญ่ที่สุดติดต่อกันในค่าเลขฐานสองของจำนวนเต็มนั้น

เมื่อได้รับการป้อนข้อมูลกลับมา00

หากตัวเลขมีหลายเส้นที่มีความยาวเท่ากันคุณจะต้องกลับตำแหน่งของริ้วสุดท้าย

อินพุต

จำนวนเต็มมากกว่าหรือเท่ากับ 0

เอาท์พุต

จำนวนเต็มคำนวณตามที่อธิบายด้านล่าง

กฎระเบียบ

  • นี่คือโค้ดกอล์ฟดังนั้นโค้ดที่สั้นที่สุดเป็นไบต์ในแต่ละภาษาจะชนะ
  • ช่องโหว่มาตรฐานเป็นสิ่งต้องห้าม

ตัวอย่างและกรณีทดสอบ

ตัวอย่างที่ 1

  • ฟังก์ชันของคุณส่งผ่านจำนวนเต็ม 142
  • 142 เท่ากับ 1,0001110 ในไบนารี
  • แนวที่ยาวที่สุดคือ "111" (แนวของสามเส้น)
  • แนวเริ่มต้นที่ตำแหน่ง 2 ^ 1
  • ฟังก์ชันของคุณจะคืนค่า 1 ตามผลลัพธ์

ตัวอย่างที่ 2

  • ฟังก์ชันของคุณผ่านจำนวนเต็ม 48
  • 48 เท่ากับ 110000 ในหน่วยไบนารี่
  • แนวที่ยาวที่สุดคือ "11" (แนวของสองเส้น)
  • แนวเริ่มต้นที่ตำแหน่ง 2 ^ 4
  • ฟังก์ชันของคุณจะคืนค่า 4 ตามผลลัพธ์

ตัวอย่างที่ 3

  • ฟังก์ชันของคุณผ่านจำนวนเต็ม 750
  • 750 เท่ากับ 1011101110 ในไบนารี
  • แนวที่ยาวที่สุดคือ "111" (แนวของสามเส้น)
  • เนื่องจากมีเส้นริ้วสองเส้นที่มีความยาวเท่ากันเราจึงกลับเป็นริ้วในภายหลัง
  • แนวต่อมาเริ่มต้นที่ตำแหน่ง 2 ^ 5
  • ฟังก์ชันของคุณคืนค่า 5 ตามผลลัพธ์

1
คุณต้องมีเกณฑ์การชนะเช่นcode-golf
Okx

@Okx มันถูกกล่าวถึงในร่างกายของตัวเองดังนั้นฉันจึงเพิ่มแท็ก
สิ้นเชิงมนุษย์

0ตรวจสอบให้แน่ใจทดสอบคน นั่นเป็นกรณีทดสอบที่สำคัญ
mbomb007

2
แทนที่จะเป็น "Last Streak" หรือ "Streak ล่าสุด" ฉันขอแนะนำ "Streak ที่มีค่าสถานที่มากที่สุด"
aschepler

@Okx เหตุใดเกณฑ์การชนะจึงเป็นสิ่งจำเป็น ทำไมมันไม่สามารถเป็นแค่ปริศนาได้?
corsiKa

คำตอบ:


21

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

Ba\ÐƤṀċ¬

ลองออนไลน์!

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

Ba\ÐƤṀċ¬  Main link. Argument: n


B         Binary; convert n to base 2.

   ÐƤ     Apply the link to the left to all postfixes of the binary array.
 a\         Cumulatively reduce by logical AND.

          For example, the array

          [1, 0, 1, 1, 1, 0, 1, 1, 1, 0]

          becomes the following array of arrays.

          [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
             [0, 0, 0, 0, 0, 0, 0, 0, 0]
                [1, 1, 1, 0, 0, 0, 0, 0]
                   [1, 1, 0, 0, 0, 0, 0]
                      [1, 0, 0, 0, 0, 0]
                         [0, 0, 0, 0, 0]
                            [1, 1, 1, 0]
                               [1, 1, 0]
                                  [1, 0]
                                     [0]

     Ṁ    Take the lexicographical maximum, i.e., the array with the most 1's at
          the beginning, breaking ties by length.

       ¬  Yield the logical NOT of n, i.e., 0 if n > 0 and 1 if n = 0.

      ċ   Count the occurrences of the result to the right in the one to the left.

ขอแสดงความยินดี!
Defacto

24

JavaScript (ES6), 41 40 36 34 ไบต์

บันทึกแล้ว 4 ไบต์ขอบคุณ @ThePirateBay

f=x=>(k=x&x/2)?f(k):Math.log2(x)|0

กรณีทดสอบ

อย่างไร?

กรณีทั่วไป x> 0

เราเรียกซ้ำแล้วซ้ำอีกและอินพุตxด้วยx / 2ซึ่งจะลดรูปแบบของบิตที่ต่อเนื่องกันเรื่อย ๆ จนกระทั่งเหลือเพียงบิตขวาสุดของลำดับเท่านั้น เราเก็บสำเนาของค่าที่ไม่เป็นศูนย์ล่าสุดและกำหนดตำแหน่งของบิตที่สำคัญที่สุดโดยการปัดเศษชั้นลอการิทึมฐานที่ 2

ด้านล่างนี้คือขั้นตอนที่เราดำเนินการเพื่อหาx = 750 ( 1011101110ในรูปแบบไบนารี)

    1011101110 --.
,----------------'
'-> 1011101110
AND 0101110111
    ----------
=   0001100110 --.
,----------------'
'-> 0001100110
AND 0000110011
    ----------
=   0000100010 --.  --> output = position of MSB = 5  (0000100010)
,----------------'                                         ^
'-> 0000100010
AND 0000010001
    ----------
=   0000000000

กรณีขอบ x = 0

กรณีพิเศษทันทีที่นำไปสู่x = 0 Math.log2(0) | 0ลอการิทึมของการ0ประเมินค่า-Infinityและไบนารีบิตเรทหรือบังคับให้บีบบังคับเป็นจำนวนเต็ม 32 บิต ตามข้อกำหนดของการดำเนินการนามธรรมToInt32สิ่งนี้ให้สิ่งที่คาดหวัง0:

ถ้าnumberคือNaN , +0 , −0 , + ∞หรือ−∞ให้ผลตอบแทนที่ +0


ข้อผิดพลาดนี้สำหรับอินพุต0ซึ่งเป็นส่วนหนึ่งของช่วงอินพุต
Justin Mariner

@JustinMariner แก้ไขแล้ว
Arnauld

เกี่ยวกับอะไรMath.log2(k)|0แทน31-Math.clz32(k)อะไร หรือว่าฉันขาดอะไรไป?

@ThePirateBay Math.log2(k)|0x=0เป็นจริงทั้งสั้นและง่ายสำหรับกรณีพิเศษ ขอบคุณ :)
Arnauld

1
อัลกอริทึมที่ดีมากและคำอธิบายที่ดี ผมดำเนินการใน14 ไบต์ของรหัสเครื่อง
Peter Cordes

12

รหัสเครื่อง x86, 14 ไบต์

ใช้@ อัลกอริทึม Arnauld ของของx &= x>>1และสละตำแหน่งบิตชุดสูงสุดในขั้นตอนก่อนที่จะกลายเป็นx0

เรียกใช้ได้จาก C / C ++ พร้อมลายเซ็นunsigned longest_set(unsigned edi);ใน x86-64 System V ABI เช่นเดียวกับเครื่องไบต์รหัสจะถอดรหัสวิธีเดียวกันในโหมด 32 บิต แต่มาตรฐาน 32 ediบิตเรียกประชุมไม่หาเรื่องใส่ครั้งแรกใน (การเปลี่ยนการลงทะเบียนอินพุตecxหรือedxสำหรับ Windows _fastcall/ _vectorcallหรือgcc -mregparmสามารถทำได้โดยไม่ทำลายอะไร)

   address   machine-code
             bytes
                         global longest_set
 1                       longest_set:
 2 00000000 31C0             xor  eax, eax    ; 0 for input = 0
 3                       
 4                       .loop:               ; do{
 5 00000002 0FBDC7           bsr  eax, edi    ;  eax = position of highest set bit
 6                           ;; bsr leaves output unmodified when input = 0 (and sets ZF)
 7                           ;; AMD documents this; Intel manuals say unspecified but Intel CPUs implement it
 8 00000005 89F9             mov  ecx, edi
 9 00000007 D1E9             shr  ecx, 1
10 00000009 21CF             and  edi, ecx
11 0000000B 75F5             jnz .loop        ; } while (x &= x>>1);
12                       
13 0000000D C3               ret

BSRคำสั่งของ x86 (Bit Scan Reverse) นั้นสมบูรณ์แบบสำหรับสิ่งนี้ทำให้เรามีดัชนีบิตโดยตรงแทนที่จะนับศูนย์นำหน้า ( bsrไม่ได้สร้าง 0 โดยตรงสำหรับอินพุต = 0 32-lzcnt(x)แต่เราต้องการ bsr = 31-lzcnt สำหรับอินพุตที่ไม่เป็นศูนย์ดังนั้นlzcntจะไม่บันทึกคำสั่งแม้แต่นับไบต์นับประสา Zeroing eax ก่อนที่วงจะทำงานเพราะbsr' พฤติกรรมกึ่งทางการของการออกจากปลายทางโดยไม่แก้ไขเมื่ออินพุตเป็นศูนย์)

นี่จะสั้นกว่านี้หากเราสามารถส่งคืนตำแหน่ง MSB ของการรันที่ยาวนานที่สุด ในกรณีนั้นlea ecx, [rdi+rdi](3 ไบต์) จะคัดลอก + left -shift แทนmov+ shr(4 bytes)

ดูลิงค์ TIO นี้สำหรับผู้โทร asmexit(longest_set(argc-1));

การทดสอบด้วย shell loop:

l=(); for ((i=0;i<1025;i++));do 
    ./longest-set-bitrun "${l[@]}";   # number of args = $i
    printf "$i %#x: $?\n" $i; 
    l+=($i); 
done | m

0 0: 0
1 0x1: 0
2 0x2: 1
3 0x3: 0
4 0x4: 2
5 0x5: 2
6 0x6: 1
7 0x7: 0
8 0x8: 3
9 0x9: 3
10 0xa: 3
11 0xb: 0
12 0xc: 2
13 0xd: 2
14 0xe: 1
15 0xf: 0
16 0x10: 4
17 0x11: 4
18 0x12: 4
19 0x13: 0
20 0x14: 4
21 0x15: 4

...

747 0x2eb: 5
748 0x2ec: 5
749 0x2ed: 5
750 0x2ee: 5
751 0x2ef: 0
752 0x2f0: 4
753 0x2f1: 4
754 0x2f2: 4

1
ดี! หมายเหตุสำหรับผู้ที่ (เช่นฉัน) มีความคุ้นเคยกับภาษาแอสเซมบลีอื่น ๆ : mnemonic x86 BSR ย่อมาจาก "Bit Scan Reverse" ไม่ใช่ "Branch to SubRoutine"
Arnauld

@Arnauld: จุดที่ดีแก้ไขเพื่อถอดรหัสช่วยในการจำเช่นเดียวกับการเชื่อมโยงไปยังรายการคู่มืออ้างอิง insn
Peter Cordes

5

เยลลี่ , 19 17 11 ไบต์

HÐĿ&\ḟ0ṪBL’

ลองออนไลน์!

-6 (!) ไบต์ขอบคุณการสังเกตของ @ Dennis

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

HÐĿ&\ḟ0ṪBL’
HÐĿ         - halve repeatedly until reaching 0 due to rounding
   &\       - cumulative AND
     ḟ0Ṫ    - final non-zero, or 0 if all elements are 0
        BL  - length of binary representation (log base 2). 0->[0]->1
          ’ - decrement

ข้อผิดพลาดสำหรับ0ซึ่งอยู่ในช่วงอินพุต
Mr. Xcoder

@ Mr.Xcoder แก้ไข
fireflame241

คุณสามารถบันทึกไบต์สำหรับการแก้ไขด้วยȯ-µ...
Jonathan Allan

@JanathanAllan ฉันไม่เข้าใจว่า OR-ing จะช่วยได้อย่างไร คุณมีรหัสหรือไม่
fireflame241

1
ตั้งแต่Bเสมอกลับอาร์เรย์ที่ขึ้นต้นด้วยหนึ่ง1 , สามารถกลายเป็นBUṪMṪ’×Ṡ ṪBL’นอกจากนี้คุณไม่จำเป็นต้องใช้และประหยัดมากกว่าหนึ่งไบต์ḟ0 ¹Ðf
Dennis

5

Python 2 , 45 ไบต์

f=lambda x:f(x&x/2)if x&x/2else len(bin(x))-3

ลองออนไลน์!

บันทึกจำนวนมากต้องขอบคุณ Dennis! (หัวขึ้นlen(bin(...))-3แทนmath.frexp)

ขอบคุณ @xnor สำหรับการค้นหาข้อผิดพลาดซึ่งโชคดีที่สามารถแก้ไขได้อย่างง่ายดาย!


ดูเหมือนว่าจะให้คำตอบที่ผิดเช่นx=3ฉันคิดว่าเพราะand/orวงจรสั้นผิดเมื่อฟังก์ชันส่งคืนค่า 0
xnor

@ xnor ขอบคุณที่สังเกตว่า! มันคงที่
Mr. Xcoder

4

เพิร์ล 6 ,45 35 ไบต์

รุ่นที่ได้รับการปรับปรุงอย่างมากนี้ได้รับความอนุเคราะห์จาก @nwellnhof

{.msb+1-(.base(2)~~m:g/1+/).max.to}

ลองออนไลน์!


คุณสามารถจับคู่:gเพื่อรับการแข่งขันทั้งหมด ด้วยโอเปอเรเตอร์ที่จับคู่แบบอัจฉริยะฉันสามารถเล่นกอล์ฟได้ถึง 40 ไบท์:{sort(.base(2).flip~~m:g/1+/).tail.from}
nwellnhof

และถึง 35 ไบต์:{.msb+1-(.base(2)~~m:g/1+/).max.to}
nwellnhof

@nwellnhof ขอบคุณมาก ฉันพลาดอย่างใด:gและไม่ได้คิดออกว่าฉันจะใช้คำวิเศษณ์กับผู้ประกอบการ smartmatch ได้อย่างไร นอกจากนี้ยังมี.msbวิธีการที่เป็นประโยชน์มากที่นี่และผมไม่ทราบเกี่ยวกับมันก่อน
Ramillies

3

Python 2 , 89 78 ไบต์

m=t=i=j=0
for c in bin(input()):
 t=-~t*(c>'0');i+=1
 if t>m:j=i;m=t
print i-j

ลองออนไลน์!

แก้ไข: บันทึก 11 ไบต์ขอบคุณ Mr. Xcoder




@ Mr.Xcoder ฉันก็คิดเช่นนั้นแม้ว่าคำถามจะขอให้เขียนฟังก์ชั่นเป็นพิเศษ
Jonathan Frech

@JonathanFrech ฉันไม่คิดว่า OP หมายจริงๆฟังก์ชั่น อาจเป็นเพียงคำทั่วไป
Mr. Xcoder

@ Mr.Xcoder โปรดอธิบายสิ่งนี้ ขอขอบคุณ
lifebalance

3

05AB1E , 14 12 11 ไบต์

bDγàŠrkrJgα

ลองออนไลน์! หรือเรียกใช้กรณีทดสอบ

คำอธิบาย

bDγàŠrkrJgα  Implicit input (ex: 750)
bD           Convert input to binary string and duplicate
                 '1011101110', '1011101110'
  γ          Split into groups of 1s or 0s
                 '1011101110', ['1', '0', '111', '0', '111', '0']
   à         Pull out max, parsing each as an integer
                 '1011101110', ['1', '0', '0', '111', '0'], '111'
    Šrk      Rearrange stack and get first index of max run of ones
                 ['1', '0', '0', '111', '0'], 2
       rJg   Reverse stack, join the array to a string, and get its length
                 2, 7
          α  Get absolute difference
                 5

3

J , 18 17 ไบต์

(#-0{#\\:#.~\)@#:

ลองออนไลน์!

คำอธิบาย

(#-0{#\\:#.~\)@#:  Input: integer n
               #:  Binary
     #\            Length of each prefix
       \:          Sorted down using
         #.~\      Mixed base conversion on each prefix
   0{              Get the value at index 0
  -                Subtract from
 #                 Length

ลื่นมาก ไม่แน่ใจว่าฉันเข้าใจอย่างถ่องแท้ว่าเกิดอะไรขึ้นกับการแปลงฐานแบบผสม ทำไมมันถึงนับจำนวนของต่อเนื่องที่ส่วนท้ายของสตริง? นอกจากนี้ถ้าฐานที่ระบุไว้บนxของ dyad นั้นมีค่าทั้งหมด 0 และ 1 นั่นหมายความว่าอย่างไร หมายเลขฐาน 2 มีตัวเลข0และ1ดังนั้น1หมายเลขฐานจึงมีตัวเลข ... 0? ถ้าอย่างนั้น1หมายความว่าอะไรในบริบทนั้น และเป็นฐาน0จำนวนเพียงแค่เสมอ0?
โยนาห์

@Jonah เป็นเรื่องที่มากขึ้นเนื่องจากมีการใช้การแปลงฐานแบบผสม x #. yการคำนวณครั้งแรกจะw =: */\. }. x , 1ส่งกลับ+/ w * y
ไมล์

ดังนั้นคุณจะพิจารณาว่านี่เป็นการแฮ็กกอล์ฟมากกว่าการใช้ที่ถูกกฎหมาย#.เนื่องจากคุณต้องพึ่งพารายละเอียดการใช้งานภายในมากกว่าการใช้ API สาธารณะ
โจนาห์

3

C # (.NET Core) , 64 60 ไบต์

T=a=>(a&a/2)>0?T(a&a/2):Math.Log(a,2)<0?0:(int)Math.Log(a,2)

ลองออนไลน์!

AC # เวอร์ชันของคำตอบของ@ Arnauld

กิตติกรรมประกาศ

บันทึกได้ 4 ไบต์ด้วย Kevin Cruijssen

C # (. NET Core) , 131 123 + 18 = 141 ไบต์

a=>{string s=Convert.ToString(a,2),t=s.Split('0').OrderBy(x=>x.Length).Last();return a<1?0:s.Length-s.IndexOf(t)-t.Length;}

ลองออนไลน์!

+18 ไบต์สำหรับ using System.Linq;

กิตติกรรมประกาศ

บันทึก 8 ไบต์ขอบคุณ Grzegorz Puławski

Degolfed

a=>{
    string s=Convert.ToString(a,2),      // Convert to binary
    t=s.Split('0')                       // get largest group of 1's
       .OrderBy(x=>x.Length)
       .Last();
    return 
        a<1?0:                          // handle 0 case
        s.Length-s.IndexOf(t)-t.Length; // get position in reversed string
}

C # (. NET Core) , 164 161 ไบต์

a=>{var s=Convert.ToString(a,2);int c=0,l=0,p=0,k=0,j=s.Length-1,i=j;for(;i>=0;i--){if(s[i]>'0'){if(i==j||s[i+1]<'1'){p=i;c=0;}if(++c>=l){l=c;k=p;}}}return j-k;}

ลองออนไลน์!

ไม่ใช่Linqวิธีแก้ปัญหาซึ่งฉันแน่ใจว่าสามารถปรับปรุงได้แม้ว่าจะไม่มีอะไรปรากฏขึ้นทันที

Degolfed

a=>{
    var s=Convert.ToString(a,2); // Convert to binary
    int c=0,l=0,p=0,k=0,j=s.Length-1,i=j;
    for(;i>=0;i--)               // Loop from end of string
    {
        if(s[i]>'0')             // if '1'
        {
            if(i==j||s[i+1]<'1') // if first digit or previous digit was '0'
            {
                p=i;             // set the position of the current group
                c=0;             // reset the count
            }
            if(++c>=l)           // if count is equal or greater than current largest count
            {
                l=c;             // update largest count
                k=p;             // store position for this group
            }
        }
    }
    return j-k;                  // as the string is reversed, return string length minus position of largest group
}

1
คุณสามารถบันทึกได้ 8 ไบต์โดยrการเขียนคำตอบแรก: tio.run/##dY9RS8MwFIWfza/…
Grzegorz Puławski

คุณสามารถบันทึกสองไบต์ในพอร์ตของArnauldของคุณเช่นนี้:T=a=>{int x=(int)Math.Log(a,2);return(a&=a/2)>0?T(a):x<0?0:x;}
Kevin Cruijssen

1
หรือแม้กระทั่งอีกสองไบต์ที่บันทึกไว้ ( 60 ไบต์ ):T=a=>(a&a/2)>0?T(a&a/2):Math.Log(a,2)<0?0:(int)Math.Log(a,2)
Kevin Cruijssen

2

Huskขนาด 12 ไบต์

→S§-€¤≠Lo▲gḋ

ลองออนไลน์!

คำอธิบาย

                 Implicit input, e.g                           750
           ḋ     Convert to binary                             [1,0,1,1,1,0,1,1,1,0]
          g      Group equal elements                          [[1],[0],[1,1,1],[0],[1,1,1],[0]]
        o▲       Maximum                                       [1,1,1]
    €            Index of that substring in the binary number  3
     ¤≠L         Absolute difference of lengths                abs (3 - 10) = 7
 S§-             Subtract the two                              7 - 3 = 4
→                Increment                                     5

2

เยลลี่ ,  14 13 12  11 ไบต์

Bµṣ0Ṫ$ƤMḢạL

ลิงก์ monadic ที่รับและส่งคืนจำนวนเต็มที่ไม่เป็นลบ

ลองออนไลน์! หรือดูการทดสอบในตัว

อย่างไร?

Bµṣ0Ṫ$ƤMḢạL - Main link: number, n                   e.g. 750
B           - convert to a binary list                    [1,0,1,1,1,0,1,1,1,0]
 µ          - monadic chain separation, call that b
      Ƥ     - map over prefixes:  (i.e. for [1], [1,0], [1,0,1], [1,0,1,1],...)
     $      -   last two links as a monad:                e.g.: [1,0,1,1,1,0,1,1]
   0        -     literal zero                                   0
  ṣ         -     split (prefix) at occurrences of (0)           [[1],[1,1,1],[1,1]]
    Ṫ       -     tail                                                        [1,1]
       M    - maximal indices                             [5,9]
        Ḣ   - head                                        5
          L - length (of b)                               10
         ạ  - absolute difference                         5

ฉันมีโซลูชันที่คล้ายกัน แต่ใช้ŒrṪPกับคำนำหน้าแทน
ไมล์

2

เยลลี่ขนาด 19 ไบต์

BŒgḄṀB
BwÇɓÇL+ɓBL_‘

ลองออนไลน์!

ขอบคุณ Jonathan Allan สำหรับการบันทึก 4  6 ไบต์!

ฉันทำงานมากเกินไปที่จะละทิ้งสิ่งนี้แม้ว่ามันจะนาน ฉันอยากจะเพิ่มวิธีแก้ปัญหาที่ค้นหาสตริงย่อยที่ยาวที่สุดของ1s ในการแทนฐานสอง ...

คำอธิบาย

BŒgḄṀB - ลิงค์ผู้ช่วยเหลือ Monadic จะใช้กับÇในลิงค์ถัดไป

B - การเป็นตัวแทนไบนารี
 Œg - กลุ่มทำงานขององค์ประกอบที่เท่ากันติดต่อกัน
   Ḅ - แปลงจากเลขฐานสองเป็นจำนวนเต็ม
    Ṁ - ค่าสูงสุด
     B - แปลงจากจำนวนเต็มเป็นไบนารี


BwÇɓÇL + ɓBL_ '- ลิงก์หลัก

B - การเป็นตัวแทนไบนารี (จากอินพุต)
  Ç - ลิงก์สุดท้ายเป็น monad ใช้จำนวนเต็มอินพุท
 w - ดัชนีรายการย่อยแรก
   ɓ - เริ่มต้นห่วงโซ่ dyadic แยก ฝืนอาร์กิวเมนต์
    Ç - ลิงก์สุดท้ายเป็น monad
     L - ความยาว
      + - การเพิ่ม
       ɓ - เริ่มต้นห่วงโซ่ dyadic แยก ฝืนอาร์กิวเมนต์
        B - ไบนารี
         L - ความยาว
          _ '- ลบและเพิ่มผลลัพธ์ (เพราะ Jelly ใช้การจัดทำดัชนี 1 รายการ)
              - เอาท์พุทโดยปริยาย

ลิงก์ผู้ช่วยของคุณอาจเป็นBŒgḄṀBแทน
Jonathan Allan

@JanathanAllan โอ้ว้าวขอบคุณมาก!
Mr. Xcoder

ลิงก์หลักของคุณอาจเป็นBwÇɓÇL+ɓBL_‘
Jonathan Allan

@JanathanAllan ว้าวขอบคุณอีกครั้ง!
Mr. Xcoder

2

Kotlin , 77 ไบต์

{val b=it.toString(2)
b.reversed().lastIndexOf(b.split(Regex("0+")).max()!!)}

เชิดชู

{
    val b = it.toString(2)
    // Find the left position of the first instance of
    b.reversed().lastIndexOf(
            // The largest group of 1s
            b.split(Regex("0+")).max()!!)
}

ทดสอบ

var s:(Int)->Int =
{val b=it.toString(2)
b.reversed().lastIndexOf(b.split(Regex("0+")).max()!!)}
fun main(args: Array<String>) {
    r(0, 0)
    r(142, 1)
    r(48, 4)
    r(750, 5)
}

fun r(i: Int, i1: Int) {
    var v = s(i)
    println("$i -> $v [$i1] ${i1 == v}")
}

ฉันไม่ได้ทดสอบ แต่คิดว่างานนี้เป็นแบบสกาล่าด้วย
V. Courtois

2

Haskell , 101 98 96 75 ไบต์

snd.maximum.(`zip`[0..]).c
c 0=[0]
c n|r<-c$div n 2=sum[r!!0+1|mod n 2>0]:r

ลองออนไลน์! การใช้งาน:snd.maximum.(`zip`[0..]).c $ 1421อัตราผลตอบแทน

คำอธิบาย:

  • cแปลงอินพุตเป็นไบนารี่ในขณะเดียวกันก็ทำการนับความยาวของริ้วรอยหนึ่งโดยรวบรวมผลลัพธ์ในรายการ r<-c$div n 2ซ้ำคำนวณส่วนที่เหลือrของรายการนี้ในขณะที่เพิ่มความยาวปัจจุบันของแนวไปsum[r!!0+1|mod n 2>0]:r rความเข้าใจในรายการจะตรวจสอบmod n 2>0ว่านั่นคือเลขฐานสองปัจจุบันหรือไม่และถ้าใช่จะใช้ความยาวของแนวก่อนหน้า (องค์ประกอบแรกของr) และเพิ่มเข้าไปอีกหนึ่งตัว มิฉะนั้นความเข้าใจในรายการเป็นที่ว่างเปล่าและอัตราผลตอบแทนsum[] 0สำหรับอินพุตตัวอย่างc 142ให้ผลลัพธ์รายการ[0,3,2,1,0,0,0,1,0]ผลตอบแทนถัวเฉลี่ยรายการ

  • (`zip`[0..])เพิ่มตำแหน่งให้กับองค์ประกอบของรายการก่อนหน้านี้เป็นองค์ประกอบที่สองของ tuple สำหรับตัวอย่างนี้ให้[(0,0),(3,1),(2,2),(1,3),(0,4),(0,5),(0,6),(1,7),(0,8)]ตัวอย่างเช่นนี้จะช่วยให้

  • maximumค้นหา tuple lexicographically สูงสุดในรายการนี้นั่นคือความยาวแนวที่จะถูกพิจารณาก่อนเป็นพวกเขาเป็นองค์ประกอบแรกและในกรณีที่ผูกองค์ประกอบที่สองคือดัชนีขนาดใหญ่ตัดสินใจ สิ่งนี้ให้ผล(3,1)ในตัวอย่างและsndส่งกลับองค์ประกอบที่สองของ tuple




2

MS SQL Server, 437 426 407 398 bytes

ซอ Fiddle

ฉันแน่ใจว่าฉันสามารถลบการขึ้นบรรทัดใหม่ได้ แต่นี่มันมีขนาดกะทัดรัดเท่าที่ฉันต้องการ:

create function j(@ int)
returns int
as BEGIN
declare @a varchar(max)='',@b int,@c int=0,@d int=0,@e int=0,@f int=0,@g int=0,@h int=0
while @>0 BEGIN SELECT @a=cast(@%2 as char(1))+@a,@=@/2
END
SET @b=len(@a)
while @<@b
BEGIN
select @c=@d,@d=cast(substring(@a,@b-@,1)as int)
IF @d=1
BEGIN IF @c=0
SELECT @e=@,@g=1
else SET @g+=1 END
IF @g>=@h BEGIN select @h=@g,@f=@e END
SET @+=1
END
return @f
END

นี่คือรุ่นที่อ่านได้มากขึ้น:

create function BinaryString(@id int)
returns int
as BEGIN
  declare @bin varchar(max)
  declare @binLen int
  declare @pVal int = 0
  declare @Val int = 0
  declare @stC int = 0 --start of current string of 1s
  declare @stB int = 0 --start of biggest string of 1s
  declare @lenC int = 0 --length of current string of 1s
  declare @lenB int = 0 --length of biggest string of 1s

  set @bin = ''

    while @id>0
      BEGIN
        SET @bin = cast(@id%2 as varchar(1)) + @bin
        SET @id = @id/2
      END

    SET @binLen = len(@bin)

    while @id<@binLen
      BEGIN
        set @pVal = @Val
        set @Val = cast(substring(@bin,@binLen-@id,1) as int)
        IF @Val = 1 and @pVal = 0
          BEGIN 
            SET @stC = @id
            SET @lenC = 1
          END
        IF @Val = 1 and @pVal = 1
          BEGIN 
            SET @lenC = @lenC + 1
          END
        IF @lenC >= @lenB
          BEGIN
            set @lenB = @lenC
            set @StB = @StC
          END

        SET @id = @id + 1 
      END

  return @StB
END

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

I'm sure there's a better way to do this, but I didn't see a(n) SQL answer, so I figured I'd throw it out there.


If you can golf it more, please do so. But otherwise, this is great! Welcome to PPCG!
NoOneIsHere

@NoOneIsHere thanks! I realized I can shorten my function name too ;)
phroureo

2

APL (Dyalog Unicode), 22 chars = 53 bytes

Requires ⎕IO←0 which is default on many systems.

⊃⌽⍸(∨⌿↑⊆⍨b)⍷⌽b2⊥⍣¯1⊢⎕

Try it online!

 prompt for input

 yield that (separates ¯1 from )

2⊥⍣¯1 convert to base-2, using as many positions as needed

b← store as b (for binary)

 reverse

() mark the starting positions of the following in that:

⊆⍨b self-partition b (i.e. the 1-streaks of b)

 mix (make list of lists into matrix, padding with zeros)

∨⌿ vertical OR reduction (yields longest streak)

ɩndices of starting positions

 reverse

 pick the first one (yields zero if none available)


you're missing a ∇ in the footer on tio
ngn

@ngn Right you are.
Adám

1

MATL, 15 bytes

`tt2/kZ&t]xBnq&

Try it online!

Uses the half and AND idea. The k is necessary only to make it terminate for 1 - for some reason, 1 AND 0.5 returns 1, causing an infinite loop.

(alternate solution: BtnwY'tYswb*&X>)- by converting to binary and run-length encoding)


1

Google Sheets, 94 bytes

=Len(Dec2Bin(A1))-Find(MAX(Split(Dec2Bin(A1),0)),Dec2Bin(A1))-Len(MAX(Split(Dec2Bin(A1),0)))+1

No, it's not very pretty. It'd be real nice to be able to store Dec2Bin(A1) as a variable for reference.

Key point: Like Excel, the Dec2Bin function has a max input value of 511. Anything larger than that returns an error, as seen below.

Results


1

R, 117 Bytes

z=rev(Reduce(function(x,y)ifelse(y==1,x+y,y),strtoi(intToBits(scan())),,,T));ifelse(!sum(z),0,33-which.max(z)-max(z))

104 bytes! Instead of rev, use Reduce(...,T,T) to accumulate from the right (switching x,y in the function definition). Then use 1+max(z)-which.max(z) since the result is somewhat different. Use "if" instead of "ifelse" since we don't need the vectorization; aaand if you use any(z) instead of !sum(z) you drop a byte.
Giuseppe

I think we should be able to get this to less than 100 bytes.
Giuseppe

@giuseppe I feel somewhat a cheater for being here before you! Will do times tnx a bunch!
Zahiro Mor

But a nice approach no ?
Zahiro Mor

1
Oh, no worries, I saw this earlier but didn't feel like answering it because R is so bad at bit operations... Yeah, good work, you got my +1
Giuseppe

1

Excel VBA, 54 44 Bytes

-10 Bytes thanks to @EngineerToast

Anonymous VBE immediate window function that takes input from range [A1] and outputs to the VBE immediate window

?Instr(1,StrReverse([Dec2Bin(A1)]),1)+[A1>0]

1
Besides the oversight having C1 still in there instead of A1, I think you can output the Instr results directly with a little twisting for the zero input correction: ?Instr(1,StrReverse([Dec2Bin(A1)]),1)+([A1]>0) (46 bytes). True = -1 because... VBA.
Engineer Toast

@EngineerToast - Sweet! I should have seen that; I was able to drop it down 2 bytes by bringing the >0 into the [A1] notation
Taylor Scott



0

R, 66 Bytes

function(i){a=rle(intToBits(i));max(0,a[[1]][which(a[[2]]==1)])}

Explanation:

function(i){
  a = rle(                  # Run-length encode
    intToBits(i)            # The bits in i
  );                        # And assign it to a.
  max(0,                    # Return the maximum of zero and
      a[[1]][               # The lengths of a,
        which(a[[2]]==1)    # But only those where the repeated bit is 1
        ])
}

1
This returns the length of the longest streak, not its position. Check against the test cases and the specs at the top.
user2390246

I will change my downvote to an upvote once this answer is corrected. Also, note that you can use a$l instead of a[[1]] and a$v instead of a[[2]] to save some bytes :), as well as >0 instead of ==1.
Giuseppe


0

Javascript, 54 chars

f=i=>i.toString(2).split(0).sort().reverse()[0].length
  • i.toString(2) gets the binary string for the integer.
  • The .split(0) gets each sequential ones part in an array element.
  • .sort().reverse() gets us the highest value as first.
  • The [0].length gives us the length of that first value.

the starting position of number of largest consecutive 1's
L3viathan

0

Perl 5, 45 + 1 (-p)

(sprintf"%b",$_)=~/(1+)(?!.*1\1)/;$_=length$'

If you write this out on the command line of most shells, you may have to type this as:

perl -pE'(sprintf"%b",$_)=~/(1+)(?!.*1\1)/;$_=length$'"'"

The dance of the quotes at the end is just to get perl see a ', which would otherwise be consumed by the shell.


0

Retina, 52 43 bytes

Convert to binary, then replace with the length of what follows the largest string of ones.

.*
$*
+`(1+)\1
$+0
01
1

$'¶
O`
A-3`
^1+

.

Try it online - all test cases

Saved 9 bytes thanks to Martin.


You can use $+ for ${1}. But you can save even more by replacing the last stage with a bunch of stages like this: tio.run/##K0otycxL/K/…
Martin Ender

@MartinEnder Ok. The ${1} was copied from your tutorial on Github.
mbomb007
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.