Retina , 530 220 210 202 201 193 191 187 185 (184) bajtów
Kredyty dla randomra za zapisanie 3 bajtów! (I torując drogę jeszcze kilku.)
+`\.(\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!
Do celów liczenia bajtów każda linia przechodzi do osobnego pliku, ale można uruchomić powyższy kod z pojedynczego pliku, wywołując Retinę z -sflagą.
Oczekuje się najpierw gęstości (która musi zawierać kropkę dziesiętną, nawet jeśli jest to kropka), a następnie szerokości i wysokości, tj d w h.
To jest trochę powolne. Nie wypróbowałbym większości podanych przypadków testowych, ponieważ będzie działał przez wieki. Możesz jednak sprawdzić, czy działa poprawnie z przypadkami testowymi
19. 4096 2160 -> Trash!
1. 180 240 -> Trash!
1. 181 240 -> Retina!
1. 180 241 -> Retina!
0.04 10 10 -> Retina!
Zasadniczo po pomnożeniu wszystkich liczb, aby gęstość była liczbą całkowitą, nie chcesz, aby szerokość i wysokość składały się z więcej niż 4 cyfr.
Chociaż jest to powolne, jest całkowicie dokładne ... nie ma żadnych problemów ze zmiennoprzecinkowymi ani nic podobnego. Cała arytmetyka używa (jednych) liczb całkowitych.
Zasadniczo mógłbym ogolić jeszcze jeden bajt: ^można go pominąć, ale spowoduje to, że Trash!przypadki testowe będą strasznie wolne z powodu nadmiernej ilości cofania.
Wyjaśnienie
Po pierwsze, zmieńmy kolejność nierówności, aby uniknąć operacji zmiennoprzecinkowych:
√(w2 + h2) / d > 300
√(w2 + h2) > 300 d
w2 + h2 > 90000 d2
Możemy również zauważyć, że jest to niezmienna pod pomnożenie w, ha dprzez ten sam numer 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
Istnieje kilka sposobów, aby obliczyć jednoznaczną liczbę, ale wykorzystamy tożsamość
n2 = Σi=1..2n ⌊i/2⌋
To daje nam sposób na rozwiązanie problemu przy użyciu tylko arytmetyki liczb całkowitych (reprezentujących liczby całkowite w jedności).
Przejdźmy przez kod. Każda para linii jest podstawieniem wyrażenia regularnego.
+`\.(\d)(.+)( .+)
$1.$2_$3_
Powoduje to kilkakrotne przesunięcie punktu dziesiętnego gęstości w prawo, mnożąc szerokość i wysokość przez 10 ( xpowyżej). Ma to na celu zapewnienie, że wszystkie liczby są liczbami całkowitymi. Zamiast dopisywać zera, dołączam _, co będę później traktować jako zero. (Jest to sztuczka golfowa, ponieważ w przeciwnym razie musiałbym pisać, ...${3}0aby uniknąć dwuznaczności $30.) +Przed regex mówi Retinie, aby powtarzała tę zamianę, dopóki wynik nie przestanie się zmieniać (co ma miejsce, gdy wzór już nie pasuje) .
\b
#
Przygotowujemy teraz trzy liczby do konwersji na jednoargumentowe. Zasadniczo potrzebujemy znacznika ( #) przed każdą liczbą, ale krótsze jest również dodanie jednego na końcu każdej liczby, co nie wpłynie na krok konwersji.
+`(\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#
Jest to konwersja na unary, przy użyciu sztuczki opracowanej przez dan1111 . Zasadniczo tłumaczę każdą cyfrę na samą cyfrę rep, jednocześnie mnożąc istniejące cyfry przez 10 (przesuwając #znacznik w prawo w trakcie procesu). Ta reprezentacja binarna będzie zbiorem różnych cyfr, ale całkowita liczba będzie równa wartości oryginalnej liczby całkowitej. Zwróć uwagę \wna koniec - zwykle jest to po prostu 0, ale chcemy również traktować _jako zero (co jest uważane za znak słowny w wyrażeniu regularnym).
\d
11
Zamieniamy każdą cyfrę na dwie 1s, tym samym a) upewniając się, że wszystkie cyfry są takie same (co będzie konieczne później) ib) podwajając każdą z liczb.
(?=(1*)\1)[^.]
$1
Robi to dwie rzeczy: obciąża wszystkie liczby (a raczej połowę każdej liczby, obliczając sumę 2n) i dodaje wynikowe kwadraty szerokości i wysokości. Zauważ, że [^.]pasuje do 1s, #znaczników i spacji. Jeśli jest to a #lub spacja, lookahead nie przechwyci niczego, co oznacza, że wszystkie są po prostu usuwane, tj. Wyniki dla szerokości i wysokości są łączone / dodawane. .Pozostaje przecinek dziesiętny, aby oddzielić wynik dod tych. Jeśli [^.]pasuje 1zamiast, to lookahead zapewnia, że przechwycimy połowę 1sekundy po nim (zaokrągloną w dół) w grupie 1. To oblicza sumę, o której wspomniałem powyżej, która następnie da kwadrat pierwotnej liczby.
^(1+)\.\1{90000}1+
Retina!
Łańcuch jest teraz (w jedności), a następnie (w unary). Chcemy wiedzieć, czy pierwsza liczba jednoargumentowa jest krótsza niż druga. Możemy z łatwością dokonać tego zwielokrotnienia za pomocą składni grupy przechwytywania i powtarzania. Następnie używamy (zamiast ), aby upewnić się, że druga liczba jest rzeczywiście większa od tej, a nie tylko równa. Jeśli tak, zamieniamy to wszystko na .d2.w2 + h290000{n}1+1*Retina!
1.+
Trash!
Jeśli druga liczba nie była wystarczająco duża, to poprzedni krok nic nie zmieni, a ciąg znaków zacznie się od litery 1. Jeśli tak jest, po prostu zastępujemy cały ciąg znaków Trash!i gotowe.