Retina , 530 220 210 202 201 193 191 187 185 (184) Bytes
Dank an randomra für das Speichern von 3 Bytes! (Und ebnen den Weg für ein paar mehr.)
+`\.(\d)(.+)( .+)
$1.$2_$3_
\b
#
+`(\d*)#((((((((((9)|8)|7)|6)|5)|4)|3)|2)|1)|\w)
$1$1$1$1$1$1$1$1$1$1$3$4$5$6$7$8$9$10$11#
\d
11
(?=(1*)\1)[^.]
$1
^(1+)\.\1{90000}1+
Retina!
1.+
Trash!
Zu Zwecken der Byte-Zählung wird jede Zeile in eine separate Datei geschrieben. Sie können den obigen Code jedoch wie aus einer einzelnen Datei ausführen, indem Sie Retina mit dem -s
Flag aufrufen .
Dies erwartet zuerst die Dichte (die einen Dezimalpunkt enthalten muss , auch wenn es sich um einen nachgestellten handelt), gefolgt von Breite und Höhe, d d w h
. H.
Das ist etwas langsam. Ich würde die meisten Testfälle nicht ausprobieren, da sie ewig laufen werden. Sie können jedoch überprüfen, ob es mit den Testfällen ordnungsgemäß funktioniert
19. 4096 2160 -> Trash!
1. 180 240 -> Trash!
1. 181 240 -> Retina!
1. 180 241 -> Retina!
0.04 10 10 -> Retina!
Nach dem Multiplizieren aller Zahlen, um die Dichte zu einer Ganzzahl zu machen, soll die Breite und Höhe nicht mehr als 4 Stellen haben.
Dies ist zwar langsam, aber völlig genau ... es gibt keine Fließkomma-Probleme oder ähnliches. Alle Arithmetik verwendet (unäre) Ganzzahlen.
Im Prinzip könnte ich ein weiteres Byte ^
weglassen : das kann weggelassen werden, aber es wird Trash!
Testfälle aufgrund von übermäßig viel Backtracking schrecklich langsam machen .
Erläuterung
Zuerst ordnen wir die Ungleichung neu an, um Gleitkommaoperationen zu vermeiden:
√(w2 + h2) / d > 300
√(w2 + h2) > 300 d
w2 + h2 > 90000 d2
Wir können auch feststellen , dass diese invariant unter Multiplikation ist w
, h
und d
durch die gleiche Anzahl x
:
w2 + h2 > 90000 d2
(x w)2 + (x h)2 > 90000 (x d)2
x2 (w2 + h2) > 90000 x2 d2
w2 + h2 > 90000 d2
Es gibt verschiedene Möglichkeiten, eine unäre Zahl zu quadrieren, aber wir werden die Identität nutzen
n2 = Σi=1..2n ⌊i/2⌋
Dies gibt uns eine Möglichkeit, das Problem nur mit einer Ganzzahlarithmetik (die Ganzzahlen in Unary darstellt) zu lösen.
Lass uns den Code durchgehen. Jedes Zeilenpaar ist eine reguläre Ersetzung.
+`\.(\d)(.+)( .+)
$1.$2_$3_
Dadurch wird der Dezimalpunkt in der Dichte wiederholt nach rechts verschoben, während Breite und Höhe mit 10 multipliziert werden (siehe x
oben). Dies soll sicherstellen, dass alle Zahlen Ganzzahlen sind. Anstatt Nullen anzufügen, füge ich Nullen hinzu, _
die ich später als Null behandeln werde. (Dies ist ein Golf-Trick, da ich sonst schreiben müsste ...${3}0
, um Mehrdeutigkeiten zu vermeiden $30
.) Das +
vor der Regex weist Retina an, diese Ersetzung zu wiederholen, bis sich das Ergebnis nicht mehr ändert (was der Fall ist, wenn das Muster nicht mehr übereinstimmt). .
\b
#
Wir bereiten die drei Zahlen für die Umwandlung in Unary vor. Grundsätzlich benötigen wir einen Marker (das #
) vor jeder Zahl, aber es ist auch kürzer, einen am Ende jeder Zahl hinzuzufügen, was den Konvertierungsschritt nicht beeinflusst.
+`(\d*)#((((((((((9)|8)|7)|6)|5)|4)|3)|2)|1)|\w)
$1$1$1$1$1$1$1$1$1$1$3$4$5$6$7$8$9$10$11#
Dies ist die Umstellung auf Unary mit einem von dan1111 entwickelten Trick . Im Wesentlichen übersetze ich jede Ziffer in eine Wiederholungsziffer für sich selbst, während ich die vorhandenen Ziffern mit 10 multipliziere (dabei bewege ich den #
Marker nach rechts). Diese binäre Darstellung ist ein Durcheinander verschiedener Ziffern, aber die Gesamtzahl entspricht dem Wert der ursprünglichen Ganzzahl. Beachten Sie die \w
am Ende - normalerweise ist dies nur 0
, aber wir möchten auch _
als Null behandeln (was in regulären Ausdrücken als Wortzeichen betrachtet wird).
\d
11
Wir wandeln jede Ziffer in zwei 1
s um, um a) sicherzustellen, dass alle Ziffern gleich sind (was später erforderlich sein wird) und b) jede der Zahlen zu verdoppeln.
(?=(1*)\1)[^.]
$1
Dies führt zu zwei Dingen: Es quadriert alle Zahlen (oder vielmehr die Hälfte jeder Zahl, indem eine Summe berechnet wird 2n
) und addiert die resultierenden Quadrate der Breite und der Höhe. Beachten Sie, dass s, Markierungen und Leerzeichen [^.]
übereinstimmen . Wenn es sich um ein oder ein Leerzeichen handelt, erfasst der Lookahead nichts. Dies bedeutet, dass alle Elemente einfach entfernt werden, dh die Ergebnisse für die Breite und Höhe werden verkettet / hinzugefügt. Das Komma bleibt, um das Ergebnis von diesen zu trennen . Wenn Streichhölzer ein statt, dann sind die Look - Ahead stellt sicher , dass wir capture Hälfte der s , nachdem es (abgerundet) in der Gruppe . Dies berechnet die oben erwähnte Summe, die dann das Quadrat der ursprünglichen Zahl ergibt.1
#
#
.
d
[^.]
1
1
1
^(1+)\.\1{90000}1+
Retina!
Die Zeichenfolge ist jetzt (in unary), dann , dann (in unary). Wir wollen wissen, ob die erste unäre Zahl kürzer ist als die zweite. Wir können diese Multiplikation leicht mit einer Erfassungsgruppen- und Wiederholungssyntax durchführen. Wir verwenden (anstatt ) danach, um sicherzustellen, dass die zweite Zahl tatsächlich größer als diese und nicht gleich ist. Wenn ja, ersetzen wir das alles durch .d2
.
w2 + h2
90000
{n}
1+
1*
Retina!
1.+
Trash!
Wenn die zweite Zahl nicht groß genug war, hat der vorherige Schritt nichts geändert und die Zeichenfolge beginnt immer noch mit einem 1
. In diesem Fall ersetzen wir einfach die gesamte Zeichenfolge durch Trash!
und sind fertig.