สารตั้งต้นไบนารี


17

แรงบันดาลใจจากปัญหาที่สี่จากBMO2 2009

ป.ร. ให้ไว้เป็นจำนวนเต็มบวกnเป็น input หรือพารามิเตอร์กลับจำนวนของจำนวนเต็มบวกที่มีการแสดงไบนารีเกิดขึ้นเป็นบล็อกในการขยายตัวไบนารีของn

ยกตัวอย่างเช่น 13 -> 6 เพราะ 13 ในไบนารี 1101 1101, 110, 101, 11, 10, 1และมีสตริง เราจะไม่นับเลขฐานสองที่ขึ้นต้นด้วยศูนย์และเราจะไม่นับศูนย์เอง

กรณีทดสอบ

13 -> 6
2008 -> 39
63 -> 6
65 -> 7
850 -> 24
459 -> 23
716 -> 22
425 -> 20
327 -> 16

คุณอาจใช้nเป็นดังต่อไปนี้:

  • จำนวนเต็ม
  • รายการค่าความจริง / เท็จสำหรับการเป็นตัวแทนไบนารี
  • สตริงสำหรับการเป็นตัวแทนไบนารี
  • สตริง 10 ฐาน (แม้ว่าฉันไม่แน่ใจว่าทำไมใครจะทำเช่นนี้)

ทำให้รหัสของคุณสั้นที่สุด


3
คุณสามารถยืนยัน 63-> 5 และไม่ใช่ 6 ได้หรือไม่? Bin (63) = 111111 -> สตริงย่อยที่ไม่ใช่ศูนย์หกแบบ
dylnan

ที่เกี่ยวข้อง (ใช้การเรียงลำดับแทนการใช้สตริงย่อยและไม่สนใจค่าศูนย์นำหน้า)
Martin Ender

1
@dylnan Typo แก้ไขแล้ว.
0WJYxW9FMN

@MartinEnder มีความแตกต่างเพียงพอที่จะอยู่ในเว็บไซต์นี้หรือฉันจะลบมันซ้ำซ้อนหรือไม่? ฉันคิดว่ามันแตกต่างกันพอสมควร แต่คุณรู้ดีกว่าฉันมาก
0WJYxW9FMN

@ J843136028 ความแตกต่างที่ใหญ่กว่าสำหรับการไม่ทำซ้ำคือการ จำกัด เวลาในการท้าทายอื่น ๆ คุณไม่เป็นไร. (เพียงแค่โพสต์ลิงค์เพื่อให้ความท้าทายที่ปรากฏขึ้นในแถบด้านข้างของแต่ละคน.)
มาร์ตินเอนเดอร์

คำตอบ:


7

Python 3, 54 50 ไบต์

lambda n:sum(bin(i)[2:]in bin(n)for i in range(n))

ขอบคุณ Rod และ Jonathan Allan สำหรับการบันทึกสี่ไบต์


คุณสามารถย้าย+1จากช่วงไปยังbin(i)
Rod

1
ในความเป็นจริงนับตั้งแต่ที่เรามักจะนับnตัวเองและจะเสมอยกเว้น0จากการนับของเราที่เราสามารถแทนเสมอยกเว้นnและมักจะนับ0(ถัง (n) เริ่มต้น'0b...') ด้วยเหตุนี้เราสามารถลบ1,และ+1ทั้งหมดและลาbin(i)เป็นคือการบันทึกสี่ไบต์ลองออนไลน์!
Jonathan Allan

5

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

ẆQSḢ

ลองออนไลน์!

รับอินพุตเป็นรายการของ0s และ1 s

ลองออนไลน์กับตัวเลข!

คำอธิบาย:

ẆQSḢ Argument: B = list of bits, e.g. [1, 1, 0, 1]
Ẇ    Get B's non-empty sublists (i.e. [[1], [1], [0], [1], [1, 1], [1, 0], [0, 1], [1, 1, 0], [1, 0, 1], [1, 1, 0, 1]])
 Q   Keep first occurrences (i.e. [[1], [0], [1, 1], [1, 0], [0, 1], [1, 1, 0], [1, 0, 1], [1, 1, 0, 1]])
  S  Reduce by vectorized addition (i.e. [6, 4, 1, 1])
   Ḣ Pop first element (i.e. 6)

พิสูจน์การทำงาน:

โปรแกรมนี้ได้รับการป้อนตัวเลขจำนวนที่ ยังไม่มี สิ่งแรกที่ผลิตภัณฑ์นี้ทำคือใช้สสารตั้งต้นของN 2 ( Nในฐาน2 ) ซึ่งรวมถึงสตริงย่อยที่ซ้ำกันเริ่มต้นด้วย0หรือ1 1

หลังจากนั้นเราก็นำสตริงย่อยที่ไม่ซ้ำกันโดยเก็บเฉพาะการเกิดขึ้นครั้งแรกของแต่ละค่าในรายการสตริงย่อย

จากนั้นโปรแกรมนี้สรุปองค์ประกอบแรกของรายการด้วยกันแล้วองค์ประกอบที่สองแล้วสามสี่ ฯลฯ และถ้าหนึ่งของรายการไม่มีองค์ประกอบดังกล่าว0จะถือว่า ความท้าทายที่ถามคืออะไรอย่างมีประสิทธิภาพจำนวนสารตั้งต้นพิเศษที่เริ่มต้นด้วย1หมายเลขนี้มีในรูปแบบไบนารีหรือไม่ . เนื่องจากทุกองค์ประกอบแรกที่จะนับคือ1เราสามารถสรุปผลรวมแทนที่จะกรองสำหรับสารตั้งต้นที่เหมาะสม

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


4

อ็อกเท62 62ไบต์

@(n)sum(arrayfun(@(t)any(strfind((g=@dec2bin)(n),g(t))),1:n))

ลองออนไลน์!

คำอธิบาย

สำหรับการป้อนข้อมูลnรหัสทดสอบตัวเลขทั้งหมดจาก1เพื่อnดูว่าการเป็นตัวแทนไบนารีของพวกเขาเป็นสตริงย่อยของการเป็นตัวแทนไบนารีของการป้อนข้อมูล

@(n)                                                          % Anonymous function of n
        arrayfun(                                      ,1:n)  % Map over range 1:n
                 @(t)                                         % Anonymous function of t
                         strfind(               ,    )        % Indices of ...
                                                 g(t)         % t as binary string ...
                                 (g=@dec2bin)(n)              % within n as binary string
                     any(                             )       % True if contains nonzero
    sum(                                                    ) % Sum of array

3

05AB1E , 5 ไบต์

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

ŒCÙĀO

ลองออนไลน์!

คำอธิบาย

Œ        # push all substrings of input
 C       # convert to base-10 int
  Ù      # remove duplicates
   Ā     # truthify (convert non-zero elements to 1)
    O    # sum

อืม ... ฉันคิดว่าตัวกรองของฉันฉลาด bŒʒć}Ùgแต่ไม่ดีกว่า
Magic Octopus Urn


2

PowerShell , 103 92 82 ไบต์

param($s)(($s|%{$i..$s.count|%{-join$s[$i..$_]};$i++}|sort -u)-notmatch'^0').count

ลองออนไลน์!

ใช้อินพุตเป็นอาร์เรย์1และ0(ความจริงและเท็จใน PowerShell) วนซ้ำ$s(เช่นจำนวนองค์ประกอบในอาร์เรย์อินพุต) ภายในวงที่เราห่วงจากจำนวนปัจจุบัน (บันทึกเป็น$i) $s.countขึ้นไป แต่ละวงด้านในเราจะ-joinแบ่งอาร์เรย์เป็นสตริง จากนั้นเราsortกับ-uธง nique (ซึ่งสั้นกว่าselectด้วย-uธง nique และเราไม่สนใจว่าพวกเขากำลังเรียงหรือไม่) ใช้ผู้ที่ไม่ได้เริ่มต้นด้วยและใช้โดยรวม0 .countที่เหลืออยู่บนไปป์ไลน์และเอาท์พุทเป็นนัย


2

JavaScript (ES6), 55 ไบต์

f=(s,q="0b"+s)=>q&&s.includes((q--).toString(2))+f(s,q)

รับอินพุตเป็นสตริงไบนารี

นี่คือความพยายามที่น่าเศร้าในการทำกับตัวเลขและฟังก์ชันแบบเรียกซ้ำ:

f=(n,q=n)=>q&&(g=n=>n?n^q&(h=n=>n&&n|h(n>>1))(q)?g(n>>1):1:0)(n)+f(s,q-1)

วิธีการแบบเก่า 74 ไบต์

s=>(f=s=>+s?new Set([+s,...f(s.slice(1)),...f(s.slice(0,-1))]):[])(s).size

รับอินพุตเป็นสตริงไบนารีด้วย


1

Python 2 ,  118  81 ไบต์

ขอบคุณ @Rod สำหรับการบันทึก 37 ไบต์!

lambda n:len({int(n[i:j+1],2)for i in range(len(n))for j in range(i,len(n))}-{0})

รับอินพุตเป็นสตริงไบนารี

ลองออนไลน์!

Python 2 , 81 ไบต์

ขอบคุณ @Rod!

lambda n:len({n[i:j+1]for i in range(len(n))for j in range(i,len(n))if'1'==n[i]})

รับอินพุตเป็นสตริงไบนารี

ลองออนไลน์!


คุณสามารถยอมรับสตริงไบนารีเป็นอินพุตคุณยังสามารถแทนที่set(...)ด้วย{...}และxrangeด้วยrange
ร็อด

นอกจากนี้คุณยังสามารถย้าย+1จากช่วงไปยังชิ้นและสลับs.startswithไปint(s,2) เช่นนี้
ร็อด

1
หากคุณต้องการรักษาแนวทางเดิมของคุณคุณสามารถใช้วิธีนี้กับจำนวนไบต์เดียวกัน
Rod

1

เยลลี่ 5 ไบต์

ẆḄQṠS

ลองออนไลน์!

รับอินพุตเป็นรายการ 1s และ 0s ส่วนท้ายของลิงก์ใช้ฟังก์ชันกับตัวอย่างแต่ละตัวอย่างในโพสต์

โจนาธานอัลลันชี้ให้เห็นว่าẆḄQTLเป็นทางเลือก 5 ไบต์ซึ่งใช้Tอะตอมซึ่งค้นหาดัชนีขององค์ประกอบที่เป็นความจริงทั้งหมด

คำอธิบาย

Take bin (13) = 1101 เป็นตัวอย่าง อินพุตคือ[1,1,0,1]

ẆḄQṠS
Ẇ       All contiguous sublists -> 1,1,0,1,11,10,01,110,101,1101 (each is represented as a list)
 Ḅ      From binary to decimal. Vectorizes to each element of the above list -> 1,1,0,1,3,2,1,6,5,13
  Q     Unique elements
   Ṡ    Sign. Positive nums -> 1 , 0 -> 0.
    S   Sum

รับแนวคิด "ใช้ความจริง" (ลงชื่อในกรณีนี้) จากคำตอบที่ 05AB1E


1
คุณสามารถใช้อะตอมของดัชนีความจริงของเยลลี่TกับẆḄQTL
โจนาธานอัลลัน

1

R , 88 77 ไบต์

function(x)sum(!!unique(strtoi(mapply(substring,x,n<-1:nchar(x),list(n)),2)))

ลองออนไลน์!

รับอินพุตเป็นสตริงไบนารี

ใช้mapplyสร้างอาร์เรย์ของสตริงย่อยทั้งหมดของอินพุต strtoiแปลงให้เป็น2จำนวนเต็มฐานและฉันหาผลรวมของการแปลงแบบลอจิคัล ( !!) ของรายการในผลลัพธ์


1

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

.+
*
+`(_+)\1
$1#
#_
_
wp`_.*

ลองออนไลน์! ฉันต้องลองใช้wตัวดัดแปลงของ Retina 1.0 แก้ไข: บันทึก 8 ไบต์ด้วย @MartinEnder คำอธิบาย:

.+
*

แปลงจากทศนิยมเป็นเอก

+`(_+)\1
$1#
#_
_

แปลงจากนารี่เป็นไบนารีโดยใช้#สำหรับ0และ_เป็น 1

wp`_.*

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


คุณสามารถม้วนสุดท้ายสามขั้นตอนเป็นหนึ่งโดยใช้q(หรือpปรับปรุง) wนอกเหนือไปจาก คุณไม่จำเป็นต้องระบุCอย่างชัดเจนเนื่องจากเป็นประเภทสเตจเริ่มต้นหากมีแหล่งที่มาเพียงแหล่งเดียว
Martin Ender

@MartinEnder ขอบคุณฉันยังคงเคยMเป็นประเภทสเตจเริ่มต้น!
Neil

ดีCครับคือสิ่งที่Mเคยเป็น :)
Martin Ender

ฉันรู้ว่าทำไมมันเป็นค่าเริ่มต้นมันเพิ่งเริ่มชินกับการเปลี่ยน
Neil

1

Pyth , 8 ไบต์

l #{vM.:

ลองที่นี่!

รับอินพุตเป็นสตริงไบนารี

.:สร้างสตริงย่อยทั้งหมดvMประเมินแต่ละอัน (นั่นคือมันแปลงจากไบนารี่), การทำ{สำเนาซ้ำ, <space>#กรองตามข้อมูลประจำตัวและlรับความยาว


1

ภาษา Wolfram (Mathematica) , 35 ไบต์

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

Union@Subsequences@#~Count~{1,___}&

ลองออนไลน์!


อะไร___ทำอย่างไร
FrownyFrog

การจับคู่รูปแบบ _ เป็นรายการเดียว __ เป็นหนึ่งรายการขึ้นไป ___ เป็น 0 หรือมากกว่า
Kelly Lowder



0

Java, 232 ไบต์

String b=toBin(n);
l.add(b);
for(int i=1;i<b.length();i++){
for(int j=0;j<=b.length()-i;j++){
String t="";
if((""+b.charAt(j)).equals("0"))continue;
for(int k=0;k<i;k++){
t+=""+b.charAt(j+k);
}
if(!l.contains(t))l.add(t);
}
}
return l.size();

โดยที่ n คืออินพุต b คือการนำเสนอแบบไบนารีและ l คือรายการของสตริงย่อยทั้งหมด การโพสต์ครั้งแรกที่นี่จำเป็นต้องปรับปรุงอย่างแน่นอนและอย่าลังเลที่จะชี้ให้เห็นข้อผิดพลาดใด ๆ ! แก้ไขเล็กน้อยเพื่อให้สามารถอ่านได้


ยินดีต้อนรับสู่ PPCG! เกี่ยวกับการแทรกบรรทัดใหม่ของคุณเพื่อให้สามารถอ่านได้มักจะต้องการให้มีรุ่นหนึ่งคะแนนซึ่งมีจำนวนไบต์ตรงตามที่เขียนไว้ในส่วนหัวและจากนั้นจะมีเวอร์ชันที่ไม่ได้แปลหรืออ่านง่ายกว่าเพื่อความสะดวกในการอ่าน
Laikoni

@Laikoni ขอบคุณสำหรับการเฮฮา! จะเก็บไว้ในใจสำหรับโพสต์ในอนาคต!
ทำลาย

String b=...,tและint i=...,j,kบันทึกตัวอักษรสำหรับการประกาศซ้ำประเภทเดียวกัน รหัสของคุณจะไม่ถือว่าเป็นรายการเพราะมันเป็นตัวอย่างทั้งโปรแกรมเต็มรูปแบบหรือชิ้นส่วนการทำงานคุณต้องเขียนฟังก์ชั่นหรือห่อรหัสของคุณในรูปแบบแลมบ์ดา
Unihedron

0

ทูต , 35 ไบต์

`-&1@`#@Unique@(UnBin=>Subsets@Bin)

ลองออนไลน์!

เท่า:

{#Unique[UnBin=>Subsets[Bin[_]]]-1}

คำอธิบาย

ฉันจะอธิบายรุ่นที่สองเนื่องจากง่ายต่อการติดตาม (ชัดเจน):

{#Unique[UnBin=>Subsets[Bin[_]]]-1}
{                                 }   lambda: _ = first argument
                        Bin[_]        convert to binary
                Subsets[      ]       all subsets of input
         UnBin=>                      map UnBin over these subsets
  Unique[                      ]      remove all duplicates
 #                              -1    size - 1 (since subsets is improper)


0

Java 8, 160 159 158 ไบต์

import java.util.*;b->{Set s=new HashSet();for(int l=b.length(),i=0,j;i<l;i++)for(j=l-i;j>0;s.add(new Long(b.substring(i,i+j--))))s.add(0L);return~-s.size();}

อินพุตเป็นไบนารีสตริง
จะต้องมีวิธีที่สั้นกว่า .. >.>

คำอธิบาย:

ลองออนไลน์

import java.util.*;          // Required import for Set and HashSet
b->{                         // Method with String as parameter and integer as return-type
  Set s=new HashSet();       //  Create a Set
  for(int l=b.length(),      //  Set `l` to the length of the binary-String
      i=0,j;i<l;i++)         //  Loop from 0 up to `l` (exclusive)
    for(j=l-i;j>0;           //   Inner loop from `l-i` down to `0` (exclusive)
      s.add(new Long(b.substring(i,i+j--))))
                             //    Add every substring converted to number to the Set
      s.add(0L);             //    Add 0 to the Set
  return~-s.size();}         //  Return the amount of items in the Set minus 1 (for the 0)

0

C ++, 110 ไบต์

#include<set>
std::set<int>s;int f(int n){for(int i=1;i<n;i+=i+1)f(n&i);return n?s.insert(n),f(n/2):s.size();}

นี่คือฟังก์ชั่นวนซ้ำ เราใช้ a std::setเพื่อนับค่าโดยไม่สนใจสิ่งที่ซ้ำกัน การเรียกแบบเรียกซ้ำสองครั้งปิดบิตด้านซ้าย ( f(n&i)) และปิดทางขวา (f(n/2) ) ในที่สุดจะผลิตสตริงย่อยทั้งหมดเป็นจำนวนเต็ม

โปรดทราบว่าหากคุณต้องการโทรอีกครั้งsจะต้องล้างระหว่างการโทร

โปรแกรมทดสอบ

#include <cstdlib>
#include <iostream>

int main(int, char **argv)
{
    while (*++argv) {
        auto const n = std::atoi(*argv);
        s={};
        std::cout << n << " -> " << f(n) << std::endl;
    }
}

ผล

./153846 13 2008 63 65 850 459 716 425 327
13 -> 6
2008 -> 39
63 -> 6
65 -> 7
850 -> 24
459 -> 23
716 -> 22
425 -> 20
327 -> 16



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