Retina , 530 220 210 202 201 193 191 187 185 (184) bytes
Créditos ao randomra por economizar 3 bytes! (E abrindo caminho para mais algumas.)
+`\.(\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!
Para fins de contagem de bytes, cada linha entra em um arquivo separado, mas você pode executar o código acima como em um único arquivo, chamando Retina com o -s
sinalizador.
Isso espera que a densidade primeiro (que deve conter um ponto decimal, mesmo que seja à direita), seguida por largura e altura, ou seja d w h
.
Isso é um pouco lento. Eu não tentaria a maioria dos casos de teste fornecidos, porque ele será executado por séculos. No entanto, você pode verificar se ele funciona corretamente com os casos de teste
19. 4096 2160 -> Trash!
1. 180 240 -> Trash!
1. 181 240 -> Retina!
1. 180 241 -> Retina!
0.04 10 10 -> Retina!
Basicamente, depois de multiplicar todos os números para tornar a densidade um número inteiro, você não deseja que a largura e a altura tenham mais de 4 dígitos.
Enquanto isso é lento, é completamente exato ... não há problemas de ponto flutuante ou algo assim. Toda aritmética está usando números inteiros (unários).
Em princípio, eu poderia economizar mais um byte: ^
pode ser omitido, mas isso tornará Trash!
os casos de teste terrivelmente lentos devido a quantidades excessivas de retorno.
Explicação
Primeiro, vamos reorganizar a desigualdade para evitar operações de ponto flutuante:
√(w2 + h2) / d > 300
√(w2 + h2) > 300 d
w2 + h2 > 90000 d2
Também podemos notar que este é invariante sob multiplicação w
, h
e d
pelo mesmo número 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
Existem várias maneiras de colocar um número unário ao quadrado, mas usaremos a identidade
n2 = Σi=1..2n ⌊i/2⌋
Isso nos dá uma maneira de resolver o problema usando apenas aritmética inteira (representando números inteiros em unário).
Vamos analisar o código. Cada par de linhas é uma substituição de regex.
+`\.(\d)(.+)( .+)
$1.$2_$3_
Isso move repetidamente o ponto decimal na densidade para a direita, multiplicando a largura e a altura por 10 ( x
acima). Isso é para garantir que todos os números sejam inteiros. Em vez de acrescentar zeros, estou acrescentando _
, que tratarei como zero mais tarde. (Esse é um truque de golfe, porque, caso contrário, eu precisaria escrever ...${3}0
para evitar ambigüidades $30
.) O +
na frente do regex diz ao Retina para repetir essa substituição até que o resultado pare de mudar (o que acontece quando o padrão não corresponde mais) .
\b
#
Estamos preparando os três números para a conversão em unário agora. Em princípio, precisamos de um marcador (o #
) na frente de cada número, mas é mais curto adicionar um ao final de cada número também, o que não afetará a etapa de conversão.
+`(\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#
Esta é a conversão para unário, usando um truque que foi desenvolvido por dan1111 . Basicamente, estou traduzindo cada dígito para um dígito repetitivo, enquanto multiplica os dígitos existentes por 10 (movendo o #
marcador para a direita no processo). Essa representação binária será uma mistura de dígitos diferentes, mas o número total será igual ao valor do número inteiro original. Observe o \w
final - normalmente isso é justo 0
, mas também queremos tratar _
o zero (que é considerado um caractere de palavra no regex).
\d
11
Transformamos cada dígito em dois 1
s, assim: a) garantindo que todos os dígitos sejam os mesmos (o que será necessário posteriormente) eb) dobrando cada um dos números.
(?=(1*)\1)[^.]
$1
Isso faz duas coisas: esquadra todos os números (ou melhor, metade de cada número, calculando uma soma acima 2n
) e adiciona os quadrados resultantes da largura e da altura. Observe que [^.]
corresponde a 1
s, #
marcadores e espaços. Se for um #
ou um espaço, a cabeça de impressão não captura nada, o que significa que todos são simplesmente removidos, ou seja, os resultados para a largura e altura são concatenados / adicionados. O ponto decimal .
permanece para separar o resultado d
daqueles. Se [^.]
corresponder a um 1
, o lookahead garantirá que capturamos metade dos 1
s depois dele (arredondado para baixo) no grupo 1
. Isso calcula a soma que eu mencionei acima, que produzirá o quadrado do número original.
^(1+)\.\1{90000}1+
Retina!
A cadeia é agora (em unário), então , então (em unário). Queremos saber se o primeiro número unário vezes é menor que o segundo. Podemos facilmente fazer essa multiplicação usando um grupo de captura e sintaxe de repetição. Usamos (em vez de ) posteriormente para garantir que o segundo número seja realmente maior que isso e não apenas igual. Nesse caso, substituímos tudo isso por .d2
.
w2 + h2
90000
{n}
1+
1*
Retina!
1.+
Trash!
Se o segundo número não for grande o suficiente, a etapa anterior não terá alterado nada e a sequência ainda começará com a 1
. Se for esse o caso, apenas substituímos a cadeia inteira por Trash!
e pronto.