Regex (hương vị PCRE), 66 (65🐌) byte
Lấy cảm hứng khi thấy cả Martin Ender và jaytea , hai thiên tài regex, đã viết các giải pháp regex cho mã golf này, tôi đã tự viết từ đầu. Regex kiểm tra chính nổi tiếng không xuất hiện bất cứ nơi nào trong giải pháp của tôi.
Đừng đọc nó nếu bạn không muốn một số ma thuật regex đơn phương hư hỏng cho bạn. Nếu bạn muốn tự mình tìm ra phép thuật này, tôi khuyên bạn nên bắt đầu bằng cách giải quyết một số vấn đề trong biểu thức chính của ECMAScript:
- Khớp các số nguyên tố (nếu bạn chưa quen với việc này trong regex)
- Kết hợp sức mạnh của 2 (nếu bạn chưa làm như vậy). Hoặc chỉ cần làm việc theo cách của bạn thông qua Regex Golf , bao gồm Prime và Powers. Đảm bảo thực hiện cả bộ bài toán Cổ điển và Teukon.
Tìm cách ngắn nhất để khớp với các lũy thừa của N trong đó N là một hằng số (nghĩa là được chỉ định trong biểu thức chính quy, không phải đầu vào) có thể là tổng hợp (nhưng không bắt buộc phải có). Ví dụ, quyền hạn của 6.
Tìm cách khớp các lũy thừa Nth, trong đó N là hằng số> = 2. Ví dụ, phù hợp với hình vuông hoàn hảo. (Đối với khởi động, phù hợp với quyền hạn chính .)
Nối các câu lệnh nhân đúng. Ghép các số tam giác.
Khớp các số Fibonacci (nếu bạn điên như tôi) hoặc nếu bạn muốn bám vào thứ gì đó ngắn hơn, khớp với các tuyên bố lũy thừa chính xác (đối với sự khởi động, trở lại như một logarit trong cơ sở 2 của lũy thừa 2 - phần thưởng, làm tương tự cho bất kỳ số nào, làm tròn số đó theo cách bạn muốn) hoặc số giai thừa (để khởi động, khớp với số nguyên thủy ).
Ghép các số phong phú (nếu bạn điên như tôi)
Tính một số vô tỷ cho độ chính xác được yêu cầu (ví dụ: chia đầu vào cho căn bậc hai của 2, trả về kết quả làm tròn dưới dạng khớp)
(Công cụ regex mà tôi đã viết có thể giúp ích, vì nó rất nhanh trong các biểu thức toán học đơn phương và bao gồm một chế độ số đơn phương có thể kiểm tra phạm vi của các số tự nhiên (nhưng cũng có chế độ chuỗi có thể đánh giá các biểu thức không đơn nhất hoặc đơn phương với các dấu phân cách). Theo mặc định, nó tương thích với ECMAScript, nhưng có các phần mở rộng tùy chọn (có thể thêm một cách chọn lọc các tập hợp con của PCRE, hoặc thậm chí là tìm kiếm phân tử, thứ mà không có công cụ regex nào khác có).)
Mặt khác, hãy đọc và cũng đọc GitHub Gist này (cảnh báo, nhiều kẻ phá hoại) ghi lại hành trình đẩy regex ECMAScript để giải quyết các hàm số tự nhiên tăng độ khó (bắt đầu bằng bộ câu đố của teukon, không phải tất cả đều là toán học, điều này đã gây ra điều này hành trình).
Cũng như các giải pháp regex khác cho vấn đề này, đầu vào được đưa ra dưới dạng hai số trong đơn vị thống kê, được phân tách bằng dấu phẩy, thể hiện phạm vi bao gồm. Chỉ có một số được trả lại. Regex có thể được sửa đổi để trả về tất cả các số có chung một thừa số nguyên tố lớn nhất nhỏ nhất, như các kết quả khớp riêng biệt, nhưng điều đó sẽ yêu cầu giao diện có độ dài thay đổi và đặt \K
trong một cái nhìn hoặc trả về kết quả dưới dạng bắt thay vì khớp.
Kỹ thuật được sử dụng ở đây của phép chia ẩn lặp đi lặp lại theo thừa số nguyên tố nhỏ nhất giống hệt với kỹ thuật được sử dụng trong chuỗi Kết hợp có độ dài là câu trả lời sức mạnh thứ tư mà tôi đã đăng một lúc trước.
Không có thêm rắc rối:
((.+).*),(?!.*(?=\1)(((?=(..+)(\5+$))\6)*)(?!\2)).*(?=\1)\K(?3)\2$
Bạn có thể thử nó ở đây.
Và phiên bản khoảng cách miễn phí, với các bình luận:
# No ^ anchor needed, because this algorithm always returns a
# match for valid input (in which the first number is less than
# or equal to the second number), and even in /g mode only one
# match can be returned. You can add an anchor to make it reject
# invalid ranges.
((.+).*), # \1 = low end of range; \2 = conjectured number that is the
# smallest number in the set of the largest prime factor of each
# number in the range; note, it is only in subsequent tests that
# this is implicitly confined to being prime.
# We shall do the rest of our work inside the "high end of range"
# number.
(?! # Assert that there is no number in the range whose largest prime
# factor is smaller than \2.
.*(?=\1) # Cycle tail through all numbers in the range, starting with \1.
( # Subroutine (?3):
# Find the largest prime factor of tail, and leave it in tail.
# It will both be evaluated here as-is, and later as an atomic
# subroutine call. As used here, it is not wrapped in an atomic
# group. Thus after the return from group 3, backtracking back
# into it can increase the value of tail – but this won't mess
# with the final result, because only making tail smaller could
# change a non-match into a match.
( # Repeatedly divide tail by its smallest prime factor, leaving
# only the largest prime factor at the end.
(?=(..+)(\5+$)) # \6 = tool to make tail = \5 = largest nontrivial factor of
# current tail, which is implicitly the result of dividing it
# by its smallest prime factor.
\6 # tail = \5
)*
)
(?!\2) # matches iff tail < \ 2
)
# now, pick a number in the range whose largest prime factor is \2
.*(?=\1) # Cycle tail through all numbers in the range, starting with \1.
\K # Set us up to return tail as the match.
(?3) # tail = largest prime factor of tail
\2$ # Match iff tail == \2, then return the number whose largest
# prime factor is \2 as the match.
Thuật toán có thể dễ dàng được chuyển sang ECMAScript bằng cách thay thế lệnh gọi chương trình con bằng một bản sao của chương trình con và trả lại kết quả khớp như một nhóm chụp thay vì sử dụng \ K. Kết quả có độ dài 80 byte:
((x+)x*),(?!.*(?=\1)((?=(xx+)(\4+$))\5)*(?!\2)).*(?=\1)(((?=(xx+)(\8+$))\9)*\2$)
Hãy thử trực tuyến!
Lưu ý rằng ((.+).*)
có thể thay đổi thành ((.+)+)
, giảm kích thước 1 byte (từ 66 xuống còn 65 byte ) mà không mất chức năng chính xác - nhưng biểu thức chính thức bùng nổ theo cấp số nhân trong sự chậm chạp.
Hãy thử trực tuyến! (Phiên bản làm chậm theo cấp số nhân ECMAScript 79 byte)