Viết một máy tính Morse


23

Viết chương trình hoặc hàm lấy biểu thức toán học trong mã Morse làm đầu vào và trả về giải pháp trong mã Morse.

Các hoạt động hợp lệ là cộng: +và trừ: _(gạch dưới). Bạn có thể giả sử rằng bạn sẽ chỉ nhận được đầu vào số nguyên không âm và kết quả sẽ không âm.

Biểu thức sẽ chứa ít nhất hai thuật ngữ và tối đa mười thuật ngữ. Sẽ không có hai toán tử liền kề .----+_-...., và sẽ không có dấu ngoặc đơn.

Các chữ số được phân tách bằng các khoảng trắng đơn. Bạn có thể chọn tách các toán tử khỏi các số bằng một khoảng trắng ở mỗi bên (xem ví dụ).

Tương đương Morse cho các chữ số 0-9 là:

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

Ví dụ:

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

Các quy tắc tiêu chuẩn liên quan đến các định dạng I / O, vv được áp dụng. Một vài dấu cách và một dòng mới được chấp nhận. Bạn không thể chia số trên một số dòng. Bạn không thể sử dụng evalhoặc tương đương.

Đây là mã golf, vì vậy mã ngắn nhất tính bằng byte sẽ thắng.

Câu trả lời:


3

Pyth, 69 63 byte

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

Hãy thử nó ở đây

Hoặc sử dụng bộ kiểm tra

Giải trình

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

Đã lưu 6 byte nhờ @Jakube!


J_.:s*R5"-.-"5để xây dựng các con số. Có lẽ thậm chí rút ngắn khi sử dụng chuỗi đóng gói.
Jakube

5

Võng mạc, 132 byte

Một giải pháp lộn xộn, đầu tiên vượt qua.

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

Hãy thử trực tuyến!


3

MATL , 75 71 69 68 byte

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

Hãy thử trực tuyến!

Giải thích chung

Tôi sử dụng định dạng mã theo sau để thụt lề thể hiện sự lồng nhau của các hoạt động.

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.

Giải thích chi tiết

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

1

Javascript (es6) 236 byte

nhiều chỗ để cải thiện

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` `


chia tay

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` `   

sử dụng

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("----. -----+----.+..--- ----._..... .....+---..+-...._.----+----.+----._..--- -----")

0

Bash tinh khiết, 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, tôi có thể lưu 10 byte để đạt 307 bằng cách viết dòng 1:

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

thay vì (nhưng tôi thích):

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

Mẫu vật:

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

hoặc nếu morsebộ chuyển đổi không được cài đặt:

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) ---.. ....-
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.