망막 , 530 220 210 202 201 193 191 187 185 (184) 바이트
3 바이트 절약을위한 randomra의 크레딧! (그리고 몇 가지 더 길을 포장합니다.)
+`\.(\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!
바이트 수 계산을 위해 각 줄은 별도의 파일로 이동하지만 -s플래그 와 함께 Retina를 호출하여 단일 파일에서와 같이 위의 코드를 실행할 수 있습니다 .
이것은 밀도가 먼저 ( 후행이더라도 소수점을 포함 해야 함) 예상하고 너비와 높이가 뒤 따릅니다 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위). 이것은 모든 숫자가 정수가되도록하기위한 것입니다. 0을 추가하는 대신을 추가 _하고 있습니다. 나중에 0으로 처리합니다. (이것은 골프 트릭입니다. 그렇지 않으면 ...${3}0에 대한 모호함을 피하기 위해 작성해야합니다 $30.) +정규 표현식 앞에는 Retina가 결과가 더 이상 변경되지 않을 때 까지이 대체를 반복하도록 지시합니다 (패턴이 더 이상 일치하지 않는 경우) .
\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,하지만 우리가 치료하고자하는 _(단어 정규식의 문자로 간주되는)뿐만 아니라 0으로.
\d
11
우리는 각 숫자를 두 개의 숫자로 바꾸어 1a) 모든 숫자가 같은지 확인하고 (나중에 필요할 것임) b) 각 숫자를 두 배로 늘립니다.
(?=(1*)\1)[^.]
$1
이것은 두 가지 일을합니다 : 그것은 모든 수의 제곱 (또는 합을 계산하여 각 숫자의 절반 2n)과 너비와 높이의 결과 제곱을 더합니다. 공지 사항이 [^.]일치 1의, #마커와 공간. 그것이 #공간이거나 공간이라면, lookahead는 아무것도 포착하지 못합니다. 즉, 모든 것이 단순히 제거됩니다. 즉 너비와 높이에 대한 결과가 연결 / 추가됩니다. 소수점 .은 결과와 분리됩니다 d. 만약 [^.]일치하는 1대신, 다음 내다 것을 보장의 우리 캡처 절반 1의 IT (둥근 아래) 그룹의 후 1. 이것은 위에서 언급 한 합계를 계산하여 원래 숫자의 제곱을 산출합니다.
^(1+)\.\1{90000}1+
Retina!
문자열은 이제 (단항으로), 그 다음에 (단항으로)입니다. 첫 번째 단항 수가 두 번째보다 짧은 지 알고 싶습니다 . 캡처 그룹과 반복 구문을 사용하여이 곱셈을 쉽게 수행 할 수 있습니다 . 우리 는 두 번째 숫자가 실제로 그것 보다 크고 같지 않도록하기 위해 이후에 (대신에 )를 사용합니다 . 그렇다면 모든 것을로 대체합니다 .d2.w2 + h290000{n}1+1*Retina!
1.+
Trash!
두 번째 숫자가 충분히 크지 않으면 이전 단계에서 아무것도 변경되지 않았고 문자열은 여전히로 시작합니다 1. 이 경우 전체 문자열을 바꾸고 Trash!완료합니다.