Translate Morse code based on tone duration

APL (Dyalog), 65 62 60 57 bytes

-3 thanks to ngn.

Tacit prefix function.

morse'/|[-.]+'⎕S'&'∘(⊃∘'/. -'¨6|'1+|(00)+'⎕S 1)

Try it online! Header, f←, and Footer are just to allow calling the function from Input while retaining TIO's byte count. In a normal APL session (corresponding to TIO's Input field), it would not be needed.

⎕CY'dfns'copy the dfns workspace (library)

() apply this tacit function:
'1+|(00)+'⎕S 1 PCRE Search 1-runs and even-length 0-runs and return matches' lengths
6| division remainder when divided by 6
⊃∘'/. -'¨ for each match length, pick the corresponding character from this string
'/|[-.]+'⎕S'&'∘ PCRE Search slashes and dash/dot-runs and return those
morse translate from Morse code to regular text

Python 2, 142 135 bytes

lambda s:''.join(' E-T----Z-Q---RSWU--2FH-V980NIMA--1CBYX-6--GDOK534PLJ-7'[int('0'+l.replace('111','3'),16)%57]for l in s.split('000'))

Try it online!


Splits the string into letters on 000 (0 thus means space)

Replaces each 111 with 3, and converts into base 16.

Then each number is modded by 57, which gives a range of 0..54, which is the index of the current character.

Previous version that converted to base 3:

Python 2, 273 252 247 bytes

lambda s:''.join(chr(dict(zip([0,242,161,134,125,122,121,202,229,238,241]+[2]*7+[5,67,70,22,1,43,25,40,4,53,23,49,8,7,26,52,77,16,13,2,14,41,17,68,71,76],[32]+range(48,91)))[int('0'+l.replace('111','2').replace('0',''),3)])for l in s.split('000'))

Try it online!

Previous version that converted to binary:

Python 2, 282 261 256 bytes

lambda s:''.join(chr(dict(zip([0,489335,96119,22391,5495,1367,341,1877,7637,30581,122333]+[2]*7+[23,469,1885,117,1,349,477,85,5,6007,471,373,119,29,1911,1501,7639,93,21,7,87,343,375,1879,7543,1909],[32]+range(48,91)))[int('0'+l,2)])for l in s.split('000'))

Try it online!

Ruby, 123 bytes

->s{s.split(/0000?/).map{|r|r[0]?"YE9_0IZTO_BHKU58V_GR_SFA__1_4NP_60X_____C__D_ML7WQ3__2__J"[r.to_i(2)%253%132%74]:" "}*""}

Try it online!

Split the input string on character limit. Use 3 or 4 OFF bits so that spaces are converted to empty strings. Take the base 2 value of every character, and bring into a reasonable range (less than 60 possible values) using modulo on 3 successive divisions.