พูดตัวเลขตั้งแต่ 0 ถึง 9


15

แรงบันดาลใจจากคำถามนี้จากอุปกรณ์อิเล็กทรอนิกส์ SEนี่คือความท้าทายสำหรับคุณ:

เขียนโปรแกรมหรือรูทีนย่อยที่ใช้ตัวเลขทศนิยม (0 ถึง 9) และพูดออกเสียงโดยไม่ต้องใช้เครื่องมือสังเคราะห์เสียงพูดที่มีอยู่

การป้อนข้อมูล:

คุณอาจขอให้ใส่ตัวเลขในรูปแบบที่สมเหตุสมผลเช่นสตริงของ ASCII, อาร์เรย์ของจำนวนเต็ม, ตัวเลขเข้ารหัส BCD เป็นต้นหากวิธีการแก้ปัญหาของคุณเป็นโปรแกรมที่ปฏิบัติการได้คุณอาจใช้อินพุตเป็น พารามิเตอร์บรรทัดคำสั่งอ่านจากอินพุตมาตรฐานหรือรับในลักษณะที่สมเหตุสมผลอื่น ๆ

โปรแกรมของคุณจะต้องสามารถพูดได้อย่างน้อยแปดหลักต่อการร้องขอ คุณอาจสันนิษฐานว่าตัวเลขตัวแรกไม่ใช่ศูนย์เว้นแต่เป็นตัวเลขหลักเดียว

เอาท์พุท:

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

คุณมีอิสระในการตัดสินใจรายละเอียดเกี่ยวกับวิธีการพูดตัวเลข แต่ผลลัพธ์ของคุณควรประกอบด้วยตัวเลขภาษาอังกฤษที่พูดในลักษณะที่เข้าใจได้โดยผู้พูดภาษาอังกฤษทั่วไปและควรชัดเจนพอที่ผู้ฟังจะสามารถถอดความได้อย่างถูกต้อง ตัวเลขสุ่มแปดหลักที่พูด ไม่เพียง beeping nครั้งไม่นับ อย่าลืมที่จะรวมการหยุดระหว่างตัวเลข

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

ใช้กฎการให้คะแนนแบบมาตรฐาน: คะแนนของคุณคือความยาวของรหัสเป็นไบต์หรือหากรหัสของคุณเขียนด้วยข้อความ Unicode ในหน่วย Unicode คะแนนต่ำสุดชนะ ภาษาใดก็ได้

ตามคำถามเดิมเกี่ยวกับอุปกรณ์อิเล็กทรอนิกส์ SE เป็นเรื่องเกี่ยวกับการเขียนโปรแกรมแบบฝังตัวฉันรู้สึกว่าควรโยนกระดูกให้ผู้เขียนโดยใช้ภาษาระดับต่ำ: หากโซลูชันของคุณเขียนด้วยภาษาที่รวบรวมคุณอาจเลือกที่จะนับความยาวของไฟล์ปฏิบัติการที่คอมไพล์ในหน่วยไบต์เป็นคะแนนของคุณ (ใช่ไบต์.classที่คอมไพล์แล้วล่วงหน้าเช่นไฟล์Java ก็ใช้ได้เช่นกัน) หากคุณเลือกที่จะใช้ประโยชน์จากตัวเลือกนี้โปรดรวมสำเนาของไฟล์ที่ประมวลผลได้ในคำตอบของคุณ (เช่นฐานสิบหก) พร้อมกับซอร์สโค้ดของคุณ และเวอร์ชันคอมไพเลอร์และตัวเลือกที่คุณใช้ในการสร้าง

การกล่าวถึงอย่างมีเกียรติพร้อมด้วยค่าหัว +50 ตัวแทนจะได้รับคำตอบแรกที่ตรงตามเกณฑ์ของคำถามเดิมกล่าวคือสามารถทำงานบน MCU แบบฝังที่มีแฟลชขนาด 4 kb และ SRAM 1 kb

ข้อ จำกัด:

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

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


ps ฉันอาจโพสต์วิธีแก้ปัญหาด้วยตัวเองในภายหลังถ้าฉันจัดการเพื่อให้มันสร้างสิ่งที่ฟังดูเข้าใจได้จริง อย่าอายที่โพสต์ของคุณเอง; ณ จุดนี้คำตอบใด ๆคือคำตอบที่ดี
Ilmari Karonen

1
เราได้รับอนุญาตให้ดาวน์โหลดฐานข้อมูลตัวเลขพูด (และนับขนาดต่อคะแนน) หรือเราต้องบันทึกเสียงของเราเองหรือไม่? ฉันสงสัยว่าฉันสามารถสร้างอัลกอริทึมการพูดตัวอย่าง
John Dvorak

อืมม ... ส่วน "เอาท์พุท" ไม่ได้ระบุว่าเราจะต้องส่งออกตัวอย่างเสียงพูด เราอนุญาตให้ส่งเสียงบี๊บสิบครั้งหรือไม่
John Dvorak

@PeterTaylor: ถ้าคุณนับขนาดของพวกเขาเป็นส่วนหนึ่งของคะแนนของคุณมันก็โอเค ฉันแค่กังวลว่าอาจมีบางระบบที่มีตัวอย่างเสียงของตัวเลขฝังอยู่ที่ไหนสักแห่งในสภาพแวดล้อมรันไทม์มาตรฐาน
Ilmari Karonen

3
เนื่องจากดูเหมือนว่ามีคนจำนวนมากที่ไม่ได้อ่านคำถามไปจนถึงตอนท้ายและโพสต์ข้อความที่น่าสนใจรอบ ๆ ห้องสมุดเฮฟวี่เวท
ปีเตอร์เทย์เลอร์

คำตอบ:


10

ruby - 3710 = รหัส 90 ตัวอักษร + ข้อมูล 3620 ไบต์

require'zlib'
$><<$*[0].chars.map{|x|Zlib::Inflate.inflate File.open(x).read}.join(?0*5e3)

input: อาร์กิวเมนต์บรรทัดคำสั่งเดียวจำนวนที่จะอ่าน

เอาต์พุต: ข้อมูลเสียงดิบ, PCM 8 บิต / 8kHz

สิ่งนี้สามารถอ่านสตริงอินพุตใด ๆ ได้ตราบใดที่

  • ประกอบด้วยอักขระที่เป็นชื่อไฟล์ที่ถูกต้องเท่านั้น สำหรับสี่ตัวอักษรเท่านั้นคุณสามารถขยายที่ตั้งค่าเป็นอักขระทั้งหมด
  • คุณมีไฟล์ที่จำเป็น
  • ทำไมคุณเว้นวรรคคุณดีโอ้อะพอสโทรฟีทีสเปซ em em en en space ดีทีระยะเวลา

5e3เข้ารหัสการหยุดชั่วคราวระหว่างสองคำ ที่นี่ 5 ตัวอย่าง ~ = 0.6 วินาที ปรับแต่งตามต้องการ

ตอนนี้ส่วนที่ยุ่งยากคือการรับไฟล์ตัวอย่างเป็น 4K และยังสามารถแตกไฟล์ได้อย่างง่ายดายและมีคุณภาพเพียงพอ นี่คือวิธีที่ฉันได้รับ:

  • ใช้เครื่องมือแปลงข้อความเป็นคำพูดที่สามารถสร้างไฟล์เสียงได้ Wikipedia มีหนึ่งรายการ
  • ป้อนข้อความที่มีตัวเลขทั้งหมดอยู่ใกล้กัน ฉันใช้http://en.wikipedia.org/wiki/Base_13
  • downsample
  • ตัดออกจากแต่ละส่วนร่วมในการแก้ไขเสียง
  • บันทึกเป็นไฟล์ดิบ
  • กำจัดแต่ละตัวอย่าง (ทิ้งบิตลำดับต่ำ)
  • ยุบ

ตอนนี้เราต้องเลือกอัตราตัวอย่างและจำนวนการทำลายล้าง มากเกินไปและเสียงจะไม่สามารถเข้าใจได้ น้อยเกินไปและคุณไม่พอดี ฉันได้ตัดสินที่ 8kHz / 3b มี: https://github.com/honnza/drops/raw/master/digits.zip

  • 8KHz * 4b / ตัวอย่างและคุณภาพสูงกว่า - ใหญ่เกินไป
  • 8KHz * 3b / ตัวอย่าง - คุณภาพต่ำ แต่เหมาะกับ 4K
  • 8KHz * 2b / ตัวอย่าง - kch kchhhhhhhhh [ไม่เข้าใจ]
  • 2KHz * 8b / ตัวอย่าง - ใหญ่เกินไป
  • 2KHz * 3b / ตัวอย่าง - kch kchhhhhhhhh
  • 1KHz * 8b / ตัวอย่าง - kch kchhhhhhhhh

นี่คือสคริปต์การทำลายล้าง:

require'zlib'
Dir.glob "*.raw" do |fname|
  File.open fname[/\d/], "wb" do |out|
    File.open fname do |input|
      bytes = input.bytes.to_a
      bytes.map! {|x|x&0xE0}
      dfl = Zlib::Deflate.deflate(bytes.pack("C*"),9)
      dfl.each_byte do |byte|
        out.print byte.chr
      end
      puts "done #{fname}: #{dfl.size}"
    end
  end
end

สำหรับความท้าทายเริ่มต้น: มีพื้นที่ 476 ไบต์สำหรับโค้ดและตารางไฟล์ สิ่งนี้อาจมากเกินไปเล็กน้อยขึ้นอยู่กับว่าเราจะได้รับห้องสมุด DEFLATE ขนาดเล็กเพียงใด หากจำเป็นเราสามารถตัดมุมบางส่วนที่นี่และโดยการตัดตัวอย่างเสียงให้ละเอียดขึ้นเล็กน้อย [fo:r]หรือ[o:]ไม่สำคัญจริงๆ แต่จะช่วยประหยัดไบต์ ฉันค่อนข้างใจดีเมื่อตัดตัวเลข นอกจากนี้รูปแบบการทำลายล้างที่แตกต่างกันหรือการเสียสละการทำลายล้างสำหรับการสุ่มตัวอย่างบางอย่างอาจช่วยได้ - ฉันจะเล่นกับสิ่งเหล่านี้ในภายหลัง นอกจากนี้การปล่อยส่วนหัว DEFLATE อาจช่วยประหยัดพื้นที่ได้เล็กน้อย

การต่อตัวอย่างเสียงนั้นง่ายมาก แต่ 4K นั้นค่อนข้างแคบ หากคุณไม่ได้ถูกผูกมัดด้วยพื้นที่ 4k ฉันขอแนะนำการทำลายล้างน้อยกว่า 4 บิตต่อตัวอย่างอัตราค่าโดยสารค่อนข้างดีและค่อนข้างใหญ่เพียงเล็กน้อยเท่านั้น


+1 ไม่เลว ความชัดเจนนั้นค่อนข้างน้อย: ฉันพยายามถ่ายทอดตัวเลขสุ่มสองสามตัวและได้รับอัตราความสำเร็จประมาณ 70% (ฉันหวังว่าจะมีบางสิ่งที่ใกล้ถึง 99%) ฉันยังคงอยู่เล็กน้อยในรั้วเกี่ยวกับสิ่งที่กล่าวถึงเกียรติ: ในขณะที่คุณทำข้อโต้แย้งที่ดีว่า 4K สามารถทำได้ด้วยวิธีนี้คุณไม่ได้แสดงให้เห็นจริงมัน แม้ว่าคุณจะทิ้งทับทิมสำหรับ C (ซึ่งดูเหมือนว่าพอง่ายที่จะทำผมต้องการจะยินดีที่จะมีส่วนที่เกี่ยวกับความเชื่อ) คุณสามารถจริงๆพอดีกับตัวถอดรหัสยุบในแฟลชพื้นที่ที่เหลืออยู่? บวกกับที่ฉันสังเกตคุณภาพเสียงค่อนข้างแย่
Ilmari Karonen

ps เคล็ดลับเล็ก ๆ น้อย ๆ เกี่ยวกับการบีบอัดที่ดีกว่า: คุณสามารถบีบอัดตัวอย่างทั้งหมดให้มีความยาวคงที่ด้วยไบต์ว่าง (ซึ่งควรบีบอัดได้ดี) และต่อเชื่อมเป็นไฟล์บีบอัดไฟล์เดียวจากนั้นคลายและบีบอัด นอกจากนี้เคล็ดลับ KZIP จากคำตอบนี้จะช่วยให้คุณบีบอัดข้อมูลได้ดีขึ้น สุดท้ายลองแก้ไขไฟล์เสียงที่รวมกันเพื่อแทนที่หน่วยเสียงที่เหมือนกันด้วยสำเนาที่แน่นอน
Ilmari Karonen

ตัวอย่างเสียงต้นฉบับนั้นไม่เข้าใจอย่างแน่นอนทั้ง IMO - การสุ่มตัวอย่างทำให้เกิดความเสียหายเล็กน้อย ห้องสมุด DEFLATE ที่เล็กที่สุดที่ฉันรู้จัก - ห้องสมุดแรกที่เชื่อมโยงโดย wikipeda - มีน้ำหนักประมาณ 500b คุณต้องการให้ฉันส่งพอร์ตไปยังอุปกรณ์เฉพาะนั้นหรือไม่ ฉันอาจไปถึงแล้ว แต่ฉันไม่เคยเขียนรหัสให้ ARM มาก่อน
John Dvorak

ฉันค่อนข้างประหลาดใจเกี่ยวกับอัตราความสำเร็จ 70% - ฉันพบว่าตัวเลขเข้าใจง่าย ตัวเลขใดที่คุณสับสนมากที่สุด
John Dvorak

แจงไปยัง Cortex M0 อาจเป็นบิตมากเกินไปที่จะขอ ( แต่ถ้าคุณสามารถทำเช่นนั้นที่ต้องการจะน่ากลัว!) แต่ฉันไม่คิดว่าไบนารีแบบสแตนด์อะโลน (+ ไฟล์ข้อมูลถ้ามี) ที่เหมาะสมภายใต้ 4k ดูเหมือนจะเป็นการสาธิตที่สมเหตุสมผล (ไม่จำเป็นต้องลิงก์แบบคงที่ใน libc สำหรับไฟล์ I / O เนื่องจากคุณไม่จำเป็นต้องใช้อุปกรณ์ดังกล่าว แต่ควรนับรหัส DEFLATE) โดยทั่วไปสิ่งที่คุณสามารถโพสต์เป็นคำตอบสำหรับคำถามเดิม ในอุปกรณ์อิเล็กทรอนิกส์ SE และพูดอย่างมั่นใจ "ถ้าคุณคอมไพล์ไฟล์นี้ในอุปกรณ์ของคุณฉันเดิมพันได้พอดี"
Ilmari Karonen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.