Sommes entières diluées

26

Un entier positif peut être dilué en insérant un 0entre deux bits dans son expansion binaire. Cela signifie qu'un nnombre de bits a des n-1dilutions, qui ne sont pas nécessairement toutes distinctes.

Par exemple, pour 12(ou 1100en binaire), les dilutions sont

11000 = 24
   ^

11000 = 24
  ^

10100 = 20
 ^

Dans ce défi, nous allons prendre la somme de toutes les dilutions, à l'exclusion du nombre d'origine. Car 12, en prenant la somme des 24, 24, 20résultats dans 68, il 68devrait en être de même pour la sortie de 12.

Défi

Étant donné un entier positif n > 1en entrée, émettez / retournez la somme diluée comme expliqué ci-dessus.

Exemples

in    out
---   ---
2       4
3       5
7      24
12     68
333  5128
512  9216

Règles

  • L'entrée et la sortie peuvent être supposées correspondre au type d'entier natif de votre langue.
  • L'entrée et la sortie peuvent être données dans n'importe quel format pratique .
  • Un programme complet ou une fonction sont acceptables. S'il s'agit d'une fonction, vous pouvez renvoyer la sortie plutôt que de l'imprimer.
  • Les failles standard sont interdites.
  • Il s'agit de donc toutes les règles de golf habituelles s'appliquent et le code le plus court (en octets) l'emporte.
AdmBorkBork
la source
"Tout format pratique" inclut-il une chaîne binaire?
Shaggy
1
@Shaggy "Tout format pratique" est censé inclure les méthodes d'entrée / sortie, pas le format . En tant que tel, je vais dire non, vous devez prendre l'entrée comme un entier ou une chaîne représentant cet entier.
AdmBorkBork
Beau défi!
Manish Kundu
1
Cette séquence est actuellement (30 janvier 2018) pas dans l'OEIS
Giuseppe

Réponses:

12

Python 2 , 43 39 octets

f=lambda n,i=2:n/i and n*2-n%i+f(n,i*2)

Essayez-le en ligne!


Comment?

Chaque appel de la fonction récursive calcule une seule dilution. La position de l'inséré 0est log2(i). La fonction se répète jusqu'à ce qu'elle isoit plus grande que net que l'insertion se fasse à gauche du nombre. Si i>n, n/iévalue à 0, qui est une valeur fausse en Python.

n*2décale la totalité du chiffre binaire numéro un vers la gauche n%iou n % 2**(position of insertion)calcule la valeur de la partie qui ne doit pas être décalée vers la gauche. Cette valeur est soustraite du nombre décalé.

Exemple (n = 7)

call       n/i          bin(n)  n*2     n%i   dilution       return value

f(7, i=2)  3 => truthy  0b111   0b1110  0b1   0b1101 = 13    13 + f(7, 2*2) = 13 + 11 = 24
f(7, i=4)  1 => truthy  0b111   0b1110  0b11  0b1011 = 11    11 + f(7, 4*2) = 11 + 0 = 11
f(7, i=8)  0 => falsy                                        0
ovs
la source
7

Gelée , 11 octets

BJṖ2*ɓdḅḤ}S

Essayez-le en ligne!

Comment ça marche

BJṖ2*ɓdḅḤ}S  Main link. Argument: n (integer)

B            Binary; convert n to base 2. This yields a digit array A.
 J           Indices; yield [1, ..., len(A)].
  Ṗ          Pop; remove the last element, yielding [1, 2, ..., len(A)-1].
   2*        Elevate 2 to these powers, yielding [2, 4, ..., 2**(len(A)-1)].
             Let's call the result B.
     ɓ       Begin a new, dyadic chain, with left argument n and right argument B.
      d      Divmod; yield [n/b, n%b], for each b in B.
        Ḥ}   Unhalve right; yield 2b for each b in B, i.e., [4, 8, ..., 2**len(A)].
       ḅ     Unbase; convert each [n/b, n%b] from base 2b to integer, yielding
             (2b)(n/b) + (n%b).
          S  Take the sum.
Dennis
la source
5

MATL , 13 octets

tZl:W&\5ME*+s

Essayez-le sur MATL Online! Ou vérifiez tous les cas de test .

Explication

Considérez la saisie 12comme exemple.

t     % Implicit input. Duplicate
      % STACK: 12, 12
Zl    % Binary logarithm
      % STACK: 12, 3.584962500721156
:     % Range (rounds down)
      % STACK: 12, [1 2 3]
W     % Power with base 2, element-wise
      % STACK: 12, [2 4 8]
&\    % 2-output modulus, element-wise: pushes remainders and quotients
      % STACK: [0 0 4], [6 3 1]
5M    % Push array of powers of 2, again
      % STACK: [0 0 4], [6 3 1], [2 4 8]
E     % Multiply by 2
      % STACK: [0 0 4], [6 3 1], [4 8 16]
*     % Multiply, element-wise
      % STACK: [0 0 4], [24 24 16]
+     % Add, element-wise
      % STACK: [24 24 20]
s     % Sum of array. Implicit display
      % STACK: 68
Luis Mendo
la source
4

C,  58  56 octets

Merci à @Dennis d'avoir économisé deux octets!

s,k;f(n){for(s=0,k=2;k<=n;k*=2)s+=n/k*k*2+n%k;return s;}

Essayez-le en ligne!

C (gcc) , 50 octets

s,k;f(n){for(s=0,k=2;k<=n;)s+=n%k+n/k*(k+=k);k=s;}

Le retour par k=s;est un comportement non défini, mais fonctionne avec gcc lorsque les optimisations sont désactivées. En outre, n%k+n/k*(k+=k)a un comportement non spécifié , mais semble fonctionner correctement avec gcc.

Essayez-le en ligne!

Steadybox
la source
s,k;f(n){for(s=0,k=2;k<=n;)s+=n%k+n/k*(k*=2);return s;}(55 octets)
Kevin Cruijssen
1
On ne sait pas lequel est évalué en premier n%kou n/k*(k*=2).
Steadybox
1
@KevinCruijssen Le côté évalué en premier n'est pas spécifié. C est comme ça ...
Steadybox
2
Ah, je vois que vous avez bien ajouté cela dans votre réponse. Je ne savais pas que ce genre de comportement indéfini s'était produit en C. J'ai trois heures d'expérience en C, donc je ne sais presque rien à ce sujet. TIL :) En Java for(s=0,k=2;k<=n;)s+=n%k+n/k*(k*=2);return s;est très bien, et n%ksera toujours évalué avant n/k*(k*=2)et n/kévaluera également avant k*=2. Merci pour l'explication. (Je vais supprimer certains de mes commentaires maintenant pour réduire l'encombrement.)
Kevin Cruijssen
J'adore utiliser UB comme fonctionnalité. Et le golf de code dans une langue réelle devrait être dans une autre catégorie de toute façon :)
Regis Portalez
4

Gelée , 9 8 octets

BḊḄÐƤạḤS

Essayez-le en ligne!

B                        to binary          42 -> 1 0 1 0 1 0
 Ḋ                       drop first                 0 1 0 1 0
  ḄÐƤ                    each suffix to decimal   10 10 2 2 0
      Ḥ                  double the input                  84
     ạ                   absolute difference   74 74 82 82 84
       S                 add them up                      396

Inversement,: B¹ƤṖ+BḄSobtenez les préfixes, supprimez-les en dernier, ajoutez-les à l'entrée et additionnez.

FrownyFrog
la source
4

J , 20 15 14 octets

+/@}:@:+[\&.#:

Essayez-le en ligne.

15 octets

1#.-,+:-#.\.@#:

Essayez-le en ligne!

     +:             Input×2
       -            Subtract
        #.\.@#:     The list of binary suffixes of input (in decimal)
   -,               Append negative input
1#.                 Add them up
FrownyFrog
la source
pourquoi la formule double moins fonctionne-t-elle? pourquoi est-ce équivalent à des dilutions?
Jonah
1
La dilution @Jonah consiste à ajouter un certain préfixe binaire (nombre «arrondi vers le bas») au nombre, ce qui équivaut à ajouter le nombre entier à lui-même (à la fois le préfixe et le reste), puis à soustraire le reste.
FrownyFrog
4

Japt , 12 11 octets

¢¬£¢iYTÃÅxÍ

Essayez-le


Explication

                 :Implicit input of integer U
¢                :Convert to base-2 string
 ¬               :Split to an array of individual characters/digits
  £    Ã         :Map over the elements, with Y being the current 0-based index
   ¢             :  Convert U to a base-2 string
    iYT          :  Insert a 0 in that string at index Y
        Å        :Slice off the first element of the array
          Í      :Convert each element to a base-10 integer
         x       :Reduce by addition
Hirsute
la source
3

JavaScript (ES6), 41 40 octets

1 octet enregistré grâce à Mr.Xcoder

f=(n,k=1)=>k<n&&(n&k)+2*(n&~k)+f(n,k-~k)

Cas de test

Arnauld
la source
3

Rétine , 53 50 47 octets

.+
*
+`(_+)\1
$1O
O_
_
L$`\B
$`O$'
+%`\B
¶$`¶
_

Essayez-le en ligne! Le lien inclut des cas de test. Edit: sauvé 3 octets grâce à @MartinEnder. Explication:

.+
*
+`(_+)\1
$1O
O_
_

Convertissez de décimal en binaire, mais en utilisant O pour représenter 0, car ce n'est pas un chiffre, et _ pour représenter 1, car c'est le caractère de répétition par défaut dans Retina 1.

L$`\B
$`O$'

Insérez un O entre chaque paire de chiffres et rassemblez les résultats sous forme de liste.

+%`\B
¶$`¶

Convertissez du binaire en unaire. (Cette conversion produit des Os supplémentaires , mais peu nous importe.)

_

Additionnez et convertissez en décimal.

Neil
la source
La conversion binaire en décimale peut être effectuée en 12 octets (économie de 3): tio.run/##K0otycxLNPz/… Voir cette réponse pour savoir comment cela fonctionne.
Martin Ender
@MartinEnder Merci, j'oublie toujours ça. (J'ai également été légèrement déçu que la version alternative ne fonctionne que sur un seul numéro.)
Neil
Eh bien, dans le cas où vous avez chaque numéro sur sa propre ligne, vous pouvez le faire fonctionner avec un numéro supplémentaire %. Si c'est plus compliqué, vous aurez besoin de quelque chose comme /[O_]+/_.
Martin Ender
2

Pyth , 13 octets

smiXd.BQZ2Ssl

Essayez-le ici!

Explication

smiXd.BQZ2Ssl | Programme complet.

           sl | Logarithme en base 2 de l'entrée, basé sur un entier.
          S | Créez la plage entière [1 ... le logarithme au sol].
 m | Et mappez une fonction dessus.
------------ + - + ----------------------------------- ------------------
  iXd.BQZ2 | La fonction à mapper (utilise une variable d).
     .BQ | Dans la représentation binaire de l'entrée ...
   XZ | ... Insérez un zéro ...
    d | ... à l'index d.
  i 2 | Et convertissez le résultat de la base 2 en entier.
------------ + - + ----------------------------------- ------------------
s | Additionnez la liste résultante.
M. Xcoder
la source
2

Gelée , 10 octets

BµLḤ_J’×µḄ

Essayez-le en ligne!

Pas le plus court actuellement, mais il se pourrait qu'il y ait un moyen de contourner Bµ µḄ...

Explication

BµLḤ_J’×µḄ    Main link. Argument: n (integer)
B             Binary; convert n to an binary of binary digits. Call this A.
 µ            Start a new monadic link with argument A.
  L           Length; yield len(A). We'll call this l.
   Ḥ          Unhalve; yield l * 2.
     J        Length range; yield [1, 2, ..., l].
    _         Subtract; yield [l*2 - 1, l*2 - 2, ..., l].
      ’       Decrement; subtract one from each item.
       ×      Multiply each item by the corresponding item in A. Call this B.
        µ     Start a new monadic link with argument B.
         Ḅ    Unbinary; convert from a binary array to a decimal.

Fondamentalement, cela fonctionne en multipliant chaque chiffre binaire par un nombre magique. Je ne peux pas l'expliquer sans le visualiser, alors voici le nombre binaire avec lequel nous travaillerons:

1111

Comme expliqué par le défi, la sortie que nous voulons est la somme de ces nombres binaires:

10111  = 2^4 + 2^2 + 2^1 + 2^0
11011  = 2^4 + 2^3 + 2^1 + 2^0
11101  = 2^4 + 2^3 + 2^2 + 2^0

Cependant, nous n'avons pas à insérer de zéros: l'atome "non binaire" de Jelly acceptera des nombres autres que juste 0et 1. Quand nous nous permettons d'utiliser2 , ce modèle devient plus simple:

2111   = 2*2^3 + 1*2^2 + 1*2^1 + 1*2^0
2211   = 2*2^3 + 2*2^2 + 1*2^1 + 1*2^0
2221   = 2*2^3 + 2*2^2 + 2*2^1 + 1*2^0

Lorsque nous résumons les chiffres de chaque colonne, nous obtenons

6543   = 6*2^3 + 5*2^2 + 4*2^1 + 3*2^0 = 48 + 20 + 8 + 3 = 79.

L'astuce que cette réponse utilise consiste à générer ce modèle et à multiplier chaque chiffre par le chiffre correspondant dans l'original pour annuler les colonnes nécessaires. 12, par exemple, serait représenté comme

 1100
×6543
=6500  = 6*2^3 + 5*2^2 + 0*2^1 + 0*2^0 = 48 + 20 + 0 + 0 = 68.
ETHproductions
la source
1

Husk , 13 12 octets

-1 octet grâce à @Mr. Xcoder!

ṁḋ§z·+Θḣotṫḋ

Essayez-le en ligne!

Explication

ṁḋ§z·+Θḣ(tṫ)ḋ  -- example input: 6
            ḋ  -- convert to binary: [1,1,0]
  §            -- fork argument
        (tṫ)   -- | tail of tails: [[1,0],[0]]
       ḣ       -- | heads: [[1],[1,1],[1,1,0]]
   z           -- and zipWith the following (example with [1,0] [1])
    · Θ        -- | prepend 0 to second argument: [0,1]
     +         -- | concatenate: [1,0,0,1]
               -- : [[1,0,1,0],[1,1,0,0]]
ṁ              -- map the following (example with [1,0,1,0]) and sum
 ḋ             -- | convert from binary: 10
               -- : 22
ბიმო
la source
1

Pip , 21 18 octets

2*a-a%2**_MS1,#TBa

Essayez-le en ligne!

Explication

Appelez notre numéro d'entrée a. Pour chaque index binaire iauquel nous voulons insérer un zéro, nous pouvons calculer les bits à gauche du point d'insertion as a // 2**i(où //est la division entière et l' **exponentiation), les bits à droite du point d'insertion as a % 2**i, et donc l'entier dilué as 2 * (a // 2**i) * 2**i + (a % 2**i). Mais (a // 2**i) * 2**iest égal à a - (a % 2**i), et nous pouvons donc réorganiser une formule plus courte: 2 * (a - a % 2**i) + a % 2**i= 2 * a - a % 2**i.

2*a-a%2**_MS1,#TBa
                       a is 1st command-line argument (implicit)
               TBa     Convert a to binary
              #        Length of the binary expansion
            1,         Range from 1 up to (but not including) that number
          MS           Map this function to the range and sum the results:
2*a-a%2**_              The above formula, where _ is the argument of the function
                       The final result is autoprinted
DLosc
la source
1

R , 141 48 octets

function(n,l=2^(1:log2(n)))sum(n%%l+(n%/%l*2*l))

Essayez-le en ligne!

Soit je fais quelque chose de vraiment mal, soit R est tout simplement horrible à manipuler. Le portage de l'approche de Luis Mendo est facile, correct et golfique.

Mais si vous voulez vraiment vous occuper des opérations de bits, MickyT a suggéré les 105 octets suivants:

function(i)sum(sapply(1:max(which(b<-intToBits(i)>0)),function(x)packBits(head(append(b,F,x),-1),"i")))-i

Essayez-le en ligne!

Giuseppe
la source
Voici un octet de 111 octets dont vous pourriez sûrement en retirer un peu plus.
MickyT
@MickyT Cheers! très agréable, bien que porter une approche entièrement différente soit mieux!
Giuseppe
1

Lot, 92 77 octets

@set/an=2,t=0
:l
@if %1 geq %n% set/at+=%1*2-(%1%%n),n*=2&goto l
@echo %t%

Modifier: basculé sur la même formule que tout le monde utilise.

Neil
la source
0

Attaché , 57 octets

Sum##UnBin=>{Join[Join=>_,"0"]}=>SplitAt#1&`:@{#_-1}##Bin

Essayez-le en ligne!

Je pensais aborder le problème à partir d'une approche de manipulation non binaire, car une telle approche n'est pas pratique dans Attache. Je dois enquêter sur certaines parties de cette approche pour trouver des alternatives.

Explication

Voici une version étendue:

Define[$joinByZero, {Join[Join=>_,"0"]}]

Define[$insertionPoints,
    SplitAt#1&`:@{#_-1}
]

Define[$f,
Sum##UnBin=>joinByZero=>insertionPoints##Bin
]

Cela prend simplement la représentation binaire du nombre, le fractionne à certains points, y insère des zéros, reconvertit en décimal et les additionne.

Conor O'Brien
la source
0

J , 33 octets

1#.[:}:#.@(<\;@(,0;])"0<@}.\.)@#:

Il y a très probablement beaucoup de place pour le golf.

Comment?

@#: convertir en binaire et

<@}.\. - trouvez tous les suffixes, déposez le premier chiffre de chacun et encadrez

<\ - trouver tous les préfixes et les encadrer

(,0;])"0 - à chaque préfixe ajouter 0 puis ajouter le suffixe décapité correspondant

;@ raze (unbox)

1#.[:}:#.@ - convertir en décimal, réduire et additionner

Essayez-le en ligne!

Galen Ivanov
la source