Võng mạc , 530 220 210 202 201 193 191 187 185 (184) byte
Tín dụng cho Randomra để tiết kiệm 3 byte! (Và mở đường cho một cặp vợ chồng nữa.)
+`\.(\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!
Đối với mục đích đếm byte, mỗi dòng đi trong một tệp riêng biệt, nhưng bạn có thể chạy mã ở trên như từ một tệp bằng cách gọi Retina bằng -s
cờ.
Điều này mong đợi mật độ trước tiên ( phải chứa một dấu thập phân, ngay cả khi đó là mật độ dấu), tiếp theo là chiều rộng và chiều cao, nghĩa là d w h
.
Đây là một chút chậm. Tôi sẽ không thử hầu hết các trường hợp thử nghiệm nhất định, bởi vì nó sẽ chạy trong nhiều năm. Tuy nhiên, bạn có thể kiểm tra xem nó có hoạt động chính xác với các trường hợp thử nghiệm không
19. 4096 2160 -> Trash!
1. 180 240 -> Trash!
1. 181 240 -> Retina!
1. 180 241 -> Retina!
0.04 10 10 -> Retina!
Về cơ bản, sau khi nhân tất cả các số qua để biến mật độ thành một số nguyên, bạn không muốn chiều rộng và chiều cao có nhiều hơn 4 chữ số.
Mặc dù điều này là chậm, nhưng nó hoàn toàn chính xác ... không có vấn đề dấu phẩy động hay bất cứ điều gì tương tự. Tất cả số học đang sử dụng số nguyên (đơn nguyên).
Về nguyên tắc, tôi có thể cạo thêm một byte: ^
có thể bỏ qua, nhưng nó sẽ làm cho Trash!
các trường hợp thử nghiệm bị chậm khủng khiếp do số lượng quay lại quá nhiều.
Giải trình
Trước tiên, hãy sắp xếp lại bất đẳng thức để tránh các phép toán dấu phẩy động:
√(w2 + h2) / d > 300
√(w2 + h2) > 300 d
w2 + h2 > 90000 d2
Chúng tôi cũng có thể nhận thấy rằng đây là bất biến theo cách nhân w
, h
và d
do cùng một số 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
Có một số cách để bình phương một số đơn nguyên, nhưng chúng ta sẽ sử dụng danh tính
n2 = Σi=1..2n ⌊i/2⌋
Điều này cho chúng ta một cách để giải quyết vấn đề chỉ sử dụng số học số nguyên (đại diện cho số nguyên trong đơn nguyên).
Chúng ta hãy đi qua mã. Mỗi cặp dòng là một sự thay thế regex.
+`\.(\d)(.+)( .+)
$1.$2_$3_
Điều này liên tục di chuyển dấu thập phân trong mật độ sang phải trong khi nhân chiều rộng và chiều cao với 10 ( x
ở trên). Điều này là để đảm bảo rằng tất cả các số là số nguyên. Thay vì nối các số 0, tôi đang nối thêm _
, mà sau này tôi sẽ coi là số không. (Đây là một mẹo chơi gôn, vì nếu không tôi cần phải viết ...${3}0
để tránh sự mơ hồ $30
.) Phía +
trước biểu thức chính thức nói với Retina lặp lại sự thay thế này cho đến khi kết quả ngừng thay đổi (đó là trường hợp khi mô hình không còn phù hợp) .
\b
#
Chúng tôi đang chuẩn bị ba số để chuyển đổi thành unary ngay bây giờ. Về nguyên tắc, chúng ta cần một điểm đánh dấu (trước #
) trước mỗi số, nhưng nó sẽ ngắn hơn để thêm một điểm vào cuối mỗi số, điều này sẽ không ảnh hưởng đến bước chuyển đổi.
+`(\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#
Đây là chuyển đổi sang unary, sử dụng một thủ thuật đã được dan1111 phát triển . Về cơ bản, tôi đang dịch mỗi chữ số thành một chữ số lặp lại của chính nó, trong khi nhân các chữ số hiện có với 10 (di chuyển #
điểm đánh dấu sang phải trong quy trình). Biểu diễn nhị phân này sẽ khá lộn xộn với các chữ số khác nhau, nhưng tổng số sẽ bằng với giá trị của số nguyên ban đầu. Lưu ý \w
ở cuối - thông thường đây chỉ là 0
, nhưng chúng tôi cũng muốn coi _
là số không (được coi là một ký tự từ trong regex).
\d
11
Chúng tôi biến mỗi chữ số thành hai 1
s, do đó a) đảm bảo tất cả các chữ số đều giống nhau (sẽ cần thiết sau này) và b) nhân đôi mỗi số.
(?=(1*)\1)[^.]
$1
Điều này thực hiện hai điều: nó bình phương tất cả các số (hoặc đúng hơn một nửa của mỗi số, bằng cách tính tổng 2n
), và thêm các bình phương kết quả của chiều rộng và chiều cao. Lưu ý rằng [^.]
phù hợp với 1
s, #
đánh dấu và không gian. Nếu đó là một #
hoặc một không gian, giao diện sẽ không thu được bất cứ thứ gì, có nghĩa là tất cả những thứ đó chỉ bị xóa, tức là kết quả cho chiều rộng và chiều cao được nối / thêm vào. Dấu thập phân .
vẫn còn để phân tách kết quả cho d
những người. Nếu [^.]
khớp với một 1
thay vào đó, thì cái nhìn đảm bảo rằng chúng ta chụp được một nửa số 1
sau nó (làm tròn xuống) trong nhóm 1
. Điều này sẽ tính tổng tôi đã đề cập ở trên, sau đó sẽ mang lại bình phương của số ban đầu.
^(1+)\.\1{90000}1+
Retina!
Chuỗi bây giờ (trong unary), sau đó , (unary). Chúng tôi muốn biết nếu số lần unary đầu tiên ngắn hơn lần thứ hai. Chúng ta có thể dễ dàng thực hiện phép nhân này bằng cách sử dụng cú pháp bắt nhóm và lặp lại. Chúng tôi sử dụng (thay vì ) sau đó để đảm bảo rằng số thứ hai thực sự lớn hơn số đó và không chỉ bằng nhau. Nếu vậy, chúng tôi thay thế tất cả bằng cách .d2
.
w2 + h2
90000
{n}
1+
1*
Retina!
1.+
Trash!
Nếu số thứ hai không đủ lớn, thì bước trước đó sẽ không thay đổi gì và chuỗi vẫn sẽ bắt đầu bằng a 1
. Nếu đó là trường hợp, chúng tôi chỉ cần thay thế toàn bộ chuỗi bằng Trash!
và được thực hiện.