Regex Golf: ภูมิภาคของอิตาลีเทียบกับสหรัฐอเมริกา


23

เราพบปัญหาเกี่ยวกับmeta-regex-golfซึ่งได้รับแรงบันดาลใจจากการ์ตูน xkcd

ลิขสิทธิ์ 2013 Randall Munroe

แต่สนามกอล์ฟ Regex นี้ก็ดูสนุกเช่นกัน! ฉันต้องการแยกความแตกต่างระหว่างรัฐของสหรัฐอเมริกาและภูมิภาคของอิตาลี ทำไม? ฉันเป็นพลเมืองของทั้งสองประเทศและฉันมักจะมีปัญหากับเรื่องนี้*

ภูมิภาคของประเทศอิตาลีนั้น

Abruzzo, Valle d'Aosta, Puglia, Basilicata, Calabria, Campania, Emilia-Romagna, Friuli-Venezia Giulia, Lazio, Liguria, Lombardia, Marche, Molise, Piemonte, Sardegna, Sicilia, Trentino-Alto Adige/Südtirol, Toscana, Umbria, Veneto

และสหรัฐอเมริกาเป็น

Alabama, Alaska, Arizona, Arkansas, California, Colorado, Connecticut, Delaware, Florida, Georgia, Hawaii, Idaho, Illinois, Indiana, Iowa, Kansas, Kentucky, Louisiana, Maine, Maryland, Massachusetts, Michigan, Minnesota, Mississippi, Missouri, Montana, Nebraska, Nevada, New Hampshire, New Jersey, New Mexico, New York, North Carolina, North Dakota, Ohio, Oklahoma, Oregon, Pennsylvania, Rhode Island, South Carolina, South Dakota, Tennessee, Texas, Utah, Vermont, Virginia, Washington, West Virginia, Wisconsin, Wyoming

งานของคุณคือการเขียนโปรแกรมที่แยกรายการเหล่านี้ด้วยนิพจน์ทั่วไป นี่คือเกมใหม่ดังนั้นนี่คือ

กฎระเบียบ

  • การแยกความแตกต่างระหว่างรายการจะต้องทำด้วยนิพจน์ทั่วไปที่ตรงกันเดียว
  • คะแนนของคุณคือความยาวของนิพจน์ทั่วไปนั้นเล็กกว่าดีกว่า

เพื่อให้ชัดเจน: งานทั้งหมดจะต้องทำโดยการแสดงออกปกติ - ไม่มีการกรองไม่มีการแทนที่ไม่มีอะไร ... แม้ว่าพวกเขาจะทำด้วยการแสดงออกปกติ นั่นคืออินพุตควรถูกส่งโดยตรงไปยังนิพจน์ทั่วไปและสามารถใช้คำตอบแบบไบนารีเท่านั้น (จับคู่ / ไม่ตรงกัน) ในส่วนต่อมาของรหัส อินพุตไม่ควรถูกตรวจสอบหรือเปลี่ยนแปลงโดยสิ่งใดนอกจากนิพจน์ที่ตรงกัน ข้อยกเว้น : การกินอาหารขึ้นบรรทัดใหม่ด้วยบางสิ่งที่คล้ายกับรูบี้chompก็ดี

โปรแกรมของคุณควรมีรายการเดียว (ตามด้วยตัวเลือก\nหรือEOFถ้าทำให้ง่ายขึ้น) จากรายการใดรายการหนึ่งจาก stdin และพิมพ์เพื่อ stdout ชื่อของรายการนั้น ในกรณีนี้รายการของเรามีการตั้งชื่อและItalyUSA

ในการทดสอบรหัสของคุณเพียงแค่เรียกใช้ทั้งสองรายการ พฤติกรรมอาจไม่ได้กำหนดสำหรับสตริงที่ไม่ได้เกิดขึ้นในรายการ

เกณฑ์การให้คะแนน

สิ่งนี้อาจจะต้องทำในแต่ละภาษา ในภาษา Perl

m/foobarbaz/

เป็นนิพจน์ทั่วไปที่ตรงกัน อย่างไรก็ตามใน Python

import re
re.compile('foobarbaz')

ทำสิ่งเดียวกัน เราจะไม่นับคำพูดของ Python ดังนั้นฉันบอกว่าเราไม่นับm/และสุดท้าย/ใน Perl ในทั้งสองภาษาข้างต้นควรได้รับคะแนน 9

เพื่อชี้แจงจุดที่ยกขึ้นโดยอภิสิทธิ์ความยาวที่แท้จริงของนิพจน์การจับคู่คือคะแนนแม้ว่าคุณจะสร้างมันแบบไดนามิก ตัวอย่างเช่นถ้าคุณพบว่ามีการแสดงออกที่มีมนต์ขลังm,

n="foo(bar|baz)"
m=n+n

จากนั้นคุณไม่ควรรายงานคะแนน 12: mมีความยาว 24 และเพื่อให้ชัดเจนยิ่งขึ้นนิพจน์ทั่วไปที่สร้างขึ้นไม่สามารถพึ่งพาอินพุตได้ นั่นจะเป็นการอ่านอินพุตก่อนที่จะส่งผ่านไปยังนิพจน์ทั่วไป

ตัวอย่างเซสชัน

input> Calabria
Italy
input> New Hampshire
USA
input> Washington
USA
input> Puglia
Italy

*อันที่จริงมันเป็นเรื่องโกหก ฉันไม่เคยมีปัญหาใด ๆ กับเรื่องนี้เลย


คุณกรุณาอธิบายสิ่งที่คุณหมายถึงโดย "ไม่มีการกรองไม่มีการแทนที่ไม่มีอะไรเลย ... แม้ว่าสิ่งเหล่านั้นจะทำด้วยการแสดงออกปกติ" เพียงเพื่อชี้แจงก็หมายความว่าการกรองการเปลี่ยนรายการของรัฐ / ภูมิภาคหรือการมุ่งเน้นที่กว้างขึ้น?
อภิสิทธิ์

@Abhijit แก้ไขแล้ว ชัดเจนกว่านี้ไหม
บูธโดย

3

1
"พฤติกรรมอาจไม่ได้กำหนดสำหรับสตริงที่ไม่ได้เกิดขึ้นในรายการ" กฎนี้ใช้งานไม่ได้ : อนุญาตให้ส่งคืนUSAในกรณีที่มีสตริงดังกล่าวดังนั้นคุณจะต้องตรวจสอบภูมิภาคอิตาลีและกลับมาเป็นUSAอย่างอื่น
o0 '

1
@boothby ดีไม่มีมันเป็นตรรกะที่เรียบง่าย: มันเป็นพื้นถามเพียง regexp เพื่อให้ตรงกับภูมิภาคอิตาลี แต่คำพูดโดยไม่จำเป็นในวิธีที่ซับซ้อนมาก ทั้งประเด็นเกี่ยวกับรัฐอเมริกันทั้งหมดไม่เกี่ยวข้องกับคำถามที่เกิดขึ้นจริงขอขอบคุณข้อผิดพลาดนี้ สิ่งนี้ทำให้คำถามน่าสนใจน้อยลง
o0 '

คำตอบ:


10

Perl - 51 36 ไบต์ (สำหรับ regex)

print<>=~/.A|ise|net|te|z.o|[cp]a|[lr]ia|r[cd]/?"Italy
":"USA
"

ไม่มีอะไรพิเศษ แต่อาจโพสต์ได้ดีเพราะมันแตกต่างจากโซลูชัน 51 ไบต์อื่น ๆ

หรืออีกทางหนึ่งสั้นลงโซลูชันที่มีอยู่ของฉันสั้นลง 15 ไบต์ ฉันคิดว่าตอนนี้ฉันชนะ


7

Perl, 40 ตัวอักษร

เมื่อเข้าใกล้สิ่งนี้จากอีกทางหนึ่งกล่าวคือจับคู่กับสหรัฐฯ:

[DNIOWy]|ss|M.n|^A.*a|or|[aguh]i|[sth]\b

คุณลักษณะเฉพาะของ Perl / PCRE เฉพาะใน regexp คือ\bword boundary anchor ซึ่งฉันใช้แทน$anchor end-of-string เพื่อให้ตรงกับ "South Carolina"

นี่คือ regexp ใน Perl one-liner สำหรับการทดสอบ:

perl -nE 'say /[DNIOWy]|ss|M.n|^A.*a|or|[aguh]i|[sth]\b/ ? "USA" : "Italy"'

นี่คือชุดทดสอบการทดสอบแบบกอล์ฟที่มากขึ้น: perl -pe '$ _ = / re /? "USA \ n": "Italy \ n"'
นามแฝง

3
@ นามแฝง: meh ตราบใดที่มันไม่ได้นับคะแนนก็สามารถอ่านได้
Ilmari Karonen

5

ทับทิม (regex ธรรมดา), 44

$_ = gets.chomp
puts /'|-|(([^gn]i|gn|at)a|[hst]e|to|zo)$|To|La|pa/ ? "Italy" : "USA"

คุณรู้อะไรไหม? การพิจารณาตัวพิมพ์เล็กและตัวพิมพ์ใหญ่เป็นจุดยึดคำเริ่มต้นที่ดีที่สุด

ผมไม่แน่ใจ แต่ผมคิดว่าผมเป็นหนี้paเพื่อตอบ Hax0r778 ของ



3

JavaScript 42

alert(/at|gn|mp|sc|-|'|((zi?|t)o|[hts]e|[lrd]ia)$/g.test(prompt())?"Italy":"USA")

ตอนแรกฉันจะทำงานนี้ออกมาจากฝั่งอเมริกาเนื่องจากการกำจัด KWXY จากรายชื่อ USA ทำให้หลายรัฐอยู่ห่าง ...

หากเราไปพร้อมกับเครื่องหมายลูกศรไขมันเราสามารถลดสิ่งนี้เป็นฟังก์ชั่นที่เรียบง่ายพร้อมกับตัวแปรส่งคืน

r=s=>/at|gn|mp|sc|-|'|((zi?|t)o|[hts]e|[lrd]ia)$/g.test(s)?"Italy":"USA"

> r("South Dakota") // USA
> r("Puglia") // Italy
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.