使用摩尔斯电码字体?
Console.Write(params[0]);
pfft,每个人都是评论家 (46认同)
我不认为该字体使用'ASCII':) (2认同)
如果它包含 - 和a.char,当然. (2认同)
hobbs.. 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
提取莫尔斯字典.每个符号都是根据两个字符定义的,可以是字面点或短划线,也可以是对另一个定义字符值的引用.E和T包含伪字符以避免解码器; 我们稍后会删除它们.
读取并格式化输入."Hello world"
变"H E L L O / W O R L D"
下一步取决于输入和输出字典是不同的,因此将输入中的点转换为未使用的字符(垂直条|
)
将其在morse词典中出现的输入中的任何char替换为字典中的值,直到不会发生替换.
删除步骤1中提到的虚拟字符.
打印输出.
在最终版本中,字典针对运行时效率进行了优化:
所有单符号字符(E和T)和双符号字符(A,I,M和N)直接定义并在一次通过中解码.
所有三个符号字符都是根据两个符号字符和一个文字符号定义的,两次传递解码.
所有四个符号字符都是根据两个双符号字符定义的,两次传递解码,三次替换.
五符号和六符号字符(数字和标点符号)分三次解码,分别有四次或五次替换.
由于高尔夫代码每循环只替换一个字符(以保存一个字符的代码!),循环次数限制为输入长度的五倍(如果仅使用字母,则为输入长度的三倍).但通过添加g
到s///
操作中,环的数目限制为3个(2如果仅使用alphabetics).
Hello 123 H E L L O / 1 2 3 II .] AI AI M- / AO UM SM .... . .-.. .-.. --- / .-M- .A-- I.-- .... . .-.. .-.. --- / .---- ..--- ...--
没错,但是这段代码几乎可以给出任何荧光笔的胃灼热.:) (15认同)
护目镜!他们什么都不做! (7认同)
男人,StackOverflow真的很难突出Perl ...... (5认同)
@kibibu - 不,你在想J(http://en.wikipedia.org/wiki/J_%28programming_language%29). (3认同)
@hobbs - 无论编辑战争围栏的哪一方都可能落后,emacs cperl模式都做得很好.它处理这个,没有汗水. (2认同)
@Chris Lutz我使用vim,这也正确地突出了这一点.Emacs,Vim和Kate很好地处理Perl; 大多数其他东西,包括大多数基于网络的代码格式化程序,都被一些更具异国情调的引用,甚至有时甚至是正则表达式所引发.@kibibu:那里有一点道理.这并不是真的,但Perl对灵活性和简洁性的双重强调,当被用于强迫性水平时,可以带来良好的打高尔夫球.:) (2认同)
ACoolie.. 16
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()
提取数据而不是算术.另请注意,使用不等式检测空格; 它认为每个字符"小于逗号"都是一个空格.
for
循环,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,
dmckee.. 7
我正在使用紧凑的符号编码,但我不知道是否比使用的隐式树更好,所以我在这里提供编码以防其他人可以使用它.
考虑字符串:
--..--..-.-.-..--...----.....-----.--/
其中包含所有需要的序列作为子串.我们可以通过offset和length 来编码符号,如下所示:
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用第一个(buggy和不完整)版本做了一个python实现.Hobbs做了一个非常紧凑的perl版本,我根本不懂.
是的,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
和for
循环的逻辑组合成单个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的字符(即,来自'\n'
)的垃圾.您仍然会从!"#$%&'()*+[\]^_
` {|}~
或任何超过ASCII 126的任何内容中获取垃圾.
这应该使代码完全可移植.编译:
gcc -std=c89 -funsigned-char morse.c
这-std=c89
是可选的.-funsigned-char
但是,这是必要的,否则你将获得逗号和完全停止的垃圾.
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值.因此编码的字符数组具有'4'作为第33个字符(索引32).
这种技术类似于用于编码ACoolie,strager (2),Miles,pingw33n,Alec和Andrea解决方案中的字符的技术,但稍微简单一点,每位只需要一次操作(移位/分割),而不是两次(移位) /分割和减少).
编辑:
通过阅读其余的实现,我看到Alec和Anon提出了这种编码方案 - 使用保护位 - 在我做之前.Anon的解决方案特别有趣,使用Python的bin
功能并剥离"0b"
前缀和保护位[3:]
,而不是像Alec和我那样循环,转换和移位.
作为奖励,此版本还处理hyphen(-....-
),斜杠(-..-.
),冒号(---...
),分号(-.-.-.
),等号(-...-
)和符号(.--.-.
).只要允许8位字符,这些字符就不需要额外的代码字节来支持.此版本不再支持任何字符而不增加代码长度(除非莫尔斯代码更多/更少于符号).
因为我发现旧的实现仍然很有趣,并且文本有一些适用于此版本的注意事项,所以我在下面的帖子中留下了以前的内容.
好吧,大概是用户界面可以吸,对吧?所以,借用strager,我已经替换了gets()
,它提供了缓冲的回声线路输入getch()
,它提供了无缓冲的,无回声的字符输入.这意味着您输入的每个字符都会立即转换为屏幕上的摩尔斯电码.也许这很酷.它不再适用于stdin或命令行参数,但它非常小.
不过,我保留下面的旧代码作为参考.这是新的.
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 打破循环并退出程序.
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);}
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只能添加3个字符.必须替换长字符串的第一个字符\x9C
.这次偏移是必要的,否则大量字符在32以下,并且必须用转义码表示.
与以前一样,处理命令行参数而不是stdin会添加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);}
使用摩尔斯电码字体?
Console.Write(params[0]);
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
提取莫尔斯字典.每个符号都是根据两个字符定义的,可以是字面点或短划线,也可以是对另一个定义字符值的引用.E和T包含伪字符以避免解码器; 我们稍后会删除它们.
读取并格式化输入."Hello world"
变"H E L L O / W O R L D"
下一步取决于输入和输出字典是不同的,因此将输入中的点转换为未使用的字符(垂直条|
)
将其在morse词典中出现的输入中的任何char替换为字典中的值,直到不会发生替换.
删除步骤1中提到的虚拟字符.
打印输出.
在最终版本中,字典针对运行时效率进行了优化:
所有单符号字符(E和T)和双符号字符(A,I,M和N)直接定义并在一次通过中解码.
所有三个符号字符都是根据两个符号字符和一个文字符号定义的,两次传递解码.
所有四个符号字符都是根据两个双符号字符定义的,两次传递解码,三次替换.
五符号和六符号字符(数字和标点符号)分三次解码,分别有四次或五次替换.
由于高尔夫代码每循环只替换一个字符(以保存一个字符的代码!),循环次数限制为输入长度的五倍(如果仅使用字母,则为输入长度的三倍).但通过添加g
到s///
操作中,环的数目限制为3个(2如果仅使用alphabetics).
Hello 123 H E L L O / 1 2 3 II .] AI AI M- / AO UM SM .... . .-.. .-.. --- / .-M- .A-- I.-- .... . .-.. .-.. --- / .---- ..--- ...--
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()
提取数据而不是算术.另请注意,使用不等式检测空格; 它认为每个字符"小于逗号"都是一个空格.
for
循环,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,
我正在使用紧凑的符号编码,但我不知道是否比使用的隐式树更好,所以我在这里提供编码以防其他人可以使用它.
考虑字符串:
--..--..-.-.-..--...----.....-----.--/
其中包含所有需要的序列作为子串.我们可以通过offset和length 来编码符号,如下所示:
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用第一个(buggy和不完整)版本做了一个python实现.Hobbs做了一个非常紧凑的perl版本,我根本不懂.
'.- /'{~;2,~&.>(]`(<&3:)@.(a:=])"0)}.&,:&.>E20+193ACD'{~0>.45-~a.i.toupper
J击败C!真棒!
用法:
'.- /'{~;2,~&.>(]`(<&3:)@.(a:=])"0)}.&,:&.>E20+193ACD'{~0>.45-~a.i.toupper 'Hello World' .... . .-.. .-.. --- / .-- --- .-. .-.. -.. '.- /'{~;2,~&.>(]`(<&3:)@.(a:=])"0)}.&,:&.>E20+193ACD'{~0>.45-~a.i.toupper 'Hello, Stackoverflow.' .... . .-.. .-.. --- .-.-.- / ... - .- -.-. -.- --- ...- . .-. ..-. .-.. --- .-- --..--
Python 3 One Liner:172个字符
print(' '.join('/'if c==' 'else''.join('.'if x=='0'else'-'for x in bin(ord("?Á?ÁÿïçãáàðøüþÁÁÁÁÁ?ÁÅ×ÚÌÂÒÎÐÄ×ÍÔÇÆÏÖÝÊÈÃÉÑËÙÛÜ"[ord(c)-44])-192)[3:])for c in input().upper()))
(将翻译表编码为unicode代码点.工作正常,它们在我的Windows Vista机器上的测试中显示得很好.)
编辑通过删除一些不必要的空格和括号(使列表comps gen exps)减少到184个字符.
再次编辑:在看到其他答案之前,删除了更多我不知道的空格 - 所以降到176.
使用''.join而不是''.join再次编辑到172(呜呜!)并单独执行空格.(咄!)
转换为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) })); }
不支持输入结尾处的换行符,因此请使用类似的内容
echo -n Hello, Stackoverflow| ../golfscript.rb morse.gs
' '/{{.32|"!etianmsurwdkgohvf!l!pjbxcyzq"?)"UsL?/'#! 08<>"@".,?0123456789"?=or 2base(;>{'.-'\=}%' '}%}%'/'*
字母是一种特殊情况,并转换为小写,并以二进制位置排序.
其他一切都由翻译表完成