7
\$\begingroup\$

Inspired by the Morse code question, and the Twinkle Twinkle little star question, write a program to accept a letter and generate the morse code audio for that letter.

\$\endgroup\$
2
  • \$\begingroup\$ Shell script (2 characters): cw. Accepts a line from standard input. Before running, do sudo apt-get install cw. \$\endgroup\$ Commented May 21, 2011 at 16:52
  • \$\begingroup\$ What are the allowed sounds we can use? Would 1hz be allowed, despite being considerably lower than what a human can hear (and my speaker can produce)? What should the timing be? \$\endgroup\$
    – rydwolf
    Commented Apr 8, 2021 at 20:53

5 Answers 5

6
\$\begingroup\$

Windows PowerShell, 200

Makes a dot 70 ms long. Accordingly, a dash is 210 ms and the gap between both is 70 ms as well.

[char[]](-split' ☺ ☺    ☺ ☺  ☺       ☺  ☺☺           ☺☺☺ ☺ ☺  ☺   ☺☺ ☺  ☺☺☺  ☺☺  ☺☺ ☺  ☺      ☺   ☺    ☺  ☺☺ ☺  ☺ ☺ ☺☺ ☺☺  ')[[char]"$input".ToUpper()-65]|%{[Console]::Beep(880,70+140*$_)
sleep -m 70}

Since this contains control characters, here's a hexdump:

000: 5B 63 68 61 72 5B 5D 5D │ 28 2D 73 70 6C 69 74 27  [char[]](-split'
010: 00 01 20 01 00 00 00 20 │ 01 00 01 00 20 01 00 00   ☺ ☺    ☺ ☺  ☺
020: 20 00 20 00 00 01 00 20 │ 01 01 00 20 00 00 00 00       ☺  ☺☺
030: 20 00 00 20 00 01 01 01 │ 20 01 00 01 20 00 01 00       ☺☺☺ ☺ ☺  ☺
040: 00 20 01 01 20 01 00 20 │ 01 01 01 20 00 01 01 00    ☺☺ ☺  ☺☺☺  ☺☺
050: 20 01 01 00 01 20 00 01 │ 00 20 00 00 00 20 01 20   ☺☺ ☺  ☺      ☺
060: 00 00 01 20 00 00 00 01 │ 20 00 01 01 20 01 00 00    ☺    ☺  ☺☺ ☺
070: 01 20 01 00 01 01 20 01 │ 01 00 00 27 29 5B 5B 63  ☺ ☺ ☺☺ ☺☺  ')[[c
080: 68 61 72 5D 22 24 69 6E │ 70 75 74 22 2E 54 6F 55  har]"$input".ToU
090: 70 70 65 72 28 29 2D 36 │ 35 5D 7C 25 7B 5B 43 6F  pper()-65]|%{[Co
0A0: 6E 73 6F 6C 65 5D 3A 3A │ 42 65 65 70 28 38 38 30  nsole]::Beep(880
0B0: 2C 37 30 2B 31 34 30 2A │ 24 5F 29 0A 73 6C 65 65  ,70+140*$_)◙slee
0C0: 70 20 2D 6D 20 37 30 7D │                          p -m 70}

I have tried several variants pf packing the data more tightly, but PowerShell is quite verbose in unpacking them again, so I don't gain much, sadly.

\$\endgroup\$
2
  • \$\begingroup\$ What the bloody hell is that?! Please 'splain how smileys make Morse code? \$\endgroup\$
    – Iszi
    Commented Dec 16, 2013 at 20:27
  • \$\begingroup\$ Character 1 in code page 437 is a control character, but has a glyph in the mapping table. This glyph is a smiley. When displaying control characters in that code page without interpreting them (e.g. by writing directly to video memory) it becomes said smiley. The relevant data is in the hex dump I provided. \$\endgroup\$
    – Joey
    Commented Dec 16, 2013 at 22:30
3
\$\begingroup\$

QBASIC (236 characters)

I count each newline as one character because QBasic seems to work fine without carriage returns, at least when running in DOSBox. Note that it only supports letters, not digits or punctuation.

INPUT Y$:C&=2^(26-ASC(Y$)MOD 32):A&=31313855AND C&:B&=60257815AND C&:M&=29932103:GOSUB S
IF A&OR B&THEN M&=34172681:GOSUB S
IF A&THEN M&=9538602:GOSUB S
IF A&AND B&THEN M&=66070:GOSUB S
END
S:SOUND 750,SGN(M&AND C&)*2+1:SOUND 0,1:RETURN
\$\endgroup\$
2
  • \$\begingroup\$ Ok, I have to admit having trouble figuring out how you pull the tones out of the numbers again. Could you elaborate a bit on how you do it? \$\endgroup\$
    – Joey
    Commented May 21, 2011 at 22:27
  • \$\begingroup\$ @Joey: Added an explanation to my JScript.NET answer, which works the same way. \$\endgroup\$ Commented May 22, 2011 at 2:24
3
\$\begingroup\$

JScript .NET (174 characters)

A little-known programming language from Microsoft, it combines the (relative) terseness of JavaScript with the power of the .NET Common Language Runtime. Thanks minitech and Joey for Console.Beep.

This program accepts a single letter from standard input (A-Z or a-z only). It does not explicitly add intra-character pauses, but they do exist, at least on Windows 7.

morse.js

function S(a){K.Beep(750,!!(a&C)*99+50)}import System;var K=Console,C=1<<26-K.Read()%32,A=31313855&C,B=60257815&C;S(29932103);(A||B)&&S(34172681);A&&S(9538602);A&&B&&S(66070)

Compile with:

%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\jsc morse.js

Explanation

Six 32-bit integers, of which 26 bits are used in each, serve as lookup tables. Each bit in a table corresponds to a letter of the alphabet, bit 25 used for A and bit 0 used for Z.

C = 1 << (26 - (K.Read() % 32)),

Because Morse code is a variable-length code that uses between 1 and 4 symbols for each letter, the tables 31313855 (bit 1) and 60257815 (bit 0) can together represent one less than the length of each letter's code.

A = 31313855 & C,
B = 60257815 & C;

The program uses additional lookup tables to store the dots and dashes for each letter. Using logic expressions of A and B, it stops once it has sent the correct number of symbols to the sound card.

S(29932103);
(A || B) && S(34172681);
A && S(9538602);
A && B && S(66070);

In each of the four lookup tables above, a zero represents a dot; a one represents a dash. !! (logical "not-not") is used to normalize false to 0 and true to 1 (to compensate for the differing locations of bits within the integer). The multiplication and addition of this value causes a dot to be a 50 ms, 750 Hz tone and a dash to be a (50 + 99) = 149 ms tone.

function S(a) {
  K.Beep(750, !!(a & C) * 99 + 50)
}
\$\endgroup\$
3
\$\begingroup\$

Sure.

VB.NET, 235 223 221 218 210 209 208 209 characters


With the appropriate structures, it is 245 characters.

Requires Option Strict to be Off for the latest one.

For Each c In"sl lsss lsls lss s ssls lls ssss ss slll lsl slss ll ls lll slls llsl sls sss l ssl sssl sll lssl lsll llss".Split()(Asc(UCase(Console.ReadKey.KeyChar))-65)
Console.Beep(1E3,200-(c="l")*400)
Next

Recent edits:

  • Fixed the incorrect "b".
  • Changed 999 to 1E3 so I can finally have that perfect thousand ;-)
  • Used boolean->integer conversion to save 2 characters.
\$\endgroup\$
7
  • 2
    \$\begingroup\$ The task says »Write a program ...«. I only see a few statements that won't compile on their own. Adding the module and sub declarations brings this to 272. \$\endgroup\$
    – Joey
    Commented May 20, 2011 at 0:10
  • 2
    \$\begingroup\$ Who cares? Those are an unfair handicap and add absolutely nothing to the functionality of the program. I believe (as is noted in all of my questions here on Code Golf/Challenges) that default language structure should be able to be omitted from submissions to level the playing field. If you disagree, so be it. All I see here is over-sensitive nitpicking, and although nitpicking is great on programming forums, that kind of goes too far. \$\endgroup\$
    – Ry-
    Commented May 20, 2011 at 0:59
  • 2
    \$\begingroup\$ As for handicap and nitpicking: You may have your opinion there, but unless a task specifically asks for a code snippet instead of a function or complete program then your answer is just wrong according to the task specification. It's fine when your own tasks use a different metric, but respect that not everyone else uses it for their tasks. There are languages that golf better than others. No handicap you use will change that; we've discussed that on Meta already a while ago. \$\endgroup\$
    – Joey
    Commented May 20, 2011 at 1:17
  • \$\begingroup\$ @Joey: Using the Split() function would prevent me from saving a space after In so it comes to the same number of characters. Maybe it has been discussed on Meta, but really - this is the important part. \$\endgroup\$
    – Ry-
    Commented May 20, 2011 at 1:22
  • 4
    \$\begingroup\$ Adding the extra boilerplate does add something to the functionality of the program: it adds the ability for people who don't know the language to test it without having to learn the syntax. \$\endgroup\$ Commented May 20, 2011 at 7:13
1
\$\begingroup\$

Powershell, 184 120 bytes

for($d='0;?3,>5:.H7<1/9@E42-6B8CG='[$args[0][0]-65]-42;$d-1){[Console]::Beep(880,200*($d%2*3+1))
$d=$d-shr1
sleep -m 70}

Test script:

$f = {

for($d='0;?3,>5:.H7<1/9@E42-6B8CG='[$args[0][0]-65]-42;$d-1){[Console]::Beep(880,200*(($d%2)*3+1))
$d=$d-shr1
sleep -m 70}

}

&$f "A"
sleep -m 700
&$f "B"

I used a timing setup for beginers:

  • the dot duration is 200ms
  • the gap between elements is less then dot duration (70 ms)
  • the dash duration is 4 dot durations
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.