Verwässerte ganzzahlige Summen


26

Eine positive ganze Zahl kann durch Einfügen von a zwischen zwei Bits in ihrer binären Erweiterung verdünnt werden 0. Dies bedeutet, dass eine n-Bit-Zahl n-1Verdünnungen aufweist, die nicht unbedingt alle verschieden sind.

Zum Beispiel sind für 12(oder 1100in binärer Form) die Verdünnungen

11000 = 24
   ^

11000 = 24
  ^

10100 = 20
 ^

Bei dieser Herausforderung nehmen wir die Summe aller Verdünnungen, ausschließlich der ursprünglichen Zahl. Nimmt 12man die Summe der 24, 24, 20Ergebnisse in sich 68, so 68sollte die Ausgabe für 12.

Herausforderung

Bei einer positiven Ganzzahl n > 1als Eingabe wird die verdünnte Summe wie oben erläutert ausgegeben / zurückgegeben.

Beispiele

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

Regeln

  • Es kann davon ausgegangen werden, dass die Eingabe und Ausgabe in den systemeigenen Ganzzahltyp Ihrer Sprache passen.
  • Die Ein- und Ausgabe kann in jedem beliebigen Format erfolgen .
  • Es ist entweder ein vollständiges Programm oder eine Funktion zulässig. Bei einer Funktion können Sie die Ausgabe zurückgeben, anstatt sie zu drucken.
  • Standardlücken sind verboten.
  • Dies ist daher gelten alle üblichen Golfregeln, und der kürzeste Code (in Byte) gewinnt.

Enthält "irgendein geeignetes Format" eine Binärzeichenfolge?
Shaggy

1
@Shaggy „Jedes geeignetes Format“ sollte inklusive seine Methode der Eingabe / Ausgabe, nicht - Formats . Daher sage ich nein, Sie müssen Eingaben als Ganzzahl oder als Zeichenfolge für diese Ganzzahl annehmen.
AdmBorkBork

Schöne Herausforderung!
Manish Kundu

1
Diese Sequenz ist derzeit (30 Jan 2018) nicht im OEIS
Giuseppe

Antworten:


12

Python 2 , 43 39 Bytes

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

Probieren Sie es online!


Wie?

Jeder Aufruf der rekursiven Funktion berechnet eine einzelne Verdünnung. Die Position des eingefügten 0ist log2(i). Die Funktion wird solange wiederholt, bis igrößer als nund die Einfügung links von der Zahl ist. Wenn i>n, wird n/iausgewertet 0, was in Python ein falscher Wert ist.

n*2Verschiebt die gesamte Binärzahl um eine Stelle nach links n%ioder n % 2**(position of insertion)berechnet den Wert des Teils, der nicht nach links verschoben werden soll. Dieser Wert wird von der verschobenen Zahl abgezogen.

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

Jelly , 11 Bytes

BJṖ2*ɓdḅḤ}S

Probieren Sie es online!

Wie es funktioniert

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 Bytes

tZl:W&\5ME*+s

Probieren Sie es bei MATL Online! Oder überprüfen Sie alle Testfälle .

Erläuterung

Betrachten Sie die Eingabe 12als Beispiel.

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 Bytes

Vielen Dank an @Dennis für das Speichern von zwei Bytes!

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

Probieren Sie es online!

C (gcc) , 50 Bytes

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

Die Rückgabe von k=s;ist undefiniertes Verhalten, funktioniert jedoch mit gcc, wenn Optimierungen deaktiviert sind. Hat n%k+n/k*(k+=k)auch nicht spezifiziertes Verhalten , scheint aber gut mit gcc zu funktionieren.

Probieren Sie es online!


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

1
Es ist nicht zu sagen, welche zuerst ausgewertet wird n%koder n/k*(k*=2).
Steadybox

1
@KevinCruijssen Welche Seite zuerst bewertet wird, ist unbekannt. C ist wie das ...
Steadybox

2
Ah, ich sehe, dass Sie das in Ihrer Antwort tatsächlich hinzugefügt haben. Wusste nicht, dass diese Art von undefiniertem Verhalten in C passiert ist. Ich habe eine dreistündige Erfahrung in C, daher weiß ich kaum etwas darüber. Bis :) In Java for(s=0,k=2;k<=n;)s+=n%k+n/k*(k*=2);return s;ist völlig in Ordnung, und n%kwird immer vorher ausgewertet n/k*(k*=2)und n/kwird auch vorher ausgewertet k*=2. Danke für die Erklärung. (Ich werde jetzt einige meiner Kommentare löschen, um das
Durcheinander

Ich liebe es, UB als Feature zu nutzen. Und Code Golfing in einer realen Sprache sollte sowieso in einer anderen Kategorie sein :)
Regis Portalez

4

Gelee , 9 8 Bytes

BḊḄÐƤạḤS

Probieren Sie es 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

Umgekehrt B¹ƤṖ+BḄS: Präfixe abrufen, zuletzt ablegen, zur Eingabe hinzufügen und summieren.


4

J , 20 15 14 Bytes

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

Probieren Sie es online aus.

15 Bytes

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

Probieren Sie es online!

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

warum funktioniert die double minus formel Warum ist es gleichbedeutend mit Verdünnungen?
Jonah

1
@Jonah Dilution fügt der Zahl ein bestimmtes binäres Präfix (Zahl "abgerundet") hinzu. Dies entspricht dem Hinzufügen der ganzen Zahl zu sich selbst (sowohl Präfix als auch Rest) und dem anschließenden Subtrahieren des Restes.
FrownyFrog

4

Japt , 12 11 Bytes

¢¬£¢iYTÃÅxÍ

Versuch es


Erläuterung

                 :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 bis 40 Byte

Dank Mr.Xcoder 1 Byte gespeichert

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

Testfälle


3

Netzhaut , 53 50 47 Bytes

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

Probieren Sie es online! Link enthält Testfälle. Bearbeiten: 3 Bytes dank @MartinEnder gespeichert. Erläuterung:

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

Konvertieren Sie von Dezimal in Binär, verwenden Sie jedoch O, um 0 darzustellen, da dies keine Ziffer ist, und _, um 1 darzustellen, da dies das Standard-Wiederholungszeichen in Retina 1 ist.

L$`\B
$`O$'

Fügen Sie zwischen jedem Ziffernpaar ein O ein und sammeln Sie die Ergebnisse als Liste.

+%`\B
¶$`¶

Konvertiert von binär zu unär. (Diese Konvertierung erzeugt zusätzliche Os, aber das ist uns egal.)

_

Summieren und in Dezimalzahl umwandeln.


Die Umwandlung von Binär in Dezimal kann in 12 Bytes erfolgen (3 werden gespart): tio.run/##K0otycxLNPz/… Siehe diese Antwort für die Funktionsweise.
Martin Ender

@MartinEnder Danke, das vergesse ich immer wieder. (Ich war auch etwas enttäuscht, dass die alternative Version nur für eine einzelne Nummer funktioniert.)
Neil

Nun, in dem Fall, dass Sie jede Nummer in einer eigenen Zeile haben, können Sie dafür sorgen, dass sie mit einer zusätzlichen Nummer funktioniert %. Wenn es komplizierter ist, brauchen Sie so etwas /[O_]+/_.
Martin Ender

2

Pyth , 13 Bytes

smiXd.BQZ2Ssl

Probieren Sie es hier aus!

Erläuterung

smiXd.BQZ2Ssl | Volles Programm.

           sl | Der Logarithmus zur Basis 2 der Eingabe, der auf eine Ganzzahl begrenzt ist.
          S | Erstellen Sie den Integer-Bereich [1 ... den Floored-Logarithmus].
 m | Und ordne eine Funktion darüber zu.
------------ + - + ----------------------------------- ------------------
  iXd.BQZ2 | Die abzubildende Funktion (verwendet eine Variable d).
     .BQ | In der binären Darstellung des Eingangs ...
   XZ | ... eine Null einfügen ...
    d | ... bei Index d.
  i 2 | Und konvertieren Sie das Ergebnis von Basis 2 in eine Ganzzahl.
------------ + - + ----------------------------------- ------------------
s | Summiere die resultierende Liste.

2

Gelee , 10 Bytes

BµLḤ_J’×µḄ

Probieren Sie es online!

Derzeit nicht die kürzeste, aber es könnte sein, dass es einen Ausweg gibt Bµ µḄ...

Erläuterung

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.

Grundsätzlich funktioniert dies, indem jede Binärzahl mit einer magischen Zahl multipliziert wird. Ich kann es nicht erklären, ohne es zu visualisieren, also ist hier die Binärzahl, mit der wir arbeiten werden:

1111

Wie durch die Herausforderung erklärt, ist die Ausgabe, die wir wollen, die Summe dieser Binärzahlen:

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

Wir müssen jedoch eigentlich keine Nullen einfügen: Jellys "unbinäres" Atom akzeptiert andere Zahlen als nur 0und 1. Wenn wir es uns erlauben 2, wird dieses Muster einfacher:

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

Wenn wir die Ziffern in jeder Spalte zusammenfassen, erhalten wir

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

Der Trick, den diese Antwort verwendet, besteht darin, dieses Muster zu generieren und jede Ziffer mit der entsprechenden Ziffer im Original zu multiplizieren, um die erforderlichen Spalten zu löschen. 12 wäre beispielsweise dargestellt als

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


1

Husk , 13 12 Bytes

-1 Byte dank @Mr. Xcoder!

ṁḋ§z·+Θḣotṫḋ

Probieren Sie es online!

Erläuterung

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

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

Probieren Sie es online!

Erläuterung

Rufen Sie unsere Eingangsnummer an a. Für jeden Binärindex, ibei dem wir eine Null einfügen möchten, können wir die Bits links vom Einfügepunkt als a // 2**i(wobei //Ganzzahldivision und **Exponentiation ist), die Bits rechts vom Einfügepunkt als a % 2**iund daher die verdünnte Ganzzahl als berechnen 2 * (a // 2**i) * 2**i + (a % 2**i). Ist (a // 2**i) * 2**iaber gleich a - (a % 2**i), und so können wir zu einer kürzeren Formel umstellen: 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 Bytes

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

Probieren Sie es online!

Entweder mache ich etwas wirklich Falsches oder R ist einfach schrecklich, wenn es um Manipulation geht. Porting Luis Mendo Ansatz ist einfach, zu korrigieren und Golfy.

Aber wenn Sie wirklich nur mit Bit-Operationen herumspielen wollen, hat MickyT die folgenden 105 Bytes vorgeschlagen:

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

Probieren Sie es online!


Hier ist eine 111-Byte- Datei, aus der Sie sicher noch ein paar herausholen können.
MickyT

@ MickyT Prost! Sehr schön, obwohl es besser ist, einen ganz anderen Ansatz zu portieren!
Giuseppe


1

Batch, 92 77 Bytes

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

Bearbeiten: Wechselt zu derselben Formel, die alle anderen verwenden.




0

Attache , 57 Bytes

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

Probieren Sie es online!

Ich dachte, ich würde das Problem von einem Ansatz ohne Bitmanipulation aus angehen, da ein solcher Ansatz in Attache unpraktisch ist. Ich muss einige Teile dieses Ansatzes auf Alternativen untersuchen.

Erläuterung

Hier ist eine erweiterte Version:

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

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

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

Dies nimmt einfach die binäre Darstellung der Zahl, teilt sie an bestimmten Punkten, fügt dort Nullen ein, wandelt sie in Dezimalzahlen um und summiert sie zusammen.


0

J , 33 Bytes

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

Höchstwahrscheinlich gibt es viel Raum für weiteres Golfen.

Wie?

@#: in binär umwandeln und

<@}.\. - Finden Sie alle Ausreichenden, lassen Sie die erste Ziffer aus jedem Kästchen fallen

<\ - Finde alle Präfixe und boxe sie ein

(,0;])"0 - Fügen Sie an jedes Präfix den Wert 0 und dann das entsprechende Suffix mit Enthauptung an

;@ raze (Unbox)

1#.[:}:#.@ - Umrechnung in Dezimal, Kürzel und Summe

Probieren Sie es online!

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.