Retina or Trash?
Retina, 530 220 210 202 201 193 191 187 185 (184) bytes
Credits to randomra for saving 3 bytes! (And paving the way for a couple more.)
+`\.(\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!
For byte-counting purposes, each line goes in a separate file, but you can run the above code as is from a single file by invoking Retina with the -s
flag.
This expects the density first (which must contain a decimal point, even if it's a trailing one), followed by width and height, i.e. d w h
.
This is a bit slow. I wouldn't try most of the given test cases, because it will run for ages. However, you can check that it works correctly with the test cases
19. 4096 2160 -> Trash!
1. 180 240 -> Trash!
1. 181 240 -> Retina!
1. 180 241 -> Retina!
0.04 10 10 -> Retina!
Basically, after multiplying all numbers through to make the density an integer, you don't want the width and height to have more than 4 digits.
While this is slow, it is completely exact... there are no floating point issues or anything like that. All arithmetic is using (unary) integers.
In principle, I could shave off one more byte: the ^
can be omitted, but it will make Trash!
test cases horribly slow due to excessive amounts of backtracking.
Explanation
First, let's rearrange the inequality to avoid floating point operations:
√(w2 + h2) / d > 300
√(w2 + h2) > 300 d
w2 + h2 > 90000 d2
We can also notice that this is invariant under multiplying w
, h
and d
by the same number 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
There are several ways to square a unary number, but we'll be making use of the identity
n2 = Σi=1..2n ⌊i/2⌋
This gives us a way to solve the problem using only integer arithmetic (representing integers in unary).
Let's go through the code. Each pair of lines is a regex substitution.
+`\.(\d)(.+)( .+)
$1.$2_$3_
This repeatedly moves the decimal point in the density to the right while multiplying width and height by 10 (the x
above). This is to ensure that all numbers are integers. Instead of appending zeroes, I'm appending _
, which I'll be treating as zero later on. (This is a golfing trick, because otherwise I'd need to write ...${3}0
to avoid ambiguity with $30
.) The +
in front of the regex tells Retina to repeat this substitution until the result stops changing (which is the case when the pattern no longer matches).
\b
#
We're preparing the three numbers for conversion to unary now. In principle, we need a marker (the #
) in front of each number, but it's shorter to add one to the end of each number as well, which won't affect the conversion step.
+`(\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#
This is the conversion to unary, using a trick that has been developed by dan1111. Essentially I'm translating each digit to a rep-digit of itself, while multiplying the existing digits by 10 (moving the #
marker to the right in the process). This binary representation will be quite a jumble of different digits, but the total number will be equal to the value of the original integer. Note the \w
at the end - normally this is just 0
, but we want to treat _
as zero as well (which is considered a word character in regex).
\d
11
We turn each digit into two 1
s, thereby a) ensuring all digits are the same (which will be necessary later) and b) doubling each of the numbers.
(?=(1*)\1)[^.]
$1
This does two things: it squares all numbers (or rather half of each number, by computing a sum over 2n
), and adds the resulting squares of the width and the height. Notice that [^.]
matches 1
s, #
markers and spaces. If it's a #
or a space, the lookahead won't capture anything, which means all of those are simply removed, i.e. the results for the width and height are concatenated/added. The decimal point .
remains to separate the result for d
from those. If [^.]
matches a 1
instead, then the lookahead ensures that we capture half of the 1
s after it (rounded down) in group 1
. This computes the sum I mentioned above, which will then yield the square of the original number.
^(1+)\.\1{90000}1+
Retina!
The string is now d2
(in unary), then .
, then w2 + h2
(in unary). We want to know if the first unary number times 90000
is shorter than the second. We can easily do this multiplication using a capturing group and {n}
repetition syntax. We use 1+
(instead of 1*
) afterwards to ensure that the second number is actually greater than that and not just equal. If so, we replace all of that by Retina!
.
1.+
Trash!
If the second number wasn't big enough, then the previous step won't have changed anything and the string will still start with a 1
. If that's the case, we just replace the entire string by Trash!
and are done.
Python, 49
lambda w,h,d:"RTertaisnha!!"[w*w+h*h<=9e4*d*d::2]
Uses string interleaving.
It turned out shorter to square both sides than to use the complex norm.
w*w+h*h<=9e4*d*d
abs(w+1j*h)<=300*d
CJam, 30 29 27 bytes
q~mh300/<"Retina""Trash"?'!
Requires input to be in form of diagonal width height
UPDATE: 1 byte saved thanks to Dennis!
Try it online here