Abwechselnd etwas schmierend

12

Einführung

Für diese Herausforderung müssen Sie die nachgestellten Nullen einer Ganzzahl-Binärdarstellung auf setzen 010101…. Dies wird am besten anhand eines Beispiels erläutert:

In Anbetracht der Ganzzahl 400besteht der erste Schritt darin, sie in eine Binärzahl umzuwandeln:

110010000

Wie wir sehen können, ist das fünfte Bit das niedrigstwertige 1Bit. Von dort aus ersetzen wir die unteren Nullen durch 0101:

110010101

Zuletzt konvertieren wir das zurück in dezimal: 405

Herausforderung

Bei einer positiven Ganzzahl wird der entsprechende Ergebniswert des oben definierten Prozesses zurückgegeben / ausgegeben.

Regeln

  • Diese Sequenz ist nur für Ganzzahlen mit mindestens einem 1Bit definiert, sodass die Eingabe immer ≥ 1 ist
  • Sie können die Eingabe stattdessen als Zeichenfolge und als Liste von Dezimalstellen vornehmen
  • Sie müssen keine ungültigen Eingaben verarbeiten

Testfälle

Hier sind einige weitere Testfälle mit den Zwischenschritten (Sie müssen diese nicht ausdrucken / zurücksenden):

In -> … -> … -> Out
1 -> 1 -> 1 -> 1
2 -> 10 -> 10 -> 2
3 -> 11 -> 11 -> 3
4 -> 100 -> 101 -> 5
24 -> 11000 -> 11010 -> 26
29 -> 11101 -> 11101 -> 29
32 -> 100000 -> 101010 -> 42
192 -> 11000000 -> 11010101 -> 213
400 -> 110010000 -> 110010101 -> 405
298 -> 100101010 -> 100101010 -> 298
ბიმო
quelle
Können wir eine 32-Bit-Ganzzahl annehmen?
Arnauld
@ Arnauld: Sicher!
22.
9
Eine Golfidee: Wenn ndie maximale Potenz von 2 die Eingabe teilt, lautet die Antwort einfach(input) + ceil((2^n - 2)/3)
JungHwan Min 22.12.17

Antworten:

12

Python 3 , 20 Bytes

lambda n:(n&-n)//3+n

Probieren Sie es online!

Erläuterung

Nehmen Sie 192als Beispiel. Seine binäre Form ist 11000000, und wir müssen es konvertieren 11010101.

Wir stellen fest, dass wir 10101die Zahl ergänzen müssen . Dies ist eine geometrische Reihe ( 4^0 + 4^1 + 4^2), die eine geschlossene Form als hat (4^3-1)/(4-1). Dies ist das Gleiche wie 4^3//3bei der //Ganzzahldivision.

Wenn es 101010so wäre, dann wäre es immer noch eine geometrische Reihe ( 2×4^0 + 2×4^1 + 2×4^2), 2×4^3//3aus den oben genannten Gründen.

Wie auch immer, 4^3und 2×4^3wäre nur das am wenigsten signifikante Bit, das wir erhalten durch n&-n:

Wir bemerken, dass das Komplement von nist 00111111. Wenn wir eins hinzufügen, wird es 01000000und überschneidet sich nur mit n=11000000der niedrigstwertigen Ziffer. Beachten Sie, dass "ergänzen und eins hinzufügen" nur Negation ist.

Undichte Nonne
quelle
6
@ Mr.Xcoder schöne Sportlichkeit
Undichte Nonne
1
Funktioniert das evtl. lambda n:(n&-n)//3+nauch? Besteht alle Beispiel-Testfälle , sollte aber meiner Intuition nach nicht gültig sein, oder?
Mr. Xcoder
@ Mr.Xcoder es ist ja gültig.
Undichte Nonne
1
Warum nicht mit Python 2 ein Byte speichern? TIO
FlipTack
4
@FlipTack Ich hasse Python 2
Leaky Nun
8

Gelee , 5 Bytes

&N:3+

Probieren Sie es online!

Diesmal eine Portierung von Leaky Nuns Herangehensweise (zumindest habe ich ihm geholfen, ein bisschen Golf zu spielen: P)

Gelee , 7 Bytes

^N+4:6ạ

Probieren Sie es online!

Nutzt den fantastischen Ansatz von JungHwan Min mit indirekter Hilfe von Martin Ender .

Mr. Xcoder
quelle
Dennis hat eine sehr ähnliche 5-Byte-Lösung gepostet und dann gelöscht, kurz nachdem Sie diese Änderung vorgenommen haben. So etwas wie &N:3|. Herzliche Glückwünsche; Du hast Dennis in Jelly geschlagen! (Aber nicht ganz out-golfed.)
wizzwizz4
@ wizzwizz4 Ich habe wirklich nicht viel getan, außer ein kleines Golfspiel für Leakys Herangehensweise vorzuschlagen und es dann zu portieren. Aber eh :-)
Mr. Xcoder
Dies ist die erste Nur-ASCII-Gelee-Antwort, die ich je gesehen habe.
MD XF
6

Wolfram Language (Mathematica) , 36 28 26 24 Bytes

-8 Bytes dank @MartinEnder und -2 Bytes dank @ Mr.Xcoder

#+⌊(#~BitAnd~-#)/3⌋&

Probieren Sie es online!

Wir müssen nur die Anzahl der nachgestellten Nullen in der Eingabe finden und die Zahl mit abwechselnden 0s und 1s mit einer Länge von eins weniger finden und zur Eingabe hinzufügen.

So, 400 -> 11001000 -> 110010000 + 0000 -> 110010101 + 101 -> 405

Die explizite Formel für die nZahl mit abwechselndem 1s und 0s wurde in A000975 auf OEIS angegeben. Wir können die nth-Zahl verwenden, da keine zwei verschiedenen Zahlen die gleiche Länge in binären Zahlen haben und alternierende Ziffern haben können.

JungHwan min
quelle
1
2^#~IntegerExponent~2ist(BitXor[#,#-1]+1)/2
Martin Ender
@ MartinEnder wow! Und dann kann ich einfach die Brüche kombinieren, um mehr Bytes zu reduzieren
JungHwan Min
1
24 Bytes . Sie können #+⌊(#~BitAnd~-#)/3⌋&stattdessen verwenden.
Mr. Xcoder
@ Mr.Xcoder bearbeitet :)
JungHwan Min
5

J , 19-18 Bytes

+(2|-.i.@#.-.)&.#:

Probieren Sie es online!

Schnelle Erklärung

Dies ist eine alte Antwort, aber sie ist der aktuellen sehr ähnlich. Sie zählt die nachgestellten Nullen nur unterschiedlich. In den Kommentaren finden Sie einen Link, der erklärt, wie es funktioniert.

+(2|i.@i.&1@|.)&.#:
                 #:  Convert to binary list
       i.&1@|.       Index of last 1 from right
            |.         Reverse
       i.&1            Index of first 1
    i.               Range [0, index of last 1 from right)
  2|                 That range mod 2
               &.    Convert back to decimal number
+                    Add to the input

Andere Antwort:

Vorherige Antwort (19 Bytes).

+(2|i.@i.&1@|.)&.#:

Länger als es sein sollte, weil von \rechts nach links geht.

+(2|#*-.#.-.)\&.(|.@#:)
cole
quelle
1
18 Bytes+(2|-.i.@#.-.)&.#:
Meilen
@miles etwas dagegen zu erklären, was dort mit der Basiskonvertierung los ist? Ich vermute, es hat etwas mit den Nullen zu tun, aber ich bin mir nicht sicher.
Cole
#.~ zählt die Anzahl der nachgestellten Wahrheiten , also müssen wir #.~ -. #:die Anzahl der nachgestellten Nullen zählen
Meilen
@ Meilen Ah! Das ist sehr, sehr schlau.
Cole
4

Julia 0,6 , 12 Bytes

!n=n|n&-n÷3

Probieren Sie es online!

Dennis
quelle
Dies sieht nach einer effizienten Methode aus. Können Sie die Priorität des Operators erklären? Zum Beispiel kann ich nicht sagen, ob es als ausgewertet wird ((!n=(n|n))&-n)/3, oder !n=(((n|n)&(-n))/3), etc.
MD XF
In Julia, hat Bitoperatoren die gleichen Präzedenzfälle wie ihre arithmetischen Pendants, so |ist , wie +und &ist wie *. Daher n|n&-n÷3wird analysiert als n | ((n&-n) ÷3).
Dennis
3

JavaScript (ES6), 40 bis 39 Byte

Übernimmt die Eingabe als 32-Bit-Ganzzahl.

n=>n|((n&=-n)&(m=0xAAAAAAAA)?m:m/2)&--n

Testfälle

Arnauld
quelle
2

05AB1E , 13 8 5 Bytes

5 Bytes dank Mr. Xcoder und JungHwan Min's netter Formel
gespart Weitere 3 dank Mr. Xcoder gespart

(&3÷+

Probieren Sie es online!

Erläuterung

(      # negate input
 &     # AND with input
  3÷   # integer divide by 3
    +  # add to input
Emigna
quelle
1
Vielleicht ist es erwähnenswert, dass die Portierung der Mathematica-Antwort 8 Bytes
Mr. Xcoder,
@ Mr.Xcoder: Oh, das ist eine nette Formel.
Emigna
1
Hat 05ab1e bitweises UND? Wenn ja, (<bitwise and here>3÷+sollte für ~ 5 Bytes arbeiten.
Mr. Xcoder
2

R , 71 58 Bytes

danke an nofp für -6 bytes

function(n){n=n%/%(x=2^(0:31))%%2
n[!cumsum(n)]=1:0
n%*%x}

Probieren Sie es online!

Angenommen, die Eingabe ist eine 32-Bit-Ganzzahl. R hat doubleohnehin nur 32-Bit-Ganzzahlen mit Vorzeichen (Umwandlung in, wenn eine Ganzzahl überläuft) und keine 64-Bit- oder vorzeichenlosen Ints.

Giuseppe
quelle
Sie können die konvertieren , which.max(n):1-1um !cumsum(n)eine bekommen 65 Bytes Lösung
NofP
@NofP danke! Das ist eine großartige Idee.
Giuseppe
2

Brainfuck , 120 Bytes

>+<[[>-]++>[[>]>]<[>+>]<[<]>-]>[-<+>[-<[<]<]>]>[>]<[>+<[->+<]<[->+<]<]>>[<]+>[-[-<[->+<<+>]>[-<+>]]<[->++<]<[->+<]>>>]<<

Probieren Sie es online!

Beginnt mit dem Wert in der aktuellen Zelle und endet mit der Zelle mit dem Ausgabewert. Funktioniert natürlich nicht bei Zahlen über 255, da dies die Zellenbegrenzung für typisches Brainfuck ist, funktioniert aber, wenn Sie eine unendliche Zellengröße annehmen.

Scherzen
quelle
1

PowerShell , 168 Byte

param($n)$a=($c=[convert])::ToString($n,2);if(($x=[regex]::Match($a,'0+$').index)-gt0){$c::ToInt32(-join($a[0..($x-1)]+($a[$x..$a.length]|%{(0,1)[$i++%2]})),2)}else{$n}

Probieren Sie es online!

Autsch. Die Konvertierung von / nach Binär- und Array-Slicing ist nicht die Stärke von PowerShell.

Nimmt die Eingabe $nals Zahl an. Wir sofort convertdie binäre Basis 2und speichern das in $a. Als nächstes haben wir ein if / else Konstrukt. Die if-Klausel prüft, ob a regex Matchgegen 1 oder mehr 0s am Ende der Zeichenfolge ( '0+$') indexan einer Stelle steht, die größer ist als 0(dh der Anfang der Binärzeichenfolge). Wenn dies der Fall ist, müssen wir mit etwas arbeiten, elsewir geben nur die Nummer aus.

Innerhalb von ifschneiden wir die xersten Ziffern und verknüpfen +sie mit den restlichen Ziffern. Für die verbleibenden Ziffern durchlaufen wir sie jedoch und wählen entweder a 0oder 1, um stattdessen ausgegeben $i++%2zu werden. Dies bringt uns das 010101...Muster anstelle von 0s am Ende. Wir fassen das dann -joinwieder zu einem String zusammen und $cwandeln es wieder in einen Int32from base um 2.

In beiden Fällen bleibt die Nummer in der Pipeline und die Ausgabe ist implizit.

AdmBorkBork
quelle
1

APL + WIN, 43 Bytes

p←+/^\⌽~n←((⌊1+2⍟n)⍴2)⊤n←⎕⋄2⊥((-p)↓n),p⍴0 1

Fordert zur Eingabe des Bildschirms auf

Graham
quelle
1

Python 3 , 56 Bytes

lambda n:eval((bin(n).rstrip("0")+"01"*n)[:len(bin(n))])

Probieren Sie es online!

Ich bin noch nicht sehr zufrieden damit, aber ich wollte die Formel wirklich nicht verwenden ... -2 danke an Rod . -1 Danke an Jonathan Frech .

Mr. Xcoder
quelle
eval(...)statt int(...,2)könnte ein Byte speichern.
Jonathan Frech
1

Rubin , 15 Bytes

Ein weiterer Hafen von Leaky Nuns Annäherung.

->k{(k&-k)/3+k}

Probieren Sie es online!

Tom Lazar
quelle
1

AWK , 24 Bytes

Ein Hafen der Mathmatica-Antwort von JungHwan Min

$0=int(and($0,-$0)/3+$0)

Probieren Sie es online!

Noskcaj
quelle
1

JavaScript ES6, 13 Byte

n=>(n&-n)/3|n

f = 
n=>(n&-n)/3|n
;
console.log (f(8));
console.log (f(243));
console.log (f(1048576));
console.log (f(33554432));

l4m2
quelle
1

C 56 Bytes

i,k;f(n){for(k=i=1;n>>i<<i==n;k+=++i&1)k*=2;return n|k;}

Probieren Sie es online!

C (gcc), 50 Bytes

i,k;f(n){for(k=i=1;n>>i<<i==n;k+=++i&1)k*=2;k|=n;}

Probieren Sie es online!

 51  48 Bytes mit Arnauld's Lösung :

Vielen Dank an @ l4m2 für das Speichern von drei Bytes!

m;f(n){return n|((n&-n)&(m=-1u/3*2)?m:m/2)&n-1;}

Probieren Sie es online!

43 mit gcc:

m;f(n){m=n|((n&-n)&(m=-1u/3*2)?m:m/2)&n-1;}

Probieren Sie es online!

Steadybox
quelle
0xAAAAAAAA=>-1u/3*2
l4m2
0

Gelee , 13 Bytes

BŒgṪµ2Ḷṁ×CḄ+³

Probieren Sie es online!

Erläuterung

Nehmen Sie als Beispieleingabe 24.

BŒgṪµ2Ḷṁ×CḄ+³
B                Binary representation of the input → 11000
 Œg              Group runs of equal length → [[1,1],[0,0,0]]
   Ṫ             Tail → [0,0,0]
    µ            New monadic link
     2Ḷ          [0,1] constant
       ṁ         Mold [0,1] to the shape of [0,0,0] → [0,1,0]
        ×        Multiply [0,1,0] by...
         C       1-[0,0,0]. If last bit(s) of the original input are 1 this will add nothing to the original input
          Ḅ      Convert to decimal from binary → 2
           +³    Add this with the original input → 26
dylnan
quelle