รหัสมอร์สไปยังเอาต์พุตมาตรฐาน


13

คำถามนี้เกี่ยวข้องกับการป้อนข้อมูลในรหัสมอร์สเป็น (จุด) และ - (เครื่องหมายลบ) พร้อมช่องว่างเพื่อแยกอินพุต งานของคุณคือการแปลงรหัสเป็นเอาต์พุตมาตรฐาน คุณสามารถสรุปได้ว่าการป้อนข้อมูลที่มีเพียงสัญลักษณ์ตัวอักษรที่พบในตัวอักษรนานาชาติรหัสมอร์สพบที่นี่: http://en.wikipedia.org/wiki/Morse_code#Letters.2C_numbers.2C_punctuation

เอาต์พุตทั้งหมดควรใช้อักษรตัวพิมพ์เล็ก ควรตีความพื้นที่สองเท่าเป็นคำเว้นวรรค

ตัวอย่างอินพุต:

. -..- .- -- .--. .-.. . .-.-.-  ... --- ...

เอาท์พุท:

example. sos

รหัสที่สั้นที่สุดหลังจากชนะสองสัปดาห์


คุณบอกว่า 'สัญลักษณ์สัญลักษณ์' เท่านั้นคืออักขระและสัญลักษณ์ดังกล่าวใช่ไหม
Sinkingpoint

@Quirliom "สัญลักษณ์" ทั้งหมดในลิงค์นั้นเป็นตัวละคร สิ่งที่คุณสามารถใส่ในสตริงเป็นตัวละคร (โดยทั่วไป) อย่างไรก็ตามส่วนหนึ่งของคำถามนั้นโดยทั่วไปแล้วบอกว่ามอร์สทุกบิตจะใช้ได้จริง
Justin

@Quirliom ใช่ตัวละครทุกตัวของมอร์สเช่น .- สำหรับ 'a' และ สำหรับ 'e' นั้นถูกต้อง ไม่ต้องจัดการกับอักขระที่ไม่ใช่มอร์ส

สิ่งที่เกี่ยวกับพื้นที่ตัวอักษรและพื้นที่คำ? พื้นที่หนึ่งสำหรับอดีตและสอง (หรือมากกว่า) สำหรับหลัง?
Paul R

มีการเชื่อมโยงเล็กน้อย (ยกเลิก): stackoverflow.com/questions/1352587/code-golf-morse-code
javatarz

คำตอบ:


8

Mathematica 62

Mathematicaช่วยให้เราโกง

f=ToLowerCase@StringDrop[WolframAlpha[". .- "<>#,"Result"],2]&

f@"."
f@". -..- .- -- .--. .-.. . .-.-.-"
f@".... .- ...- .  -.-- --- ..-  -- --- --- . -..  - --- -.. .- -.-- ..--.."

อี

ตัวอย่าง.

วันนี้คุณ mooed

สองสัญลักษณ์แรก.และ.-จำเป็นต้องตีความรหัสขนาดเล็กอย่างถูกต้อง


กรณีนี้ไม่มีการแปลงเป็นตัวพิมพ์เล็ก
ปีเตอร์เทย์เลอร์

@PeterTaylor มันสามารถแก้ไขได้ง่าย f=ToLowerCase@StringDrop[WolframAlpha[". .- "<>#,"Result"],2]&สำหรับกรณีที่ต่ำกว่า
ybeltukov

การใช้ Wolfram Alpha api ไม่ต้องการรหัสแอปพลิเคชันหรือไม่ ถ้าเป็นเช่นนั้นไม่ควรเพิ่มในจำนวนตัวละคร? อย่างไรก็ตามทางออกที่ฉลาดมาก
Björn Lindqvist

@ BjörnLindqvistเพียงแค่ประเมินว่าคำสั่งนี้ในMathematicaนั้นจะใช้งานได้ดี
ybeltukov

23

Drat ฉันหวังว่าจะได้มาที่นี่ก่อนที่ GolfScripters จะมาถึง :-(

Anyhoo ...

C: 228 ตัวอักษร:

char n,t,m[9],*c=" etianmsurwdkgohvf l pjbxcyzq  54 3   2& +    16=/   ( 7   8 90    $       ?_    \"  .    @   '  -        ;! )     ,    :";
main(){while(scanf("%s",m)>0){for(t=m[6]=n=0;m[n];n++)t+=t+1+(m[n]&1);putchar(c[t]);}}

ฉันคิดว่าฉันจะเพิ่มคำอธิบายว่ามันทำงานอย่างไร

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

                     dot <-- (start) --> dash
                e                               t
        i               a               n               m
    s       u       r       w       d       k       g       o
  h   v   f   ·   l   ·   p   j   b   x   c   y   z   q   ·   ·
 5 4 · 3 · · · 2 & · + · · · · 1 6 = / · · · ( · 7 · · · 8 · 9 0
····$·······?_····"··.····@···'··-········;!·)·····,····:·······

เริ่มต้นที่ด้านบนของต้นไม้ทำงานทางลงในขณะที่ย้ายไปทางซ้ายสำหรับจุดและไปทางขวาสำหรับเส้นประ จากนั้นเอาท์พุทอักขระใดก็ตามที่คุณเกิดขึ้นเมื่อสตริงอินพุตสิ้นสุดลง (เช่นเมื่อพบอักขระช่องว่าง) ดังนั้นสำหรับตัวอย่างเช่นสามจุดและเส้นประจะนำคุณไปvผ่านทางe, และi sแทนการตรวจสอบอย่างชัดเจนจุด (ASCII \x2e) และขีดกลาง (ASCII \x2d) เราจะต้องตรวจสอบบิตสุดท้าย ( m[n]&1) ซึ่งเป็น 0 .และ -1

หกแถวเพียงพอที่จะเข้ารหัสทุกอย่างยกเว้น$ซึ่งมี 7 จุด / ขีดกลาง: ...-..-แต่เนื่องจากข้อมูลอินพุตถูกรับรองว่าถูกต้องจึงสามารถแก้ไขได้อย่างง่ายดายโดยตัดทอนอินพุตที่ 6 อักขระ ( m[6]=0) และตีความ...-..เป็น$แทน นอกจากนี้เรายังสามารถตัด 7 ไบต์สุดท้ายออกจากข้อมูลทรีได้เนื่องจากมันว่างเปล่าและไม่จำเป็นถ้าอินพุตถูกต้อง


1
เคล็ดลับดีที่จะละทิ้งอักขระตัวสุดท้ายของรหัส 6 ตัวและย่อตารางการค้นหาให้สั้นลง
Peter Taylor

2
ฉันโหวตมากขึ้นเพื่อความชัดเจนของการอภิปรายเกี่ยวกับคุณภาพของอัลกอริทึม การทำงานที่ดี.
Michael Stern

ดูว่าคุณอาจโกนไม่กี่ตัวอักษรโดยการประมวลผลตัวอักษรโดยตัวอักษรแทนการอ่านสตริงทั้งใน. cอาจจะ inlined บางทีคุณอาจใช้โมดูโล & ออฟเซ็ตเพื่อพยายามหาค่าที่สูงกว่าด้วยกัน นี่คือสิ่งที่ฉันทำในการแก้ปัญหาของฉัน อย่างไรก็ตามงานดี!
FireFly

8

GolfScript ( 116 113 97 ตัวอักษร)

รวมถึงอักขระที่ไม่สามารถพิมพ์ได้ที่ใช้ในตารางการค้นหาดังนั้นฉันจึงให้มันเป็นเอาต์พุต xxd:

0000000: 6e2d 2720 272f 7b60 7b5c 6261 7365 2035
0000010: 3925 2210 a9cd 238d 57aa 8c17 d25c d31b
0000020: 432d 783e 277a 3823 e146 e833 6423 23ac
0000030: e72a 39d5 021c 4e33 3b30 3138 dc51 2044
0000040: 3aa7 d001 df4b 2032 333f 36ae 51c3 223d
0000050: 7d2b 5b35 2d34 5d2f 2b32 3333 257d 256e
0000060: 2b

สิ่งนี้จะถอดรหัสเป็นโปรแกรมที่เทียบเท่า

n-' '/{`{\base 59%"\x10\xA9\xCD#\x8DW\xAA\x8C\x17\xD2\\\xD3\eC-x>'z8#\xE1F\xE83d##\xAC\xE7*9\xD5\x02\x1CN3;018\xDCQ D:\xA7\xD0\x01\xDFK 23?6\xAEQ\xC3"=}+[5-4]/+233%}%n+

ซึ่งเป็นหลัก

n-' '/{`{\base 59%"MAGIC STRING"=}+[5-4]/+233%}%n+

สิ่งนี้ใช้แฮชที่สมบูรณ์แบบ (ไม่น้อยที่สุด) ตามแนวคิดหลักของอัลกอริธึมที่เหมาะสมที่สุดสำหรับการสร้างฟังก์ชันแฮชที่สมบูรณ์แบบน้อยที่สุด เช็กฮาวาสและมัสกี้สกี; 1992 แนวคิดพื้นฐานของพวกเขาคือคุณใช้สองฟังก์ชันแฮชf1และf2พร้อมกับตารางการค้นหาgและแฮชที่สมบูรณ์แบบคือ(g[f1(str)] + g[f2(str)]) % m(ซึ่งmเป็นจำนวนสตริงที่เราต้องการแยกแยะ) gบิตฉลาดเป็นวิธีที่พวกเขาสร้าง พิจารณาค่าทั้งหมดf1(str)และf2(str)สำหรับสตริงที่strน่าสนใจเป็นโหนดในกราฟที่ไม่มีทิศทางและเพิ่มขอบระหว่างf1(str)และf2(str)สำหรับแต่ละสาย พวกเขาต้องการไม่เพียง แต่ที่ขอบแต่ละข้างจะแตกต่างกัน แต่กราฟนั้นมีลักษณะเป็นวง ดังนั้นมันจึงเป็นเพียง DFS เพื่อกำหนดน้ำหนักให้กับโหนด (เช่นเพื่อเติมตารางการค้นหาg) เพื่อให้แต่ละขอบมีผลรวมที่ต้องการ

Czech et al สร้างฟังก์ชั่นแบบสุ่มf1และf2แสดงผ่านตารางการค้นหา แต่ไม่ชัดเจน: ฉันค้นหาแฮชที่เหมาะสมโดยใช้การแปลงฐานแบบง่ายด้วยฐานสองแบบที่แตกต่างกันตั้งแต่ -10 ถึง 9 ฉันยังผ่อนคลายข้อกำหนดแบบวนรอบ ผมไม่ได้ต้องการที่จะกำหนดเงื่อนไขให้เป็นค่าที่ 0-54 แต่รหัส ASCII ที่สอดคล้องกันเพื่อให้มากกว่าการ(g[f1(str)] + g[f2(str)]) % mที่ฉันต้องการสำหรับบางคน(g[f1(str)] + g[f2(str)]) % N N > 'z'แต่นั่นช่วยให้อิสระในการลองที่หลากหลายNและดูว่ามีรายการใดบ้างที่อนุญาตให้ใช้ตารางการค้นหาที่ถูกต้องgไม่ว่าจะมีรอบใด ไม่เหมือนเช็กและอัลฉันไม่สนใจว่าการค้นหาฟังก์ชันแฮชที่สมบูรณ์แบบคือ O (n ^ 4)

กราฟที่สร้างขึ้นโดย-4baseและ5basemod 59คือ:

กราฟแสดงผลโดยจุดที่มีการปรับแต่งเล็กน้อย

ซึ่งค่อนข้างดีนอกเหนือจากส่วนประกอบที่เชื่อมต่อที่ใหญ่ที่สุดซึ่งมีความยาวสามรอบ 1 เราต้องขึ้นไปN=233ก่อนที่เราจะสามารถหาส่วนประกอบgที่สอดคล้องกันได้


การเข้ารหัสที่เป็นไปได้อื่น ๆ สำหรับตารางการค้นหา: การเข้ารหัสที่ต่างกันจะไม่ช่วยได้เนื่องจากไม่มีโครงสร้าง อาจเป็นไปได้ที่จะใช้ประโยชน์จากการไม่ทำซ้ำของค่าโดยการเข้ารหัสเป็นการเปลี่ยนแปลง แต่ช่องว่างจำเป็นต้องจัดการแยกต่างหาก (54 ตัวอักษรเอาท์พุท => 30 ไบต์ของเอนโทรปีบวกกับการถอดรหัสการรันต้องน้อย 15 ไบต์หากเข้ารหัส เป็นการแปลงฐานแบบตรงอาจเป็นไปได้ที่จะปรับปรุงจากผลรวม 92 ไบต์ปัจจุบัน) หรือเราอนุญาตให้ 138 รายการ (เอนโทรปีมากกว่า 98 ไบต์รวมถึงการถอดรหัส)
Peter Taylor

เนื่องจากเป็นรหัสที่ไม่ใช่คำนำหน้าเราจึงไม่สามารถลองใช้การทำงานหนักของ zlib ได้อย่างง่ายดาย
Peter Taylor

4

C, 169 ตัวอักษร

ฉันไม่พบฟังก์ชันแฮชที่ดีกว่านี้ ..

(ฉันโพสต์รหัสไม่รู้จักจบ แต่นับมันย่อให้เล็กลงเพื่อลดเพียงทำ:%s/ //g | %j!ในกลุ่มแล้วใส่ช่องว่างในสตริงตัวอักษรกลับ)

c, v = 1;

main() {
  while (c = getchar(), ~c)
    v = c < 33? putchar(
      "& etianmsurwdkgohvf.l.pjbxcyzq..54.3.;!2).+...,16=/:..(.7.?_8.9o\"...$...@...'..-"[v < 64? (v != 40)*v : v % 51 + 33]
    ), 1 : v * 2 + c % 2;
}

ทดสอบการทำงาน

( morse.inเป็นเพียงตัวอักษรทั้งหมดในมอร์สในบรรทัดแยกต่างหาก):

% clang morse.c && ./a.out </tmp/morse.in
abcdefghijklmnopqrstuvwxyzO123456789.,?'!/()&:;=+-_"$@
% ./a.out <<<'. -..- .- -- .--. .-.. . .-.-.-  ... --- ...'
example. sos

คำอธิบาย

อันนี้ตรงไปตรงมาค่อนข้าง c < 33พบว่าตัวละครที่ช่องว่าง / คั่น ( , \n, EOF, ... ) c % 2แปลจุดหรือเส้นประเป็นบิต ความคิดคือการสร้างตัวเลขที่ไม่ซ้ำกันสำหรับตัวละครแต่ละตัวโดยเพียงตีความเป็นเลขฐานสอง (หลังจากนำหน้าด้วย 1 เพื่อจัดการกับความยาวตัวแปร) (การตีความนี้เป็นv*2 + c%2ส่วนหนึ่ง) จากนั้นฉันได้รับ 137-char LUT ซึ่งฉันบีบอัดด้วยการแปลงค่าผลลัพธ์ (ค่าv < 64? v : v % 51 + 33คงที่ที่พบผ่านการทดลองและข้อผิดพลาดและโดยดูที่การกระจายและพยายามหาช่องว่างขนาดใหญ่) น่าเสียดายที่ฟังก์ชันแฮชนี้มีการชนกันครั้งเดียวซึ่งเป็นสาเหตุที่ฉันต้องทำกรณีพิเศษใน40 → '&'การจับคู่


4

R , 145 ไบต์

แปลจุดเป็น 2 ซึ่งเป็นเส้นประที่ 1 และตีความหมายเลขในส่วนประกอบและรับ mod 89 ซึ่งให้หมายเลขเฉพาะที่เราสามารถใช้ในตารางแฮช การมี 13 (111 ฐาน -3) หมายถึงการเพิ่ม 1 เนื่องจาก ASCII 13 ไม่ทำงานใน TIO

cat(c(letters,0:9,".")[match(strtoi(chartr(".-","12",scan(,"",t=scan(,""))),3)%%89+1,utf8ToInt('DG,)62	5N*EHMAI.%"!4=@'))],sep='')

ลองออนไลน์!

R , 236 ไบต์ (ไม่ใช่การแข่งขัน)

สิ่งนี้จะไม่สามารถแข่งขันได้ แต่มันจะช่วยให้เราแสดงสิ่งที่น่าสนใจใน R: เก็บแผนผังรหัสมอร์สไว้ในโครงสร้างภาษาที่ยกมาmและดึงมันออกมาจากรหัสของจุดและขีดกลางโดยใช้ข้อเท็จจริงที่[[สามารถนำไปใช้ซ้ำ รายการ ยกตัวอย่างเช่นm[[c(2,2,3,2)]]ดึงจุดจุดเส้นประจุดหรือ "f"

m=quote(.(e(i(s(h(5,4),v(,3)),u(f,M(,2))),a(r(l,.(.(,.),)),w(p,j(,1)))),t(n(d(b(6),x),k(c,y)),m(g(z(7),q),o(D(8),S(9,0))))))
for(w in scan(,"",t=scan(,"")))
cat(chartr("MDS","-. ","if"(is.symbol(z<-m[[(utf8ToInt(w)==45)+2]]),z,z[[1]])))

ลองออนไลน์!


1

Powershell, 193 ไบต์

$n=1
-join("$args "|% t*y|%{if($_-32){$n=$n*2+($_-ne'.')}else{("  etianmsurwdkgohvf l pjbxcyzq  54 3   2& +~16=/   ( 7   8 90~~~?~ `"  .~@   '  -~~;! )~ ,~:~~~~$"-replace'~','    ')[$n]
$n=1}})

บททดสอบหัก Golfed:

$f = {

$n=1
-join(
    "$args "|% t*y|%{
        if($_-32){
            $n=$n*2+($_-ne'.')
        }else{
            ("  etianmsurwdkgohvf l pjbxcyzq  54 3   2& +~16=/   ( 7   8 90~~~?~ `"  .~@   '  -~~;! )~ ,~:~~~~$"-replace'~','    ')[$n]
            $n=1
        }
    }
)

}

@(
    ,("example. sos",". -..- .- -- .--. .-.. . .-.-.-  ... --- ...")
    ,("0123456789abcdefghijklmnopqrstuvwxyz","----- .---- ..--- ...-- ....- ..... -.... --... ---.. ----. .- -... -.-. -.. . ..-. --. .... .. .--- -.- .-.. -- -. --- .--. --.- .-. ... - ..- ...- .-- -..- -.-- --..")
    ,("hello world", ".... . .-.. .-.. ---  .-- --- .-. .-.. -..")
) | % {
    $expected,$s = $_
    $result = &$f $s
    "$($result-eq$expected): $result"
}

เอาท์พุท:

True: example. sos
True: 0123456789abcdefghijklmnopqrstuvwxyz
True: hello world

0

จาวาสคริปต์ (165 ไบต์, ใช้งานได้เพียงสี่ระนาบ)

n=''.replace(/\./g,1).replace(/-/g,0).split(' ')
l='|te|mnai|ogkdwrus|cöqzycxbjpälüfvh'.split('|')
r=''
for(i in n){r+=l[n[i].length][parseInt(n[i],2)]}
alert(r)

อินพุตควรถูกกำหนดให้nเรียกใช้โค้ดต่อไปนี้เพื่อรับเอาต์พุต:

n='. -..- .- -- .--. .-.. .'.replace(/\./g,1).replace(/-/g,0).split(' ')
l='|te|mnai|ogkdwrus|cöqzycxbjpälüfvh'.split('|')
r=''
for(i in n) {r+=l[n[i].length][parseInt(n[i],2)]}
alert(r)

สิ่งนี้ไม่เพียง แต่ดูเหมือนจะเป็นการใช้งานที่ไม่สมบูรณ์ แต่มันก็ไม่สามารถใช้งานได้ Fiddle + Chrome ให้ข้อผิดพลาดCannot read property '42' of undefinedและ IdeOne รายงานข้อผิดพลาด (แม้ว่าจะไม่มีข้อความที่เป็นประโยชน์)
ปีเตอร์เทย์เลอร์

ลองแก้ไข :)
Timtech

@PeterTaylor มีการระบุว่ารองรับเพียงสี่ระนาบคือรหัสมอร์สยาวถึง 4 ตัวจึงไม่ยอมรับการ. -..- .- -- .--. .-.. . .-.-.-ป้อนข้อมูลเนื่องจากรหัสสุดท้ายมีความยาว 6 ตัวอักษร ในสคริปต์ตัวอย่างฉันละเว้นและไปพร้อมกับการ. -..- .- -- .--. .-..แจ้งเตือน ( example)
aularon

นี่คือซอที่มีรหัสบล็อกที่สอง: jsfiddle.net/aularon/AHY4e/1
aularon
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.