Die binäre binäre Erweiterung

9

Normalerweise zerlegen wir eine Zahl in Binärziffern, indem wir sie mit Zweierpotenzen mit einem Koeffizienten von 0oder 1für jeden Term zuweisen :

25 = 1*16 + 1*8 + 0*4 + 0*2 + 1*1

Die Wahl von 0und 1ist ... nicht sehr binär. Wir werden die wahre binäre Expansion durchführen, indem wir mit Potenzen von 2 expandieren, aber mit einem Koeffizienten von 1oder -1stattdessen:

25 = 1*16 + 1*8 + 1*4 - 1*2 - 1*1

Das sieht jetzt binär aus.

Bei jeder positiven Zahl sollte es trivial sein, Folgendes zu sehen:

  • Jede ungerade Zahl hat unendlich viele echte binäre Erweiterungen
  • Jede gerade Zahl hat keine echten binären Erweiterungen

Damit eine echte binäre Erweiterung genau definiert werden kann, muss die Erweiterung am geringsten sein , dh mit der kürzesten Länge.


Geben Sie bei jeder positiven, ungeraden Ganzzahl nihre wahre binäre Erweiterung von der höchstwertigen Ziffer zur niedrigstwertigen Ziffer (oder in umgekehrter Reihenfolge) zurück.

Regeln:

  • Da dies , sollten Sie versuchen, dies in kürzester Zeit zu tun . Builtins sind erlaubt.
  • Jede Ausgabe, die die Koeffizienten darstellen und auflisten kann, ist akzeptabel: ein Array, eine Folge von Koeffizienten mit Trennzeichen usw.
  • Es gelten Standard-Golfschlupflöcher.
  • Ihr Programm sollte für Werte innerhalb der Standardgröße Ihrer Sprache arbeiten.

Testfälle

25 -> [1,1,1,-1,-1]
47 -> [1,1,-1,1,1,1]
1 -> [1]
3 -> [1,1]
1234567 -> [1,1,-1,-1,1,-1,1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,1]
Voile
quelle
Verwandt aber ganz anders.
Giuseppe
4
Einfacher Algorithmus: In Basis 2 konvertieren, Nullen durch -1 ersetzen, LSD nach vorne setzen.
Josiah Winslow
Voile: Ich habe die Abstimmungen nicht erklärt, sondern nur einen Algorithmus für Leute skizziert, die Basiskonvertierungsbefehle in ihrer Sprache haben.
Josiah Winslow
Können wir den Wert als gepackte Bits mit dem üblichen Platzwert, aber der neuen Interpretation der beiden Zustände zurückgeben, da Sie wirklich daran interessiert sind, wirklich binär zu sein? dh elektrisch ist es nur Hoch- oder Niederspannung (oder was auch immer), und es ist nicht meine Schuld, wenn Standard-Debugger 0anstelle des -1Niederspannungszustands drucken . Der Anrufer, der die Bits empfängt, weiß, was sie bedeuten. (Es ist immer noch eine nicht triviale Bitmanipulationsübung, da ein Rechtsdrehen nur funktioniert, wenn es 32 signifikante Bits hat. Beispielsweise benötigt eine 5-Bit-Zahl eine Drehbreite von 5.)
Peter Cordes
Muss die Ausgabe Trennzeichen enthalten? Ist111-1-1 eine gültige Ausgabe für 25?
Oliver

Antworten:

7

Japt , 6 Bytes

¤é r0J

Probieren Sie es online aus!

Erläuterung:

¤é r0J  // Test input:                  25
¤       // Binary the input:            11001
 é      // Rotate 1 chars to the right: 11100
   r0J  // Replace 0s with -1:          111-1-1
Oliver
quelle
1
Ah, die Rotation; dass ‚s , warum es nicht für mich arbeiten.
Shaggy
2
Drehen??? Dagnabbit.
Giuseppe
3

Pyth ,  12  11 Bytes

|R_1.>jQ2 1

Probieren Sie es hier aus!


Wie?

| R_1.> JQ2 1 Vollständiges Programm.

      jQ2 Konvertiert die Eingabe in eine Binärliste.
     .> 1 Drehen Sie die Liste oben zyklisch um 1 Stelle nach rechts.
| R_1 Ersetze 0 durch -1.
               Implizit ausgeben.

Zunächst stellen wir fest, dass die Aufgabe nur darin besteht, "das 0s in der binären Schrift durch -1s zu ersetzen und um 1 Stelle nach rechts zu verschieben". - Genau das sollten wir tun! Die binäre Konvertierung gibt uns eine Liste von 0s und 1s. Alles , was wir hier tun sollten , ist eine Golfy Weg zu konvertieren finden 0zu -1. Der bitweise Operator |(bitweises ODER) ist unser Freund. Die Karte über der binären Darstellung verschob sich mit |und -1. Wenn die aktuelle Nummer lautet 0, wird sie in konvertiert -1.

Mr. Xcoder
quelle
Ich glaube nicht, dass es einen besseren Weg gibt. ;)
Josiah Winslow
@ JosiahWinslow Ich tue ... Ich versuche es zu finden
Mr. Xcoder
Hm? Der Algorithmus scheint optimal zu sein, vielleicht liegt das daran, dass ich Pyth nicht kenne.
Josiah Winslow
@ JosiahWinslow Den besseren Weg gefunden. Syntaktisch besser, nicht algorithmisch besser.
Herr Xcoder
@ Mr.Xcoder Und jetzt gibt es wirklich keine, zumindest für mich.
Erik der Outgolfer
3

JavaScript (ES6), 35 34 Byte

f=n=>n?[...f(n>>=1),!n|n%2||-1]:[]

Testschnipsel

ETH-Produktionen
quelle
2

Perl 6 , 72 Bytes

Es gibt sicherlich einen besseren Weg, aber das habe ich ...

->$a {grep {$a==[+] @^a.reverse Z+< ^∞},[X] (1,-1)xx $a.base(2).chars}

Probieren Sie es online aus!

Erläuterung : Diese Funktion benötigt ein Argument ( ->$a). Wir erhalten zuerst die Anzahl der benötigten Koeffizienten ( $a.base(2).chars= Anzahl der Zeichen in der Darstellung der Basis 2) und dann ein kartesisches Produkt ( X) aus so vielen Paaren (1,-1). (Das [X]bedeutet: Reduzieren Sie die folgende Liste mit X.) So erhalten wir eine Liste aller möglichen Kombinationen von 1s und -1s. Dann filtern wir ( grep) nur die Listen, die die angegebene Nummer codieren $a. Es gibt nur eine, daher erhalten wir eine Liste mit einer Liste mit den Koeffizienten.

Der grep-Block tut dies: Er nimmt sein Argument als list ( @^a), kehrt es um und komprimiert es mit einer unendlichen Liste unter 0,1,2,...Verwendung des Operators "left bit shift" +<. Das Zippen stoppt, sobald die kürzere Liste aufgebraucht ist (gut für uns!). Wir summieren dann alle Ergebnisse und vergleichen sie mit der angegebenen Zahl. Wir mussten verwenden, .reverseweil das OP verlangt, dass die Koeffizienten in der Reihenfolge von höchstwertig bis niedrigstwertig sind.

Ramillies
quelle
1

J, 11 Bytes

1-~2*_1|.#:

Probieren Sie es online aus!

Vielen Dank an @JosiahWinslow für den Algorithmus.

Irgendwelche Gedanken darüber, die Konvertierung zu verkürzen? Meine Gedanken sind die Verwendung von !.-fit (nvm, es ändert nur die Toleranz der Konvertierung).

Die Verwendung von {-take ist um 1 Zeichen länger.

_1 1{~_1|.#:
cole
quelle
1

Java 8, 101 Bytes

n->{String s=n.toString(n,2);return(s.charAt(s.length()-1)+s.replaceAll(".$","")).replace("0","-1");}

Port von @Olivers Japt-Antwort mit ein paar weiteren Bytes ..;)

Kann definitiv mit einem mathematischen Ansatz anstelle dieses String-Ansatzes gespielt werden.

Erläuterung:

Probieren Sie es hier aus.

n->{                             // Method with Integer parameter and String return-type
  String s=n.toString(n,2);      //  Convert the Integer to a binary String
  return(s.charAt(s.length()-1)  //  Get the last character of the binary String
    +s.replaceAll(".$","")       //   + everything except the last character
   ).replace("0","-1");          //  Then replace all zeroes with -1, and return the result
}                                // End of method
Kevin Cruijssen
quelle
1

R , 90 88 46 Bytes

function(n)c((n%/%2^(0:log2(n))%%2)[-1],1)*2-1

Probieren Sie es online aus!

Implementiert Olivers Algorithmus , gibt jedoch die Ziffern in umgekehrter Reihenfolge zurück. Da wir garantiert haben, dass dies nniemals gerade ist, ist das niedrigstwertige Bit (das erste) immer 1, also entfernen wir es und fügen ein 1an das Ende an, um die Rotation in R zu simulieren. Vielen Dank an Shaggy , der mich dazu gebracht hat, meine Mathematik zu korrigieren .

Durch einfaches Umschreiben rev( )der Funktionsaufrufe in der Fußzeile sollten die Werte in derselben Reihenfolge zurückgegeben werden.

ursprüngliche Antwort, 88 Bytes:

function(n,b=2^(0:log2(n)))(m=t(t(expand.grid(rep(list(c(-1,1)),sum(b|1))))))[m%*%b==n,]

Anonyme Funktion; Gibt die Werte in umgekehrter Reihenfolge mit angehängten Spaltennamen zurück.

Probieren Sie es online aus!

Erläuterung:

function(n){
 b <- 2^(0:log2(n))         # powers of 2 less than n
 m <- expand.grid(rep(list(c(-1,1)),sum(b|1))) # all combinations of -1,1 at each position in b, as data frame
 m <- t(t(m))               # convert to matrix
 idx <- m%*%b==n            # rows where the matrix product is `n`
 m[idx,]                    # return those rows
}
Giuseppe
quelle
Ich würde diese Ausgabe nicht als gültig betrachten. Schlagen Sie vor, den Autor der Herausforderung um Bestätigung zu bitten.
Shaggy
@Shaggy umgekehrte Reihenfolge ist ausdrücklich erlaubt: from the most significant digit to the least significant digit (or in reversed order).daher sollte dies durchaus akzeptabel sein.
Giuseppe
1
Umgekehrte Reihenfolge , nicht umgekehrte Vorzeichen. Eine gültige Ausgabe für 25wäre beispielsweise [1,1,1,-1,-1]oder [-1,-1,1,1,1].
Shaggy
1
@ Shaggy ah, du hast recht, ich habe nur die Mathematik falsch gemacht! sollte 2*bits - 1statt sein 1-2*bits. Vielen Dank.
Giuseppe
0

CJam, 12 Bytes

Ein Port meiner Golfscript-Antwort.

qi2b{_+(}%)\
Josiah Winslow
quelle
0

Golfscript, 14 13 14 Bytes

-1 Byte, weil ich vergessen habe, %existiert. +1 Byte, weil ich auch vergessen habe, dass die Eingabe eine Zeichenfolge ist.

~2base{.+(}%)\
Josiah Winslow
quelle
1
Wenn Sie davon ausgehen, dass die Eingabe als Ganzzahl vorliegt, sollten Sie den Code einschließen {}, um ihn zu einem Block zu machen. Vollständige Programme können nur als Zeichenfolgen eingegeben werden.
Peter Taylor
Ähm ... was? Ich meinte, die Zahl wird als Ganzzahl anstatt als Zeichenfolge mit einer Zahl verschoben.
Josiah Winslow
In diesem Fall ist Ihre Antwort kein vollständiges Programm und muss daher eine "Funktion" oder im Fall von GolfScript ein Block sein. Daher ist es {2base{.+(}%\}für 15 Bytes. Ebenso Ihre CJam-Antwort.
Peter Taylor
Dies ist ein vollständiges Programm. Eingaben in Golfscript werden zu Beginn des Programms implizit auf den Stapel verschoben, und Eingaben in CJam werden vor der Ausführung angegeben und mit dem Befehl q aufgerufen.
Josiah Winslow
Ich bin mit GolfScript vertraut . ( Und CJam ). Wenn Sie behaupten möchten, dass es sich um ein vollständiges Programm handelt, müssen Sie ihm ein Präfix voranstellen ~.
Peter Taylor