compter ceux à portée

20

Défi :

Comptez le nombre de uns 1dans la représentation binaire de tous les nombres entre une plage.


Contribution :

Deux entiers positifs non décimaux


Production :

La somme de tous les 1s dans la plage entre les deux nombres.


Exemple :

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

Je n'ai expliqué que le premier exemple, sinon cela aurait pris énormément d'espace si j'avais essayé de les expliquer pour chacun d'eux.


Remarque :

  • Les nombres peuvent être séparés de plus de 1000
  • Toutes les entrées seront valides.
  • La sortie minimale sera de un.
  • Vous pouvez accepter le nombre comme un tableau de deux éléments.
  • Vous pouvez choisir la façon dont les numéros sont commandés.

Critères gagnants:

C'est le donc le code le plus court en octets pour chaque langue gagne.

Muhammad Salman
la source
1
OEIS A000788
Leaky Nun
1
Pouvons-nous prendre l'entrée comme une sorte de type de plage ( IntRangedans Kotlin, Rangedans Ruby)?
snail_
Fait d'amusement: cas 1000 - 2000donne 5938, mais de réduire le cas par 1000, le résultat diminue également de 1000: 0-1000 = 4938. Preuve
steenbergh

Réponses:

9

JavaScript (ES6), 38 octets

Prend une entrée dans la syntaxe de curry (a)(b).

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

Essayez-le en ligne!

Commenté

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
Arnauld
la source
6

Python 2 , 47 octets

f=lambda x,y:y/x and bin(x).count('1')+f(x+1,y)

Essayez-le en ligne!

Dennis
la source
1
Astuce à éviter >=...
Erik the Outgolfer
5

Java (JDK 10) , 55 octets

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

Essayez-le en ligne!

Olivier Grégoire
la source
IntStream.range(a,b+1).map(Integer::bitCount).sum()
saka1029
@ saka1029 Les importations sont obligatoires. C'est donc en fait a->b->java.util.stream.IntStream.range(a,b+1).map(Integer::bitCount).sum(), pour un total de 74 octets. Même si l'importation n'était pas obligatoire, les paramètres le sont, donc il faudrait écrire a->b->IntStream.range(a,b+1).map(Integer::bitCount).sum(), ce qui compte pour 57 octets
Olivier Grégoire
Vous pourriez également avoir a->b->IntStream.range(a,b+1).map(Long::bitCount).sum()une amélioration de 1 octet. Marginal, mais toujours un.
NotBaal
@NotBaal Comme mentionné par Olivier dans le commentaire ci-dessus, les importations sont obligatoires, donc elles devraient l'être a->b->java.util.stream.IntStream.range(a,b+1).map(Long::bitCount).sum()(71 octets).
Kevin Cruijssen
4

05AB1E , 4 octets

ŸbSO

Essayez-le en ligne!

M. Xcoder
la source
Exactement la solution que j'ai obtenue :). +1.
Magic Octopus Urn
4

MATL , 5 4 octets

&:Bz

Essayez-le en ligne!

Merci à Luis Mendo d'avoir enregistré un octet!

(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)

Giuseppe
la source
4

R , 41 34 octets

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

Essayez-le en ligne!

Fortement inspiré de l'autre solution R de ngm . Cela utilise une approche différente après la conversion en bits. Un grand merci à Giuseppe pour avoir fait allusion à une solution possible de 34 octets.

JayCe
la source
34 octets c'est possible! J'oublie où j'ai vu le truc (je sais que je ne l'ai pas trouvé) mais il y a une conversion plus délicate en un sumvecteur mable - je posterai si vous / ngm ne le trouvez pas.
Giuseppe
@Giuseppe Effectivement!
JayCe
2
Je l'ai réduit à 37 octets en utilisant une technique qui pourrait autrement être utile. A également découvert cela sdet varcontraint tout ce qu'ils peuvent doubler.
ngm
Vous pouvez utiliser pryr::fpour enregistrer 4 octets: tio.run/##K/qfZvu/…
pajonk
@pajonk bon point! Mais j'essaie de m'en tenir aux packages R de base plutôt qu'à R + pryr. Je vais chercher sur méta ce qui peut être considéré comme du "pur R".
JayCe
3

Gelée , 4 octets

rBFS

Essayez-le en ligne!

Explication

rBFS - Programme complet. Prend les deux entrées des arguments de la ligne de commande.
r - Gamme.
 B - Pour chacun, convertissez en binaire.
  FS - Aplatir et additionner.
M. Xcoder
la source
O_o, c'était rapide?
Muhammad Salman
@MuhammadSalman Eh bien, le défi est aussi une sorte d'OMI triviale.
M. Xcoder
Peut-être, mais une réponse une minute après la publication.
Muhammad Salman
1
@ MuhammadSalman Oui, ce n'est pas vraiment aussi rapide pour des défis triviaux comme celui-ci; la connaissance de Jelly s'ensuit également. Le véritable effort va par exemple dans la langue de ce mois-ci, QBasic. ;-)
Erik the Outgolfer
@EriktheOutgolfer: Pouvez-vous répondre à cela dans QBasic / BrainF ** k?
Muhammad Salman
3

Python 3 , 56 54 52 octets

Cela peut être joué plus imo. -2 octets grâce à Mr.Xcoder -2 plus d'octets grâce à MI Wright

lambda a,b:''.join(map(bin,range(a,b+1))).count('1')

Essayez-le en ligne!

Cookies de moulin à vent
la source
2

Bash + utilitaires communs, 50

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

Essayez-le en ligne!

La conversion d'entiers en chaînes binaires est toujours un peu pénible en bash. L'approche ici est légèrement différente - convertissez les entiers en octaux, puis remplacez chaque chiffre octal par le nombre de 1 binaires qu'il contient. Ensuite, nous pouvons simplement additionner tous les chiffres convertis

Traumatisme numérique
la source
2

APL + WIN, 33 26 octets

Demande le vecteur d'entiers:

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

Essayez-le en ligne! Gracieuseté de Dalog Classic

Explication:

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
Graham
la source
2

R , 44 40 37 octets

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

Essayez-le en ligne!

Précédemment:

function(a,b)sum(strtoi(intToBits(a:b)))
function(a,b)sum(as.integer(intToBits(a:b)))
ngm
la source
2

Octave avec boîte à outils de communication, 21 octets

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

Essayez-le en ligne!

Le code devrait être assez évident. Nombre d'éléments non nuls dans la représentation binaire de chacun des nombres de la plage.

Ce serait @(a,b)nnz(dec2bin(a:b)-48)sans la boîte à outils de communication.

Stewie Griffin
la source
1

Husk , 4 octets

Σṁḋ…

Essayez-le en ligne!

Explication

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

la source
1

PHP, 97 octets

(bien sûr, cela peut être raccourci, mais je voulais utiliser les fonctions)

Essayez-le en ligne

Code

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

Explication

<?=
 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
Francisco Hahn
la source
il semble que vous pouvez juste faire ce
dzaima
Pendant une seconde, j'ai absolument oublié que vous pouvez définir le nom de la fonction php directement en tant que paramètre :-(
Francisco Hahn
$argv[0]est le nom du programme ou "-"; Vous devriez travailler avec$argv[1] et $argv[2]. Et vous pouvez utiliser à la joinplace de implode, raccourcir cela à 68 octets:<?=substr_count(join(array_map(decbin,range($argv[1],$argv[2]))),1);
Titus
1

PowerShell , 72 octets

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

Essayez-le en ligne!

Long à cause de la conversion en binaire [convert]::ToString($_,2)et de l'élimination des zéros -replace0. Sinon, nous prenons simplement les numéros d'entrée, faisons une plage $x..$yet pour chaque numéro de la plage, convertissons-le en binaire, supprimons les zéros, prenez-les .length(c'est-à-dire le nombre de ceux qui restent) et ajoutez-le à notre $osortie.

AdmBorkBork
la source
essayez d'utiliser à la countplace length:)
mazzy
1
@mazzy countsera toujours 1parce que nous comptons la lengthchaîne, pas un tableau.
AdmBorkBork
chaîne! tu as raison. Merci. -replace0est intelligent.
mazzy
1

Pip , 10 octets

$+JTB:a\,b

Essayez-le en ligne!

Explication

            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 +)
DLosc
la source
1

Fusain , 10 octets

IΣ⭆…·NN⍘ι²

Essayez-le en ligne! Le lien est vers la version détaillée du code. Explication:

     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
Neil
la source
1

Brachylog , 8 octets

⟦₂ḃᵐcọht

Essayez-le en ligne!

Explication

⟦₂         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
Fatalize
la source
1

K (ngn / k) , 19 13 octets

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

Essayez-le en ligne!

{ }est une fonction avec des arguments xety

!1+y est la liste 0 1 ... y

x_ supprime les x premiers éléments

2\ code chaque int comme une liste de chiffres binaires de même longueur (ceci est spécifique à ngn / k)

+/ somme

+//somme jusqu'à convergence; dans ce cas, somme de la somme de toutes les listes de chiffres binaires

ngn
la source
1

Perl 6 , 32 30 octets

-1 octets grâce à Brad Gillbert

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

Essayez-le en ligne!

Explication:

[…](@_)    #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
Jo King
la source
1
Vous pouvez le réduire d'un octet si vous utilisez [...](@_)au lieu de($^a..$^b)
Brad Gilbert b2gills
1

J , 16, 15 14 octets

1 octet économisé grâce à FrownyFrog!

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

Essayez-le en ligne!

Explication:

Un verbe dyadique, l'argument de gauche est la borne inférieure mde la plage, la droite - la supérieure 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
Galen Ivanov
la source
Pouvez-vous faire 14?
FrownyFrog
@FrownyFrog J'essaierai plus tard dans la journée (apparemment c'est possible, puisque vous demandez :))
Galen Ivanov
@FrownyFrog 15 pour l'instant, j'essaie toujours ...
Galen Ivanov
1
14
FrownyFrog
@FrownyFrog Aah, si facile! Je pensais à }.mais toujours dans une fourchette et non dans un crochet. Merci!
Galen Ivanov
1

QBasic, 95 93 83 82 octets

@DLosc m'a sauvé un certain lot un des octets!

Enregistré un autre octet en utilisant cette technique !

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

Langue du mois FTW!

Explication

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

Le dernier testcase de 1000 à 2000 fonctionne réellement, dans QBasic 4.5 fonctionnant sur Dosbox: Hij doet het!

steenbergh
la source