Código Morse a salida estándar

13

Esta pregunta implica tomar la entrada en el código Morse como. (punto) y - (símbolo menos), con espacios para separar la entrada. Su tarea es convertir el código a salida estándar. Puede suponer que la única entrada contiene símbolos de caracteres que se encuentran en el alfabeto del Código Morse Internacional, que se encuentra aquí: http://en.wikipedia.org/wiki/Morse_code#Letters.2C_numbers.2C_punctuation .

Todos los resultados deben usar letras minúsculas. Un doble espacio debe interpretarse como un espacio de palabras.

Entrada de muestra:

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

Salida:

example. sos

El código más corto después de dos semanas gana.

Peter Taylor
fuente
¿Dices que solo 'símbolos de caracteres' son esos caracteres y símbolos?
Sinkingpoint
@Quirliom Todos los "símbolos" en ese enlace son caracteres. Cualquier cosa que puedas poner en una Cadena es un personaje (bueno, básicamente). Sin embargo, esa parte de la pregunta es básicamente decir que cada bit de morse será válido.
Justin
@Quirliom Sí, cada 'personaje' Morse, como .- para 'a' y. para 'e' es válido. No es necesario manejar caracteres que no sean Morse.
¿Qué pasa con el espacio de letras y el espacio de palabras? ¿Un espacio para el primero y dos (o más) para el segundo?
Paul R
Ligeramente (no) relacionado: stackoverflow.com/questions/1352587/code-golf-morse-code
javatarz

Respuestas:

8

Mathematica 62

Mathematica nos permite hacer trampa

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

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

mi

ejemplo.

¿Te mugía hoy?

Los dos primeros símbolos .y .-son necesarios para interpretar los códigos pequeñas correctamente.

ybeltukov
fuente
Falta la conversión a minúsculas.
Peter Taylor
@PeterTaylor Se puede modificar fácilmente f=ToLowerCase@StringDrop[WolframAlpha[". .- "<>#,"Result"],2]&para minúsculas.
ybeltukov
¿El uso de la API Wolfram Alpha no requiere una identificación de la aplicación? Si es así, ¿no debería eso agregar al recuento de caracteres? Sin embargo, una solución muy inteligente.
Björn Lindqvist
@ BjörnLindqvist Simplemente evalúe exactamente este comando en Mathematica , se bifurca bien.
ybeltukov
23

Drat, esperaba llegar aquí antes de que llegaran los GolfScripters :-(

Anyhoo ...

C: 228 caracteres:

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

Pensé agregar una explicación de cómo funciona esto.

Los datos de entrada se analizan de acuerdo con los datos del árbol *c, que se pueden expandir de la siguiente manera ( ·para representar un nodo vacante):

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

Comenzando en la parte superior del árbol, trabaje hacia abajo mientras se mueve hacia la izquierda para un punto y hacia la derecha para un guión. Luego, muestre el carácter en el que se encuentre cuando termine la cadena de entrada (es decir, cuando se encuentre un carácter de espacio en blanco). Entonces, por ejemplo, tres puntos y un guión lo llevarán av través de e, iy s. En lugar de verificar explícitamente los puntos (ASCII \x2e) y los guiones (ASCII \x2d), solo necesitamos verificar el último bit ( m[n]&1), que es 0 para .y 1 para- .

Seis filas son suficientes para codificar todo excepto $, que tiene 7 puntos / guiones: ...-..-pero, dado que se garantiza que los datos de entrada son válidos, esto se puede solucionar fácilmente truncando la entrada en 6 caracteres ( m[6]=0) e interpretándola ...-..en su $lugar. También podemos cortar los últimos 7 bytes de los datos del árbol, ya que todos están vacíos y no son necesarios si la entrada es válida.

r3mainer
fuente
1
Buen truco para descartar el último carácter de los códigos de 6 caracteres y acortar la tabla de búsqueda.
Peter Taylor el
2
Estoy votando tanto por la claridad de la discusión como por la calidad del algoritmo. Buen trabajo.
Michael Stern el
Vea si puede eliminar algunos caracteres procesando carácter por carácter en lugar de leer una cadena completa. cPodría estar en línea. Tal vez podría usar el módulo y un desplazamiento para intentar juntar los valores más altos; Esto es lo que hago en mi solución. De todos modos, buen trabajo!
FireFly
8

GolfScript ( 116 113 97 caracteres)

Esto incluye caracteres no imprimibles utilizados en una tabla de búsqueda, así que lo estoy dando como salida 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

Esto decodifica a un programa 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+

que es esencialmente

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

Utiliza un hash perfecto (no mínimo) basado en la idea central de Un algoritmo óptimo para generar funciones hash perfectas mínimas; Checo, Havas y Majewski; 1992 . Su idea básica es usar dos funciones hash f1y f2, junto con una tabla de búsqueda g, y el hash perfecto es (g[f1(str)] + g[f2(str)]) % m(¿dónde mestá el número de cadenas que deseamos distinguir?); lo inteligente es la forma en que construyen g. Considere todos los valores f1(str)y f2(str)para cadenas strde interés como nodos en un gráfico no dirigido, y agregue un borde entre f1(str)yf2(str)para cada cuerda Requieren no solo que cada borde sea distinto, sino que el gráfico sea acíclico; entonces es solo un DFS para asignar pesos a los nodos (es decir, para llenar la tabla de búsqueda g) de modo que cada borde tenga la suma requerida.

Czech et al generan funciones aleatorias f1y f2se expresan a través de tablas de búsqueda, pero eso claramente no es bueno: busqué un hash adecuado utilizando conversiones de bases simples con dos bases distintas de -10 a 9. También relajé el requisito acíclico. No quería asignar las cadenas a valores del 0 al 54, sino a los códigos ASCII correspondientes, así que en lugar de tomar (g[f1(str)] + g[f2(str)]) % m, quería (g[f1(str)] + g[f2(str)]) % Nalgunos N > 'z'. Pero eso permite libertad para probar varios Ny ver si alguno de ellos permite una tabla de búsqueda válidag , independientemente de si hay ciclos. A diferencia de Czech et al., No me importa si la búsqueda de la función hash perfecta es O (n ^ 4).

El gráfico generado por -4basey 5basemod 59es:

Gráfico representado por punto con algunos ajustes menores

lo cual es bastante bueno, aparte del componente conectado más grande, que tiene tres ciclos de longitud 1. Tenemos que subir N=233antes de poder encontrar uno gque sea consistente.

Peter Taylor
fuente
Otras posibles codificaciones para la tabla de búsqueda: la codificación de diferencia no va a ayudar, porque no existe la estructura. Puede ser posible explotar la no repetición de valores codificando como una permutación, pero las brechas deben manejarse por separado (54 caracteres de salida => 30 bytes de entropía, más decodificación; las ejecuciones necesitan al menos 15 bytes si están codificadas como una conversión de base directa; podría ser posible mejorar el total actual de 92 bytes) o permutamos 138 elementos (más de 98 bytes de entropía, más decodificación).
Peter Taylor
Dado que es un código que no es prefijo, no podemos intentar fácilmente llevar el trabajo duro a una implementación zlib.
Peter Taylor
4

C, 169 caracteres

No pude encontrar una mejor función hash ...

(Publiqué el código no minificado pero lo conté minificado; para minificar solo hazlo :%s/ //g | %j!en vim, luego coloca el espacio en la cadena literal de nuevo).

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

Prueba de funcionamiento

( morse.ines solo el alfabeto completo en morse en líneas separadas):

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

Explicación

Este es bastante sencillo. c < 33encuentra un espacio en blanco / separador ( , \n, EOF, ...). c % 2traduce un punto o guión en un bit. La idea es crear un número único para cada carácter simplemente interpretándolo como un número binario (después de ponerle el prefijo 1 para tratar con la longitud variable) (esta interpretación es la v*2 + c%2parte). Luego obtengo un LUT de 137 caracteres, que compacté al descifrar el valor resultante ( v < 64? v : v % 51 + 33constantes encontradas mediante prueba y error y al mirar la distribución e intentar encontrar una gran brecha). Desafortunadamente, esta función hash tiene una sola colisión, por lo que tengo que hacer un 40 → '&'mapeo especial.

Luciérnaga
fuente
4

R , 145 bytes

Tradujo un punto a 2, un guión a 1 e interpretó el número en ternario y tomó el mod 89, que da un número único que podemos usar en una tabla hash. La presencia de un 13 (111 base-3) significa sumar 1 porque ASCII 13 no funciona en TIO.

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

Pruébalo en línea!

R , 236 bytes (no competitivos)

Esto no va a ser competitivo, pero nos permite mostrar algo interesante en R: almacenar el árbol de código Morse dentro de una estructura de lenguaje citada my recuperarlo del código de puntos y guiones simplemente usando el hecho de que [[se puede aplicar recursivamente a liza. Por ejemplo, m[[c(2,2,3,2)]]recupera punto, punto, guión, 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]])))

Pruébalo en línea!

J.Doe
fuente
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}})

Script de prueba menos golfizado:

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

Salida:

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

JavaScript (165 bytes, solo implementando cuatro planos).

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)

La entrada debe asignarse a n, ejecute el siguiente código para obtener la salida:

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
fuente
Esto no solo parece ser una implementación incompleta, sino que ni siquiera funciona. Fiddle + Chrome da error Cannot read property '42' of undefined, e IdeOne también informa un error (aunque sin un mensaje útil).
Peter Taylor
Intenta arreglarlo :)
Timtech
@PeterTaylor Se afirma que solo admite cuatro planos, es decir, códigos morse de hasta 4 caracteres de longitud, por lo que no aceptará . -..- .- -- .--. .-.. . .-.-.-como entrada, ya que el último código tiene una longitud de 6 caracteres. En el script de ejemplo, lo omito y voy con . -..- .- -- .--. .-.., que alerta ( example).
aularon
Aquí hay un violín con el segundo código de bloque: jsfiddle.net/aularon/AHY4e/1
aularon