Kode morse ke output standar


13

Pertanyaan ini melibatkan mengambil masukan dalam kode Morse sebagai. (titik) dan - (simbol minus), dengan spasi untuk memisahkan input. Tugas Anda adalah mengubah kode menjadi output standar. Anda dapat mengasumsikan bahwa input hanya berisi simbol karakter yang ditemukan dalam alfabet Kode Morse Internasional, ditemukan di sini: http://en.wikipedia.org/wiki/Morse_code#Letters.2C_numbers.2C_punctuation .

Semua output harus menggunakan huruf kecil. Ruang ganda harus ditafsirkan sebagai ruang kata.

Input sampel:

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

Keluaran:

example. sos

Kode terpendek setelah dua minggu menang.


Anda mengatakan hanya 'simbol karakter' apakah karakter dan simbol itu?
Sinkingpoint

@ Quirliom Semua "simbol" di tautan itu adalah karakter. Apa pun yang dapat Anda masukkan ke dalam String adalah karakter (well, pada dasarnya). Namun, bagian dari pertanyaan itu pada dasarnya mengatakan bahwa setiap bit morse akan valid.
Justin

@ Quirliom Ya, setiap 'karakter' Morse, seperti .- untuk 'a' dan. untuk 'e' valid. Tidak ada karakter non-Morse yang perlu ditangani.

Bagaimana dengan ruang huruf dan ruang kata? Satu ruang untuk yang pertama dan dua (atau lebih) untuk yang terakhir?
Paul R

Jawaban:


8

Mathematica 62

Mathematica memungkinkan kita untuk menipu

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

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

e

contoh.

sudahkah kamu menganiaya hari ini?

Dua simbol pertama .dan .-diperlukan untuk menafsirkan kode kecil dengan benar.


Ini kehilangan konversi ke huruf kecil.
Peter Taylor

@PeterTaylor Dapat dengan mudah dimodifikasi f=ToLowerCase@StringDrop[WolframAlpha[". .- "<>#,"Result"],2]&untuk huruf kecil.
ybeltukov

Tidak menggunakan api Wolfram Alpha memerlukan id aplikasi? Jika demikian, bukankah itu menambah jumlah karakter? Meski demikian solusi yang sangat cerdas.
Björn Lindqvist

@ BjörnLindqvist Hanya mengevaluasi dengan tepat perintah ini di Mathematica , itu bercabang baik-baik saja.
ybeltukov

23

Drat, saya berharap untuk sampai di sini sebelum GolfScripters tiba :-(

Anyhoo ...

C: 228 karakter:

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]);}}

Saya pikir saya akan menambahkan penjelasan tentang cara kerjanya.

Data input diuraikan menurut data pohon di *c, yang dapat diperluas sebagai berikut (menggunakan ·untuk mewakili node kosong):

                     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
····$·······?_····"··.····@···'··-········;!·)·····,····:·······

Mulai dari bagian atas pohon, turun ke bawah sambil bergerak ke kiri untuk satu titik dan ke kanan untuk garis putus-putus. Kemudian output karakter apa pun yang Anda berada ketika string input berakhir (yaitu, ketika karakter spasi ditemukan). Jadi misalnya, tiga titik dan tanda hubung akan membawa Anda vmelalui e, idan s. Alih-alih secara eksplisit memeriksa titik (ASCII \x2e) dan tanda hubung (ASCII \x2d), kita hanya perlu memeriksa bit terakhir ( m[n]&1), yaitu 0 untuk .dan 1 untuk -.

Enam baris sudah cukup untuk menyandikan semua kecuali $, yang memiliki 7 titik / garis:, ...-..-tetapi karena data input dijamin valid, ini dapat dengan mudah diperbaiki dengan memotong input pada 6 karakter ( m[6]=0) dan menafsirkan ...-..sebagai $gantinya. Kami juga dapat memotong 7 byte terakhir dari data hierarki, karena semuanya kosong dan tidak diperlukan jika inputnya valid.


1
Trik yang bagus untuk membuang karakter terakhir dari kode 6-karakter dan mempersingkat tabel pencarian.
Peter Taylor

2
Saya memilih voting untuk kejelasan diskusi dan kualitas algoritma. Kerja bagus.
Michael Stern

Lihat apakah Anda bisa mencukur beberapa karakter dengan memproses karakter demi karakter alih-alih membaca seluruh string. cDapat diuraikan. Mungkin Anda bisa menggunakan modulo & offset untuk mencoba menyatukan nilai-nilai yang lebih tinggi; inilah yang saya lakukan dalam solusi saya. Ngomong-ngomong, kerja bagus!
FireFly

8

GolfScript ( 116 113 97 karakter)

Ini termasuk karakter yang tidak dapat dicetak yang digunakan dalam tabel pencarian, jadi saya memberikannya sebagai output 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

Ini diterjemahkan ke program yang setara dengan

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+

yang pada dasarnya

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

Ini menggunakan hash sempurna (non-minimal) berdasarkan ide inti dari algoritma optimal untuk menghasilkan fungsi hash minimal sempurna; Ceko, Havas, dan Majewski; 1992 . Ide dasarnya adalah Anda menggunakan dua fungsi hash, f1dan f2, bersama dengan tabel pencarian g, dan hash yang sempurna adalah (g[f1(str)] + g[f2(str)]) % m(di mana mjumlah string yang ingin kami bedakan); bit pintar adalah cara mereka membangun g. Pertimbangkan semua nilai f1(str)dan f2(str)untuk untaian yang strmenarik sebagai simpul dalam grafik yang tidak diarahkan, dan tambahkan keunggulan di antara f1(str)danf2(str)untuk setiap string. Mereka tidak hanya mengharuskan setiap sisi berbeda, tetapi grafik harus asiklik; maka itu hanya DFS untuk menetapkan bobot ke node (yaitu untuk mengisi tabel pencarian g) sehingga setiap tepi memiliki jumlah yang diperlukan.

Czech et al menghasilkan fungsi acak f1dan f2yang diekspresikan melalui tabel pencarian, tapi itu jelas tidak bagus: Saya mencari hash yang cocok menggunakan konversi basis sederhana dengan dua basis berbeda dari -10 hingga 9. Saya juga melonggarkan persyaratan asiklik. Saya tidak ingin menetapkan nilai string dari 0 hingga 54, tetapi untuk kode ASCII yang sesuai, jadi daripada mengambil (g[f1(str)] + g[f2(str)]) % msaya ingin (g[f1(str)] + g[f2(str)]) % Nbeberapa N > 'z'. Tapi itu memungkinkan kebebasan untuk mencoba berbagai Ndan melihat apakah ada di antara mereka yang memungkinkan tabel pencarian yang valid g, terlepas dari apakah ada siklus. Tidak seperti Czech et al, saya tidak peduli jika pencarian untuk fungsi hash yang sempurna adalah O (n ^ 4).

Grafik yang dihasilkan oleh -4basedan 5basemod 59adalah:

Grafik yang diberikan oleh titik dengan beberapa perubahan kecil

yang cukup baik terlepas dari komponen terhubung terbesar, yang memiliki tiga siklus panjang 1. Kita harus naik N=233sebelum kita dapat menemukan gyang konsisten.


Kemungkinan penyandian lain untuk tabel pencarian: perbedaan penyandian tidak akan membantu, karena tidak ada struktur. Dimungkinkan untuk mengeksploitasi non-pengulangan nilai dengan mengkodekan sebagai permutasi, tetapi celah tersebut perlu ditangani secara terpisah (54 karakter keluaran => 30 byte entropi, ditambah pengodean ulang; proses membutuhkan setidaknya 15 byte jika dikodekan) sebagai konversi basis lurus; mungkin saja dapat meningkatkan pada total 92 byte saat ini) atau kami melakukan permutasi 138 item (lebih dari 98 byte entropi, ditambah decoding).
Peter Taylor

Karena ini adalah kode non-awalan, kami tidak dapat dengan mudah mencoba mengubah kerja keras ke implementasi zlib.
Peter Taylor

4

C, 169 karakter

Saya tidak dapat menemukan fungsi hash yang lebih baik ..

(Saya memposting kode yang tidak dijinakkan tetapi menghitungnya diperkecil; untuk memperkecil hanya lakukan :%s/ //g | %j!di vim, lalu masukkan spasi dalam string literal kembali.)

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;
}

Uji coba

( morse.inhanya seluruh alfabet dalam morse pada baris terpisah):

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

Penjelasan

Yang ini cukup mudah. c < 33menemukan karakter spasi / pemisah ( , \n, EOF, ...). c % 2menerjemahkan sebuah titik atau garis menjadi sedikit. Idenya adalah untuk membuat angka unik untuk setiap karakter hanya dengan menafsirkannya sebagai angka biner (setelah awalan dengan 1 untuk berurusan dengan panjang variabel) (interpretasi ini adalah v*2 + c%2bagian). Saya kemudian mendapatkan 137-char LUT, yang saya padukan dengan hashing nilai yang dihasilkan ( v < 64? v : v % 51 + 33, konstanta ditemukan melalui trial-and-error dan dengan melihat distribusi dan mencoba menemukan celah yang sangat besar). Sayangnya fungsi hash ini memiliki satu tabrakan, itulah sebabnya saya harus melakukan 40 → '&'pemetaan khusus.


4

R , 145 byte

Diterjemahkan titik ke 2, tanda hubung ke 1 dan menafsirkan angka dalam ternary dan mengambil mod 89, yang memberikan angka unik yang dapat kita gunakan dalam tabel hash. Kehadiran 13 (111 basis-3) berarti menambahkan 1 karena ASCII 13 tidak berfungsi di TIO.

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

Cobalah online!

R , 236 byte (tidak bersaing)

Ini tidak akan kompetitif, tetapi memungkinkan kami memamerkan sesuatu yang menarik di R: menyimpan pohon kode Morse di dalam struktur bahasa yang dikutip mdan mengambilnya dari kode titik dan garis sangat sederhana menggunakan fakta yang [[dapat diterapkan secara rekursif ke daftar. Misalnya m[[c(2,2,3,2)]]mengambil titik, titik, tanda hubung, titik atau "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]])))

Cobalah online!


1

Powershell, 193 byte

$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}})

Skrip Tes Kurang Golf:

$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"
}

Keluaran:

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

0

JavaScript (165 byte, hanya menerapkan empat pesawat.)

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)

Input harus ditugaskan n, jalankan kode berikut untuk mendapatkan output:

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)

Ini tidak hanya terlihat sebagai implementasi yang tidak lengkap, tetapi bahkan tidak berhasil. Fiddle + Chrome memberikan kesalahan Cannot read property '42' of undefined, dan IdeOne juga melaporkan kesalahan (meskipun tanpa pesan yang berguna).
Peter Taylor

Coba perbaiki :)
Timtech

@PeterTaylor Dinyatakan bahwa ia hanya mendukung empat pesawat, yaitu hingga 4 karakter kode morse panjang, sehingga tidak akan menerima . -..- .- -- .--. .-.. . .-.-.-sebagai input, karena kode terakhir adalah panjang 6 karakter. Dalam skrip contoh saya menghilangkannya dan pergi dengan . -..- .- -- .--. .-.., yang mengingatkan ( example).
aularon

Berikut ini biola dengan kode blok kedua: jsfiddle.net/aularon/AHY4e/1
aularon
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.