สำหรับจุดประสงค์ของการท้าทายนี้เราบอกว่ารูปแบบ regex จับคู่กับสตริงหากสตริงทั้งหมดถูกจับคู่กับรูปแบบไม่ใช่แค่สตริงย่อย
ด้วยรูปแบบ regex สองรูปแบบ A และ Bเราบอกว่า A นั้นมีความเชี่ยวชาญมากกว่า B หากสตริงทุกอันที่จับคู่โดย A นั้นถูกจับคู่โดยBด้วย แต่ไม่ใช่วิธีอื่น ๆ เราบอกว่า เป็นเทียบเท่าเพื่อ B ถ้ารูปแบบทั้งตรงกับชุดเดียวกันของสตริง หากรูปแบบไม่เป็นความเชี่ยวชาญมากขึ้นกว่าที่อื่น ๆ หรือพวกเขาเทียบเท่าเราบอกว่า และ B เป็นที่เปรียบมิได้
ตัวอย่างเช่นรูปแบบHello, .*!
มีความเชี่ยวชาญมากกว่า.*, .*!
; รูปแบบ(Hello|Goodbye), World!
และHello, World!|Goodbye, World!
เทียบเท่า; และรูปแบบHello, .*!
และ.*, World!
หาที่เปรียบมิได้
ความสัมพันธ์ "พิเศษกว่า" กำหนดลำดับบางส่วนที่เข้มงวดในชุดของรูปแบบ regex โดยเฉพาะอย่างยิ่งสำหรับรูปแบบ A และ Bทั้งหมดหนึ่งในสิ่งต่อไปนี้เป็นจริง:
- A มีความเชี่ยวชาญมากกว่า B ( A < B )
- B มีความเชี่ยวชาญมากกว่า A ( A > B )
- A และ B เทียบเท่า ( A = B )
- A และ B หาที่เปรียบมิได้ ( A ∥ B )
เมื่อ A และ B เปรียบเทียบ กันไม่ได้เราสามารถแยกแยะความแตกต่างระหว่างสองกรณีต่อไปนี้:
- A และ B เป็นdisjoint ( A ∥ B ) ซึ่งหมายความว่าทั้งคู่ไม่มีสตริงที่ตรงกัน
- A และ B กำลังตัดกัน ( A ≬ B ) ซึ่งหมายความว่ามีการจับคู่สตริงบางตัว
ท้าทาย
เขียนโปรแกรมหรือฟังก์ชั่นที่ใช้คู่ของรูปแบบ regex และเปรียบเทียบพวกเขาโดยใช้ลำดับข้างต้น นั่นคือถ้าทั้งสองรูปแบบมี และ B , โปรแกรมควรตรวจสอบว่า < B , > B , = B หรือ ∥ B
× 92% โบนัสโบนัส เพิ่มเติมจะมอบให้หากเมื่อรูปแบบที่เปรียบมิได้โปรแกรมจะพิจารณาว่าพวกเขากำลังตัดกันหรือแยกกัน
อินพุตและเอาต์พุต
โปรแกรมควรยอมรับสองรูปแบบ regex เป็นสตริงในรสชาติที่กำหนดไว้ด้านล่าง คุณอาจจะอ่านเข้าผ่านSTDINที่บรรทัดคำสั่งเป็นอาร์กิวเมนต์ของฟังก์ชันหรือวิธีเทียบเท่า คุณอาจคิดว่ารูปแบบนั้นถูกต้อง
โปรแกรมควรสร้างเอาท์พุทที่แตกต่างกันหนึ่งในสี่ที่แน่นอน (หรือห้าเอาท์พุตที่แตกต่างกันหากคุณกำลังจะได้โบนัสข้างต้น) ขึ้นอยู่กับผลของการเปรียบเทียบ (ผลลัพธ์ที่แน่นอนขึ้นอยู่กับคุณ) คุณสามารถเขียนผลลัพธ์ไปยังSTDOUTกลับมาว่ามันเป็นผลของฟังก์ชันหรือใช้วิธีการเทียบเท่า
รสชาติ Regex
คุณอาจสนับสนุนคุณสมบัติใด ๆ ของ regex ที่คุณต้องการ แต่คุณต้องรองรับคุณสมบัติต่อไปนี้:
- สลับ
|
กับ - ปริมาณ
*
ด้วย - การจัดกลุ่มด้วยและ
(
)
- จับคู่ตัวอักษรใด ๆ (อาจจะไม่รวมการขึ้นบรรทัดใหม่)
.
ด้วย - (ตัวเลือก: โบนัส× 80%) จับคู่คลาสตัวละครที่เรียบง่ายและไม่ตรงกับ
[…]
และ[^…]
ตามลำดับ คุณไม่จำเป็นต้องสนับสนุนคลาสอักขระที่กำหนดไว้ล่วงหน้า (เช่น[:digit:]
) แต่คุณควรสนับสนุนช่วงอักขระ - ตัวละครหนีออกมา
\
ด้วย อย่างน้อยก็ควรจะเป็นไปได้ที่จะ esacpe อักขระพิเศษ (เช่น|*().[^-]\
) และโดยเฉพาะอย่างยิ่งตัวละครพิเศษทั่วไปในรสชาติอื่น ๆ (เช่น{}
) แต่พฤติกรรมเมื่อหนีออกมาจากตัวละครที่ไม่ระบุตัวตนไม่ได้ระบุ โดยเฉพาะอย่างยิ่งคุณไม่จำเป็นต้องสนับสนุนลำดับการยกเว้นพิเศษเช่น\n
สำหรับการขึ้นบรรทัดใหม่และรายการที่คล้ายกัน การนำไปใช้ที่เป็นไปได้คือการใช้อักขระ\
ตามตัวอักษร
คุณอาจสมมติว่าตัวอักษรอินพุตที่ไม่สามารถจับคู่กับตัวอักษรใด ๆ ได้ (เช่นสามารถจับคู่โดย.
และคลาสอักขระที่ถูกทำให้เป็นโมฆะ)
กฎเพิ่มเติม
- คุณสามารถใช้ไลบรารี regex หรือฟังก์ชัน builtin regex เพื่อจุดประสงค์ในการจับคู่และแทนที่สตริงเท่านั้น
- คุณอาจเพิกเฉยต่อปัญหาที่เกี่ยวข้องกับสถานที่เช่นกฎการจัดเรียง
- เพื่อระบุชัดเจน: โปรแกรมของคุณจะต้องยุติ ควรดำเนินการในระยะเวลาที่สมเหตุสมผลโดยมีรูปแบบทั่วไป (แน่นอนไม่เกินหนึ่งชั่วโมงโดยเฉพาะน้อยกว่ามาก)
เกณฑ์การให้คะแนน
นี่คือรหัสกอล์ฟ คะแนนของคุณเป็นผลิตภัณฑ์ของรหัสขนาดในไบต์และใด ๆ ของโบนัส ต่ำสุดคะแนนชนะ
กรณีทดสอบ
รูปแบบของกรณีทดสอบมีดังนี้:
<Test ID>
<Pattern A>
<Ordering>
<Pattern B>
<Test ID>
<Pattern A>
<Ordering>
<Pattern B>
...
<Test ID>
ตัวบ่งชี้สำหรับกรณีทดสอบอยู่ที่ไหน<Pattern A>
และ<Pattern B>
เป็นรูปแบบ regex และ<Ordering>
เป็นการเรียงลำดับระหว่างกันและเป็นหนึ่งใน:
<
: มีความเชี่ยวชาญมากกว่า<Pattern A>
<Pattern B>
>
: มีความเชี่ยวชาญมากกว่า<Pattern B>
<Pattern A>
=
: รูปแบบเทียบเท่า|
: รูปแบบที่เปรียบมิได้และแยกจากกันX
: รูปแบบไม่มีที่เปรียบและตัดกัน
ค่าพิเศษ<empty pattern>
หมายถึงรูปแบบที่ว่างเปล่า
A. รูปแบบพื้นฐาน
B. รูปแบบที่ซับซ้อน
C. รูปแบบพื้นฐานพร้อมคลาสอักขระ
D. ลวดลายที่ซับซ้อนพร้อมคลาสของตัวละคร
โปรแกรมทดสอบ
ตัวอย่างต่อไปนี้สามารถใช้ในการเปรียบเทียบรูปแบบ 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>