Somme intere diluite


26

Un numero intero positivo può essere diluito inserendo un 0tra due bit nella sua espansione binaria. Ciò significa che un nnumero di bit presenta n-1diluizioni, che non sono necessariamente tutte distinte.

Ad esempio, per 12(o 1100in binario), le diluizioni sono

11000 = 24
   ^

11000 = 24
  ^

10100 = 20
 ^

In questa sfida, prenderemo la somma di tutte le diluizioni, escluso il numero originale. Per 12, prendendo la somma dei 24, 24, 20risultati 68, 68dovrebbe essere l'output per 12.

Sfida

Dato un numero intero positivo n > 1come input, output / restituisce la somma diluita come spiegato sopra.

Esempi

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

Regole

  • Si può presumere che l'input e l'output si adattino al tipo intero nativo della tua lingua.
  • L'input e l'output possono essere forniti in qualsiasi formato conveniente .
  • È accettabile un programma completo o una funzione. Se una funzione, è possibile restituire l'output anziché stamparlo.
  • Sono vietate le scappatoie standard .
  • Si tratta di quindi si applicano tutte le normali regole del golf e vince il codice più breve (in byte).

"Qualsiasi formato utile" include una stringa binaria?
Shaggy,

1
@Shaggy "Qualsiasi formato utile" deve essere comprensivo di metodi di input / output, non di formattazione . In quanto tale, sto per dire di no, devi prendere l'input come numero intero o come stringa che rappresenta quel numero intero.
AdmBorkBork,

Bella sfida!
Manish Kundu,

1
Questa sequenza non è attualmente (30 gennaio 2018) non nell'OEIS
Giuseppe

Risposte:


12

Python 2 , 43 39 byte

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

Provalo online!


Come?

Ogni chiamata della funzione ricorsiva calcola una singola diluizione. La posizione dell'inserzione 0è log2(i). La funzione ricorre fino a quando idiventa più grande di ne l'inserimento sarebbe sulla sinistra del numero. If i>n, n/ivaluta 0, che è un valore errato in Python.

n*2sposta l'intera cifra binaria numero uno a sinistra n%io n % 2**(position of insertion)calcola il valore della parte che non deve essere spostata a sinistra. Questo valore viene sottratto dal numero spostato.

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

7

Gelatina , 11 byte

BJṖ2*ɓdḅḤ}S

Provalo online!

Come funziona

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.

5

MATL , 13 byte

tZl:W&\5ME*+s

Provalo su MATL Online! Oppure verifica tutti i casi di test .

Spiegazione

Considera l'input 12come esempio.

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

4

C,  58  56 byte

Grazie a @Dennis per aver salvato due byte!

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

Provalo online!

C (gcc) , 50 byte

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

Il ritorno da k=s;è un comportamento indefinito, ma funziona con gcc quando le ottimizzazioni sono disabilitate. Inoltre, n%k+n/k*(k+=k)ha un comportamento non specificato , ma sembra funzionare bene con gcc.

Provalo online!


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

1
Non si può dire quale viene valutato per primo n%ko n/k*(k*=2).
Steadybox

1
@KevinCruijssen Quale parte viene valutata per prima non viene specificata. C è così ...
Steadybox,

2
Ah, vedo che l'hai aggiunto nella tua risposta. Non sapevo che questo tipo di comportamento indefinito fosse accaduto in C. Ho circa tre ore di esperienza in C, quindi a malapena ne so nulla. TIL :) In Java for(s=0,k=2;k<=n;)s+=n%k+n/k*(k*=2);return s;va benissimo, e n%ksarà sempre valutato prima n/k*(k*=2)e n/kvaluterà anche prima k*=2. Grazie per la spiegazione. (
Eliminerò

Adoro usare UB come funzionalità. E giocare a golf con il codice in un linguaggio reale dovrebbe essere comunque in un'altra categoria :)
Regis Portalez,

4

Gelatina , 9 8 byte

BḊḄÐƤạḤS

Provalo online!

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

Viceversa,: B¹ƤṖ+BḄSottenere i prefissi, rilasciarli per ultimi, aggiungerli all'input e sommare.


4

J , 20 15 14 byte

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

Provalo online.

15 byte

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

Provalo online!

     +:             Input×2
       -            Subtract
        #.\.@#:     The list of binary suffixes of input (in decimal)
   -,               Append negative input
1#.                 Add them up

perché la doppia formula negativa funziona? perché è equivalente alle diluizioni?
Giona

1
La diluizione di @Jonah sta aggiungendo un certo prefisso binario (numero "arrotondato per difetto") al numero, il che equivale ad aggiungere l'intero numero a se stesso (sia il prefisso che il resto) e quindi sottrarre il resto.
FrownyFrog,

4

Japt , 12 11 byte

¢¬£¢iYTÃÅxÍ

Provalo


Spiegazione

                 :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

3

JavaScript (ES6), 41 40 byte

Salvato 1 byte grazie a Mr.Xcoder

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

Casi test


3

Retina , 53 50 47 byte

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

Provalo online! Il link include casi di test. Modifica: salvato 3 byte grazie a @MartinEnder. Spiegazione:

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

Converti da decimale a binario, ma usando O per rappresentare 0, poiché non è una cifra, e _ per rappresentare 1, poiché è il carattere di ripetizione predefinito in Retina 1.

L$`\B
$`O$'

Inserisci una O tra ogni coppia di cifre e raccogli i risultati come un elenco.

+%`\B
¶$`¶

Converti da binario a unario. (Questa conversione produce ulteriori Os, ma non ci interessa.)

_

Somma e converti in decimale.


La conversione binaria in decimale può essere eseguita in 12 byte (salvando 3): tio.run/##K0otycxLNPz/… Vedi questa risposta per come funziona.
Martin Ender,

@MartinEnder Grazie, continuo a dimenticarmene. (Sono stato anche leggermente deluso dal fatto che la versione alternativa funzioni solo su un singolo numero.)
Neil

Bene, nel caso in cui hai ogni numero sulla sua stessa linea puoi farlo funzionare con un ulteriore %. Se è più complicato avresti bisogno di qualcosa del genere /[O_]+/_.
Martin Ender,

2

Pyth , 13 byte

smiXd.BQZ2Ssl

Provalo qui!

Spiegazione

smiXd.BQZ2Ssl | Programma completo.

           sl | Il logaritmo in base 2 dell'input, basato su un numero intero.
          S | Crea l'intervallo intero [1 ... il logaritmo floored].
 m | E mappare una funzione su di essa.
------------ + - + ----------------------------------- ------------------
  iXd.BQZ2 | La funzione da mappare (usa una variabile d).
     .BQ | Nella rappresentazione binaria dell'ingresso ...
   XZ | ... Inserisci uno zero ...
    d | ... All'indice d.
  i 2 | E converti il ​​risultato dalla base 2 in un numero intero.
------------ + - + ----------------------------------- ------------------
s | Somma l'elenco risultante.

2

Gelatina , 10 byte

BµLḤ_J’×µḄ

Provalo online!

Non il più breve al momento, ma potrebbe essere se c'è un modo per aggirare Bµ µḄ...

Spiegazione

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.

Fondamentalmente, questo funziona moltiplicando ogni cifra binaria per un numero magico. Non posso spiegarlo senza visualizzarlo, quindi ecco il numero binario con cui lavoreremo:

1111

Come spiegato dalla sfida, l'output che vogliamo è la somma di questi numeri binari:

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

Tuttavia, in realtà non dobbiamo inserire zero: l'atomo "non comune" di Jelly accetterà numeri diversi da solo 0e 1. Quando ci permettiamo di usare 2, questo modello diventa più semplice:

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

Quando riassumiamo le cifre in ogni colonna, otteniamo

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

Il trucco usato da questa risposta è generare questo modello e moltiplicare ogni cifra per la cifra corrispondente nell'originale per cancellare le colonne necessarie. 12, ad esempio, sarebbe rappresentato come

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


1

Husk , 13 12 byte

-1 byte grazie a @Mr. Xcoder!

ṁḋ§z·+Θḣotṫḋ

Provalo online!

Spiegazione

ṁḋ§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


1

Pip , 21 18 byte

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

Provalo online!

Spiegazione

Chiama il nostro numero di input a. Per ogni indice binario iin cui vogliamo inserire uno zero, possiamo calcolare i bit a sinistra del punto di inserimento come a // 2**i(dove //è divisione intera ed **è esponentiazione), i bit a destra del punto di inserimento come a % 2**i, e quindi l'intero intero diluito come 2 * (a // 2**i) * 2**i + (a % 2**i). Ma (a // 2**i) * 2**iè uguale a a - (a % 2**i), e quindi possiamo riorganizzare in una formula più breve: 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

1

R , 141 48 byte

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

Provalo online!

O sto facendo qualcosa di veramente sbagliato o R è terribile a manipolazione un po '. Porting dell'approccio di Luis Mendo è facile, corretto e goloso.

Ma se vuoi davvero solo andare in giro con le operazioni di bit, MickyT ha suggerito il seguente 105 byter:

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

Provalo online!


Ecco un 111 byte di cui sono sicuro che potresti prenderne un po 'di più.
MickyT

@MickyT Cheers! molto bello, anche se è meglio eseguire il porting di un approccio completamente diverso!
Giuseppe,


1

Lotto, 92 77 byte

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

Modifica: passa alla stessa formula utilizzata da tutti gli altri.




0

Attache , 57 byte

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

Provalo online!

Ho pensato di affrontare il problema con un approccio di manipolazione senza bit, dato che tale approccio non è pratico in Attache. Devo studiare alcune delle parti di questo approccio per alternative.

Spiegazione

Ecco una versione estesa:

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

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

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

Questo semplicemente prende la rappresentazione binaria del numero, lo divide in determinati punti, inserisce gli zero lì, li converte in decimali e li somma insieme.


0

J , 33 byte

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

Molto probabilmente c'è molto spazio per ulteriori golf.

Come?

@#: convertire in binario e

<@}.\. - trova tutti i suffissi, rilascia la prima cifra da ciascuna e casella

<\ - trova tutti i prefissi e li box

(,0;])"0 - a ciascun prefisso aggiungi 0 quindi aggiungi il suffisso decapitato corrispondente

;@ raze (unbox)

1#.[:}:#.@ - converti in decimale, riduzione e somma

Provalo online!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.