Morsecode zur Standardausgabe

13

Diese Frage beinhaltet die Eingabe in Morsecode als. (Punkt) und - (Minuszeichen), mit Leerzeichen, um die Eingabe zu trennen. Ihre Aufgabe ist es, den Code in die Standardausgabe umzuwandeln. Sie können davon ausgehen, dass die einzige Eingabe Zeichensymbole enthält, die im internationalen Morsecode-Alphabet enthalten sind, das hier zu finden ist: http://en.wikipedia.org/wiki/Morse_code#Letters.2C_numbers.2C_punctuation .

Alle Ausgaben sollten Kleinbuchstaben verwenden. Ein doppeltes Leerzeichen sollte als ein Wortraum interpretiert werden.

Beispieleingabe:

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

Ausgabe:

example. sos

Kürzester Code nach zwei Wochen gewinnt.

Peter Taylor
quelle
Sie sagen, nur "Zeichensymbole" sind das Zeichen und Symbole?
Sinkingpoint
@Quirliom Alle "Symbole" in diesem Link sind Zeichen. Alles, was Sie in einen String einfügen können, ist ein Zeichen (na ja, im Grunde genommen). Dieser Teil der Frage besagt jedoch im Grunde, dass jedes bisschen Morse gültig sein wird.
Justin
@Quirliom Ja, jeder Morse "Charakter", wie .- für "a" und. denn 'e' ist gültig. Es müssen keine Nicht-Morse-Zeichen behandelt werden.
Was ist mit Buchstaben und Wörtern? Ein Platz für den ersteren und zwei (oder mehr) für den letzteren?
Paul R
Ein bisschen (un) verwandt: stackoverflow.com/questions/1352587/code-golf-morse-code
javatarz

Antworten:

8

Mathematica 62

Mathematica erlaubt uns zu betrügen

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

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

e

Beispiel.

Hast du heute schon gemuht?

Die ersten beiden Symbole .und .-sind notwendig, um kleine Codes richtig zu interpretieren.

ybeltukov
quelle
Hier fehlt die Umstellung auf Kleinbuchstaben.
Peter Taylor
@ PeterTaylor Es kann leicht f=ToLowerCase@StringDrop[WolframAlpha[". .- "<>#,"Result"],2]&für Kleinbuchstaben geändert werden.
Ybeltukov
Benötigt die Wolfram Alpha-API keine Anwendungs-ID? Wenn ja, sollte das nicht die Anzahl der Zeichen erhöhen? Trotzdem sehr clevere Lösung.
Björn Lindqvist
@ BjörnLindqvist Einfach genau diesen Befehl in Mathematica auswerten , es gabelt sich gut.
Ybeltukov
23

Drat, ich hatte gehofft, hierher zu kommen, bevor die GolfScripter ankamen :-(

Wie auch immer ...

C: 228 Zeichen:

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

Ich dachte, ich würde eine Erklärung hinzufügen, wie das funktioniert.

Die Eingabedaten werden anhand der Baumdaten in analysiert *c, die wie folgt erweitert werden können ( ·zur Darstellung eines freien Knotens):

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

Beginnen Sie oben am Baum und arbeiten Sie sich nach unten, während Sie sich für einen Punkt nach links und für einen Strich nach rechts bewegen. Geben Sie dann das Zeichen aus, an dem Sie sich gerade befinden, wenn die Eingabezeichenfolge endet (dh wenn ein Leerzeichen auftritt). Zum Beispiel führen drei Punkte und ein Bindestrich zu vvia e, iund s. Anstatt explizit nach Punkten (ASCII \x2e) und Bindestrichen (ASCII \x2d) zu suchen , müssen wir nur das letzte Bit ( m[n]&1) überprüfen , das 0 für .und 1 für ist -.

Sechs Zeilen reichen aus, um alles zu codieren, mit Ausnahme von $7 Punkten / Strichen : ...-..-. Da die Eingabedaten jedoch garantiert gültig sind, kann dies leicht behoben werden, indem die Eingabe auf 6 Zeichen ( m[6]=0) gekürzt ...-..und $stattdessen als interpretiert wird. Wir können auch die letzten 7 Bytes aus den Baumdaten entfernen, da sie alle leer sind und nicht benötigt werden, wenn die Eingabe gültig ist.

zimperliches Ossifrage
quelle
1
Ein guter Trick, um das letzte Zeichen eines 6-stelligen Codes zu verwerfen und die Nachschlagetabelle zu verkürzen.
Peter Taylor
2
Ich stimme sowohl für die Klarheit der Diskussion als auch für die Qualität des Algorithmus. Gute Arbeit.
Michael Stern
Sehen Sie nach, ob Sie ein paar Zeichen abschneiden können, indem Sie Zeichen für Zeichen verarbeiten, anstatt eine ganze Zeichenfolge ceinzulesen. Vielleicht könnten Sie Modulo & ein Offset verwenden, um zu versuchen, die höheren Werte zusammenzudrücken; Das ist, was ich in meiner Lösung mache. Wie auch immer, gute Arbeit!
FireFly
8

GolfScript ( 116 113 97 Zeichen)

Dies schließt nicht druckbare Zeichen ein, die in einer Nachschlagetabelle verwendet werden. Daher gebe ich sie als xxd-Ausgabe aus:

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

Dies dekodiert zu einem Programm, das äquivalent zu ist

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+

Das ist im Wesentlichen

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

Hierbei wird ein (nicht minimaler) perfekter Hash verwendet, der auf der Kernidee eines optimalen Algorithmus zum Erzeugen minimaler perfekter Hash-Funktionen basiert . Tscheche, Havas und Majewski; 1992 . Ihre Grundidee ist, dass Sie zwei Hash-Funktionen verwenden f1und f2zusammen mit einer Nachschlagetabelle gund dem perfekten Hash (g[f1(str)] + g[f2(str)]) % m(wo mist die Anzahl der Zeichenfolgen, die wir unterscheiden möchten); Das Schlaue ist die Art, wie sie bauen g. Betrachten Sie alle Werte f1(str)und f2(str)Zeichenfolgen strvon Interesse als Knoten in einem ungerichteten Diagramm und fügen Sie eine Kante zwischen f1(str)und hinzuf2(str)für jede Zeichenfolge. Sie erfordern nicht nur, dass jede Kante unterschiedlich ist, sondern dass der Graph azyklisch ist; dann ist es nur ein DFS, den Knoten eine Gewichtung zuzuweisen (dh die Nachschlagetabelle aufzufüllen g), so dass jede Kante die erforderliche Summe hat.

Czech et al erzeugt Zufallsfunktionen f1und f2die über Lookup - Tabellen ausgedrückt werden, aber das ist eindeutig nicht gut: ich nach einem geeigneten Hash mit einfachen Basiskonvertierungen mit zwei verschiedenen Basen von -10 bis 9. suchte ich die azyklische Anforderung auch entspannt. Ich wollte nicht die Saiten auf Werte von 0 bis 54, aber mit den entsprechenden ASCII - Codes zuzuweisen, so anstatt nehmen (g[f1(str)] + g[f2(str)]) % mwollte ich (g[f1(str)] + g[f2(str)]) % Nfür einige N > 'z'. Dies ermöglicht es jedoch, verschiedene zu testen Nund festzustellen, ob eine gültige Nachschlagetabelle zulässig ist g, unabhängig davon, ob es Zyklen gibt. Im Gegensatz zu Czech et al ist es mir egal, ob die Suche nach der perfekten Hash-Funktion O (n ^ 4) ist.

Die von -4baseund 5basemod erzeugte Grafik 59ist:

Diagramm von Punkt mit einigen geringfügigen Änderungen gerendert

Das ist ziemlich gut, abgesehen von der größten verbundenen Komponente, die drei Zyklen mit der Länge 1 hat. Wir müssen aufsteigen, N=233bevor wir eine gkonsistente finden können.

Peter Taylor
quelle
Andere mögliche Codierungen für die Nachschlagetabelle: Die Differenzcodierung hilft nicht weiter, da die Struktur nicht vorhanden ist. Es könnte möglich sein, die Nichtwiederholung von Werten durch Codierung als Permutation auszunutzen, aber entweder müssen die Lücken separat behandelt werden (54 Ausgabezeichen => 30 Byte Entropie plus Decodierung; die Läufe benötigen mindestens 15 Byte, wenn sie codiert sind als reine Basiskonvertierung, möglicherweise nur zur Verbesserung der aktuellen Gesamtgröße von 92 Byte), oder wir permutieren 138 Elemente (mehr als 98 Byte Entropie plus Decodierung).
Peter Taylor
Da es sich um einen Nicht-Präfix-Code handelt, können wir nicht einfach versuchen, die harte Arbeit auf eine zlib-Implementierung zu übertragen.
Peter Taylor
4

C 169 Zeichen

Ich konnte keine bessere Hash-Funktion finden.

(Ich habe den nicht vervollständigten Code gepostet, ihn aber als vervollständigt gezählt. Zum Vervollständigen einfach :%s/ //g | %j!in vim ausführen und dann das Leerzeichen im String-Literal zurücksetzen .)

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

Testlauf

( morse.inist nur das ganze Alphabet in Morse in getrennten Zeilen):

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

Erläuterung

Dieser ist ziemlich einfach. c < 33findet ein Leerzeichen / Trennzeichen ( , \n, EOF, ...). c % 2Übersetzt einen Punkt oder Strich in ein Bit. Die Idee ist, eine eindeutige Nummer für jedes Zeichen zu erstellen, indem Sie es einfach als Binärzahl interpretieren (nachdem Sie der Variablenlänge 1 vorangestellt haben) (diese Interpretation ist der v*2 + c%2Teil). Ich erhalte dann eine 137-Zeichen-LUT, die ich komprimiert habe, indem ich den resultierenden Wert ( v < 64? v : v % 51 + 33Konstanten, die durch Versuch und Irrtum gefunden wurden, und indem ich die Verteilung betrachte und versuche, eine große Lücke zu finden) hashe. Leider hat diese Hash-Funktion eine einzige Kollision, weshalb ich die 40 → '&'Zuordnung in Sonderfällen vornehmen muss.

FireFly
quelle
4

R , 145 Bytes

Übersetzte einen Punkt in eine 2, einen Strich in eine 1 und interpretierte die Zahl ternär und nahm den Mod 89, der eine eindeutige Zahl ergibt, die wir in einer Hash-Tabelle verwenden können. Das Vorhandensein einer 13 (111 Base-3) bedeutet das Hinzufügen von 1, da ASCII 13 in TIO nicht funktioniert.

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

Probieren Sie es online!

R , 236 Bytes (nicht konkurrierend)

Dies wird nicht wettbewerbsfähig sein, aber es ermöglicht uns, etwas Interessantes in R zu demonstrieren: Speichern Sie den Morse-Code-Baum in einer zitierten Sprachstruktur mund rufen Sie ihn aus dem Code von Punkten und Strichen ab, indem Sie einfach die Tatsache [[verwenden, die rekursiv auf angewendet werden kann Listen. Ruft zum Beispiel m[[c(2,2,3,2)]]Punkt, Punkt, Strich, Punkt oder "f" ab.

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

Probieren Sie es online!

J.Doe
quelle
1

Powershell, 193 Bytes

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

Weniger Golf Test-Skript:

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

Ausgabe:

True: example. sos
True: 0123456789abcdefghijklmnopqrstuvwxyz
True: hello world
mazzy
quelle
0

JavaScript (165 Byte, nur vier Ebenen implementierend.)

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)

Die Eingabe sollte zugewiesen werden n, führen Sie den folgenden Code aus, um die Ausgabe zu erhalten:

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)
aularon
quelle
Dies scheint nicht nur eine unvollständige Implementierung zu sein, sondern funktioniert auch nicht. Fiddle + Chrome gibt einen Fehler aus Cannot read property '42' of undefinedund IdeOne meldet auch einen Fehler (allerdings ohne nützliche Meldung).
Peter Taylor
Versuchen Sie es zu beheben :)
Timtech
@PeterTaylor Es wird angegeben, dass es nur vier Ebenen unterstützt, dh bis zu 4 Zeichen lange Morsecodes, daher wird es nicht . -..- .- -- .--. .-.. . .-.-.-als Eingabe akzeptiert , da der letzte Code 6 Zeichen lang ist. Im Beispielskript lasse ich es weg und gehe mit . -..- .- -- .--. .-.., welche Warnungen ( example).
aularon
Hier ist eine Geige mit dem zweiten Blockcode: jsfiddle.net/aularon/AHY4e/1
aularon