พยางค์คำภาษาอังกฤษ - ชนิดของ


11

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

คุณมีสองทางเลือก:

  • เขียนโปรแกรมที่รับสตริงจาก STDIN และส่งผลลัพธ์ไปยัง STDOUT
  • เขียนฟังก์ชั่นที่รับสตริงเป็นพารามิเตอร์เดียวและส่งคืนผลลัพธ์

สเปค

  • ในกรณีนี้สตริงหมายถึงโครงสร้างเหมือนสตริงใด ๆ ในภาษาที่คุณเลือก (อาร์เรย์ไบต์, อาร์เรย์อักขระ, สตริง ... )
  • สระนั้น a, e, i, o, u
  • สตริงที่ให้ไว้มี1 <= n <= 10คำโดยที่แต่ละตัวมีความยาวระหว่าง1 - 30อักขระ, รวม .. ผลลัพธ์ของคุณควรเป็นคำที่ใส่ยัติภังค์
  • ตัวอักษรทั้งหมดเป็นตัวพิมพ์เล็กและคำคั่นด้วยช่องว่างเสมอ ดังนั้นอินพุตประกอบด้วยอักขระ[a-z ]
  • ใช้กฎตามลำดับความสำคัญ
  • เมื่อแบ่งคำแล้วให้เริ่มอีกครั้งทางด้านขวาของคำ

กฎสำหรับการเรียงพยางค์ตามลำดับความสำคัญ

สองสระเดียวกันติดต่อกันนับเป็นหนึ่ง (เช่น. feetมีเพียงหนึ่งสระ แต่beatและfindingมีสอง) ทุกพยางค์มีสระหนึ่งเสียงดังนั้นจึงมีหนึ่งพยางค์สำหรับสระแต่ละตัว

  1. หากทั้งคำมีเพียงสี่ตัวอักษรให้คืนมันไม่เปลี่ยนแปลง (ข้ามสิ่งนี้ไปยังคำอื่น ๆ )
  2. หากคำนั้นมีเพียงเสียงสระเดียวให้ส่งคืนคำที่ไม่เปลี่ยนแปลง
  3. หากคำนั้นมีสองเสียงติดต่อกันให้แบ่งระหว่างเสียงนั้น (เช่น. diaspora-> di-as-po-ra)
  4. เมื่อพยัญชนะสองตัวขึ้นไปอยู่ระหว่างสระสองตัว (เหมือนกันหรือต่างกัน) ให้หารตามพยัญชนะตัวแรก (เช่นsis-ter) เว้นแต่ว่าส่วนพยัญชนะคือckซึ่งในกรณีนี้จะแบ่งคำหลังจากนั้น (เช่น. nickel-> nick-el)
  5. เมื่อyเสียงสระมาระหว่างเสียงสระสองตัวให้แบ่งคำหลังคำนั้น (เช่นpaying-> pay-ing)
  6. เมื่อพยัญชนะตัวหนึ่งอยู่ระหว่างสระสองสระ (เหมือนหรือต่างกัน) ให้หารหน้าพยัญชนะ (เช่นdra-gon)
  7. ส่งคืนคำที่ไม่เปลี่ยนแปลงถ้าไม่สามารถแบ่งได้

ฉันเลือกกฎเหล่านี้เพราะสามารถนำไปใช้ซ้ำได้โดยไม่มีปัญหาและไม่ต้องใช้ตารางการออกเสียง ดังนั้นจึงไม่ถูกต้องและตัวอย่างเช่นกฎ # 5 มักไม่ถูกต้อง โดยทั่วไปแล้วมันเป็น

ตัวอย่าง

In:  hello world
Out: hel-lo world

In:  have a nice day
Out: have a nice day

In:  pour some nickel and xenon there
Out: pour some nick-el and xe-non the-re

คุณแน่ใจx-e-nonเหรอ การอ้างอิงสำหรับกฎ # 4?
John Dvorak

@JanDvorak "เมื่อคำถูกแบ่งออกให้เริ่มอีกครั้งด้วยครึ่งทางด้านขวาของคำ" ตามด้วยกฎ # 6
seequ

ฉันหมายความว่าไม่ควรแยก # 4 ระหว่างพยางค์เท่านั้น?
John Dvorak

1
กฎ # 1 เกี่ยวข้องกับคำสี่ตัวอักษร แล้วคำที่มีตัวอักษรน้อยกว่าสี่ตัวล่ะ? เช่นlua
บาดเจ็บทางดิจิตอล

1
@DigitalTrauma พวกเขาได้รับเกียรติตามปกติ แต่ไม่ค่อยมีสองพยางค์
seequ

คำตอบ:


6

Ruby, 144 ไบต์

หากเราไม่สามารถกำจัดได้แล้ว regex ยักษ์ตัวเดียวล่ะ?

puts gets.split.map {|w| w.scan(/(^.{4}$|[^aeiou]*([aeiou])\2?((?=[^aeiouy]?[aeiou])|ck|[^aeiou]((?=.*[aeiou])|.*$)|$))/).map(&:first)*'-'}*' '

เอาท์พุทบางส่วน:

echo "hello world" | ruby syllable.rb
hel-lo world

echo "have a nice day" | ruby syllable.rb
have a nice day

echo "pour some nickel and xenon in there" | ruby syllable.rb
pour some nick-el and xe-non in the-re

echo "diaspora dragon paying sister hemlock happy quicksilver" | ruby syllable.rb
di-as-po-ra dra-gon pay-ing sis-ter hem-lock happy qu-ick-sil-ver

8

ลัวะ 292

Lua อาจไม่ใช่ภาษาที่ดีที่สุดในการทำสิ่งนี้ แต่ใช้งานได้ มันไหลลื่นเหมือนคำถามที่ถาม กฎส่วนใหญ่เป็นไปตามการเพิ่มประสิทธิภาพบางอย่าง: # 2 ถูกข้ามไป (ไม่จำเป็นเว้นแต่จะมีคำเสียงสระเดียวที่มี "ck" ในตอนเริ่มต้น) และกฎ ck และ y จะผ่านไปก่อนส่วนที่เหลือของ # 4 และ # 6 ซึ่งรวมกัน เนื่องจากเสียงสระบางคำในคำต้องถูกจับสองครั้ง (หลังจากหนึ่งยัติภังค์และอีกอันก่อน) การค้นหานั้นจึงถูกดำเนินการสองครั้ง

i=io.read()v="([aeiou])"for s in i:gfind("%l+ ?")do
if s:len()~=4 then
s=s:gsub(v..v,function(x,y)if x==y then return x..y;end;return x.."-"..y;end)s=s:gsub("ck"..v,"ck-%1")s=s:gsub(v.."y"..v,"%1y-%2")for b=1,2 do
s=s:gsub(v.."([^aeiou\-]?)([^aeiou\-]+)"..v,"%1%2-%3%4")end
end
io.write(s)end

Ungolfed

function checkEquals(x,y)
    if x==y then 
        return x..y
    end
    return x.."-"..y
end
i=io.read()
v="([aeiou])"
for s in i:gfind("%l+ ?") do
    if s:len()~=4 then
        s=s:gsub(v..v,checkEquals)
        s=s:gsub("ck"..v,"ck-%1")
        s=s:gsub(v.."y"..v,"%1y-%2")
        for b=1,2 do
            s=s:gsub(v.."([^aeiou\-]?)([^aeiou\-]+)"..v,"%1%2-%3%4")
        end
    end
    io.write(s)
end

ทดสอบที่นี่: http://ideone.com/g57TzA


ฉันไม่มีทับทิม แต่ก็ดูเหมือนดี
seequ

4

Bash + coreultils, 173 ไบต์

ฉันคิดว่าฉันมีการเปลี่ยนแปลงกฎล่าสุดทั้งหมด:

v=aeiou
r="[$v])/\1-\2/g"
s=s/\([$v]
e="$s[^$v-])([^$v-]+$r
"
tr \  \\n|sed -r "/^([a-z]{4}|[^$v]*[$v][^$v]*)$/bx
$s)($r
${s}ck)($r
$e$e${s}y)($r
$s)([^$v-]$r
:x"|tr \\n \ 

โปรดสังเกตว่าอักขระตัวสุดท้ายของบรรทัดสุดท้ายคือ(เว้นวรรค)

ฉันคิดว่าสิ่งนี้เพียงพอที่จะตอบสนอง"ไม่สามารถอ่านได้และไม่สามารถทำลาย" ;-)

รับอินพุตจาก STDIN

การทดแทน regex ส่วนใหญ่ตรง บรรทัดแรกของsedนิพจน์นั้นตรงกับกฎ 1 และ 2 จากนั้นก็ข้ามไปที่:xป้ายกำกับที่ส่วนท้ายของนิพจน์

trs ที่เริ่มต้นและจุดสิ้นสุดของท่อให้คำขึ้นบรรทัดใหม่แยกออกจากกันดังนั้นพวกเขาจะง่ายขึ้นสำหรับsedการจัดการกับ ฉันหวังว่าจะทำและsedตอบทั้งหมดแต่วิธีนี้ง่ายกว่าและง่ายกว่า

ตัวอย่าง:

$ ./sylabify.sh <<< "diaspora nickel sister dragon hello world have a nice day pour some nickel and xenon there paying tricks quicksilver"
di-as-po-ra nick-el sis-ter dra-gon hel-lo world have a nice day pour some nick-el and xe-non the-re pay-ing tricks qu-ic-ksil-ver $ 

โอ๊ะฉันลืมกฎ # 3 ไปแล้ว ทุกอย่างปกติดี.
seequ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.