นับคนอยู่ในช่วง


20

ถาม:

นับจำนวนของคน1ในการเป็นตัวแทนไบนารีของจำนวนทั้งหมดระหว่างช่วง


อินพุต:

จำนวนเต็มบวกที่ไม่ใช่ทศนิยมสองตัว


ผลผลิต:

ผลรวมของ1s ทั้งหมดที่อยู่ในช่วงระหว่างตัวเลขสองตัว


ตัวอย่าง:

4 , 7        ---> 8
4  = 100 (adds one)   = 1
5  = 101 (adds two)   = 3
6  = 110 (adds two)   = 5
7  = 111 (adds three) = 8

10 , 20     ---> 27
100 , 200   ---> 419
1 , 3       ---> 4
1 , 2       ---> 2
1000, 2000  ---> 5938

ฉันได้อธิบายเพียงตัวอย่างแรกเท่านั้นมิฉะนั้นมันจะใช้พื้นที่จำนวนมากถ้าฉันพยายามอธิบายให้พวกเขาทั้งหมด


บันทึก :

  • ตัวเลขสามารถแยกออกจากกันได้มากกว่า 1,000
  • อินพุตทั้งหมดจะถูกต้อง
  • ผลผลิตขั้นต่ำจะเป็นหนึ่ง
  • คุณสามารถรับตัวเลขเป็นอาร์เรย์ของสององค์ประกอบ
  • คุณสามารถเลือกวิธีการเรียงลำดับหมายเลขได้

เกณฑ์การชนะ:

นี่คือสั้นที่สุดในหน่วยไบต์สำหรับแต่ละภาษาที่ชนะ



1
เราจะรับอินพุตเป็นประเภทช่วงบางประเภท ( IntRangeใน Kotlin Rangeใน Ruby) ได้ไหม
หอยทาก _

สนุกจริง: กรณี1000 - 2000ผลตอบแทนถัวเฉลี่ย 5938 แต่กรณีที่ต่ำกว่าโดย 1000 ผลที่ได้ยังลดลงด้วย 0-1000 = 49381000: หลักฐาน
steenbergh

คำตอบ:


9

JavaScript (ES6), 38 ไบต์

(a)(b)จะเข้าในไวยากรณ์ currying

a=>b=>(g=c=>a>b?0:1+g(c^c&-c||++a))(a)

ลองออนไลน์!

แสดงความคิดเห็น

a => b => (         // given the input values a and b
  g = c =>          // g = recursive function taking c = current value
    a > b ?         // if a is greater than b:
      0             //   stop recursion and return 0
    :               // else:
      1 +           //   add 1 to the final result
      g(            //   and do a recursive call to g() with:
        c ^ c & -c  //     the current value with the least significant bit thrown away
        || ++a      //     or the next value in the range if the above result is 0
      )             //   end of recursive call
)(a)                // initial call to g() with c = a


5

Java (JDK 10) , 55 ไบต์

a->b->{int c=0;for(;a<=b;)c+=a.bitCount(b--);return c;}

ลองออนไลน์!


IntStream.range(a,b+1).map(Integer::bitCount).sum()
saka1029

@ saka1029 การนำเข้ามีผลบังคับใช้ จริง ๆ แล้วมันa->b->java.util.stream.IntStream.range(a,b+1).map(Integer::bitCount).sum()มีทั้ง 74 ไบต์ แม้ว่าการนำเข้าจะไม่บังคับ แต่เราก็ต้องเขียนa->b->IntStream.range(a,b+1).map(Integer::bitCount).sum()ซึ่งนับเป็น 57 ไบต์
Olivier Grégoire

คุณอาจมีa->b->IntStream.range(a,b+1).map(Long::bitCount).sum()การปรับปรุง 1 ไบต์ ขอบ แต่ยังคงหนึ่ง
NotBaal

@NotBaal ตามที่ Olivier กล่าวไว้ในความคิดเห็นข้างต้นการนำเข้ามีผลบังคับใช้ดังนั้นจึงควรเป็นa->b->java.util.stream.IntStream.range(a,b+1).map(Long::bitCount).sum()(71 ไบต์)
Kevin Cruijssen




4

R , 41 34 ไบต์

function(a,b)sum(intToBits(a:b)>0)

ลองออนไลน์!

แรงบันดาลใจอย่างมากจากการแก้ปัญหาอื่น ๆ โดย R NGM วิธีนี้ใช้วิธีที่แตกต่างหลังจากการแปลงเป็นบิต ต้องขอขอบคุณ Giuseppe อย่างมากสำหรับคำใบ้ที่มีขนาด 34 ไบต์


34 ไบต์เป็นไปได้! ฉันลืมที่ฉันเห็นเคล็ดลับ (ฉันรู้ว่าฉันไม่ได้เกิดขึ้นกับมัน) แต่มีการแปลงที่ยากขึ้นไปเป็นsumเวคเตอร์เวกเตอร์ - ฉันจะโพสต์ถ้าคุณ / ngm ไม่สามารถหาได้
Giuseppe

@iuseppe แน่นอน!
JayCe

2
ฉันได้มันถึง37 ไบต์โดยใช้เทคนิคที่อาจเป็นประโยชน์ ค้นพบสิ่งนั้นsdและvarบีบบังคับสิ่งที่พวกเขาสามารถทำได้
ngm

คุณสามารถใช้pryr::fเพื่อบันทึก 4 ไบต์: tio.run/##K/qfZvu/…
pajonk

@pajonk จุดดี! แต่ฉันพยายามยึดติดกับแพ็คเกจ R พื้นฐานมากกว่า R + pryr ฉันกำลังจะค้นหาเมตาว่าอะไรคือ "pure R"
JayCe

3

เยลลี่ 4 ไบต์

rBFS

ลองออนไลน์!

คำอธิบาย

rBFS - โปรแกรมเต็มรูปแบบ รับอินพุตทั้งสองจากอาร์กิวเมนต์บรรทัดคำสั่ง
r - พิสัย
 B - สำหรับแต่ละแปลงเป็นไบนารี
  FS - แบนและผลรวม

O_o นั่นเร็วไหม
มูฮัมหมัดซาลมาน

@ MuhammadSalman เอาล่ะความท้าทายก็เป็นเหมือน IMO เล็กน้อย
นาย Xcoder

อาจเป็น แต่คำตอบหนึ่งนาทีหลังจากโพสต์
มูฮัมหมัดซาลมาน

1
@ MuhammadSalman ใช่มันไม่ได้เร็วขนาดนั้นสำหรับความท้าทายเล็กน้อยเช่นนี้ ความรู้เกี่ยวกับเจลลี่ก็เป็นไปตามนั้น ความพยายามที่แท้จริงดำเนินไปเช่นภาษาของเดือนนี้ QBasic ;-)
Erik the Outgolfer

@EriktheOutgolfer: คุณสามารถตอบคำถามนี้ใน QBasic / BrainF ** k ได้ไหม?
มูฮัมหมัดซาลมาน





2

Bash + ยูทิลิตี้ทั่วไป, 50

jot -w%o - $@|tr 247356 1132|fold -1|paste -sd+|bc

ลองออนไลน์!

การแปลงจำนวนเต็มเป็นสตริงไบนารีจะเจ็บปวดเล็กน้อยใน bash วิธีการที่นี่แตกต่างกันเล็กน้อย - แปลงจำนวนเต็มเป็นฐานแปดจากนั้นแทนที่ตัวเลขฐานแปดแต่ละตัวด้วยจำนวนของไบนารี 1 ที่มันมีอยู่ จากนั้นเราก็สามารถรวมตัวเลขที่แปลงได้ทั้งหมด


2

APL + WIN, 33 26 ไบต์

พรอมต์สำหรับเวกเตอร์ของจำนวนเต็ม:

+/,((↑v)⍴2)⊤(1↓v)+0,⍳-/v←⎕

ลองออนไลน์! ความอนุเคราะห์จาก Dalog Classic

คำอธิบาย:

v←⎕ prompt for input of a vector of two integers max first

(v←1↓v)+0,⍳-/ create a vector of integers from min to max

(↑v)⍴2 set max power of 2 to max 

⊤ convert integers to a matrix of binaries

+/, convert matrix to a vector and sum


2

ระดับแปดเสียงพร้อมกล่องเครื่องมือการสื่อสารขนาด 21 ไบต์

@(a,b)nnz(de2bi(a:b))

ลองออนไลน์!

รหัสควรชัดเจนพอสมควร จำนวนขององค์ประกอบที่ไม่ใช่ศูนย์ในการเป็นตัวแทนไบนารีของแต่ละตัวเลขในช่วง

นี่จะ@(a,b)nnz(dec2bin(a:b)-48)ไม่มีกล่องเครื่องมือการสื่อสาร


1

Husk , 4 ไบต์

Σṁḋ…

ลองออนไลน์!

คำอธิบาย

Σṁḋ…
   …     Get the (inclusive) range.
 ṁḋ      Convert each to binary and concatenate.
Σ        Get the sum.


1

PHP, 97 ไบต์

(แน่ใจว่าสิ่งนี้จะสั้นลง แต่ต้องการใช้ฟังก์ชั่น)

ลองออนไลน์

รหัส

<?=substr_count(implode(array_map(function($v){return decbin($v);},
 range($argv[0],$argv[1]))),1);

คำอธิบาย

<?=
 substr_count(   //Implode the array and count every "1"
  implode(
    array_map(function($v){return decbin($v);}, //Transform every decimal to bin
          range($argv[0],$argv[1])   //generate a range between the arguments
     )
),1);   //count "1"'s

ดูเหมือนว่าคุณจะสามารถทำสิ่งนี้ได้
dzaima

สำหรับวินาทีฉันลืมไปอย่างแน่นอนว่าคุณสามารถตั้งชื่อฟังก์ชั่น php โดยตรงเป็นพารามิเตอร์ :-(
Francisco Hahn

$argv[0]คือชื่อโปรแกรมหรือ "-"; คุณควรจะทำงานกับและ$argv[1] $argv[2]และคุณสามารถใช้joinแทนการimplodeตัดทอนนี้ถึง 68 ไบต์:<?=substr_count(join(array_map(decbin,range($argv[1],$argv[2]))),1);
ติตัส

1

PowerShellขนาด 72 ไบต์

param($x,$y)$x..$y|%{$o+=([convert]::ToString($_,2)-replace0).length};$o

ลองออนไลน์!

ยาวเนื่องจากการแปลงไบนารีและการกำจัดของเลขศูนย์[convert]::ToString($_,2) -replace0มิฉะนั้นเราก็แค่ใส่ตัวเลขทำช่วง$x..$yและสำหรับแต่ละตัวเลขในช่วงนั้นแปลงเป็นเลขฐานสองเอาค่าศูนย์เอาตัวเลข.lengthนั้น (นั่นคือจำนวนที่เหลืออยู่) และเพิ่มลงใน$output ของเรา


ลองใช้countแทนlength:)
mazzy

1
@mazzy countจะเป็น1เพราะเรานับจำนวนlengthของสตริงไม่ใช่อาร์เรย์
AdmBorkBork

สตริง! คุณพูดถูก ขอบคุณ -replace0เป็นคนฉลาด
mazzy




1

ถ่าน 10 ไบต์

IΣ⭆…·NN⍘ι²

ลองออนไลน์! การเชื่อมโยงคือการใช้รหัสเวอร์ชันอย่างละเอียด คำอธิบาย:

     NN     Input numbers
   …·       Inclusive range
  ⭆         Map over range and join
        ι   Current value
         ²  Literal 2
       ⍘    Convert to base as string
 Σ          Sum of digits
I           Cast to string
            Implicitly print



1

K (ngn / k) , 19 13 ไบต์

{+//2\x_!1+y}

ลองออนไลน์!

{ }เป็นฟังก์ชันที่มีอาร์กิวเมนต์xและy

!1+y คือรายการ 0 1 ... y

x_ หยดองค์ประกอบ x แรก

2\ เข้ารหัสแต่ละ int เป็นรายการของเลขฐานสองที่มีความยาวเท่ากัน (นี่คือเฉพาะสำหรับ ngn / k)

+/ รวม

+//ผลรวมจนกระทั่งการบรรจบกัน ในกรณีนี้ผลรวมของผลรวมของรายการเลขฐานสองทั้งหมด


1

Perl 6 , 32 30 ไบต์

-1 ไบต์ขอบคุณ Brad Gillbert

{[…](@_)>>.base(2).comb.sum}

ลองออนไลน์!

คำอธิบาย:

[…](@_)    #Range of parameter 1 to parameter 2
       >>    #Map each number to
                      .sum  #The sum of
                 .comb      #The string of
         .base(2)    #The binary form of the number

1
คุณสามารถลดได้ทีละไบต์ถ้าคุณใช้[...](@_)แทน($^a..$^b)
Brad Gilbert b2gills

1

J , 16, 15 14 ไบต์

บันทึก 1 ไบต์ขอบคุณ FrownyFrog!

+/@,@#:@}.i.,]

ลองออนไลน์!

คำอธิบาย:

คำกริยา dyadic อาร์กิวเมนต์ซ้ายเป็นขีด จำกัด ล่างmของช่วงหนึ่งที่เหมาะสม - nบน

            ,    append                      
             ]   n to the
          i.     list 0..n-1
         }.      drop m elements from the beginning of that list 
      #:@        and convert each element to binary 
    ,@           and flatten the table
 +/@             and find the sum

คุณสามารถทำให้มัน 14?
FrownyFrog

@FrownyFrog ผมจะพยายามต่อมาในวันนี้ (เห็นได้ชัดว่ามันเป็นไปได้เนื่องจากคุณจะถาม :))
เลน Ivanov

@FrownyFrog 15สำหรับตอนนี้ฉันยังคงพยายาม ...
Galen Ivanov


@FrownyFrog Aah ง่ายมาก! ฉันกำลังคิดถึง}.แต่อยู่ในส้อมเสมอและไม่ได้อยู่ในเบ็ด ขอบคุณ!
Galen Ivanov

1

QBasic, 95 93 83 82 ไบต์

@DLosc บันทึกฉันบางมากของไบต์!

บันทึกอีกหนึ่งไบต์โดยใช้เทคนิคนี้ !

INPUT a,b
FOR i=a TO b
k=i
FOR j=i TO 0STEP-1
x=k>=2^j
s=s-x
k=k+x*2^j
NEXT j,i
?s

ภาษาของเดือน FTW!

คำอธิบาย

INPUT a,b           Ask user for lower and upper bound
FOR i=a TO b        Loop through that range
k=i                 we need a copy of i to not break the FOR loop
FOR j=i TO 0STEP-1  We're gonna loop through exponents of 2 from high to low.
                    Setting the first test up for 4 to 2^4 (etc) we know we're overshooting, but that 's OK
x=k>=2^j            Test if the current power of 2 is equal to or smaller than k 
                    (yields 0 for false and -1 for true)
s=s-x               If k is bigger than 2^j, we found a 1, so add 1 to our running total s
                    (or sub -1 from the total s...)
k=k+x*2^j           Lower k by that factor of 2 if the test is true, else by 0
NEXT                Test the next exponent of 2
NEXT                process the next number in range
?s                  print the total

ผลงานสุดท้ายของ 1,000 ถึง 2000 ใช้งานได้จริงใน QBasic 4.5 ที่ทำงานบน Dosbox: Hij doet het!

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