Codice Morse allo standard output


13

Questa domanda implica prendere input nel codice Morse come. (punto) e - (simbolo meno), con spazi per separare l'input. Il tuo compito è convertire il codice in output standard. Puoi presumere che l'unico input contenga i simboli dei caratteri che si trovano nell'alfabeto del codice Morse internazionale, che puoi trovare qui: http://en.wikipedia.org/wiki/Morse_code#Letters.2C_numbers.2C_punctuation .

Tutti gli output dovrebbero usare lettere minuscole. Un doppio spazio dovrebbe essere interpretato come uno spazio di parole.

Input di esempio:

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

Produzione:

example. sos

Vince il codice più breve dopo due settimane.


Dici che solo "simboli dei personaggi" sono personaggi e simboli?
Affondamento,

@Quirliom Tutti i "simboli" in quel link sono caratteri. Tutto ciò che puoi mettere in una stringa è un personaggio (beh, in pratica). Tuttavia, quella parte della domanda sta sostanzialmente dicendo che ogni pezzettino di morse sarà valido.
Justin

@Quirliom Sì, ogni "personaggio" Morse, come .- per "a" e. per 'e' è valido. Nessun personaggio non Morse deve essere gestito.

Che dire dello spazio delle lettere e dello spazio delle parole? Uno spazio per il primo e due (o più) per il secondo?
Paul R,

Risposte:


8

Mathematica 62

Mathematica ci permette di imbrogliare

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

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

e

esempio.

hai muggito oggi?

I primi due simboli .e .-sono necessari per interpretare correttamente i piccoli codici.


Manca la conversione in lettere minuscole.
Peter Taylor,

@PeterTaylor Può essere facilmente modificato in f=ToLowerCase@StringDrop[WolframAlpha[". .- "<>#,"Result"],2]&minuscolo.
Ybeltukov,

L'utilizzo dell'API Wolfram Alpha non richiede un ID applicazione? Se è così, questo non dovrebbe aggiungersi al conteggio dei personaggi? Tuttavia soluzione molto intelligente.
Björn Lindqvist,

@ BjörnLindqvist Basta valutare esattamente questo comando in Mathematica , forcherà bene.
ybeltukov,

23

Drat, speravo di arrivare qui prima dell'arrivo dei GolfScripters :-(

Anyhoo ...

C: 228 caratteri:

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

Ho pensato di aggiungere una spiegazione di come funziona.

I dati di input vengono analizzati in base ai dati dell'albero in *c, che possono essere espansi come segue (utilizzando ·per rappresentare un nodo libero):

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

Partendo dalla cima dell'albero, scendi verso il basso mentre ti sposti verso sinistra per un punto e verso destra per un trattino. Quindi emetti qualunque carattere ti trovi quando termina la stringa di input (cioè, quando viene incontrato un carattere di spazio). Così, per esempio, tre punti e un pizzico vi porterà a vvia e, ie s. Invece di controllare esplicitamente la presenza di punti (ASCII \x2e) e trattini (ASCII \x2d), dobbiamo solo controllare l'ultimo bit ( m[n]&1), che è 0 per .e 1 per -.

Sono sufficienti sei righe per codificare tutto tranne $, che ha 7 punti / trattini: ...-..-ma poiché i dati di input sono garantiti come validi, questo può essere facilmente risolto troncando l'input a 6 caratteri ( m[6]=0) e interpretando ...-..come $invece. Possiamo anche eliminare gli ultimi 7 byte dai dati dell'albero, poiché sono tutti vuoti e non sono necessari se l'input è valido.


1
Bel trucco per scartare l'ultimo carattere di codici di 6 caratteri e abbreviare la tabella di ricerca.
Peter Taylor,

2
Sto votando tanto per la chiarezza della discussione quanto per la qualità dell'algoritmo. Buon lavoro.
Michael Stern,

Vedi se riesci a radere alcuni caratteri elaborando carattere per carattere invece di leggere un'intera stringa in c. Forse potresti usare modulo & un offset per provare a schiacciare insieme i valori più alti; questo è ciò che faccio nella mia soluzione. Comunque, bel lavoro!
FireFly

8

GolfScript ( 116 113 97 caratteri)

Questo include caratteri non stampabili usati in una tabella di ricerca, quindi lo sto dando come 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

Questo decodifica in un programma equivalente a

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+

che è essenzialmente

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

Questo utilizza un hash perfetto (non minimale) basato sull'idea di base di un algoritmo ottimale per generare funzioni hash perfette minime; Ceco, Havas e Majewski; 1992 . La loro idea di base è che tu usi due funzioni hash f1e f2, insieme a una tabella di ricerca g, e l'hash perfetto sia (g[f1(str)] + g[f2(str)]) % m(dov'è mil numero di stringhe che vogliamo distinguere); la parte intelligente è il modo in cui costruisconog . Considerare tutti i valori f1(str)e le f2(str)stringhe strdi interesse come nodi in un grafico non orientato e aggiungere un bordo tra f1(str)ef2(str)per ogni stringa. Richiedono non solo che ciascun bordo sia distinto, ma che il grafico sia aciclico; quindi è solo un DFS per assegnare pesi ai nodi (cioè per popolare la tabella di ricerca g) in modo tale che ogni bordo abbia la somma richiesta.

Czech et al generano funzioni casuali f1e f2che sono espresse tramite tabelle di ricerca, ma chiaramente non va bene: ho cercato un hash adatto usando semplici conversioni di base con due basi distinte da -10 a 9. Ho anche rilassato il requisito aciclico. Non volevo assegnare le stringhe ai valori da 0 a 54, ma ai corrispondenti codici ASCII, quindi piuttosto che prendere (g[f1(str)] + g[f2(str)]) % mne volevo (g[f1(str)] + g[f2(str)]) % Nalcuni N > 'z'. Ma ciò consente alla libertà di provare vari Ne vedere se qualcuno di essi consente una tabella di ricerca valida g, indipendentemente dal fatto che ci siano cicli. A differenza di Czech et al. Non mi interessa se la ricerca della funzione hash perfetta è O (n ^ 4).

Il grafico generato da -4basee 5basemod 59è:

Grafico reso da punto con alcune piccole modifiche

che è abbastanza carino a parte il più grande componente connesso, che ha tre cicli di lunghezza 1. Dobbiamo andare N=233prima di trovare un gche è coerente.


Altre possibili codifiche per la tabella di ricerca: la codifica delle differenze non aiuta, perché non esiste la struttura. Potrebbe essere possibile sfruttare la non ripetizione dei valori codificando come una permutazione, ma entrambi gli spazi devono essere gestiti separatamente (54 caratteri di output => 30 byte di entropia, oltre alla decodifica; le corse hanno bisogno di almeno 15 byte se codificate come una conversione di base semplice; potrebbe essere possibile migliorare solo l'attuale 92 byte) o stiamo permutando 138 elementi (oltre 98 byte di entropia, oltre alla decodifica).
Peter Taylor,

Poiché si tratta di un codice non prefisso, non possiamo facilmente provare a dedicare il duro lavoro a un'implementazione zlib.
Peter Taylor,

4

C, 169 caratteri

Non sono riuscito a trovare una funzione hash migliore ..

(Ho pubblicato il codice non mininato ma l'ho contato minimizzato; per minimizzare basta fare :%s/ //g | %j!in vim, quindi rimettere letteralmente lo spazio nella stringa.)

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

Prova

( morse.inè solo l'intero alfabeto in morse su righe separate):

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

Spiegazione

Questo è abbastanza semplice. c < 33trova uno spazio bianco / separatore ( , \n, EOF, ...). c % 2traduce un punto o un trattino in un po '. L'idea è quella di creare un numero univoco per ciascun personaggio semplicemente interpretandolo come un numero binario (dopo averlo prefissato con 1 per gestire la lunghezza variabile) (questa interpretazione è la v*2 + c%2parte). Poi ottengo un LUT a 137 caratteri, che ho compattato con l'hashing del valore risultante ( v < 64? v : v % 51 + 33, costanti trovate tramite tentativi ed errori e osservando la distribuzione e cercando di trovare un enorme divario). Sfortunatamente questa funzione hash ha una singola collisione, motivo per cui devo 40 → '&'mappare il caso speciale .


4

R , 145 byte

Tradotto un punto in 2, un trattino in 1 e interpretando il numero in ternario e prendendo la mod 89, che fornisce un numero univoco che possiamo usare in una tabella hash. La presenza di un 13 (111 base-3) significa aggiungere 1 perché ASCII 13 non funziona in TIO.

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

Provalo online!

R , 236 byte (non concorrenti)

Questo non sarà competitivo, ma ci permetterà di mostrare qualcosa di interessante in R: memorizzare l'albero del codice Morse all'interno di una struttura linguistica quotata me recuperarlo dal codice di punti e trattini semplicemente usando il fatto che [[può essere applicato in modo ricorsivo a elenchi. Ad esempio m[[c(2,2,3,2)]]recupera punto, punto, trattino, punto o "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]])))

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

Script di test meno golfato:

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

Produzione:

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

0

JavaScript (165 byte, implementando solo quattro piani).

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)

L'input deve essere assegnato a n, eseguire il codice seguente per ottenere l'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)

Non solo sembra un'implementazione incompleta, ma non funziona nemmeno. Fiddle + Chrome dà errore Cannot read property '42' of undefinede IdeOne segnala anche un errore (anche se senza un messaggio utile).
Peter Taylor,

Prova a risolverlo :)
Timtech,

@PeterTaylor Si afferma che supporta solo quattro piani, cioè fino a 4 caratteri Morse lunghi, quindi non accetta . -..- .- -- .--. .-.. . .-.-.-come input, poiché l'ultimo codice è lungo 6 caratteri. Nello script di esempio lo ometto e vado con . -..- .- -- .--. .-.., che avvisi ( example).
aularon,

Ecco un violino con il secondo codice di blocco: jsfiddle.net/aularon/AHY4e/1
aularon
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.