Dyalog APL ( 75 73 69 68 Zeichen)
Hier ist ein weiterer und fünfter Versuch (höchstwahrscheinlich mein letzter); Ich habe den Tag damit verbracht, einen Code zu schreiben, der kürzer als 80 Zeichen ist und den Regeln entspricht. Diese Herausforderung machte meinen Tag!
Endlich habe ich eine APL-Zeile mit 75 Zeichen erhalten, die mit Dyalog APL funktioniert (aber nicht auf der Online-Interpreterseite, da die ⍎
Ausführungsfunktion verwendet wird). Dies ist die folgende:
(N,D)÷D∨N←(⍎'0',1↓I/⍨2=+\P)+(⍎'0',I/⍨2>+\P)×D←D+0=D←⍎'0',⌽2↓⍕¯1+10⊥P←'.'=I← '1.2.3'
Natürlich könnte ich es etwas kürzer machen, aber die Sonderfälle, in denen ein, zwei oder drei Felder fehlen. Mein Code kann sogar den ..
Eingabefall verarbeiten.
Ich weiß, dass APL schwer zu lesen ist, und da die Leute gerne verstehen, wie ein Teil des Codes tatsächlich funktioniert, hier einige Erklärungen. Grundsätzlich berechne ich den letzten Nenner in der Variablen D und den letzten Zähler in der Variablen N.
APL wird von rechts nach links analysiert.
- Zunächst wird der String in der Variablen I (
I←
) gespeichert .
- Dann wird es auf einen Vektor von Booleschen Werten abgebildet, der angibt, wo sich ein Punkt befindet, und dieser Vektor wird P (
P←'.'=
) genannt. Zum Beispiel wird '1.2.3' auf 0 1 0 1 0 abgebildet.
- Dieser Vektor ist Ziffern in der Basis 10 (
10⊥
); jetzt ist '1.2.3' 1010.
- Dann wird 1 von dieser Zahl abgezogen (entweder mit
1-⍨
oder mit ¯1+
, hier habe ich die zweite gewählt). Jetzt ist '1.2.3' 1009.
- Dann wird diese Zahl in einen String (
⍕
) umgewandelt, zwei Anfangsziffern werden entfernt ( 2↓
), was in unserem anfänglichen '1.2.3'-Beispiel 09 ergibt; Die Zeichenfolge ist umgekehrt ( ⌽
).
- In diesem Fall füge ich als Sonderfall vor der Zeichenfolge eine anfängliche 0 hinzu. Es macht mich traurig, die vier Zeichen zu verwenden,
'0',
aber ich habe es getan, um einen Fehler zu vermeiden, wenn das zweite und dritte Feld beide leer sind. Die Zeichenfolge wird zurück in eine Zahl ( ⍎
) konvertiert und in D gespeichert, was der Nenner ist, außer wenn beide letzten Felder leer sind, da in diesem Fall D gleich 0 ist.
- Das Teil
D←D+0=
des Codes hat D auf 1 gesetzt, wenn es aktuell null ist, und jetzt enthält D den Nenner (jedoch vor der GCD-Division).
- Dieser Nenner wird multipliziert (
×
) mit dem Inhalt der Anfangszeichenfolge I bis zu dem zweiten Punkt, mit (⍎'0',I/⍨2>+\P)
dem wieder bei P begonnen wird (0 1 0 1 0 in meinem Beispiel), addiert die aufeinanderfolgenden Zahlen, indem sie kumuliert werden (was 0 1 1 2 ergibt 2 in meinem Beispiel), überprüfen Sie, welche Werte kleiner als 2 sind (was den Booleschen Vektor zu 1 1 1 0 0 macht), und nehmen Sie die entsprechenden Zeichen in I; Eine weitere 0 wird vor der Zeichenfolge hinzugefügt, um eine weitere Überfüllung zu verhindern (wenn die beiden Anfangsfelder leer sind), und das Ganze wird in eine Zahl umgewandelt.
- Der letzte Teil der Eingabezeichenfolge wird zum vorherigen Produkt hinzugefügt
(⍎'0',1↓I/⍨2=+\P)
, wobei P erneut verwendet wird, indem erneut kumuliert wird, überprüft wird, welche Werte gleich 2 sind (siehe vorherige Erläuterung), die Zeichen verwendet werden und der erste Punkt entfernt wird , fügt ein vorbeugendes Anfangszeichen 0 hinzu und wandelt es in eine Zahl um.
- Dieses Produkt, gefolgt von einer Summe, wird in N gespeichert, welches der Zähler ist.
- Schließlich wird die GCD mit D∨N berechnet und beide Zahlen werden durch diese GCD geteilt.
edit: Hier ist ein Fix für 73 Zeichen:
(N,D)÷D∨N←(⍎'0',1↓P/I)+(⍎'0',I/⍨~P←2=+\P)×D←D+0=D←⍎'0',⌽2↓⍕¯1+10⊥P←'.'=I←
Die Idee dieses Hacks ist, zunächst den Fall zu berechnen, in dem die kumulative Addition Werte gleich 2 hat, diese für später zu speichern und diese bitweise Maske zu invertieren, um den ersten Fall zu erhalten. Die Berechnung des nächsten Falls erfordert daher weniger Zeichen.
Bearbeiten: Hier ist eine weitere Korrektur für 69 Zeichen:
(N,D)÷D∨N←(⍎'0',1↓P/I)+(⍎'0',I/⍨~P←2=+\P)×D←⍎'1⌈0',⌽2↓⍕¯1+10⊥P←'.'=I←
Die Idee dieses Hacks ist es, den kompliziertesten Sonderfall als APL-Code in die zu bewertende Zeichenfolge einzubetten (bei der Konvertierung von Zeichenfolge zu Zahl).
Bearbeiten: Hier ist eine weitere Korrektur für 68 Zeichen:
(N,D)÷D∨N←(⍎'0',1↓P/I)+(⍎'0',I/⍨~P←2=+\P)×D←⍎'1⌈0',⌽3↓⍕1-10⊥P←'.'=I←
Die Idee dieses Hacks ist es, das Hinzufügen von -1 zu dem Wert zum Subtrahieren von 1 zu diesem Wert durch die Operation zum Subtrahieren dieses Werts zu 1 zu ersetzen und später ein Zeichen mehr am Anfang zu entfernen (dies ist das Minuszeichen).
bearbeiten: Kosmetische Veränderung:
(N,D)÷D∨N←(⍎'0',1↓P/I)+(⍎'0',I/⍨~P←2=+\P)×D←1⌈⍎'0',⌽3↓⍕1-10⊥P←'.'=I←
Keine Größenverbesserung, aber zufriedener damit, die maximale Funktion aus dem zu bewertenden Code herauszuholen.
9/99
?