порахуйте їх у діапазоні


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

Я пояснив лише перший приклад, інакше це зайняло б величезну кількість простору, якби я спробував пояснити їх усім.


Примітка :

  • Цифри можуть бути окремими на 1000
  • Весь вхід буде дійсним.
  • Мінімальний вихід буде один.
  • Ви можете прийняти число як масив з двох елементів.
  • Ви можете вибрати спосіб упорядкування номерів.

Критерії виграшу:

Це тому найкоротший код у байтах для кожної мови виграє.



1
Чи можемо ми сприймати дані як певний тип діапазону ( IntRangeу Котліні, Rangeу Рубі)?
равлик_

Цікавий факт: випадок 1000 - 2000дає 5938, але опустити випадок на 1000, то результат також знижується на 1000: 0-1000 = 4938. Доказ
steenbergh

Відповіді:


9

JavaScript (ES6), 38 байт

Здійснює введення в синтаксис currying (a)(b).

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 байт
Олів'є Грегоар

Ви також a->b->IntStream.range(a,b+1).map(Long::bitCount).sum()можете покращити 1 байт. Маргінальна, але все ж одна.
NotBaal

@NotBaal Як згадував Олів'є у коментарі вище, імпорт є обов'язковим, тому він повинен бути 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 . Для цього використовується інший підхід після перетворення в біти. Величезне спасибі Джузеппе за натяк на можливе 34 байтне рішення.


34 байт можливо! Я забуваю, де я бачив трюк (я знаю, що я його не придумав), але є більш складне перетворення у sumвекторний mable - я опублікую повідомлення, якщо ви / ngm не зможете його знайти.
Джузеппе

@Giuseppe Дійсно!
JayCe

2
Я знизив його до 37 байт, використовуючи техніку, яка в іншому випадку може бути корисною. Також виявив, що sdі varпримусити все, що можна, подвоїти.
ngm

Ви можете використовувати pryr::fдля збереження 4 байти: tio.run/##K/qfZvu/…
pajonk

@pajonk хороший момент! Але я намагаюся дотримуватися базових пакетів R, а не R + pryr. Я збираюся шукати на мета, що можна вважати "чистим R".
JayCe

3

Желе , 4 байти

rBFS

Спробуйте в Інтернеті!

Пояснення

rBFS - Повна програма. Бере два входи з аргументів командного рядка.
r - дальність.
 В - Для кожного перетворіть у двійкове.
  FS - Зрівняти і суму.

О_о, це було швидко?
Мухаммад Салман

@MuhammadSalman Ну, виклик також є своєрідним тривіальним ІМО.
Містер Xcoder

Це може бути, але відповідь через хвилину після публікації.
Мухаммад Салман

1
@MuhammadSalman Так, це не дуже швидко для тривіальних викликів, як ця; знання Джелі також випливає. Справжні зусилля стосуються, наприклад, мови цього місяця, QBasic. ;-)
Ерік Аутгольфер

@EriktheOutgolfer: Чи можете ви відповісти на це у QBasic / BrainF ** k?
Мухаммад Салман





2

Bash + загальні комунальні послуги, 50

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

Спробуйте в Інтернеті!

Перетворення цілих чисел у двійкові рядки - це завжди біль у баші. Підхід тут дещо інший - конвертуйте цілі числа в вісімкові, а потім замініть кожну восьмеричну цифру на кількість двійкових 1s, які вона містить. Тоді ми можемо просто підсумувати всі перетворені цифри


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

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 безпосередньо як параметр :-(
Франциско Хан

$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їх (тобто кількість залишилися) та додаємо їх до нашого $oвиводу.


спробуйте використовувати countнатомість length:)
mazzy

1
@mazzy countзавжди буде, 1тому що ми рахуємо lengthрядок, а не масив.
AdmBorkBork

рядок! ти правий. Спасибі. -replace0розумний.
маззи







1

К (нг / к) , 19 13 байт

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

Спробуйте в Інтернеті!

{ }є функцією з аргументами xіy

!1+y є списком 0 1 ... у

x_ скидає перші х елементів

2\ кодує кожну int як список двійкових цифр однакової довжини (це властиво ngn / k)

+/ сума

+//сума до конвергенції; у цьому випадку сума суми всіх двійкових розрядів


1

Perl 6 , 32 30 байт

-1 байт завдяки Бреду Гілберту

{[…](@_)>>.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)
Бред Гілберт b2gills

1

J , 16, 15 14 байт

1 байт збережено завдяки FrownyFrog!

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

Спробуйте в Інтернеті!

Пояснення:

Діадичне дієслово, лівий аргумент - нижня межа 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 Я спробую пізніше сьогодні (мабуть, це можливо, оскільки ви просите :))
Гален Іванов,

@FrownyFrog 15 поки що я все ще намагаюся ...
Гален Іванов,


@FrownyFrog Аа, так просто! Я думав про це, }.але завжди у вилці, а не в гачку. Спасибі!
Гален Іванов

1

QBasic, 95 93 83 82 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

Останній зразок від 1000 до 2000 насправді працює в QBasic 4.5, який працює на Dosbox: Hij doet het!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.