đếm những người trong phạm vi


20

Thử thách :

Đếm số lượng những cái 1trong biểu diễn nhị phân của tất cả số giữa một phạm vi.


Đầu vào :

Hai số nguyên dương không thập phân


Đầu ra:

Tổng của tất cả các 1s trong phạm vi giữa hai số.


Thí dụ :

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

Tôi chỉ giải thích ví dụ đầu tiên nếu không nó sẽ chiếm một khoảng không gian lớn nếu tôi cố gắng giải thích cho tất cả chúng.


Chú thích :

  • Các số có thể cách nhau hơn 1000
  • Tất cả đầu vào sẽ hợp lệ.
  • Sản lượng tối thiểu sẽ là một.
  • Bạn có thể chấp nhận số là một mảng gồm hai phần tử.
  • Bạn có thể chọn cách các số được đặt hàng.

Tiêu chí chiến thắng:

Đây là để mã ngắn nhất tính theo byte cho mỗi ngôn ngữ sẽ thắng.



1
Chúng ta có thể lấy đầu vào là một loại loại phạm vi ( IntRangetrong Kotlin, Rangetrong Ruby) không?
ốc_

Thực tế thú vị: trường hợp 1000 - 2000mang lại 5938, nhưng giảm 1000 trường hợp, kết quả cũng giảm 1000 : 0-1000 = 4938. Bằng chứng
steenbergh

Câu trả lời:


9

JavaScript (ES6), 38 byte

Đưa đầu vào theo cú pháp currying (a)(b).

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

Hãy thử trực tuyến!

Đã bình luận

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 byte

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

Hãy thử trực tuyến!


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

@ saka1029 Việc nhập khẩu là bắt buộc. Vì vậy, nó thực sự a->b->java.util.stream.IntStream.range(a,b+1).map(Integer::bitCount).sum(), cho toàn bộ 74 byte. Ngay cả khi việc nhập không bắt buộc, các tham số là, vì vậy chúng tôi phải viết a->b->IntStream.range(a,b+1).map(Integer::bitCount).sum(), được tính là 57 byte
Olivier Grégoire

Bạn cũng có thể có a->b->IntStream.range(a,b+1).map(Long::bitCount).sum()một cải tiến 1 byte. Bên lề, nhưng vẫn là một.
Không phải

@NotBaal Như Olivier đã đề cập trong bình luận ở trên, nhập khẩu là bắt buộc, vì vậy nó phải là a->b->java.util.stream.IntStream.range(a,b+1).map(Long::bitCount).sum()(71 byte).
Kevin Cruijssen



4

MATL , 5 4 byte

&:Bz

Hãy thử trực tuyến!

Cảm ơn Luis Mendo vì đã tiết kiệm một byte!

(implicit input a and b, a<b)
&:                              % two-element input range, construct [a..b]
  B                             % convert to Binary as a logical vector (matrix)
   z                            % number of nonzero entries
(implicit output of the result)


4

R , 41 34 byte

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

Hãy thử trực tuyến!

Lấy cảm hứng từ giải pháp R khác của ngm . Điều này sử dụng một cách tiếp cận khác sau khi chuyển đổi thành bit. Rất cảm ơn Giuseppe đã gợi ý về một giải pháp 34 byte có thể.


34 byte là có thể! Tôi quên nơi tôi đã nhìn thấy mánh khóe (tôi biết tôi đã không nghĩ ra nó) nhưng có một chuyển đổi khó hơn thành một sumvectơ có thể đọc được - tôi sẽ đăng nếu bạn không tìm thấy nó.
Giuseppe

@Giuseppe Thật vậy!
JayCe

2
Tôi đã giảm xuống còn 37 byte bằng cách sử dụng một kỹ thuật có thể hữu ích. Cũng phát hiện ra điều đó sdvarép buộc bất cứ điều gì họ có thể tăng gấp đôi.
ngm

Bạn có thể sử dụng pryr::fđể lưu 4 byte: tio.run/##K/qfZvu/ Kẻ
pyjama

@pajonk điểm tốt! Nhưng tôi đang cố bám vào các gói R cơ sở hơn là R + pryr. Tôi sẽ tìm kiếm trên meta những gì có thể được coi là "thuần R".
JayCe

3

Thạch , 4 byte

rBFS

Hãy thử trực tuyến!

Giải trình

rBFS - Chương trình đầy đủ. Lấy hai đầu vào từ các đối số dòng lệnh.
r - Phạm vi.
 B - Đối với mỗi, chuyển đổi thành nhị phân.
  FS - Làm phẳng và tổng hợp.

O_o, đó là nhanh?
Muhammad Salman

@MuhammadSalman Vâng, thử thách cũng là loại IMO tầm thường.
Ông Xcoder

Nó có thể, nhưng một câu trả lời một phút sau khi đăng.
Muhammad Salman

1
@MuhammadSalman Vâng, điều đó không thực sự nhanh đối với những thử thách tầm thường như thế này; kiến thức về Jelly cũng xảy ra. Nỗ lực thực sự là ngôn ngữ của tháng này, QBasic. ;-)
Erik người vượt trội

@EriktheOutgolfer: Bạn có thể trả lời câu hỏi này trong QBasic / BrainF ** k không?
Muhammad Salman





2

Bash + tiện ích chung, 50

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

Hãy thử trực tuyến!

Chuyển đổi số nguyên thành chuỗi nhị phân luôn là một chút đau đớn trong bash. Cách tiếp cận ở đây hơi khác một chút - chuyển đổi các số nguyên thành số bát phân, sau đó thay thế mỗi chữ số bát phân bằng số nhị phân 1s chứa. Sau đó, chúng tôi chỉ có thể tổng hợp tất cả các chữ số chuyển đổi


2

APL + THẮNG, 33 26 byte

Lời nhắc cho vectơ số nguyên:

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

Hãy thử trực tuyến! Phép lịch sự của Dalog Classic

Giải trình:

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

R , 44 40 37 byte

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

Hãy thử trực tuyến!

Trước đây:

function(a,b)sum(strtoi(intToBits(a:b)))
function(a,b)sum(as.integer(intToBits(a:b)))

2

Octave với hộp công cụ truyền thông, 21 byte

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

Hãy thử trực tuyến!

Các mã nên khá rõ ràng. Số phần tử khác không trong biểu diễn nhị phân của mỗi số trong phạm vi.

Điều này sẽ @(a,b)nnz(dec2bin(a:b)-48)không có hộp công cụ truyền thông.


1

Husk , 4 byte

Σṁḋ…

Hãy thử trực tuyến!

Giải trình

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


1

PHP, 97 byte

(chắc chắn điều này có thể được rút ngắn, nhưng muốn sử dụng các chức năng)

Dùng thử trực tuyến

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

Giải trình

<?=
 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

có vẻ như bạn chỉ có thể làm điều này
dzaima

Trong một giây, tôi hoàn toàn quên rằng bạn có thể đặt tên của hàm php trực tiếp làm tham số :-(
Francisco Hahn

$argv[0]là tên chương trình hoặc "-"; Bạn nên làm việc với $argv[1]$argv[2]. Và bạn có thể sử dụng jointhay vì implode, rút ​​ngắn này xuống còn 68 byte:<?=substr_count(join(array_map(decbin,range($argv[1],$argv[2]))),1);
Tít

1

PowerShell , 72 byte

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

Hãy thử trực tuyến!

Lâu vì chuyển đổi thành nhị phân [convert]::ToString($_,2)và thoát khỏi các số không -replace0. Mặt khác, chúng ta chỉ lấy các số đầu vào, tạo một phạm vi $x..$yvà cho mỗi số trong phạm vi chuyển đổi nó thành nhị phân, loại bỏ các số không, lấy số .lengthđó (nghĩa là số lượng còn lại) và thêm nó vào số liệu của chúng tôi $o.


countthay vào đó hãy thử sử dụng length:)
mazzy

1
@mazzy countsẽ luôn là 1vì chúng ta đang đếm lengthchuỗi, không phải là một mảng.
admBorkBork

chuỗi! bạn đúng rồi. cảm ơn. -replace0thông minh.
mazzy


1

Pip , 10 byte

$+JTB:a\,b

Hãy thử trực tuyến!

Giải trình

            a and b are command-line args (implicit)
      a\,b  Inclusive range from a to b
   TB:      Convert to binary (: forces TB's precedence down)
  J         Join into a single string of 1's and 0's
$+          Sum (fold on +)


1

Than , 10 byte

IΣ⭆…·NN⍘ι²

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Giải trình:

     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

Brachylog , 8 byte

⟦₂ḃᵐcọht

Hãy thử trực tuyến!

Giải trình

⟦₂         Ascending range between the two elements in the input
  ḃᵐ       Map to base 2
    c      Concatenate
     ọ     Occurrences of each element
      h    Head: take the list [1, <number of occurrences of 1>]
       t   Tail: the number of occurrences of 1


1

K (ngn / k) , 19 13 byte

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

Hãy thử trực tuyến!

{ }là một hàm với các đối số xy

!1+y là danh sách 0 1 ... y

x_ giảm các phần tử x đầu tiên

2\ mã hóa mỗi int dưới dạng một danh sách các chữ số nhị phân có cùng độ dài (điều này đặc trưng cho ngn / k)

+/ tổng

+//tổng cho đến khi hội tụ; trong trường hợp này tổng của tất cả các danh sách chữ số nhị phân


1

Perl 6 , 32 30 byte

-1 byte nhờ Brad Gillbert

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

Hãy thử trực tuyến!

Giải trình:

[…](@_)    #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
Bạn có thể giảm nó xuống một byte nếu bạn sử dụng [...](@_)thay vì($^a..$^b)
Brad Gilbert b2gills

1

J , 16, 15 14 byte

Lưu 1 byte nhờ FrownyFrog!

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

Hãy thử trực tuyến!

Giải trình:

Một động từ dyadic, đối số bên trái là giới hạn dưới mcủa phạm vi, bên phải - phía trên 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

Bạn có thể làm cho nó 14?
FrownyFrog

@FrownyFrog Tôi sẽ thử sau hôm nay (dường như là có thể, vì bạn đang hỏi :))
Galen Ivanov

@FrownyFrog 15 hiện tại, tôi vẫn đang cố gắng ...
Galen Ivanov


@FrownyFrog Aah, thật dễ dàng! Tôi đã suy nghĩ về }.nhưng luôn ở trong một ngã ba và không phải trong một cái móc. Cảm ơn!
Galen Ivanov

1

QBasic, 95 93 83 82 byte

@DLosc đã cứu tôi một số rất nhiều byte!

Đã lưu một byte khác bằng kỹ thuật này !

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

Ngôn ngữ của tháng FTW!

Giải trình

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

Bản thử nghiệm cuối cùng từ 1000 đến 2000 thực sự hoạt động, trong QBasic 4.5 chạy trên Dosbox: Hij doet het!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.