จำนวนขององค์ประกอบที่ไม่ว่างที่แตกต่างกันของการขยายฐานสอง


19

การเรียงลำดับคือลำดับใด ๆ ที่คุณสามารถหาได้จากอีกอันด้วยการลบจำนวนอักขระใด ๆ subsequences ไม่ว่างเปล่าที่แตกต่างของ100มี0, 1, 00, ,10 100subsequences ไม่ว่างเปล่าที่แตกต่างของ1010มี0, 1, 00, 01, 10, 11,010 , 100, 101, ,1101010

เขียนโปรแกรมหรือฟังก์ชั่นที่ให้จำนวนเต็มบวก nส่งกลับจำนวนของ subsequences ไม่ว่างเปล่าที่แตกต่างกันของการขยายตัวไบนารีของn

ตัวอย่าง: ตั้งแต่4เป็น100ในไบนารีและเราเห็นว่ามันมีห้า subsequences f(4) = 5ไม่ว่างเปล่าที่แตกต่างกันข้างต้นดังนั้น เริ่มต้นจากn = 1ลำดับเริ่มต้น:

1, 3, 2, 5, 6, 5, 3, 7, 10, 11, 9, 8, 9, 7, 4, 9, 14, 17, 15, 16, 19, 17, 12

อย่างไรก็ตามโปรแกรมของคุณจะต้องใช้งานได้กับn <2 50ภายในไม่กี่วินาทีบนเครื่องที่ทันสมัย ตัวอย่างขนาดใหญ่:

f(1099511627775) = 40
f(1099511627776) = 81
f(911188917558917) = 728765543
f(109260951837875) = 447464738
f(43765644099) = 5941674

4
ฉันไม่เห็นด้วยกับการ จำกัด เวลา
ATaco

1
เรื่องนี้ฟังดูคุ้นเคยจริงๆโดยเฉพาะหลังจากดูที่เนื้อเรื่อง ปรากฎว่าฉันมองเข้าไปในลำดับที่เกี่ยวข้องอย่างใกล้ชิดเมื่อต้นปีนี้ แต่ฉันนับจำนวนเลขฐานสองที่แตกต่างกันไม่ใช่สายอักขระไบนารีคุณจะได้รับเมื่อรับการจัดเรียง (ดังนั้นฉันจึงลดเลขศูนย์นำหน้า) ฉันทำแซนด์บ็อกซ์แล้ว แต่เนื่องจากความเท่าเทียมในโพสต์ Math.SE มันน่าจะเป็นผลมาจากความท้าทาย Stern-Brocot พล็อตของลำดับของคุณเป็นบิตที่ดีกว่า (เช่นวุ่นวายมากขึ้น) แม้ว่า :)
Martin Ender

5
@ATaco การ จำกัด เวลามีเหตุผลที่ดี มีอัลกอริทึมที่มีประสิทธิภาพและเป็นที่น่าสนใจ แต่สามารถเล่นกอล์ฟได้ดี ถ้าฉันไม่มีข้อ จำกัด ด้านเวลาฉันรู้สึกว่าเกือบทุกคำตอบจะทำให้เดรัจฉานบังคับได้ทั้งหมดซึ่งเร็วมากจะไม่ทำงานอีกต่อไป ในความรู้สึกพวกเขาไม่ใช่คำตอบ
orlp

คำตอบ:


10

Python 3 , 95 ไบต์ 83 ไบต์

[-12 ไบต์ขอบคุณ Mr.XCoder :)]

def f(x):
 v=[2,1];c=1
 for i in bin(x)[3:]:k=int(i);c+=v[k];v[1-k]+=v[k]
 return c

ลองออนไลน์!

หมายเหตุเกี่ยวกับอัลกอริทึม อัลกอริธึมคำนวณการเพิ่มขึ้นของลำดับที่เป็นเอกลักษณ์ที่กำหนดโดยบิต ณ ตำแหน่งที่กำหนด t การเพิ่มสำหรับบิตแรกจะเป็น 1 เสมอจากนั้นอัลกอริธึมจะทำงานตามลำดับของบิต s (t) และเพิ่มการเพิ่ม v [s (t)] ในแต่ละขั้นตอนการเพิ่มส่วนเสริมของ s (t), v [1 - s (t)] ได้รับการปรับปรุงเป็น v [1] + v [0] ตัวเลขสุดท้ายคือผลรวมของการเพิ่มขึ้นทั้งหมด

มันควรจะทำงานใน O (log2 (n)) โดยที่ n คือหมายเลขอินพุต



8

JavaScript (ES6), 53 51 ไบต์

f=(n,r=~(a=[]))=>n<1?~r:f(n/2,r*2-~~a[n&=1],a[n]=r)

กรณีทดสอบ

จัดรูปแบบและแสดงความคิดเห็น

f = (                      // f is a recursive function taking:
  n,                       //   n = integer
  r = ~(                   //   r = last result, initially set to -1
    a = []                 //   and using a[] = last results for 0 and 1,
  )                        //   implicitly initialized to [0, 0]
) =>                       //
  n < 1 ?                  // if n is less than 1:
    ~r                     //   we're done: return -(r + 1)
  :                        // else:
    f(                     //   do a recursive call with:
      n / 2,               //     n / 2
      r * 2 - ~~a[n &= 1], //     updated result = r * 2 - last result for this binary digit
      a[n] = r             //     update last result for this binary digit
    )                      //   end of recursive call

รุ่นที่ไม่ใช่แบบเรียกซ้ำ 63 ไบต์

บันทึก 3 ไบต์ด้วย @ThePirateBay

s=>[...s.toString(2)].map(l=c=>l[p=r,r=r*2-~~l[c],c]=p,r=1)|r-1

กรณีทดสอบ


ฉันคิดว่าคุณสามารถบันทึก 3 ไบต์โดยการกำหนดฟังก์ชั่นภายใน (อาร์กิวเมนต์แรกของmap) ให้กับตัวแปรธงlแทนอาร์เรย์ที่ว่างเปล่า

@ThePirateBay นิสัยดี ขอบคุณ!
Arnauld

7

Python 2 , 56 ไบต์

f=lambda x,a=1,b=1:x and f(x/2,a+~x%2*b,x%2*a+b)or a+b-2

ลองออนไลน์!

ใช้วิธีการจาก NofPNofP

59 ไบต์ซ้ำ ๆ กัน:

x=input()
v=[1,1]
while x:v[x%2]=sum(v);x/=2
print sum(v)-2

ลองออนไลน์!


อัลกอริทึมที่ดี คุณจะเพิ่มคำอธิบายสั้น ๆ เกี่ยวกับสาเหตุที่ใช้งานได้ไหม
โยนาห์

6

เยลลี่ 10 ไบต์

B3;BSṛ¦/’S

การใช้งานนี้@ ปรับปรุง XNOR ของบน@ อัลกอริทึมของ NofPอัลกอริทึมของ

ลองออนไลน์!

พื้นหลัง

ให้(เป็น1 ... เป็นn )เป็นลำดับไบนารี จำกัด สำหรับจำนวนเต็มที่ไม่เป็นลบแต่ละค่าk ≤ nให้นิยามo kเป็นจำนวนองค์ประกอบที่ไม่ซ้ำกันของ( 1 , ... , a k )ที่ว่างเปล่าหรือสิ้นสุดใน1 , z kเป็นจำนวนองค์ประกอบพิเศษที่เป็นเอกลักษณ์ ว่างเปล่าหรือสิ้นสุดใน0 0

เห็นได้ชัดว่าo 0 = z 0 = 1เนื่องจากลำดับเดียวของลำดับว่างคือลำดับว่าง

สำหรับดัชนีแต่ละk , จำนวน subsequences ของ(ก1 , ... เป็นk )คือo k + Z k - 1 (ลบ1บัญชีสำหรับความจริงที่ว่าทั้งสองo kและZ kนับลำดับว่างเปล่า) จำนวนไม่ว่างเปล่า subsequences จึงo k Z + k - 2 ความท้าทายขอให้คำนวณo n + z n - 2 2

เมื่อใดก็ตามที่k> 0เราสามารถคำนวณo kและz kซ้ำได้ มีสองกรณี:

  • k = 1

    z k = z k-1เนื่องจาก( 1 , ... , a k-1 )และ(a 1 , ... , k-1 , 1)มีองค์ประกอบเดียวกันที่ลงท้ายด้วย0 0

    สำหรับแต่ละo k - 1 subsequences ไม่ว่างเปล่าของ(ก1 , ... เป็นk )สิ้นสุดที่1เราสามารถลบต่อท้าย1ที่จะได้รับหนึ่งในo K-1 + Z K-1 - 1 subsequences (เป็น1 ... เป็นK-1 ) ตรงกันข้ามผนวก1ให้กับแต่ละหลังo K-1 + Z K-1 - 1ลำดับผลการค้นหาในหนึ่งในo k - 1อดีตลำดับ ดังนั้นo k - 1 = oK-1 + Z K-1 - 1และ o k = o K-1 + Z k-1

  • a k = 0

    ในทำนองเดียวกันกับกรณีก่อนหน้านี้เราได้รับสูตร recursive o k = o K-1และZ k = Z K-1 + O k-1

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

B3;BSṛ¦/’S  Main link. Argument: n (positive integer)

B           Binary; convert n to base 2.
 3;         Prepend a 3.
   B        Binary; convert all integers in the resulting array to base 2, mapping
            0 to [0], 1 to [1], and the prepended 3 to [1, 1].
       /    Reduce the resulting array by the quicklink to the left, which will be 
            called with left argument [x, y] (integer pair) and right argument [j] 
            (either [0] or [1]).
      ¦     Sparse application.
    S           Compute the sum (x + y) and...
     ṛ          for each index in the right argument (i.e., for j)...
            replace the element of [x, y] at that index with (x + y).
       ’    Decrement both integers in the resulting pair.
        S   Take the sum.

เฮ้เดนนิสคุณจะเพิ่มคำอธิบายสั้น ๆ เกี่ยวกับสาเหตุที่อัลกอริทึมทำงานอย่างไร
โยนาห์

ฉันได้เพิ่มคำอธิบายแล้ว
Dennis

4

05AB1E , 12 ไบต์

0¸sbvDO>yǝ}O

ลองออนไลน์! คำอธิบาย: ตามที่อธิบายโดยคำตอบอื่น ๆ จำนวนของการประกอบสำหรับสตริงไบนารีa..y0ที่ลงท้ายด้วย 1 จะเหมือนกับหมายเลขสำหรับสตริงไบนารีa..yในขณะที่ตัวเลขที่ลงท้ายด้วย a 0นั้นคือจำนวนทั้งหมดของการประกอบสำหรับไบนารี สตริงa..y(ซึ่งแต่ละคนจะได้รับ0ส่วนต่อท้าย) บวกหนึ่งสำหรับ0ตัวเอง แตกต่างจากคำตอบอื่น ๆ ฉันไม่ได้รวมการเรียงลำดับที่ว่างเปล่าเพราะสิ่งนี้ช่วยประหยัดไบต์ที่สร้างสถานะเริ่มต้น

0¸s             Push [0] under the input
   b            Convert the input to binary
    v     }     Loop over the digits
     D          Duplicate the array
      O         Take the sum
       >        Increment
        yǝ      Replace the index corresponding to the binary digit
           O    Take the sum of the final array

1

Java 8, 97 ไบต์

n->f(n,1,1)long f(long n,long a,long b){return n>0?f(n/2,a+Math.floorMod(~n,2)*b,n%2*a+b):a+b-2;}

พอร์ตของคำตอบ Python 2ของ@xnorซึ่งจะเป็นการปรับปรุงคำตอบ Python 3ของ@NnPPคำตอบ

ลองที่นี่


อาจจะเป็นเรื่องดีที่มีการแท็กอยู่เพราะในตอนแรกฉันมีสิ่งต่อไปนี้เพื่อกำหนดองค์ประกอบทั้งหมด:

import java.util.*;n->p(n.toString(n,2)).size()-1;Set p(String s){Set r=new HashSet();r.add("");if(s.isEmpty())return r;Set q=p(s.substring(1));r.addAll(q);for(Object o:q)r.add(""+s.charAt(0)+o);return r;}

ลองที่นี่

ซึ่งใช้งานได้ แต่ใช้เวลานานเกินไปสำหรับกรณีทดสอบสามครั้งล่าสุด ไม่ต้องพูดถึงอีกต่อไป ( 208 204 ไบต์ )


1

รหัสเครื่อง 6502 (C64), 321 ไบต์

00 C0 20 FD AE A2 00 9D 4F C1 E8 20 73 00 90 F7 9D 4F C1 A0 FF C8 B9 4F C1 D0
FA A2 15 CA 88 30 0A B9 4F C1 29 0F 9D 4F C1 10 F2 A9 00 9D 4F C1 CA 10 F8 A9
00 A0 07 99 64 C1 88 10 FA A0 40 A2 6C 18 BD E4 C0 90 02 09 10 4A 9D E4 C0 E8
10 F2 A2 07 7E 64 C1 CA 10 FA 88 F0 13 A2 13 BD 50 C1 C9 08 30 05 E9 03 9D 50
C1 CA 10 F1 30 D1 A2 0F A9 00 9D 3F C1 CA D0 FA A9 01 8D 3F C1 8D 47 C1 A2 08
CA BD 64 C1 F0 FA A0 09 1E 64 C1 88 90 FA B0 0A CA 30 28 A0 08 1E 64 C1 90 04
A9 47 B0 02 A9 4F 8D AF C0 86 FE A2 F8 18 BD 47 C0 7D 4F C0 9D 47 C0 E8 D0 F4
A6 FE 88 D0 DC F0 D5 A2 F8 BD 47 C0 7D 4F C0 9D 6C C0 E8 D0 F4 AD 64 C1 E9 01
8D 64 C1 A2 F9 BD 6C C0 E9 00 9D 6C C0 E8 D0 F5 A0 15 A9 00 99 4E C1 88 D0 FA
A0 40 A2 13 BD 50 C1 C9 05 30 05 69 02 9D 50 C1 CA 10 F1 0E 64 C1 A2 F9 3E 6C
C0 E8 D0 FA A2 13 BD 50 C1 2A C9 10 29 0F 9D 50 C1 CA 10 F2 88 D0 D1 E0 14 F0
06 E8 BD 4F C1 F0 F6 09 30 99 4F C1 C8 E8 E0 15 F0 05 BD 4F C1 90 F0 A9 00 99
4F C1 A9 4F A0 C1 4C 1E AB

การสาธิตออนไลน์

การสาธิตออนไลน์พร้อมการตรวจสอบข้อผิดพลาด (346 ไบต์)

การใช้งาน: เช่นsys49152,[n]sys49152,911188917558917

การ จำกัด เวลาและกรณีทดสอบจำเป็นต้องมีวิธีแก้ปัญหาในการคำนวณตัวเลข 64 บิตดังนั้นเวลาที่จะพิสูจน์ว่า C64 มีคุณสมบัติเป็น " เครื่องจักรที่ทันสมัย ";)

แน่นอนว่ามันต้องการรหัสค่อนข้างน้อยระบบปฏิบัติการไม่ได้ให้อะไรเลยสำหรับจำนวนเต็มที่มากกว่า 16 บิต ส่วนที่อ่อนแอที่นี่: ก็ยังดำเนินการอื่น (แก้ไขเล็กน้อย) ของNofP ของอัลกอริทึมรับผิดชอบ XNOR ของตัวแปรที่ดีขึ้น ขอบคุณสำหรับความคิด;)


คำอธิบาย

นี่คือรายการถอดแยกชิ้นส่วนที่แสดงความคิดเห็นของส่วนที่เกี่ยวข้องทำอัลกอริทึม

.C:c06c  A2 0F       LDX #$0F           ; 15 bytes to clear
.C:c06e  A9 00       LDA #$00
.C:c070   .clearloop:
.C:c070  9D 3F C1    STA .num_a,X
.C:c073  CA          DEX
.C:c074  D0 FA       BNE .clearloop
.C:c076  A9 01       LDA #$01           ; initialize num_a and num_b
.C:c078  8D 3F C1    STA .num_a         ; to 1
.C:c07b  8D 47 C1    STA .num_b
.C:c07e  A2 08       LDX #$08           ; 8 bytes of input to check,
.C:c080   .findmsb:                     ; start at most significant
.C:c080  CA          DEX
.C:c081  BD 64 C1    LDA .nc_num,X
.C:c084  F0 FA       BEQ .findmsb       ; repeat until non-0 byte found
.C:c086  A0 09       LDY #$09           ; 8 bits to check (+1 for pre dec)
.C:c088   .findbit:
.C:c088  1E 64 C1    ASL .nc_num,X      ; shift left, highest bit to carry
.C:c08b  88          DEY
.C:c08c  90 FA       BCC .findbit       ; bit was zero -> repeat
.C:c08e  B0 0A       BCS .loopentry     ; jump into calculation loop
.C:c090   .mainloop:
.C:c090  CA          DEX                ; next byte
.C:c091  30 28       BMI .done          ; index -1? -> done calculating
.C:c093  A0 08       LDY #$08           ; 8 bits to check
.C:c095   .bitloop:
.C:c095  1E 64 C1    ASL .nc_num,X      ; shift left, highest bit to carry
.C:c098  90 04       BCC .tgt_b         ; if 0, store addition result in num_b
.C:c09a   .loopentry:
.C:c09a  A9 47       LDA #$47
.C:c09c  B0 02       BCS .tgt_a         ; ... else store in num_a ...
.C:c09e   .tgt_b:
.C:c09e  A9 4F       LDA #$4F
.C:c0a0   .tgt_a:
.C:c0a0  8D AF C0    STA $C0AF          ; ... using self-modification.
.C:c0a3  86 FE       STX $FE            ; save byte index
.C:c0a5  A2 F8       LDX #$F8           ; index for adding
.C:c0a7  18          CLC
.C:c0a8   .addloop:
.C:c0a8  BD 47 C0    LDA $C047,X        ; load byte from num_a
.C:c0ab  7D 4F C0    ADC $C04F,X        ; add byte from num_b
.C:c0ae  9D 47 C0    STA $C047,X        ; store to num_a or num_b
.C:c0b1  E8          INX                ; next index
.C:c0b2  D0 F4       BNE .addloop       ; done if index overflown
.C:c0b4  A6 FE       LDX $FE            ; restore byte index
.C:c0b6  88          DEY                ; decrement bit index
.C:c0b7  D0 DC       BNE .bitloop       ; bits left in current byte -> repeat
.C:c0b9  F0 D5       BEQ .mainloop      ; else repeat main loop
.C:c0bb   .done:
.C:c0bb  A2 F8       LDX #$F8           ; index for adding
.C:c0bd   .addloop2:
.C:c0bd  BD 47 C0    LDA $C047,X        ; load byte from num_a
.C:c0c0  7D 4F C0    ADC $C04F,X        ; add byte from num_b
.C:c0c3  9D 6C C0    STA $C06C,X        ; store to nc_num (result)
.C:c0c6  E8          INX                ; next index
.C:c0c7  D0 F4       BNE .addloop2      ; done if index overflown
.C:c0c9  AD 64 C1    LDA .nc_num        ; load least significant result byte
.C:c0cc  E9 01       SBC #$01           ; subtract 2 (1 + negated carry)
.C:c0ce  8D 64 C1    STA .nc_num        ; store least significant result byte
.C:c0d1  A2 F9       LDX #$F9           ; index for subtract
.C:c0d3   .subloop:
.C:c0d3  BD 6C C0    LDA $C06C,X        ; subtract 0 from all other bytes
.C:c0d6  E9 00       SBC #$00           ; for handling carry if necessary
.C:c0d8  9D 6C C0    STA $C06C,X
.C:c0db  E8          INX
.C:c0dc  D0 F5       BNE .subloop       

ส่วนที่เหลือเป็นอินพุต / เอาต์พุตและการแปลงระหว่างสตริงและจำนวนเต็ม 64 บิตที่ไม่ได้รับการลงชื่อ (little-endian) โดยใช้อัลกอริทึม double-dabble ในกรณีที่คุณสนใจนี่คือแหล่งประกอบทั้งหมดสำหรับรุ่นที่มีการตรวจสอบข้อผิดพลาด - รุ่น "golfed" อยู่ในสาขา "กอล์ฟ"

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.