57

挑战

按字符计数的最短代码,将仅使用字母字符(大写和小写)、数字、逗号、句点和问号输入字符串,并以摩尔斯电码返回字符串的表示形式。摩尔斯电码输出应包含-用于长哔声(AKA 'dah')的破折号( ,ASCII 0x2D)和.用于短哔声(AKA'dit')的点( ,ASCII 0x2E)。

每个字母应该用空格分隔(' ', ASCII 0x20),每个单词应该用正斜杠分隔(/, ASCII 0x2F)。

莫尔斯电码表:

替代文字 http://liranuna.com/junk/morse.gif

测试用例:

Input:
    Hello world

Output:
    .... . .-.. .-.. --- / .-- --- .-. .-.. -..

Input:
    Hello, Stackoverflow.

Output:
    .... . .-.. .-.. --- --..-- / ... - .- -.-. -.- --- ...- . .-. ..-. .-.. --- .-- .-.-.-

代码计数包括输入/​​输出(即完整程序)。

4

32 回答 32

70

C(131 个字符)

是的,13 1

main(c){for(;c=c?c:(c=toupper(getch())-32)?
"•ƒŒKa`^ZRBCEIQiw#S#nx(37+$6-2&@/4)'18=,*%.:0;?5"
[c-12]-34:-3;c/=2)putch(c/2?46-c%2:0);}

while通过将andfor循环中的逻辑组合到一个for循环中,并将c变量的声明main作为输入参数移动到定义中,我获得了更多字符。我从strager 对另一个挑战的回答中借用了后一种技术。


对于那些尝试使用 GCC 或纯 ASCII 编辑器验证程序的人,您可能需要以下稍长的版本:

main(c){for(;c=c?c:(c=toupper(getchar())-32)?c<0?1:
"\x95#\x8CKa`^ZRBCEIQiw#S#nx(37+$6-2&@/4)'18=,*%.:0;?5"
[c-12]-34:-3;c/=2)putchar(c/2?46-c%2:32);}

由于以下更改,此版本长了 17 个字符(占相当大的 148 个字符):

  • +4:getchar()而不putchar()是非便携式getch()putch()
  • +6:两个字符的转义码,而不是非 ASCII 字符
  • +1: 32 而不是 0 用于空格字符
  • +6:添加“ c<0?1:”以抑制来自小于 ASCII 32 的字符(即 from '\n')的垃圾。您仍然会从任何!"#$%&'()*+[\]^_`{|}~或 ASCII 126 以上的任何内容中得到垃圾。

这应该使代码完全可移植。编译:

gcc -std=c89 -funsigned-char morse.c

-std=c89是可选的。但是,这-funsigned-char是必要的,否则您将得到逗号和句号的垃圾。


135 个字符

c;main(){while(c=toupper(getch()))for(c=c-32?
"•ƒŒKa`^ZRBCEIQiw#S#nx(37+$6-2&@/4)'18=,*%.:0;?5"
[c-44]-34:-3;c;c/=2)putch(c/2?46-c%2:0);}

在我看来,这个最新版本在视觉上也更具吸引力。不,它不是可移植的,并且不再受到越界输入的保护。它还有一个非常糟糕的用户界面,逐个字符输入并将其转换为摩尔斯电码并且没有退出条件(你必须点击Ctrl+ Break)。但可移植、健壮的代码和漂亮的 UI 并不是必需的。

代码的简要解释如下:

main(c){
    while(c = toupper(getch())) /* well, *sort of* an exit condition */
        for(c =
            c - 32 ? // effectively: "if not space character"
            "•ƒŒKa`^ZRBCEIQiw#S#nx(37+$6-2&@/4)'18=,*%.:0;?5"[c - 44] - 34
            /* This array contains a binary representation of the Morse Code
             * for all characters between comma (ASCII 44) and capital Z.
             * The values are offset by 34 to make them all representable
             * without escape codes (as long as chars > 127 are allowed).
             * See explanation after code for encoding format.
             */
            : -3; /* if input char is space, c = -3
                   * this is chosen because -3 % 2 = -1 (and 46 - -1 = 47)
                   * and -3 / 2 / 2 = 0 (with integer truncation)
                   */
            c; /* continue loop while c != 0 */
            c /= 2) /* shift down to the next bit */
                putch(c / 2 ? /* this will be 0 if we're down to our guard bit */
                    46 - c % 2 /* We'll end up with 45 (-), 46 (.), or 47 (/).
                                * It's very convenient that the three characters
                                * we need for this exercise are all consecutive.
                                */
                    : 0 /* we're at the guard bit, output blank space */
                );
}

代码中长字符串中的每个字符都包含一个文本字符的编码摩尔斯电码。编码字符的每一位代表一个破折号或一个点。一个代表一个破折号,一个零代表一个点。最低有效位表示莫尔斯电码中的第一个破折号或点。最后的“保护”位决定了代码的长度。也就是说,每个编码字符中的最高一位表示代码结束并且不打印。如果没有这个保护位,就无法正确打印带有尾随点的字符。

例如,字母“L .-..”在摩尔斯电码中是“”。为了用二进制表示,我们需要一个 0、一个 1 和另外两个 0,从最低有效位开始:0010。再加一个 1 作为保护位,我们得到编码的摩尔斯电码:10010,或十进制18.加上+34的偏移量得到52,即字符'4'的ASCII值。所以编码字符数组的第 33 个字符(索引 32)有一个“4”。

这种技术类似于用于在AColie'sstrager's (2)Miles'spingw33n'sAlec'sAndrea 的解决方案中对字符进行编码的技术,但稍微简单一些,每个位只需要一个操作(移位/除法),而不是两个(移位/除法和递减)。

编辑:
阅读其余的实现,我发现AlecAnon比我先提出了这种编码方案——使用保护位。Anon 的解决方案特别有趣,它使用 Python 的bin函数并用 去除"0b"前缀和保护位[3:],而不是像 Alec 和我那样循环、与和移位。

作为奖励,此版本还处理连字符 ( -....-)、斜线 ( -..-.)、冒号 ( ---...)、分号 ( -.-.-.)、等号 ( -...-) 和 at 符号 ( .--.-.)。只要允许使用 8 位字符,这些字符就不需要额外的代码字节来支持。在不增加代码长度的情况下,此版本无法支持更多字符(除非有用于大于/小于符号的莫尔斯电码)。

因为我发现旧的实现仍然很有趣,并且文本有一些适用于这个版本的警告,所以我把这篇文章的以前的内容留在了下面。


好吧,大概,用户界面很糟糕,对吧?因此,借用strager,我gets()将提供缓冲、回显行输入的替换为getch(),它提供无缓冲、无回显字符输入。这意味着您输入的每个字符都会立即转换为屏幕上的摩尔斯电码。也许这很酷。它不再适用于标准输入或命令行参数,但它非常小。

不过,我保留了下面的旧代码以供参考。这是新的。

新代码,带边界检查,171 个字符:

W(i){i?W(--i/2),putch(46-i%2):0;}c;main(){while(c=toupper(getch())-13)
c=c-19?c>77|c<31?0:W("œ*~*hXPLJIYaeg*****u*.AC5+;79-@6=0/8?F31,2:4BDE"
[c-31]-42):putch(47),putch(0);}

Enter打破循环并退出程序。

新代码,无边界检查,159 个字符:

W(i){i?W(--i/2),putch(46-i%2):0;}c;main(){while(c=toupper(getch())-13)
c=c-19?W("œ*~*hXPLJIYaeg*****u*.AC5+;79-@6=0/8?F31,2:4BDE"[c-31]-42):
putch(47),putch(0);}

下面遵循旧的 196/177 代码,并进行一些解释:

W(i){i?W(--i/2),putch(46-i%2):0;}main(){char*p,c,s[99];gets(s);
for(p=s;*p;)c=*p++,c=toupper(c),c=c-32?c>90|c<44?0:W(
"œ*~*hXPLJIYaeg*****u*.AC5+;79-@6=0/8?F31,2:4BDE"[c-44]-42):
putch(47),putch(0);}

这是基于Andrea 的 Python 答案,使用与该答案相同的技术生成莫尔斯电码。但是,我没有一个接一个地存储可编码字符并找到它们的索引,而是一个接一个地存储索引并按字符查找它们(类似于我之前的答案)。这可以防止在结尾处出现给早期实现者带来问题的长间隙。

以前一样,我使用了大于 127 的字符。将其转换为 ASCII-only 会增加 3 个字符。长字符串的第一个字符必须替换为\x9C。这次偏移量是必须的,否则大量字符在32以下,必须用转义码表示。

同样和以前一样,处理命令行参数而不是标准输入会增加 2 个字符,而在代码之间使用实空格字符会增加 1 个字符。

另一方面,这里的一些其他例程不处理 [ ,.0-9\?A-Za-z] 可接受范围之外的输入。如果从该例程中删除此类处理,则可以删除 19 个字符,使总数减少到 177 个字符。但是如果这样做了,并且无效的输入被提供给这个程序,它可能会崩溃和烧毁。

这种情况下的代码可能是:

W(i){i?W(--i/2),putch(46-i%2):0;}main(){char*p,s[99];gets(s);
for(p=s;*p;p++)*p=*p-32?W(
"œ*~*hXPLJIYaeg*****u*.AC5+;79-@6=0/8?F31,2:4BDE"
[toupper(*p)-44]-42):putch(47),putch(0);}
于 2009-08-31T02:41:22.810 回答
47

使用莫尔斯电码字体

Console.Write(params[0]);
于 2009-08-29T23:01:07.007 回答
23

Perl,170 个字符(在有经验的高尔夫球手的帮助下mauke)。为清晰起见包裹;所有换行符都是可移动的。

$_=uc<>;y,. ,|/,;s/./$& /g;@m{A..Z,0..9,qw(| , ?)}=
".-NINNN..]IN-NII..AMN-AI---.M-ANMAA.I.-].AIAA-NANMMIOMAOUMSMSAH.B.MSOIONARZMIZ"
=~/../g;1while s![]\w|,?]!$m{$&}!;print

解释:

  1. 提取莫尔斯字典。每个符号都根据两个字符定义,可以是文字点或破折号,也可以是对另一个已定义字符的值的引用。E 和 T 包含虚拟字符以避免解码器不同步;我们稍后会删除它们。
  2. 读取并格式化输入。"Hello world"变成"H E L L O / W O R L D"
  3. 下一步取决于输入和输出字典是否不同,因此将输入中的点转换为未使用的字符(竖线,|
  4. 将莫尔斯字典中出现的输入中的任何字符替换为其在字典中的值,直到没有替换发生。
  5. 删除步骤 1 中提到的虚拟字符。
  6. 打印输出。

在最终版本中,字典针对运行时效率进行了优化:

  • 所有单符号字符(E 和 T)和双符号字符(A、I、M 和 N)都直接定义并一次解码。
  • 所有三符号字符都根据两符号字符和文字符号定义,分两遍解码。
  • 所有的四符号字符都是根据两个二符号字符定义的,在两遍中解码三个替换。
  • 五个和六个符号字符(数字和标点符号)在三遍中解码,分别有四个或五个替换。

由于打高尔夫球的代码每个循环只替换一个字符(以节省一个字符的代码!),循环数被限制为输入长度的五倍(如果只使用字母,则为输入长度的三倍)。但是通过将 a 添加gs///操作中,循环的数量被限制为三个(如果只使用字母,则为两个)。

示例转换:

Hello 123
H E L L O / 1 2 3
II .] AI AI M- / AO UM SM
.... . .-.. .-.. --- / .-M- .A-- I.--
.... . .-.. .-.. --- / .---- ..--- ...--
于 2009-08-29T23:25:43.400 回答
16

Python 列表理解,159 个字符的单行

for c in raw_input().upper():print c<","and"/"or bin(ord("•ƒwTaQIECBRZ^`šŒ#S#n|':<.$402&9/6)(18?,*%+3-;=>"[ord(c)-44])-34)[3:].translate(" "*47+"/.-"+" "*206),

使用与P Daddy 的 C 实现类似的数据打包,但不以相反的顺序存储位,并用于bin()提取数据而不是算术。另请注意,使用不等式检测空格;它认为每个“小于逗号”的字符都是一个空格。

Pythonfor循环,205 个字符,包括换行符

for a in raw_input().upper():
 q='_ETIANMSURWDKGOHVF_L_PJBXCYZQ__54_3___2__+____16=/_____7___8_90'.find(a);s=''
 while q>0:s='-.'[q%2]+s;q=~-q/2
 print['/','--..--','..--..','.-.-.-',''][' ,?.'.find(a)]+s,
于 2009-08-29T23:23:10.940 回答
7

我正在为符号使用紧凑的编码,但我看不出是否比已经使用的隐式树更好,所以我在这里展示编码以防其他人可以使用它。

考虑字符串:

 --..--..-.-.-..--...----.....-----.--/

其中包含所有需要的序列作为子字符串。我们可以像这样通过偏移量和长度对符号进行编码:

       ET  RRRIIGGGJJJJ    
--..--..-.-.-..--...----.....-----.--/
          CCCC  DD WWW       00000
,,,,,,   AALLLL BBBB        11111
--..--..-.-.-..--...----.....-----.--/
  ??????  KKK  MMSSS       22222   
        FFFF  PPPP        33333
--..--..-.-.-..--...----.....-----.--/
        UUU XXXX         44444       
          NN  PPPP  OOO 55555
--..--..-.-.-..--...----.....-----.--/
               ZZZZ    66666
                      77777      YYYY
--..--..-.-.-..--...----.....-----.--/
       ......        88888 HHHH
                    99999 VVVV  QQQQ
--..--..-.-.-..--...----.....-----.--/

空格(即单词边界)在最后一个字符('/')上开始和结束。如果您看到一个好方法,请随意使用它。

当然,大多数较短的符号都有几种可能的编码。


P Daddy 找到了这个技巧的一个更短的版本(我现在可以在这里看到至少一些冗余)并做了一个很好的 c 实现。Alec使用第一个(错误且不完整的)版本进行了 python 实现。Hobbs 做了一个非常紧凑的 perl 版本,我完全不明白。

于 2009-08-30T01:40:44.900 回答
6

J,124 130 134 个字符

'.- /'{~;2,~&.>(]`(<&3:)@.(a:=])"0)}.&,&#:&.></.40-~a.i.')}ggWOKIHX`dfggggggg-@B4*:68,?5</.7>E20+193ACD'{~0>.45-~a.i.toupper

J击败C!惊人的!

用法:

   '.- /'{~;2,~&.>(]`(<&3:)@.(a:=])"0)}.&,&#:&.></.40-~a.i.')}ggWOKIHX`dfggggggg-@B4*:68,?5</.7>E20+193ACD'{~0>.45-~a.i.toupper 'Hello World'
.... . .-.. .-.. --- / .-- --- .-. .-.. -.. 

   '.- /'{~;2,~&.>(]`(<&3:)@.(a:=])"0)}.&,&#:&.></.40-~a.i.')}ggWOKIHX`dfggggggg-@B4*:68,?5</.7>E20+193ACD'{~0>.45-~a.i.toupper 'Hello, Stackoverflow.'
.... . .-.. .-.. --- .-.-.- / ... - .- -.-. -.- --- ...- . .-. ..-. .-.. --- .-- --..-- 
于 2010-05-11T16:53:56.597 回答
5

Python 3 One Liner:172 个字符

print(' '.join('/'if c==' 'else''.join('.'if x=='0'else'-'for x in bin(ord("ijÁĕÁÿïçãáàðøüþÁÁÁÁÁČÁÅ×ÚÌÂÒÎÐÄ×ÍÔÇÆÏÖÝÊÈÃÉÑËÙÛÜ"[ord(c)-44])-192)[3:])for c in input().upper()))

(将翻译表编码为 un​​icode 代码点。工作正常,它们在我的 Windows Vista 机器上的测试中显示在这里很好。)

编辑通过删除一些不必要的空格和括号(使列表 comps gen exps)减少到 184 个字符。

再次编辑:在看到其他答案之前,我什至不知道可能会删除更多空格 - 所以降至 176。

通过使用 ' '.join 而不是 ''.join 并分别处理空格,再次编辑到 172(呜呜!)。(呃!)

于 2009-08-31T01:49:44.990 回答
5

C# 266 个字符

转换为 C# 的 131 char C 解决方案产生 266 个字符:

foreach(var i in Encoding.ASCII.GetBytes(args[0].ToUpper())){var c=(int)i;for(c=(c-32!=0)?Encoding.ASCII.GetBytes("•ƒŒKa`^ZRBCEIQiw#S#nx(37+$6-2&@/4)'18=,*%.:0;?5")[c-44]-34:-3;c!=0;c/=2)Console.Write(Encoding.ASCII.GetChars(new byte[]{(byte)((c/2!=0)?46-c%2:0)}));}

这更具可读性:

foreach (var i in Encoding.ASCII.GetBytes(args[0].ToUpper()))
{
    var c = (int)i;
    for (c = ((c - 32) != 0) ? Encoding.ASCII.GetBytes("•ƒŒKa`^ZRBCEIQiw#S#nx(37+$6-2&@/4)'18=,*%.:0;?5")[c - 44] - 34 : -3
        ; c != 0
        ; c /= 2)
        Console.Write(Encoding.ASCII.GetChars(new byte[] { (byte)((c / 2 != 0) ? 46 - c % 2 : 0) }));
}
于 2009-10-11T22:56:01.350 回答
5

Golfscript - 106 个字符 - 没有有趣的字符 :)

不支持输入末尾的换行符,所以使用类似这样的东西

echo -n Hello, Stackoverflow| ../golfscript.rb morse.gs

' '/{{.32|"!etianmsurwdkgohvf!l!pjbxcyzq"?)"UsL?/'#! 08<>"@".,?0123456789"?=or
2base(;>{'.-'\=}%' '}%}%'/'*

字母是一种特殊情况,转换为小写并按其二进制位置排序。
其他一切都由翻译表完成

于 2009-11-09T21:40:37.097 回答
4

Python

不完整的解决方案,但也许有人可以从中得出完整的解决方案。不处理数字或标点符号,但重量只有 154 个字符。

def e(l):
 i='_etianmsurwdkgohvf_l_pjbxcyzq'.find(l.lower());v=''
 while i>0:v='-.'[i%2]+v;i=(i-1)/2;return v or '/'
def enc(s):return ' '.join(map(e,s))
于 2009-08-30T00:46:29.687 回答
3

这是我在 VB.Net 中作为控制台应用程序的贡献

Module MorseCodeConverter

    Dim M() As String = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", "-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----."}

    Sub Main()
        Dim I, O
        Dim a, b

        While True
            I = Console.ReadLine()
            O = ""

            For Each a In I
                b = AscW(UCase(a))
                If b > 64 And b < 91 Then
                    O &= M(b - 65) & " "
                ElseIf b > 47 And b < 58 Then
                    O &= M(b - 22) & " "
                ElseIf b = 46 Then
                    O &= ".-.-.- "
                ElseIf b = 44 Then
                    O &= "--..-- "
                ElseIf b = 63 Then
                    O &= "..--.. "
                Else
                    O &= "/"
                End If

            Next

            Console.WriteLine(O)
        End While


    End Sub

End Module

我给他留了空白以使其可读。共 1100 个字符。它将从命令行读取输入,一次一行,并将相应的输出发送回输出流。压缩版如下,只有 632 个字符。

Module Q
    Dim M() As String={".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--..","-----",".----","..---","...--","....-",".....","-....","--...","---..","----."}
    Sub Main()
        Dim I,O,a,b:While 1:I=Console.ReadLine():O="":For Each a In I:b=AscW(UCase(a)):If b>64 And b<91 Then:O &=M(b-65)&" ":ElseIf b>47 And b<58 Then:O &=M(b-22)&" ":ElseIf b=46 Then:O &=".-.-.- ":ElseIf b=44 Then:O &="--..-- ":ElseIf b=63 Then:O &= "..--.. ":Else:O &="/":End IF:Next:Console.WriteLine(O):End While
    End Sub
End Module
于 2009-08-30T02:28:20.610 回答
3

C(248 个字符)

另一个基于树的解决方案。

#define O putchar
char z[99],*t=
" ETINAMSDRGUKWOHBL~FCPJVX~YZQ~~54~3~~~2~~+~~~~16=/~~.~~7,~~8~90";c,p,i=0;
main(){gets(z);while(c=z[i++]){c-46?c-44?c:O(45):O(c);c=c>96?c-32:c;p=-1;
while(t[++p]!=c);for(;p;p/=2){O(45+p--%2);}c-32?O(32):(O(47),O(c));}}

可能是源代码树中的错误,因为维基百科似乎有问题,或者我误解了某些东西。

于 2009-08-30T03:03:58.963 回答
3

F#,256 个字符

let rec D i=if i=16 then" "else
 let x=int"U*:+F8c]uWjGbJ0-0Dnmd0BiC5?\4o`h7f>9[1E=pr_".[i]-32
 if x>43 then"-"+D(x-43)else"."+D x
let M(s:string)=s.ToUpper()|>Seq.fold(fun s c->s+match c with
|' '->"/ "|','->"--..-- "|'.'->".-.-.- "|_->D(int c-48))""

例如

M("Hello, Stack.") |> printfn "%s"

产量

.... . .-.. .-.. --- --..-- / ... - .- -.-. -.- .-.-.-

我认为我的技术到目前为止可能是独一无二的。这个想法是:

  • 有一个 ascii 范围的字符,涵盖了我们想要的大部分内容(0..Z)
  • 此范围内只有 43 个字符
  • 因此我们可以在 86 个字符的范围内编码一位(破折号或点)加上一个“下一个字符”
  • 范围 ascii(32-117) 都是“可打印”的,可以用作这个 86 字符范围
  • 所以字符串文字沿着这些线对表格进行编码

还有一点,但这是要点。逗号、句点和空格不在 0..Z 范围内,因此它们由“匹配”特别处理。0..Z 范围内的一些“未使用”字符(如“;”)在表中用作其他莫尔斯翻译的后缀,这些翻译本身不是莫尔斯“字母”。

于 2009-08-30T20:58:39.343 回答
3

C(233 个字符)

W(n,p){while(n--)putch(".-.-.--.--..--..-.....-----..../"[p++]);}main(){
char*p,c,s[99];gets(s);for(p=s;*p;){c=*p++;c=toupper(c);c=c>90?35:c-32?
"È#À#¶µ´³²±°¹¸·#####Ê#@i Že‘J•aEAv„…`q!j“d‰ƒˆ&quot;[c-44]:63;c-35?
W(c>>5,c&31):0;putch(0);}}

这需要来自标准输入的输入。从命令行获取输入会添加 2 个字符。代替:

...main(){char*p,c,s[99];gets(s);for(p=s;...

你得到:

...main(int i,char**s){char*p,c;for(p=s[1];...

我对 127 以上的字符使用 Windows-1252 代码页,但我不确定它们会如何出现在其他人的浏览器中。我注意到,至少在我的浏览器(谷歌浏览器)中,两个字符(“@”和“i”之间)没有出现。但是,如果您从浏览器中复制并粘贴到文本编辑器中,它们确实会显示出来,尽管只是小方框。

它可以仅转换为 ASCII,但这会增加 24 个字符,从而将字符数增加到 257。为此,我首先将字符串中的每个字符偏移 -64,从而最大限度地减少大于 127 的字符数。然后我在必要时替换\xXX字符转义。它改变了这一点:

...c>90?35:c-32?"È#À#¶µ´³²±°¹¸·#####Ê#@i Že‘J•aEAv„…`q!j“d‰ƒˆ&quot;[c-44]:63;
c-35?W(...

对此:

...c>90?99:c-32?"\x88#\x80#vutsrqpyxw#####\x8A#\0PA)\xE0N%Q\nU!O\5\1\66DE 1
\xE1*S$ICH"[c-44]+64:63;c-99?W(...

这是代码的格式和注释更好的版本:

/* writes `n` characters from internal string to stdout, starting with
 * index `p` */
W(n,p){
    while(n--)
        /* warning for using putch without declaring it */
        putch(".-.-.--.--..--..-.....-----..../"[p++]);

        /* dmckee noticed (http://tinyurl.com/n4eart) the overlap of the
         * various morse codes and created a 37-character-length string that
         * contained the morse code for every required character (except for
         * space).  You just have to know the start index and length of each
         * one.  With the same idea, I came up with this 32-character-length
         * string.  This not only saves 5 characters here, but means that I
         * can encode the start indexes with only 5 bits below.
         *
         * The start and length of each character are as follows:
         *
         *   A:  0,2    K:  1,3    U: 10,3    4: 18,5
         *   B: 16,4    L: 15,4    V: 19,4    5: 17,5
         *   C:  1,4    M:  5,2    W:  4,3    6: 16,5
         *   D:  9,3    N:  1,2    X:  9,4    7: 25,5
         *   E:  0,1    O: 22,3    Y:  3,4    8: 24,5
         *   F: 14,4    P:  4,4    Z:  8,4    9: 23,5
         *   G:  5,3    Q:  5,4    0: 22,5    .:  0,6
         *   H: 17,4    R:  0,3    1: 21,5    ,:  8,6
         *   I: 20,2    S: 17,3    2: 20,5    ?: 10,6
         *   J: 21,4    T:  1,1    3: 19,5
         */
}

main(){ /* yuck, but it compiles and runs */
    char *p, c, s[99];
    /* p is a pointer within the input string */
    /* c saves from having to do `*p` all the time */
    /* s is the buffer for the input string */

    gets(s); /* warning for use without declaring */

    for(p=s; *p;){ /* begin with start of input, go till null character */
        c = *p++; /* grab *p into c, increment p.
                   * incrementing p here instead of in the for loop saves
                   * one character */

        c=toupper(c); /* warning for use without declaring */

        c = c > 90 ? 35 : c - 32 ?
            "È#À#¶µ´³²±°¹¸·#####Ê#@i Že‘J•aEAv„…`q!j“d‰ƒˆ&quot;[c - 44] : 63;

        /**** OR, for the ASCII version ****/

        c = c > 90 ? 99 : c - 32 ?
           "\x88#\x80#vutsrqpyxw#####\x8A#\0PA)\xE0N%Q\nU!O\5\1\66DE 1\xE1"
           "*S$ICH"[c - 44] + 64 : 63;

        /* Here's where it gets hairy.
         *
         * What I've done is encode the (start,length) values listed in the
         * comment in the W function into one byte per character.  The start
         * index is encoded in the low 5 bits, and the length is encoded in
         * the high 3 bits, so encoded_char = (char)(length << 5 | position).
         * For the longer, ASCII-only version, 64 is subtracted from the
         * encoded byte to reduce the necessity of costly \xXX representations.
         * 
         * The character array includes encoded bytes covering the entire range
         * of characters covered by the challenge, except for the space
         * character, which is checked for separately.  The covered range
         * starts with comma, and ends with capital Z (the call to `toupper`
         * above handles lowercase letters).  Any characters not supported are
         * represented by the "#" character, which is otherwise unused and is
         * explicitly checked for later.  Additionally, an explicit check is
         * done here for any character above 'Z', which is changed to the
         * equivalent of a "#" character.
         * 
         * The encoded byte is retrieved from this array using the value of
         * the current character minus 44 (since the first supported character
         * is ASCII 44 and index 0 in the array).  Finally, for the ASCII-only
         * version, the offset of 64 is added back in.
         */

        c - 35 ? W(c >> 5, c & 31) : 0;

        /**** OR, for the ASCII version ****/

        c - 99 ? W(c >> 5, c & 31) : 0;

        /* Here's that explicit check for the "#" character, which, as
         * mentioned above, is for characters which will be ignored, because
         * they aren't supported.  If c is 35 (or 99 for the ASCII version),
         * then the expression before the ? evaluates to 0, or false, so the
         * expression after the : is evaluated.  Otherwise, the expression
         * before the ? is non-zero, thus true, so the expression before
         * the : is evaluated.
         *
         * This is equivalent to:
         *
         *     if(c != 35) // or 99, for the ASCII version
         *         W(c >> 5, c & 31);
         *
         * but is shorter by 2 characters.
         */

        putch(0);
        /* This will output to the screen a blank space.  Technically, it's not
         * the same as a space character, but it looks like one, so I think I
         * can get away with it.  If a real space character is desired, this
         * must be changed to `putch(32);`, which adds one character to the
         * overall length.
    } /* end for loop, continue with the rest of the input string */
} /* end main */

除了几个 Python 实现之外,这比这里的一切都好。我一直在想它不能再短了,但后来我找到了一些方法来剃掉更多的字符。如果有人能找到更多改进的空间,请告诉我。

编辑:

我注意到,尽管此例程拒绝任何高于 ASCII 44 的无效字符(每个字符只输出一个空格),但它不会检查低于该值的无效字符。要检查这些会在总长度上增加 5 个字符,请更改以下内容:

...c>90?35:c-32?"...

对此:

...c-32?c>90|c<44?35:"...
于 2009-08-30T21:42:08.520 回答
3

REBOL(118 个字符)

大约有 10 年历史的实施

foreach c ask""[l: index? find" etinamsdrgukwohblzfcpövxäqüyj"c while[l >= 2][prin pick"-."odd? l l: l / 2]prin" "]

引自:http ://www.rebol.com/oneliners.html

(虽然没有数字,单词只是用双空格分隔:/ ...)

于 2010-02-02T01:04:09.250 回答
2

蟒蛇2;171 个字符

与Andrea 的解决方案基本相同,但作为一个完整的程序,并使用愚蠢的技巧使其更短。

for c in raw_input().lower():print"".join(".-"[int(d)]for d in bin(
('  etianmsurwdkgohvf_l_pjbxcyzq__54_3___2%7s16%7s7___8_90%12s?%8s.%29s,'
%(('',)*5)).find(c))[3:])or'/',

(添加的换行符都可以去掉)

或者,如果您不想使用bin()2.6 中的功能,我们可以在 176 中使用:

for c in raw_input():C=lambda q:q>0and C(~-q/2)+'-.'[q%2]or'';print C(
(' etianmsurwdkgohvf_l_pjbxcyzq__54_3___2%7s16%7s7___8_90%12s?%8s.%29s,'%
(('',)*5)).find(c.lower()))or'/',

(同样,添加的换行符都可以删除)

于 2009-08-30T03:02:03.897 回答
2

Python(210 个字符)

这是一个基于Alec的完整解决方案

def e(l):
 i=(' etianmsurwdkgohvf_l_pjbxcyzq__54_3___2%7s16%7s7___8_90%12s?%8s.%29s,'%tuple('_'*5)).find(l.lower());v=''
 while i>0:v='-.'[i%2]+v;i=(i-1)/2
 return v or '/'
def enc(s):return ' '.join(map(e,s))
于 2009-08-30T13:43:02.677 回答
2

C,338 个字符

338 删除了缩进和所有可移动的换行符:

#define O putchar
#define W while
char*l="x@@@@@ppmmmmm@@FBdYcbcbSd[Kcd`\31(\b1g_<qCN:_'|\25D$W[QH0";
int c,b,o;
main(){
  W(1){
    W(c<32)
      c=getchar()&127;
    W(c>96)
      c^=32;
    c-=32;
    o=l[c/2]-64;
    b=203+(c&1?o>>3:0);
    o=c&1?o&7:o>>3;
    W(o>6)
      O(47),o=0;
    c/=2;
    W(c--)
      b+=(l[c]-64&7)+(l[c]-64>>3);
    b=(((l[b/7]<<7)+l[b/7+1])<<(b%7))>>14-o;
    W(o--)
      O(b&(1<<o)?46:45);
    O(32);
  }
}

这不是基于其他人一直采用的树方法。相反,l首先将 32 到 95 之间的所有字节的长度(包括两个字节)编码为一个字符。例如,对于长度为 3 的 D 是 -.. 而 E 是 。长度为 1。这被编码为 011 和 001,给出 011001。为了使更多字符可编码并避免转义,然后将 64 添加到总数中,给出 1011001 - 89,ASCII Y。非莫尔斯字符被分配一个长度为 0。 l(以 开头)的后半部分是\031莫尔斯电码本身的位,点为 1,破折号为 0。为避免进入高位 ASCII,此数据被编码为 7 位/字节。

代码首先c对 进行清理,然后计算出c(in o) 的莫尔斯长度,然后将所有先前字符的长度相加以产生b数据中的位索引。

最后,它遍历位,打印点和破折号。

长度 '7' 用作遇到空格时打印 / 的特殊标志。

删除括号可能会有一些小收获,但我离一些更好的结果还差得很远,而且我很饿,所以......

于 2009-08-30T20:04:39.187 回答
2

C# 使用 Linq(133 个字符)

    static void Main()
    {
        Console.WriteLine(String.Join(" ", (from c in Console.ReadLine().ToUpper().ToCharArray()
                                            select m[c]).ToArray()));
    }

好吧,所以我作弊了。您还需要按如下方式定义字典(不费心计算字符,因为这让我退出了游戏):

    static Dictionary<char, string> m = new Dictionary<char, string>() {
            {'A', ".-"},
            {'B', "-.."},
            {'C', "-.-."},
            {'D', "-.."},
            {'E', "."},
            {'F', "..-."},
            {'G', "--."},
            {'H', "...."},
            {'I', ".."},
            {'J', ".---"},
            {'K', "-.-"},
            {'L', ".-.."},
            {'M', "--"},
            {'N', "-."},
            {'O', "---"},
            {'P', ".--."},
            {'Q', "--.-"},
            {'R', ".-."},
            {'S', "..."},
            {'T', "-"},
            {'U', "..-"},
            {'V', "...-"},
            {'W', ".--"},
            {'X', "-..-"},
            {'Y', "-.--"},
            {'Z', "--.."},
            {'0', "-----"},
            {'1', ".----"},
            {'2', "..---"},
            {'3', "...--"},
            {'4', "....-"},
            {'5', "....."},
            {'6', "-...."},
            {'7', "--..."},
            {'8', "---.."},
            {'9', "----."},
            {' ', "/"},
            {'.', ".-.-.-"},
            {',', "--..--"},
            {'?', "..--.."},
        };

不过,有人可以提供一个更简洁的 C# 实现,它也像这样易于理解和维护吗?

于 2009-08-31T04:37:53.773 回答
2

Perl,206个字符,使用dmckee的idea

这比我提交的第一个要长,但我仍然认为它很有趣。和/或可怕。我不肯定。这利用了 dmckee 的编码理念,以及我在周围看到的其他几个好主意。最初,我认为“固定字符串中的长度/偏移量”不能比我的其他解决方案中的方案产生更少的数据,该方案使用每个字符固定的两个字节(以及所有可打印字节)。事实上,我确实设法将数据减少到相当少(每个字符一个字节,加上四个字节来存储我们要索引到的 26 位模式),但是再次取出它的代码更长,尽管我尽了最大努力打高尔夫球。(不太复杂,IMO,但无论如何更长)。

无论如何,206 个字符;除第一个换行符外,换行符是可移动的。

#!perl -lp
($a,@b)=unpack"b32C*",
"\264\202\317\0\31SF1\2I.T\33N/G\27\308XE0=\x002V7HMRfermlkjihgx\207\205";
$a=~y/01/-./;@m{A..Z,0..9,qw(. , ?)}=map{substr$a,$_%23,1+$_/23}@b;
$_=join' ',map$m{uc$_}||"/",/./g

解释:

  • 数据有两部分。前四个字节 ( "\264\202\317\0") 表示 32 位莫尔斯电码 ( "--.-..-.-.-----.....--..--------"),尽管仅使用前 26 位。这是“参考字符串”。
  • 数据字符串的其余部分存储代表每个字符的参考字符串的子字符串的起始位置和长度——每个字符一个字节,顺序为 (A, B, ... Z, 0, 1, ... 9 , ".", ",", "?")。这些值编码为 23 * (length - 1) + pos,解码器将其反转。最后一个起始位置当然是 22。
  • 所以解包完成了提取数据的一半工作,而第三行(如这里所见)完成了剩下的工作,现在我们有了一个带有$m{'a'} = '.-'等的哈希,所以剩下的就是匹配输入的字符,在哈希,并格式化输出,最后一行所做的......在shebang的一些帮助下,它告诉perl删除输入上的换行符,将输入行放入$_,当代码完成运行时,写$_回输出再次添加换行符。
于 2009-08-31T08:18:31.347 回答
1

C89(293 个字符)

基于其他一些答案。

编辑:缩小树(耶)。

#define P putchar
char t['~']="~ETIANMSURWDKGOHVF~L~PJBXCYZQ~~54~3",o,q[9],Q=10;main(c){for(;Q;)t[
"&./7;=>KTr"[--Q]]="2167890?.,"[Q];while((c=getchar())>=0){c-=c<'{'&c>96?32:0;c-
10?c-32?0:P(47):P(10);for(o=1;o<'~';++o)if(t[o]==c){for(;o;o/=2)q[Q++]=45+(o--&1
);for(;Q;P(q[--Q]));break;}P(32);}}
于 2009-08-30T01:55:56.880 回答
1

这是另一种方法,基于 dmckee 的工作,展示了 Python 的可读性:

Python

244 个字符

def h(l):p=2*ord(l.upper())-88;a,n=map(ord,"AF__GF__]E\\E[EZEYEXEWEVEUETE__________CF__IBPDJDPBGAHDPC[DNBSDJCKDOBJBTCND`DKCQCHAHCZDSCLD??OD"[p:p+2]);return "--..--..-.-.-..--...----.....-----.-"[a-64:a+n-128]
def e(s):return ' '.join(map(h,s))

限制:

  • dmckee 的字符串漏掉了 'Y' 字符,我懒得加了。我想你只需要改变“??” 部分,并在第二个字符串文字的末尾添加一个“-”
  • 它不会在单词之间添加“/”;又是懒

由于规则要求最少字符,而不是最少字节,如果您愿意超出可打印的 ASCII 字符,您可以至少将我的一个查找表缩小(减半)。

编辑:如果我使用天真的选择的 Unicode 字符,但只是将它们保存在源文件中的转义 ASCII 中,它仍然会缩短一点,因为解码器更简单:

Python

240 个字符

def h(l):a,n=divmod(ord(u'\x06_7_\xd0\xc9\xc2\xbb\xb4\xad\xa6\x9f\x98\x91_____\x14_AtJr2<s\xc1d\x89IQdH\x8ff\xe4Pz9;\xba\x88X_f'[ord(l.upper())-44]),7);return "--..--..-.-.-..--...----.....-----.-"[a:a+n]
def e(s):return ' '.join(map(h,s))

我认为这也使程序的意图更加清晰。

如果将其保存为 UTF-8,我相信该程序将减少到 185 个字符,使其成为最短的完整 Python 解决方案,仅次于 Perl。:-)

于 2009-08-30T06:16:30.560 回答
1

这是第三种完全不同的莫尔斯电码编码方式:

Python

232 个字符

def d(c):
 o='';b=ord("Y_j_?><80 !#'/_____f_\x06\x11\x15\x05\x02\x15\t\x1c\x06\x1e\r\x12\x07\x05\x0f\x16\x1b\n\x08\x03\r\x18\x0e\x19\x01\x13"[ord(c.upper())-44])
 while b!=1:o+='.-'[b&1];b/=2
 return o
e=lambda s:' '.join(map(d,s))

如果您能找到一种方法将其映射到某些可打印字符集,则可以节省不少字符。这可能是我最直接的解决方案,虽然我不知道它是否是最易读的。

好的,现在我在这上面浪费太多时间。

于 2009-08-30T18:41:33.190 回答
1

哈斯克尔

type MorseCode = String

program :: String
program = "__5__4H___3VS__F___2 UI__L__+_ R__P___1JWAE"
     ++ "__6__=B__/_XD__C__YKN__7_Z__QG__8_ __9__0 OMT "

decode :: MorseCode -> String
decode = interpret program
    where
    interpret         = head . foldl exec []
    exec xs       '_' = undefined : xs
    exec (x:y:xs)  c  = branch    : xs
        where
        branch (' ':ds) = c : decode ds
        branch ('-':ds) = x ds
        branch ('.':ds) = y ds
        branch []       = [c]

例如,decode "-- --- .-. ... . -.-. --- -.. ."返回"MORSE CODE".

这个程序来自优秀的文章Fun with Morse Code

于 2009-09-03T11:38:46.317 回答
1

PHP

我修改了之前的 PHP 条目以提高效率。:)

$a=array(32=>"/",44=>"--..--",1,".-.-.-",48=>"-----",".----","..---","...--","....-",".....","-....","--...","---..","----.",63=>"..--..",1,".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--..");
foreach(str_split(strtoupper("hello world?"))as$k=>$v){echo $a[ord($v)]." ";}

Komodo 在 2 行上说 380 个字符 - 额外的行只是为了便于阅读。;D 数组中穿插的 1 只是通过用数据填充该数组位置来节省 2 个字节,而不是在那之后手动跳转到数组位置。

考虑第一个与第二个。差异是显而易见的。:)

array(20=>"data",22=>"more data";
array(20=>"data",1,"more data";

然而,最终结果是,只要您使用数组位置而不是循环遍历内容,我们在这个高尔夫球场上不会这样做。

最终结果:578 个字符,减少到 380 个(198 个字符,或节省约 34.26%)。

于 2009-09-14T09:46:02.413 回答
1

Bash,我不久前写的一个脚本(时间戳说是去年),有 1661 个字符。真的只是为了好玩:)

#!/bin/sh
txt=''
res=''
if [ "$1" == '' ]; then
    read -se txt
else
    txt="$1"
fi;
len=$(echo "$txt" | wc -c)
k=1
while [ "$k" -lt "$len" ]; do
    case "$(expr substr "$txt" $k 1 | tr '[:upper:]' '[:lower:]')" in
        'e')    res="$res"'.' ;;
        't')    res="$res"'-' ;;
        'i')    res="$res"'..' ;;
        'a')    res="$res"'.-' ;;
        'n')    res="$res"'-.' ;;
        'm')    res="$res"'--' ;;
        's')    res="$res"'...' ;;
        'u')    res="$res"'..-' ;;
        'r')    res="$res"'.-.' ;;
        'w')    res="$res"'.--' ;;
        'd')    res="$res"'-..' ;;
        'k')    res="$res"'-.-' ;;
        'g')    res="$res"'--.' ;;
        'o')    res="$res"'---' ;;
        'h')    res="$res"'....' ;;
        'v')    res="$res"'...-' ;;
        'f')    res="$res"'..-.' ;;
        'l')    res="$res"'.-..' ;;
        'p')    res="$res"'.--.' ;;
        'j')    res="$res"'.---' ;;
        'b')    res="$res"'-...' ;;
        'x')    res="$res"'-..-' ;;
        'c')    res="$res"'-.-.' ;;
        'y')    res="$res"'-.--' ;;
        'z')    res="$res"'--..' ;;
        'q')    res="$res"'--.-' ;;
        '5')    res="$res"'.....' ;;
        '4')    res="$res"'....-' ;;
        '3')    res="$res"'...--' ;;
        '2')    res="$res"'..---' ;;
        '1')    res="$res"'.----' ;;
        '6')    res="$res"'-....' ;;
        '7')    res="$res"'--...' ;;
        '8')    res="$res"'---..' ;;
        '9')    res="$res"'----.' ;;
        '0')    res="$res"'-----' ;;
    esac;
    [ ! "$(expr substr "$txt" $k 1)" == " " ] && [ ! "$(expr substr "$txt" $(($k+1)) 1)" == ' ' ] && res="$res"' '
    k=$(($k+1))
done;
echo "$res"
于 2010-03-20T13:54:45.307 回答
0

C,533 个字符

我从一些评论中听取了建议并切换到标准输入。大致杀死了另外70个角色。

#include <stdio.h>
#include <ctype.h>
char *u[36] = {".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--..","-----",".----","..---","...--","....-",".....","-....","--...","---..","----."};
main(){
char*v;int x;char o;
do{
o = toupper(getc(stdin));v=0;if(o>=65&&o<=90)v=u[o-'A'];if(o>=48&&o<=57)v=u[o-'0'+26];if(o==46)v=".-.-.-";if(o==44)v="--..--";if(o==63)v="..--..";if(o==32)v="/";if(v)printf("%s ", v);} while (o != EOF);
}
于 2009-08-29T23:44:23.253 回答
0

C89(388 个字符)

这是不完整的,因为它还没有处理逗号、句号和查询。

#define P putchar
char q[10],Q,tree[]=
"EISH54V 3UF    2ARL   + WP  J 1TNDB6=X/ KC  Y  MGZ7 Q  O 8  90";s2;e(x){q[Q++]
=x;}p(){for(;Q--;putchar(q[Q]));Q=0;}T(int x,char*t,int s){s2=s/2;return s?*t-x
?t[s2]-x?T(x,++t+s2,--s/2)?e(45):T(x,t,--s/2)?e(46):0:e(45):e(46):0;}main(c){
while((c=getchar())>=0){c-=c<123&&c>96?32:0;if(c==10)P(10);if(c==32)P(47);else
T(c,tree,sizeof(tree)),p();P(' ');}}

为可读性包装。只需要两个换行符(一个用于#define,一个在 else 之后,可能是一个空格)。我添加了一些非标准字符,但没有添加非 7 位字符。

于 2009-08-30T00:16:25.183 回答
0

C(381 个字符)

char*p[36]={".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--..","-----",".----","..---","...--","....-",".....","-....","--...","---..","----."};
main(){int c;while((c=tolower(getchar()))!=10)printf("%s ",c==46?".-.-.-":c==44?"--..--":c==63?"..--..":c==32?"/":*(p+(c-97)));}
于 2009-08-30T01:10:57.867 回答
0

C , 448 字节使用 cmdline 参数:

char*a[]={".-.-.-","--..--","..--..","/",".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--..","-----",".----","..---","...--","....-",".....","-....","--...","---..","----."},*k=".,? ",*s,*p,x;main(int _,char**v){for(;s=*++v;putchar(10))for(;x=*s++;){p=strchr(k,x);printf("%s ",p?a[p-k]:isdigit(x)?a[x-18]:isalpha(x=toupper(x))?a[x-61]:0);}}

C , 416 字节使用标准输入:

char*a[]={".-.-.-","--..--","..--..","/",".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--..","-----",".----","..---","...--","....-",".....","-....","--...","---..","----."},*k=".,? ",*p,x;main(){while((x=toupper(getchar()))-10){p=strchr(k,x);printf("%s ",p?a[p-k]:isdigit(x)?a[x-18]:isalpha(x)?a[x-61]:0);}}
于 2009-08-30T01:13:17.117 回答
0

在php中,我能做的最好的事情是:615 个字符,尽管我认为可以更有效地处理值数组,但我只是找不到让数组使用字母而不是数字键的方法,而无需指定他们。

尽管如此,为了让其他人可以使用(我认为'嘲笑'是一个有效的用途......):

$alphabet = array(' '=>"/",'a'=>".-",'b'=>"-...",'c'=>"-.-.",'d'=>"-..",'e'=>".",'f'=>"..-.",'g'=>"--.",'h'=>"....",'i'=>"..",'j'=>".---",'k'=>"-.-",'l'=>".-..",'m'=>"--",'n'=>"-.",'o'=>"---",'p'=>".--.",'q'=>"--.-",'r'=>".-.",'s'=>"...",'t'=>"-",'u'=>"..-",'v'=>"...-",'w'=>".--",'x'=>"-..-",'y'=>"-.--",'z'=>"--..",'0'=>"-----",'1'=>".----",'2'=>"..---",'3'=>"...--",'4'=>"....-",'5'=>".....",'6'=>"-....",'7'=>"--...",'8'=>"---..",'9'=>"----.",'.'=>".-.-.-",','=>"--..--",'?'=>"..--..");
$text = strtolower("hello world?");
$textArray = str_split($text);
foreach($textArray as $k=>$v) {echo $alphabet[$v] . " ";}

请记住,我没有在粘贴的代码或字符数中包含开始/结束标签。我不确定这是否是作弊,但本着充分披露的精神提及。


针对 Salaryman 的评论进行了编辑,删除了不必要的变量 ' $textArray' 并缩短了变量名称,结果如下(576 个字符):

$a = array(' '=>"/",'a'=>".-",'b'=>"-...",'c'=>"-.-.",'d'=>"-..",'e'=>".",'f'=>"..-.",'g'=>"--.",'h'=>"....",'i'=>"..",'j'=>".---",'k'=>"-.-",'l'=>".-..",'m'=>"--",'n'=>"-.",'o'=>"---",'p'=>".--.",'q'=>"--.-",'r'=>".-.",'s'=>"...",'t'=>"-",'u'=>"..-",'v'=>"...-",'w'=>".--",'x'=>"-..-",'y'=>"-.--",'z'=>"--..",'0'=>"-----",'1'=>".----",'2'=>"..---",'3'=>"...--",'4'=>"....-",'5'=>".....",'6'=>"-....",'7'=>"--...",'8'=>"---..",'9'=>"----.",'.'=>".-.-.-",','=>"--..--",'?'=>"..--..");
$t=str_split(strtolower("hello world?"));
foreach($textArray as $k=>$v) {echo $a[$v] . " ";}
于 2009-08-30T01:51:40.473 回答
0

VBA/VB6 (576 个字符)

注意:没有选项显式

Function MC(S)
For I = 1 To Len(S): C = UCase(Mid(S, I, 1)): MC = MC & IIf(C = " ", "/", "") & IIf(InStr("AEFHIJLPRSUVW12345.?", C), ".", IIf(InStr("BCDGKMNOQTXYZ06789,", C), "-", "")) & IIf(InStr("BCDFHIKNSUVXY23456?", C), ".", IIf(InStr("AGJLMOPQRWZ01789,.", C), "-", "")) & IIf(InStr("BDGHLQRSVXZ34567,.", C), ".", IIf(InStr("CFJKOPUWY01289?", C), "-", "")) & IIf(InStr("CFHLPZ45678,", C), ".", IIf(InStr("JQVXY01239.?", C), "-", "")) & IIf(InStr("56789.?", C), ".", IIf(InStr("01234,", C), "-", "")) & IIf(C = "?", ".", IIf(InStr(".,", C), "-", "")) & " ": Next
End Function
于 2009-09-25T20:18:00.773 回答