Unäre Zahlen stellen normalerweise nur nichtnegative Ganzzahlen dar. Sie können jedoch wie folgt erweitert werden, um alle Ganzzahlen darzustellen:
- Eine positive ganze Zahl N wird als N dargestellt
1
:5 -> 11111
- Eine negative ganze Zahl -N wird als
0
gefolgt von N dargestellt1
:-5 -> 011111
- Null wird dargestellt als
0
Wir können dann eine Liste dieser Zahlen eindeutig darstellen, wenn wir 0
als Trennzeichen verwenden:
3,-2,0,1
111,011,0,1
111 0 011 0 0 0 1
11100110001
Ihre Aufgabe: Nehmen Sie eine Zeichenfolge, die eine solche Liste mit vorzeichenbehafteten unären Zahlen darstellt, und übersetzen Sie sie in eine Liste mit Dezimalzahlen.
Einzelheiten
Sie können davon ausgehen, dass die Eingabe eine vollständige Liste von vorzeichenbehafteten unären Zahlen ist. Insbesondere muss Ihr Programm nicht 1) leere Eingaben oder 2) Eingaben verarbeiten, die mit einem Trennzeichen enden.
Sie können davon ausgehen, dass die Größe jeder Zahl 127 nicht überschreitet. Bei Sprachen mit maximaler Größe von Zeichenfolgen oder Listen können Sie davon ausgehen, dass die Eingabe und Ausgabe in die Datenstrukturen Ihrer Sprache passen, aber Ihr Algorithmus sollte theoretisch für eine Liste von funktionieren alle Größen.
Ihr Programm oder Ihre Funktion kann E / A auf eine der Standardweisen ausführen . Die Eingabe kann eine Zeichenfolge oder eine Liste von Zeichen, Einzelzeichenfolgen, Ganzzahlen oder Booleschen Werten sein. Sie können zwei beliebige Zeichen verwenden, um 1
und zu repräsentieren 0
. wenn Sie nicht verwenden , 1
und 0
geben Sie bitte an, welche Zeichen Sie verwenden.
Die Ausgabe muss aus Dezimalzahlen in einem angemessenen Listenformat bestehen (insbesondere muss eine Art Trennzeichen zwischen den Zahlen bestehen). Negative Zahlen sollten mit einem Minuszeichen angezeigt werden. Wenn Ihre Sprache jedoch ein anderes Format für negative ganze Zahlen hat, akzeptiere ich das auch. Null kann in der Ausgabe als 0
oder dargestellt werden -0
.
Testfälle
1 -> 1
0 -> 0 (or -0, and similarly for the other test cases)
011 -> -2
1101 -> 2,1
1100 -> 2,0
11001 -> 2,-1
110001 -> 2,0,1
11100110001 -> 3,-2,0,1
00000001 -> 0,0,0,-1
01111011111111001111111111111110111111111111111100111111111111111111111110111111111111111111111111111111111111111111 -> -4,8,-15,16,-23,42
01111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 -> -127
'0's
, ist es technisch nicht einheitlich. Gute Herausforderung!0
) und das negative Vorzeichen (0
) dasselbe sind, obwohl es immer noch eindeutig ist, da Sie keine negativen Vorzeichen in der Mitte einer Zahl haben können (ist182--693-1
eine Zahl? Nein, und auch nicht1111011000101111
aus genau demselben Grund).Antworten:
Python 2 ,
73-70BytesEine Funktion, die eine Zeichenfolge als Eingabe verwendet und eine Zeichenfolgendarstellung einer Python-Liste zurückgibt. Null kann sowohl durch
0
als auch-0
(wenn es zuletzt kommt) dargestellt werden:Erläuterung
split
die Eingabezeichenfolges
auf Nullen.map
).Das ist ein langer Weg. Schließlich waren Nullen Trennzeichen. Und die Zahlen waren unärgerlich, also
len
wandeln Sie diese bequem in Dezimalzahlen um. Aber jetzt haben wir alle Nicht-Trennzeichen-Verwendungen von durcheinander gebracht0
. Glücklicherweise waren alle Verwendungen ohne Trennzeichen führende Nullen, sodass sie nach einer Trennzeichen-Null kamen und uns Zeichenfolgen mit der Länge Null gaben ('00'.split('0') == ['', '', '']
). Diese Zero-Length-Strings wurden dann auch0
wegen derlen
.replace
Jede Null, die einer anderen Zahl vorausgeht, erhält stattdessen ein negatives Vorzeichen. Das behebt die Verwendung von0
als Zeichen, bricht aber die wörtlichen Nullen. Literalen Nullen wurde ebenfalls ein Trennzeichen vorangestellt, sodass sie jetzt bei der nächsten Zahl zu Strichpaaren werden.replace
jeweils--
wieder in ein0
Element in der "Liste".quelle
Netzhaut ,
2321 BytesProbieren Sie es online!
Die erste Stufe
(.)0<newline>$1<space>
entspricht einem beliebigen Zeichen, gefolgt von einem0
. Die Übereinstimmung wird durch das erste Zeichen gefolgt von einem Leerzeichen ersetzt. Dadurch wird die Zeichenfolge in die einzelnen Zahlen aufgeteilt.Die zweite Stufe
01<newline>-1
ersetzt0
's vor einem Block von1
' s bis zum-
Zeichen.In der letzten Phase werden
1+<newline>$.&
alle Blöcke von1
's abgeglichen und durch die Länge der Gruppe ersetzt.Hier ein Beispiel mit der Ausgabe der einzelnen Stufen.
quelle
Vim, 56 Bytes
Probieren Sie es online!
Ich habe eine Weile nicht mehr in vim gepostet. Ich benutze meistens Vim, weil V manchmal ein Schmerz ist. Da der
count
Befehl, mit dem die Anzahl der Einsen in der Zeile ermittelt werden kann, alle Nullen in der Zeile überschreibt, können wir ihn anschließend nicht mehr negieren.Erläuterung:
Dies ist ein Byte kürzer als auf einfache Weise:
aufgrund der Befehlsverkettung. Da dieser die Befehle trennt, verwende ich ihn zur Erklärung.
Jetzt steht jede vorzeichenbehaftete unäre Nummer in einer eigenen Zeile. Am Beispiel von '11100110001' haben wir an dieser Stelle:
Da wir am Ende jedes Matches neue Zeilen hinzugefügt haben, hatten wir eine leere Zeile, bevor wir diese ausgeführt haben. Nachdem Sie dies ausgeführt haben, erhalten Sie eine '0' (da diese einer Anzahl von 0 '1 entspricht). Also rufen wir einfach
D
an, um diese Zeile zu löschen und lassen sie leerquelle
:%s/1+$/
+
-
anstelle von0
oder geben-0
Haskell ,
6866 BytesProbieren Sie es online! Nimmt die Eingabe als Liste von Nullen und Einsen. Anwendungsbeispiel:
f [0,0,0,1,1]
Erträge[0,-2]
.Erläuterung:
Die Musterübereinstimmung in wird
f(x:r)|(a,b)<-span(>0)r
anx
das erste Element der Eingabe,a
an eine (möglicherweise leere) Liste der folgenden1
s undb
an den Rest der Eingabe gebunden. Bei einem gegebenen Eingang[0,1,1,1,0,0,1]
, bekommen wirx=0
,a=[1,1,1]
undb=[0,0,1]
.Die aktuelle Zahl ist dann entweder die Summe aus
a
negiertem ifx=0
oder die Summe ausa
plus eins ifx=1
. Dies wird erreicht, indem mitx
in eine Liste indexiert wird, die eine Negations- und Inkrementierungsfunktion enthält, und die resultierende Funktion auf die Summe vona
: angewendet wird[(0-),(1+)]!!x$sum a
.Die Restliste
b
ist entweder leer oder enthält eine trennende Null und die nächste Zahl. Das Listenverständnis[z|_:t<-[b],z<-f t]
versucht,b
auf das Muster abzustimmen_:t
, dh das head-Element zu vergessen und den Rest der Liste daran zu bindent
. Wennb
leer, schlägt diese Übereinstimmung fehl und das Listenverständnis wird zu ausgewertet. Dies[]
ist der Basisfall für die Rekursion. Ansonsten wird die Funktionf
rekursiv angewendett
und das Listenverständnis wertetz
aus dem Ergebnis von auf alle Elemente ausf t
.quelle
Wolfram Language (Mathematica) , 80 Byte
Probieren Sie es online!
Missbraucht die Mechanik von
StringCases
, da sie überlappende Muster nicht prüft. Da wir ohne Überlappungen von links nach rechts suchen, erhalten wir immer nur die Ganzzahlen, die wir benötigen.Erläuterung
Fügen Sie am Ende eine Null hinzu
Finde alle folgenden Muster ...
Ein einzelnes Zeichen (call it
x
), gefolgt von der kürzestmöglichen Zeichenfolge mit der Länge Null oder einer längeren Zeichenfolge (call ity
), gefolgt von einer Null.Auf passendes Muster auftragen: Länge von
y
. Wennx
Null ist, negieren Sie den Wert. Sonst inkrementiere eins.Dies gilt
00
auch, day
dies eine leere Zeichenfolge wäre und wir berechnen würden-0
(== 0
).quelle
Brain-Flak , 94 (70?) Bytes
Probieren Sie es online!
Dies ist eigentlich überraschend knapp für Brain Flak.
Hier ist eine kommentierte / lesbare Version:
Wenn die Ausgabe umgekehrt sein kann, können wir dies stattdessen für 70 tun:
Dieser Tipp von mir ist fast perfekt für diese Situation. Aber es funktioniert nicht ganz, da wir eine 0 drücken müssen, bevor wir die Operation ausführen (die Einsen zählen) und die Operation in einer Schleife abläuft. Der kürzeste Weg, diesen Tipp zu verwenden, ist:
Das sind auch 94 Bytes.
quelle
Perl 5 , 40 + 1 (
-n
) = 41 BytesProbieren Sie es online!
quelle
Schale ,
20 18 17 1514 BytesProbieren Sie es online!
Erläuterung
Die Aufteilung funktioniert so.
ġ/
teilt sein Argument auf jedes Elementpaar auf,a,b
für das/a b
es falsch ist./a b
ist eine Division mit gespiegelten Argumenten, alsob
geteilt durcha
. Die relevanten Werte in diesem Programm sind:/1 1
gibt1
(wahr)./1 0
gibt0
(falsch)./0 1
gibtInf
(positive Unendlichkeit, wahr)./0 0
gibtAny
(ein spezieller NaN-ähnlicher Wert, falsch).quelle
Acc !! ,
252237 BytesVerwendet
-0
. Gibt durch Tabulatorzeichen getrennte Zahlen mit einem nachgestellten Tabulator aus. Probieren Sie es online!Zeitaufwand für das Schreiben des eigentlichen Algorithmus: 20 Minuten. Zeitdauer für das Debuggen meines dezimalen Ausgabecodes: 45 Minuten. : ^ P
Mit Kommentaren
Ich weiß nicht, ob diese Kommentare den Code sehr gut erklären - sie basieren auf meinen Notizen, die ich mir während des Schreibens gemacht habe, und setzen daher ein gewisses Verständnis dafür voraus, wie Acc !! funktioniert. Wenn etwas näher erläutert werden muss, lassen Sie es mich wissen und ich werde versuchen, es klarer zu machen.
quelle
Python 2 ,
9692 BytesProbieren Sie es online!
Danke an ovs und DLosc für jeweils 2 Bytes.
quelle
R , 119 Bytes
Probieren Sie es online!
Der Code verwendet diese Lösung von stackoverflow für ein verwandtes Problem (Danke an eifersüchtige für die Idee). Die Ausgabe ist eine durch Leerzeichen getrennte Zeichenfolge, die auf stdout gedruckt wird.
quelle
Jelly ,
1918 BytesEs muss einen besseren Weg geben ...
Ein vollständiges Programm druckt jede Nummer, gefolgt von einem Zeilenvorschub.
Probieren Sie es online!
Wie?
quelle
QBasic,
8886 BytesDas hat Spaß gemacht. Mehrere Revisionen ab einer 107-Byte-Version führten zu einem der am meisten verschleierten Teile von QBasic, die ich je geschrieben habe. (Edit: Seltsamerweise konnte ich 2 Bytes Golf spielen, indem ich den Code klarer machte.)
Hinweis: Dieses Programm liest die Benutzereingaben einzeln, ohne sie auf dem Bildschirm wiederzugeben (Ergebnis der Verwendung
INPUT$(1)
anstelle der üblichenINPUT
Anweisung). Während Sie tippen, werden die Einsen und Nullen nicht angezeigt, aber die Dezimalzahlen werden angezeigt, während sie berechnet werden. Stellen Sie sicher, dass Sie Enteram Ende der Eingabe drücken, um die letzte Zahl zu sehen und das Programm zu beenden.Ungolfed-Version
Erläuterung
(AKA "Was? Das macht doch keinen Sinn!")
Die Grundstrategie besteht darin, eine Schleife auszuführen, die
INPUT$(1)
jedes Mal ein Zeichen!
abruft, Dinge damit erledigt und so lange eine Schleife durchläuft, wie das Zeichen einen größeren ASCII-Wert hat als der von (dh, es war kein Zeilenumbruch).Wir verfolgen die laufenden Zahlen mit zwei Variablen.
num
ist die Anzahl der Zeichen in der aktuellen vorzeichenbehafteten unären Zahl (einschließlich einer führenden Null).sign
ist,1
wenn die Zahl eine führende Null hatte,0
wenn nicht. Beide müssen auf initialisiert werden0
, was für die Golf-Version sehr gut ist, da numerische Variablen in QBasic automatisch auf initialisiert werden0
.Wann immer wir ein Zeichen lesen, ist das erste, zu bestimmen, ob es
1
oder ist0
. Wir verwenden dieses Ergebnis zweimal und speichern es inisZero
. Technisch gesehen ist dieser Name irreführend, da der Wert auch dann wahr ist, wenn das Zeichen ein Zeilenumbruch ist. Beachten Sie, dass in QBasic-1
wahr und falsch ist0
.Wenn wir gerade eine Zahl (
num > 0
) lesen und eine Null oder ein Ende der Eingabe (isZero
) erreichen, müssen wir berechnen, welche Zahl wir gelesen haben.sign
speichert0
für positiv,1
für negativ. Um1
zum Positiven und-1
zum Negativen zu gelangen, brauchen wir1-2*sign
.num
speichert die richtige Größe für Positive, aber eine mehr als die Größe für Negative (da sie die Vorzeichenmarkierung enthält). So können wirnum-sign
für die Größe verwenden.Multiplizieren Sie diese und drucken Sie; dann zurücksetzen
sign
undnum
auf0
in Vorbereitung auf das Lesen der nächsten Nummer.Andernfalls (wenn wir keine Null erreicht haben oder wenn wir am Anfang einer Zahl eine Null erreicht haben) aktualisieren wir
sign
undnum
wie folgt:sign
wird,1
wenn wir auf eine führende Null schauen; ansonsten bleibt es, wenn wir uns eine anschauen, bei dem, was es schon war. Der Golf-Code lautets=s-z
:z
ist-1
. Das
wird garantiert0
(da dies der Beginn einer neuen Nummer ist),s-z
sein1
.z
ist0
. Danns-z
bleibt um jeden Werts
hatte zuvor.num
wird inkrementiert.Das ist es!
quelle
JavaScript (ES6), 60 Byte
Gibt eine durch Leerzeichen getrennte Liste von Ganzzahlen zurück.
Testfälle
Code-Snippet anzeigen
quelle
Lua , 58 Bytes
Probieren Sie es online!
Vollständiges Programm, nimmt Eingaben von der Kommandozeile entgegen und druckt die Zahlen durch Zeilenumbrüche getrennt auf stdout.
quelle