Với mục đích của thử thách này, chúng tôi nói rằng một mẫu regex khớp với một chuỗi nếu toàn bộ chuỗi được khớp với mẫu đó, không chỉ là một chuỗi con.
Với hai mẫu regex Một và B , chúng ta nói rằng A được nhiều chuyên hơn B nếu mỗi chuỗi được kết hợp bởi Một cũng được kết hợp bởi B nhưng không phải là cách khác xung quanh. Chúng ta nói rằng A là tương đương với B nếu cả hai mô hình phù hợp chính xác cùng một tập các chuỗi. Nếu không có mẫu nào chuyên biệt hơn mẫu kia và chúng không tương đương, chúng tôi nói rằng A và B là không thể so sánh được .
Ví dụ, mô hình Hello, .*!
là chuyên ngành hơn .*, .*!
; các mẫu (Hello|Goodbye), World!
và Hello, World!|Goodbye, World!
tương đương; và các mô hình Hello, .*!
và .*, World!
là không thể so sánh được.
Mối quan hệ "chuyên biệt hơn" xác định một trật tự từng phần nghiêm ngặt trên tập các mẫu biểu thức chính quy. Đặc biệt, đối với tất cả các mẫu A và B , chính xác một trong những điều sau đây là đúng:
- A chuyên hơn B ( A < B ).
- B chuyên biệt hơn A ( A > B ).
- A và B tương đương ( A = B ).
- Một và B không thể so sánh ( Một ∥ B ).
Khi A và B không thể so sánh được, chúng ta có thể phân biệt rõ hơn giữa hai trường hợp:
- Một và B là rời nhau ( Một ∥ B ), có nghĩa là không có chuỗi được kết hợp bởi cả hai.
- Một và B được giao nhau ( Một ≬ B ), có nghĩa là một số chuỗi được kết hợp của cả hai.
Thử thách
Viết chương trình hoặc hàm lấy một cặp mẫu biểu thức chính và so sánh chúng bằng cách sử dụng thứ tự trên. Đó là, nếu hai mẫu là A và B , chương trình nên xác định xem A < B , A > B ,
A = B hoặc A ∥ B .
× 92% Tiền thưởng Một phần thưởng bổ sung được đưa ra nếu, khi các mẫu không thể so sánh được, chương trình sẽ xác định xem chúng có giao nhau hay không khớp nhau.
Đầu vào và đầu ra
Chương trình nên chấp nhận hai mẫu regex, dưới dạng chuỗi, trong hương vị được xác định bên dưới. Bạn có thể đọc đầu vào thông qua STDIN , dòng lệnh , dưới dạng đối số hàm hoặc một phương thức tương đương . Bạn có thể cho rằng các mẫu là hợp lệ.
Chương trình sẽ tạo ra một trong bốn đầu ra riêng biệt (hoặc năm đầu ra riêng biệt nếu bạn sẽ nhận phần thưởng ở trên), tùy thuộc vào kết quả so sánh (đầu ra chính xác tùy thuộc vào bạn.) Bạn có thể viết đầu ra cho STDOUT , trả lại nó như là kết quả của hàm hoặc sử dụng một phương thức tương đương .
Hương vị Regex
Bạn có thể hỗ trợ bất kỳ tính năng regex nào bạn thích, nhưng bạn phải hỗ trợ các tính năng sau:
- Thay thế với
|
. - Định lượng với
*
. - Phân nhóm với
(
và)
. - Phù hợp với bất kỳ nhân vật (có thể loại trừ dòng mới) với
.
. - (Tùy chọn: × 80% Tiền thưởng) Phù hợp với các lớp nhân vật đơn giản và bị phủ định với
[…]
và[^…]
, tương ứng. Bạn không phải hỗ trợ bất kỳ lớp ký tự được xác định trước nào (ví dụ[:digit:]
) nhưng bạn nên hỗ trợ phạm vi ký tự. - Nhân vật trốn thoát với
\
. Ít nhất nên có thể esacpe các ký tự đặc biệt (nghĩa là|*().[^-]\
) và tốt nhất là các ký tự đặc biệt phổ biến trong các hương vị khác (ví dụ{}
), nhưng hành vi khi thoát các ký tự không đặc biệt là không xác định. Cụ thể, bạn không phải hỗ trợ các chuỗi thoát đặc biệt, chẳng hạn như\n
cho một dòng mới và những thứ tương tự. Một cách thực hiện có thể chỉ đơn giản là lấy ký tự theo\
nghĩa đen.
Bạn có thể giả sử sự tồn tại của một ký tự đầu vào không thể phù hợp với bất kỳ nghĩa đen nào (nghĩa là nó chỉ có thể được khớp bởi .
và các lớp ký tự bị phủ định.)
Quy tắc bổ sung
- Bạn chỉ có thể sử dụng các thư viện regex hoặc chức năng regex dựng sẵn cho mục đích khớp và thay thế chuỗi.
- Bạn có thể bỏ qua mọi vấn đề liên quan đến ngôn ngữ, chẳng hạn như quy tắc đối chiếu.
- Để nói rõ ràng: chương trình của bạn phải chấm dứt. Nó sẽ thực thi trong một khoảng thời gian hợp lý với các mẫu điển hình (chắc chắn không quá một giờ, tốt nhất là ít hơn rất nhiều.)
Chấm điểm
Đây là mã golf. Điểm của bạn là sản phẩm của kích thước mã , tính bằng byte và bất kỳ phần thưởng nào . Điểm thấp nhất sẽ thắng.
Các trường hợp thử nghiệm
Định dạng của các trường hợp thử nghiệm như sau:
<Test ID>
<Pattern A>
<Ordering>
<Pattern B>
<Test ID>
<Pattern A>
<Ordering>
<Pattern B>
...
Trường hợp <Test ID>
định danh cho trường hợp thử nghiệm <Pattern A>
và <Pattern B>
là các mẫu biểu thức chính và <Ordering>
là thứ tự giữa chúng và là một trong:
<
:<Pattern A>
là chuyên ngành hơn<Pattern B>
.>
:<Pattern B>
là chuyên ngành hơn<Pattern A>
.=
: Các mẫu tương đương.|
: Các mô hình là không thể so sánh và rời rạc.X
: Các mô hình là không thể so sánh và giao nhau.
Giá trị đặc biệt <empty pattern>
là viết tắt của mẫu trống.
A. Các mẫu cơ bản
B. Mẫu phức tạp
C. Các mẫu cơ bản với các lớp nhân vật
D. Các mẫu phức tạp với các lớp nhân vật
Chương trình kiểm tra
Đoạn mã sau có thể được sử dụng để so sánh các mẫu regex:
<style>#main {display: none;}#main[loaded] {display: inline;}.pattern_container {position: relative;}.pattern_underlay, .pattern {font: 12pt courier, monospace;overflow: hidden;white-space: pre;padding: 7px;box-sizing: border-box;}.pattern_underlay {background-color: #dddddd;color: #707070;border-radius: 4px;box-shadow: 0.5px 0.5px 2.5px #aaaaaa;}.pattern_underlay[error] {background-color: #ffccbb;}.pattern {position: absolute;left: 0px;top: 0px;background: none;border: none;width: 100%;height: 100%;resize: none;white-space: normal;}#ordering {min-width: 28pt;text-align: center;font-size: 16pt;}#status {padding: 5px;background-color: #fffdce;box-shadow: 1.5px 1.5px 3.5px #aaaaaa;font-size: 10pt;white-space: pre;display: none;}#status[error] {display: inline;background-color: #ffe8df;}#status[loading] {display: inline;}.inline_code {background-color: #dddddd;font: 12pt courier, monospace;padding: 2px;}.placeholder {visibility: hidden;}.error_text {background-color: #fffcb7};</style><span id="main"><table><tr><td><div class="pattern_container"><div class="pattern_underlay" id="pattern1_underlay"></div><textarea class="pattern" id="pattern1" oninput="compare()">Hello, .*!</textarea></div></td><td id="ordering"></td><td><div class="pattern_container"><div class="pattern_underlay" id="pattern2_underlay"></div><textarea class="pattern" id="pattern2" oninput="compare()">.*, .*!</textarea></div></td></tr></table><br></span><span id="status" loading>Loading...</span><script type='text/javascript'>var Module = {setStatus: function (status) {document.getElementById("status").innerHTML = status;if (status == "") {compare();document.getElementById("status").removeAttribute("loading");document.getElementById("main").setAttribute("loaded", 1);}}};function underlay_chars(str) {if (/^\n*$/.exec(str))return str.split("\n").map(function () { return '<span class="placeholder"> \n</span>'; });if (str.indexOf("\n") >= 0)str = str.replace(/\s*$/gm, function (m) { return m.replace(/[^\n]/g, "\0"); });return (str + "\n").split("").map(function (c) {if (c == "\0") return "·";else return '<span class="placeholder">' + c + '</span>';});}function underlay_str(str) {return underlay_chars(str).join("");}function str_to_array32(str) {a = [];for (c of str) {n = c.charCodeAt(0);a.push(n & 0xff, (n >> 8) & 0xff, (n >> 16) & 0xff, n >> 24);}a.push(0, 0, 0, 0);return a;}function compare() {try {for (e of ["pattern1_underlay", "pattern2_underlay", "status"])document.getElementById(e).removeAttribute("error");for (e of ["pattern1", "pattern2"])document.getElementById(e + "_underlay").innerHTML = underlay_str(document.getElementById(e).value);c = Module.ccall("regex_compare", "number", ["array", "array"], [str_to_array32(document.getElementById("pattern1").value),str_to_array32(document.getElementById("pattern2").value)]);if (c >= 0)document.getElementById("ordering").innerHTML = "∥≬<>="[c];else {i = Module.ccall("regex_error_index", "number", [], []);l = Module.ccall("regex_error_length", "number", [], []);e = document.getElementById("pattern" + -c + "_underlay");t = underlay_chars(document.getElementById("pattern" + -c).value);e.setAttribute("error", 1);e.innerHTML =t.slice(0, i).join("") +'<span class="error_text">' + t.slice(i, i + l).join("") + "</span>" +t.slice(i + l).join("");e.setAttribute("error", 1);throw "Pattern error: " + Module.ccall("regex_error", "string", [], []).replace(/`(.*?)'/g, '<span class="inline_code">$1</span>');}} catch (e) {document.getElementById("ordering").innerHTML = "??";document.getElementById("status").innerHTML = e;document.getElementById("status").setAttribute("error", 1);}}</script><script async type="text/javascript" src="https://gist.githack.com/anonymous/91f27d6746566c7b4e4c/raw/c563bf84a01c3a1c6e5f021369a3e730a2e74a1a/rpo.js"></script>