Сітківка , 530 220 210 202 201 193 191 187 185 (184) байт
Кредити до випадкових випадків, щоб зберегти 3 байти! (І проклавши шлях ще на пару.)
+`\.(\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!
Для цілей підрахунку байтів кожен рядок складається в окремому файлі, але ви можете запустити вищевказаний код, як і в одному файлі, звернувшись до Retina із -s
прапором.
Тут очікується спочатку щільність (яка повинна містити десяткову точку, навіть якщо вона є кінцевою), а потім шириною та висотою, тобто d w h
.
Це трохи повільно. Я б не намагався пробувати більшість поданих тестових випадків, тому що це буде працювати протягом віків. Однак ви можете перевірити, чи правильно він працює з тестовими кейсами
19. 4096 2160 -> Trash!
1. 180 240 -> Trash!
1. 181 240 -> Retina!
1. 180 241 -> Retina!
0.04 10 10 -> Retina!
В основному, помноживши всі числа на цілі, щоб щільність була цілою, вам не потрібно, щоб ширина і висота мали більше 4 цифр.
Хоча це повільно, це абсолютно точно ... немає проблем з плаваючою точкою чи чогось подібного. Вся арифметика використовує (одинарні) цілі числа.
В принципі, я міг би відголити ще один байт: ^
можна пропустити, але це зробить Trash!
тестові випадки жахливо повільними через надмірну кількість зворотних трекінгів.
Пояснення
Спочатку давайте переставимо нерівність, щоб уникнути операцій з плаваючою комою:
√(w2 + h2) / d > 300
√(w2 + h2) > 300 d
w2 + h2 > 90000 d2
Ми також можемо помітити, що це інваріантно при множенні w
, h
і d
на ту саму кількість 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
Існує кілька способів скласти одинарне число, але ми використовуємо ідентичність
n2 = Σi=1..2n ⌊i/2⌋
Це дає нам спосіб вирішити задачу, використовуючи лише цілу арифметику (представляючи цілі числа в одинакових).
Перейдемо до коду. Кожна пара рядків є заміною регулярного виразка.
+`\.(\d)(.+)( .+)
$1.$2_$3_
Це неодноразово переміщує десяткову точку в густині праворуч, помноживши ширину і висоту на 10 ( x
вище). Це потрібно для того, щоб усі числа були цілими числами. Замість того, щоб додавати нулі, я додаю _
, що згодом я буду вважати нулем. (Це хитрість з гольфу, тому що в противному випадку мені потрібно написати, ...${3}0
щоб уникнути неоднозначності $30
.) +
Перед регексом вказує Ретіні повторювати цю заміну, поки результат не перестане змінюватися (що стосується випадків, коли шаблон більше не збігається) .
\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#
Це перетворення на одинарне, використовуючи трюк, розроблений dan1111 . По суті, я перекладаю кожну цифру на саму повторну цифру, при цьому множуючи існуючі цифри на 10 (переміщуючи #
маркер вправо в процесі). Це двійкове представлення буде досить сукупністю різних цифр, але загальна кількість буде дорівнює значенню вихідного цілого числа. Зверніть увагу \w
на кінець - зазвичай це справедливо 0
, але ми також хочемо трактувати _
як нуль (що в регулярному вираженні вважається символом слова).
\d
11
Перетворюємо кожну цифру на дві 1
s, тим самим a) забезпечуючи, щоб усі цифри були однаковими (що буде потрібно пізніше) і b) подвоєння кожного з чисел.
(?=(1*)\1)[^.]
$1
Це робить дві речі: він розподіляє всі числа (а точніше половину кожного числа, обчислюючи суму більше 2n
), і додає отримані квадрати ширини та висоти. Зауважте, що [^.]
відповідає 1
s, #
маркери та пробіли. Якщо це #
або пробіл, lookahead нічого не буде захоплювати, це означає, що всі вони просто видаляються, тобто результати для ширини та висоти об'єднуються / додаються. Десяткова крапка .
залишається відокремлювати результат d
від цих. Якщо замість цього [^.]
відповідає збіг 1
, то lookahead гарантує, що ми захопимо половину 1
s після нього (округлюємо вниз) у групі 1
. Це обчислює суму, про яку я згадував вище, і отримає квадрат початкового числа.
^(1+)\.\1{90000}1+
Retina!
Рядок тепер (унарний), потім , потім (унарний). Ми хочемо знати, чи коротше перше одинарне число разів , ніж друге. Ми можемо легко зробити це множення за допомогою групи захоплення та синтаксису повторень. Ми використовуємо (замість цього ) згодом, щоб переконатися, що друге число насправді більше, ніж це, а не просто рівне. Якщо так, ми замінюємо все це на .d2
.
w2 + h2
90000
{n}
1+
1*
Retina!
1.+
Trash!
Якщо друге число було недостатньо великим, то попередній крок нічого не змінив, і рядок все одно розпочнеться з а 1
. Якщо це так, ми просто замінюємо весь рядок на Trash!
і робимо.