手机键盘打字


17

手机键盘打字

不久前有人问了这个问题,但由于规格不佳而被关闭。因此,我将以更好的规格重做它。这个问题是相关的,但方向相反。

在T9出现之前,为了在短信中输入字符,您必须多次按数字键之一才能获得所需的字符。供参考,以下是标准映射:

+-------+-------+-------+
|   1   |   2   |   3   |
|  .?!1 |  ABC2 |  DEF3 |
+-------+-------+-------+
|   4   |   5   |   6   |
|  GHI4 |  JKL5 |  MNO6 |
+-------+-------+-------+
|   7   |   8   |   9   |
| PQRS7 |  TUV8 | WXYZ9 |
+-------+-------+-------+
|   *   |   0   |   #   |
|   ←   |SPACE 0|   →   |
+-------+-------+-------+

*是Backspace,0是空格(' ')或数字0,并#确认当前字符。为了简单起见,所有字符均为大写。

当您通过该密钥的可能的字符按下一个键多次,所选字符循环:2 -> A22 -> B222 -> C2222 -> 222222 -> A,等。请注意,由于*只有一个选项,因此反复按下它会导致输入多个退格键。#连续按下多次无效。尾随#是不必要的。

此外,如果在按下某个键后立即按下另一个键,则会自动确认先前的按键。因此,223在功能上与相同22#3

您面临的挑战是将一系列按键转换成手机将显示的相应字符串。

例子

8#99999#055#33#999#22#666#2#777#3#1 -> T9 KEYBOARD
4433555#55566609666666677755533*3111 -> HELLO WORLD!
7##222#222**7#222#4 -> PPCG
00#0#00 -> 0 0

规则

  • 这是,因此最短的正确解决方案(以字节为单位)获胜
  • 获奖答案将在一周内选定
  • 禁止出现标准漏洞
  • 您的答案可能是完整程序,命名函数或匿名函数的形式,采用一种标准方法获取输入并产生输出。

排行榜

这篇文章底部的堆栈摘录从答案a)生成排行榜,答案是每种语言的最短解决方案列表,b)则是总体排行榜。

为确保您的答案显示出来,请使用以下Markdown模板以标题开头。

## Language Name, N bytes

N您提交的文件大小在哪里。如果您提高了分数,则可以通过打败旧分数保持标题。例如:

## Ruby, <s>104</s> <s>101</s> 96 bytes

如果要在标头中包含多个数字(例如,因为您的分数是两个文件的总和,或者您想单独列出解释器标志罚分),请确保实际分数是标头中的最后一个数字:

## Perl, 43 + 2 (-p flag) = 45 bytes

您还可以将语言名称设置为链接,然后该链接将显示在代码段中:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes


1
您如何产生数字?在示例中,数字为“ 9”,但是您的规范(2 -> A22 -> B...,2222 -> A....)不允许生成任何数字。
C. Quilley

1
@ C.Quilley这就是我盲目复制该图(现在已修复)所得到的。
Mego 2015年


1
@AlexA。不是骗子,这是标准的电话小键盘输入,而不是T9词典查找。
Mego 2015年

Answers:


3

K5,112字节

{(20#'((" ";".?!"),((3*!6),19 22)_`c$65+!26),'$!10)[.*x]20!#1_x}'(){$[42=*y;(-#y)_x;35=*y;x;x,,y]}/{(&~0=':x)_x}

这确实是一团糟,但我认为还有很多打高尔夫的空间。

首先,我们需要为键盘映射表构建一个查找表。有映射有2、4和5个字符的键,因此将每个条目填充到20可以简化以后对该表进行循环索引的过程:

  (20#'((" ";".?!"),((3*!6),19 22)_`c$65+!26),'$!10)
(" 0 0 0 0 0 0 0 0 0 0"
 ".?!1.?!1.?!1.?!1.?!1"
 "ABC2ABC2ABC2ABC2ABC2"
 "DEF3DEF3DEF3DEF3DEF3"
 "GHI4GHI4GHI4GHI4GHI4"
 "JKL5JKL5JKL5JKL5JKL5"
 "MNO6MNO6MNO6MNO6MNO6"
 "PQRS7PQRS7PQRS7PQRS7"
 "TUV8TUV8TUV8TUV8TUV8"
 "WXYZ9WXYZ9WXYZ9WXYZ9")

然后我将输入分成多个运行:

 {(&~0=':x)_x}"8#99999#055#33#999"
(,"8"
 ,"#"
 "99999"
 ,"#"
 ,"0"
 "55"
 ,"#"
 "33"
 ,"#"
 "999")

每次遇到*时,删除所有#个运行并删除尾随运行:

  (){$[42=*y;(-#y)_x;35=*y;x;x,,y]}/{(&~0=':x)_x}"8#99999#055#33#999"
(,"8"
 "99999"
 ,"0"
 "55"
 "33"
 "999")

然后,我准备根据每次运行的长度和第一个元素简单地索引到该查找表中。

全部一起:

  {(20#'((" ";".?!"),((3*!6),19 22)_`c$65+!26),'$!10)[.*x]20!#1_x}'(){$[42=*y;(-#y)_x;35=*y;x;x,,y]}/{(&~0=':x)_x}"4433555#55566609666666677755533*3111"
"HELLO WORLD!"

编辑:

节省5个字节:

0 3 6 9 12 15 19 22
((3*!6),19 22)

您可以缩短(20#'((" ";".?!"),0 3 6 9 12 15 19 22_`c$65+!26),'$!10)(20#'((" ";".?!"),((3*!6),19 22)_`c$65+!26),'$!10)
kirbyfan64sos

是的,我实际上是几分钟前才发现的。
JohnE

3

Python 2中,230个 206字节

import re
f=lambda a,b=dict(zip("0123456789*#"," 0~.?!1~ABC2~DEF3~GHI4~JKL5~MNO6~PQRS7~TUV8~WXYZ9~\b~".split("~"))):"".join([j and b[j][(len(i)-1)%len(b[j])]or b[i]for i,j in re.findall(r"((\d)\2*|.)",a)])

此函数创建一个函数f,该函数以一串按键作为参数,并返回手机将显示的相应字符串。它还碰巧采用了可选的第二个自变量作为字典,将键映射到它们对应的字符,例如{“ 0”:“ 0”,“ 1”:“。?!1”,...}

首先,按键字符串通过重复字符分组,例如[“ 8”,“#”,“ 99999”,“#”,...]。然后,将每个组的第一个字符映射到作为第二个参数传递的字典中,例如9映射到WXYZ9。最后,将组的长度用作字典值的偏移量。

请注意,偏移量必须在重复字符组的长度上使用模数,因为按键可能会循环。还要注意,字符映射到\ 0,并且仅在最后删除,因为99#999999不同

这是问题中每个示例的函数输出:

>>> print f("8#99999#055#33#999#22#666#2#777#3#1")
T9 KEYBOARD.
>>> print f("4433555#55566609666666677755533*3111")
HELLO WORLD!
>>> print f("7##222#222**7#222#4")
PPCG
>>> print f("00#0#00")
0 0

3

JavaScript中,214个 184 168 162字节

x=>(x.match(/(.)\1*/g,f='').map(a=>f=(l=a.length,v=' 0#.?!1#ABC2#DEF3#GHI4#JKL5#MNO6#PQRS7#TUV8#WXYZ9'.split`#`[a[0]])?f+v[--l%v.length]:a<'*'?f:f.slice(0,-l)),f)

可以将其缩小一些,但我对结果感到非常满意。将字符分成一个或多个重复的组,然后遍历数组,将每个字符映射到哈希中的值并将其添加到最终字符串中。如果遇到任意数量的“#”,它将忽略它。如果遇到任何'*',则会从最终字符串的末尾删除该数量的字符。


0

Python 2,237字节

使用cr3的字典,但没有re。

def f(i):
 d=dict(zip("0123456789"," 0|.?!1|ABC2|DEF3|GHI4|JKL5|MNO6|PQRS7|TUV8|WXYZ9".split("|")))
 s,x,j='',i[0],0
 for c in i[1:]+'#':
  if c==x:j+=1
  else:
   if x>'/':s+=d[x][j%len(d[x])]
   j=0
  if c=='*':s=s[:-1]
  x=c
 return s

-1

Python 2,265字节

时间太长了。IO:stdin,stdout。

a=reduce(lambda q,w:q+" "+[w,""][w=="#"]if q[-1]!=w else q+w,raw_input()).split()
while "*" in a:del a[a.index("*")-1:a.index("*")+1]
print"".join([(lambda a:a[len(q)%len(a)-1])(" 0:.?!1:ABC2:DEF3:GHI4:JKL5:MNO6:PQRS7:TUV8:WXYZ9".split(":")[int(q[0])])for q in a])

第三个示例7 ## 222#222 ** 7#222#4,将导致您的脚本引发ValueError:int()的无效文字,基数为10:“ *”。
cr3 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.