Escribe una calculadora Morse

23

Escriba un programa o función que tome una expresión matemática en código Morse como entrada y devuelva la solución en código Morse.

Las operaciones válidas son más: +y menos: _(guión bajo). Puede suponer que solo recibirá una entrada entera no negativa y que el resultado será no negativo.

La expresión contendrá al menos dos términos y un máximo de diez términos. No habrá dos operadores adyacentes, es decir .----+_-...., y no habrá paréntesis.

Los dígitos están separados por espacios individuales. Puede elegir que los operadores estén separados de los números por un solo espacio en cada lado (ver ejemplos).

Los equivalentes de Morse para los dígitos 0-9 son:

0  -----
1  .----
2  ..---
3  ...--
4  ....-
5  .....
6  -....
7  --...
8  ---..
9  ----.

Ejemplos:

Input
Output


.----+.----  (1+1=2) Optional input: .---- + .----
..---

-...._...--  (6-3=3) Optional input: -.... _ ...--
...--

..---_...--+..--- (2-3+2=1)
1

..---+...--_....-+---.._.....  (2+3-4+8-5=4)
....-

.---- ..---_-....+...-- ...--  (12-6+33=39)
...-- ----.

----. -----+----.+..--- ----._..... .....+---..+-...._.----+----.+----._..--- -----  (90+9+29-55+8+6-1+9+9-20=84)
---.. ....-

Se aplican las normas estándar sobre formatos de E / S, etc. Se aceptan algunos espacios finales y una nueva línea. No puede dividir el número en varias líneas. No se puede usar evalo equivalente.

Este es el código de golf, por lo que gana el código más corto en bytes.

Stewie Griffin
fuente

Respuestas:

3

Pyth, 69 63 bytes

J_.:s*R5"-.-"5jdm@Jsd`s*MC,mssdc`MKmxJdcz)"-1"+1mtyq\+@cz)dx_1K

Pruébalo aquí

O use una suite de prueba

Explicación

J_.:s*R5"-.-"5                                                  - Construct the morse sequence 0-10
              jd                                                - Prettify output (join by spaces)
                m@Jsd                                           - Get the morse for each character in output
                     `s                                         - Convert to a string
                         C,mssdc`MKmxJdcz)"-1"                  - Get the numbers
                       *M                                       - Multiply the numbers by the operators
                                              +1mtyq\+@cz)dx_1K - Turn `+` and `_` to +-1

¡Guardado 6 bytes gracias a @Jakube!

Azul
fuente
J_.:s*R5"-.-"5para construir los números. Probablemente incluso se acorte cuando se usan cadenas compactas.
Jakube
5

Retina, 132 bytes

Una solución desordenada de primer paso.

(-)+\.+
5$*.$#1$*.
(-|(\.))+ ?
$#2
\d+
$*
+`(1(_)1|(_1+)|_|\+)(.*)
$2$4$3
1+
$.0
\d
$*x5$*- 
(x)+x{5}-*
$#1$*-xxxx
(\S{5})\S*
$1
x
.

Pruébalo en línea!

randomra
fuente
3

MATL , 75 71 69 68 bytes

5:t!<t~v45+cXIO1Oj6ZC"@2#0)Iw!Xmfqb+wXK32=?10*}*+K?K9\6-O}V47-Y)Z{Zc

Pruébalo en línea!

Explicación general

Utilizo el formato de código a continuación para que la sangría exprese el anidamiento de las operaciones.

The input is split into chunks of 6 characters. The last chunk will have
5 characters padded by a 0 char.
   A 0 is initially pushed. This will contain the accumulated global result.
      Each operand (sequence of digits) is processed as follows. A "sign digit",
      1 or -1, has been previously pushed according to whether the preceding
      operator was + or - (for the first operand 1 is used as sign digit).
      Then a 0 is pushed. This will contain the accumulated operand value.
         Each digit of the operand is transformed into the a number `0`...`9` and
         accumulated to the operand value, with successive multiplications by `10`.
      When a + or - is detected, the current operand is finished. So it is 
      multiplied by its sign digit, and added to the acumulated global result.
      A new sign digit is pushed (1 for +, -1 for -), and a new 0 is pushed
      as initial accumulated operand value for the next operand.
   When a 0 char is detected instead of + or -, this marks the end of the input.
   The current global accumulated result is the definitive value. This is
   tranformed into Morse digits and displayed.

Explicación detallada

5:t!<         % first half of the 10x5 array of Morse digits, with 0 for - and 1 for .
t~v           % vertically concat second half, i.e. first half vertically flipped
45+cXI        % transform 0 1 to chars - . Copy this "digit table" to clipboard I
O             % push 0: initial value for accumulated global result
1             % push 1: sign digit for first operand
O             % push 0: initial value of operand
j             % input string
6ZC           % arrange 6-length non-overlapping blocks as columns. Last is 0-padded
"             %   for each column
  @           %   push column
  2#0)        %   split into last element and vector or remaining elements
  I           %   push digit table
  w!          %   swap and transposed into a row
  Xmfq        %   index of that row in the digit table. Subtract 1: gives the digit
  b+          %   bubble up current operand value to top. Add to the new found digit
  wXK         %   swap last char of column (+,-,space,0) to top. Copy to clipboard K
  32=         %   is it space?
  ?           %   if so
    10*       %     multiply by 10. The operand will continue with next digit
  }           %   else: the operand is done
    *         %     multiply by sign digit
    +         %     add this operand with its sign to accumulated global result
    K         %     push last char of column again
    ?         %     if it's not 0
      K9\6-   %       push 1 if it's a +, -1 if it's a -: sign digit of next operand
      O       %       push 0 to initiallize accumulated operand value of next operand
    }         %     else: it's a 0: we're done computing the result
      V       %       convert result to string to get its digits
      47-Y)   %       index the rows of the digit table that was initially pushed
      Z{Zc    %       join rows by spaces
              %     end if, implicit
              %   end if, implicit
              % end for each, implicit
              % display, implicit
Luis Mendo
fuente
1

Javascript (es6) 236 bytes

mucho margen de mejora

q=>(q.replace(/[.-]{5}/g,q=>(a=q.split`.`.length)&&q[4]=='-'?a-1:11-a).replace(/ /g,'').split(/([_+])/).reduce((l,o)=>l+(+o?(n=='_'?-(+o):+o):(n=o)&&0),0,n='')+[]).split``.map(u=>(((a='.....')+'-----').slice(5-u)+a).substr(0,5)).join` `


roto

q=>
 (
 //grab each set of 5 dits/dahs
 q.replace(/[.-]{5}/g,


  //count dits
  //if last digit is '-' return dits-1
  //else return 11-dits
  q=>(a=q.split`.`.length)&&q[4]=='-'?a-1:11-a)

   //remove spaces and split on operators + and _
   .replace(/ /g,'').split(/([_+])/)

    //reduce the array into one element
    //start with 0;
    //when we come across a number add it to the total
    //when we come across an operator change current op to it
    .reduce((l,o)=>l+(+o?(n=='_'?-(+o):+o):(n=o)&&0),0,n='')

  //cast to string
  +[])

 //turn to array
 .split``

  //turn each digit back to morse
  .map(u=>(".....-----".slice(5-u)+'.....').substr(0,5)).join` `   

uso

f=q=>(q.replace(/[.-]{5}/g,q=>(a=q.split`.`.length)&&q[4]=='-'?a-1:11-a).replace(/ /g,'').split(/([_+])/).reduce((l,o)=>l+(+o?(n=='_'?-(+o):+o):(n=o)&&0),0,n='')+[]).split``.map(u=>(((a='.....')+'-----').slice(5-u)+a).substr(0,5)).join` `

f("----. -----+----.+..--- ----._..... .....+---..+-...._.----+----.+----._..--- -----")
Charlie Wynn
fuente
0

Golpe puro, 366 317

a=----- p='v+=($a);a=${a/-/.}';q=${p/-?././-};. <(echo $p{,,,,} $q{,,,,});p(){
[ ${1:0:1} = . ]&&{ b=${1%%-*};o+=${#b};}||{ b=${1%%.*} o+=$[(5+${#b})%10];};}
s=${1//[-.]/};for i in ${1//[+_]/ };do p $i;t=${s:0:1};o+=${t// };s=${s:1};done
r=$[${o//_/-}];for ((i=0;i<${#r};i++));do w+=(${v[${r:i:1}]});done;echo ${w[@]}

Ok, podría ahorrar 10 bytes para llegar a 307 escribiendo la primera línea:

v=(----- .---- ..--- ...-- ....- ..... -.... --... ---.. ----.);p(){

en lugar de (pero me gusta):

a=----- p='v+=($a);a=${a/-/.}';q=${p/-?././-};. <(echo $p{,,,,} $q{,,,,});p(){

Muestra:

cat >/tmp/morseCalc.sh <<'eof'
#!/bin/bash
a=----- p='v+=($a);a=${a/-/.}';q=${p/-?././-};. <(echo $p{,,,,} $q{,,,,});p(){
[ ${1:0:1} = . ]&&{ b=${1%%-*};o+=${#b};}||{ b=${1%%.*} o+=$[(5+${#b})%10];};}
s=${1//[-.]/};for i in ${1//[+_]/ };do p $i;t=${s:0:1};o+=${t// };s=${s:1};done
r=$[${o//_/-}];for ((i=0;i<${#r};i++));do w+=(${v[${r:i:1}]});done;echo ${w[@]}
eof
chmod +x /tmp/morseCalc.sh

for test in 1+1 6-3 2-3+2 2+3-4+8-5 12-6+33 90+9+29-55+8+6-1+9+9-20 ;do
    string="$(sed 's/ \.\.\.-\.-$//;s/ \.-\.-\. /+/g;s/ -\.\.\.\.- /_/g' <(
        xargs < <(morse -s -- $test)))"
    out="$(/tmp/morseCalc.sh "$string")"
    res=$(morse -sd <<< "$out")
    echo "$test: $string = $out -> $res"
  done |
    fold -w 80 -s

1+1: .----+.---- = ..--- -> 2
6-3: -...._...-- = ...-- -> 3
2-3+2: ..---_...--+..--- = .---- -> 1
2+3-4+8-5: ..---+...--_....-+---.._..... = ....- -> 4
12-6+33: .---- ..---_-....+...-- ...-- = ...-- ----. -> 39
90+9+29-55+8+6-1+9+9-20: ----. -----+----.+..--- ----._..... 
.....+---..+-...._.----+----.+----._..--- ----- = ---.. ....- -> 84

o si el morseconvertidor no está instalado:

for test in .----+.---- -...._...-- ..---_...--+..---  \
 ..---+...--_....-+---.._..... ".---- ..---_-....+...-- ...--" "----. -----+\
----.+..--- ----._..... .....+---..+-...._.----+----.+----._..--- -----" ;do
    echo $test $(
        bash <(sed '$s/;f/;echo "(${o\/\/_\/-}=$r)";f/' /tmp/morseCalc.sh
            ) "$test" )
  done |
    fold -w80 -s

.----+.---- (1+1=2) ..---
-...._...-- (6-3=3) ...--
..---_...--+..--- (2-3+2=1) .----
..---+...--_....-+---.._..... (2+3-4+8-5=4) ....-
.---- ..---_-....+...-- ...-- (12-6+33=39) ...-- ----.
----. -----+----.+..--- ----._..... .....+---..+-...._.----+----.+----._..--- 
----- (90+9+29-55+8+6-1+9+9-20=84) ---.. ....-
F. Hauri
fuente