通过键盘输入您的名字


32

难题:

考虑一个带有d-pad的控制台/手持游戏,您需要在其中输入各种名称。这种现象出现在许多较旧的游戏中,然后在控制台中普及使用QWERTY(例如,我相信Wii使用QWERTY键盘布局进行输入)。通常,屏幕键盘看起来具有以下效果:

默认:

0 1 2 3 4 5 6 7 8 9
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
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 - + ^ =

即,所有字母数字键和以下内容:

_:一个空格
-:连字符
+:仅
^切换下一个字母的大小写:切换大写锁定(即,切换所有字母的大小写)
=:输入,完成

*显然,我用较短的版本替换了“ BKSP”和“ ENTER”之类的键

然后硬件将包括d垫(或某种形式的控制,在那里你可以去updownleftright

屏幕通常还可以让您从一侧直接移动到另一侧。也就是说,如果您专注于字母J,则按right将允许您移动到字母A

每当我输入自己的名字时,我总是会尝试找出最快的方法。

目标:

您的程序将接受字符串输入,该字符串可以包含任何字母数字字符(包括空格和连字符),并且您的目标是在d键盘上输出最短的按键输出以输出所需的字符串。

注意事项:

您不需要包括用于按下实际字符的按键。
焦点始终始于A
Enter,=必须到底

例:

input: Code Golf
output: 43

说明:
A -> C= 2-
C> ^= 6(向左移动)
^-> o= 5-
o> d= 2-
d> e= 1-
e> += 5-
+> _= 1-
_> += 1-
+> G= 3-
G> o= 3-
o> l= 3-
l> f= 5-
f> == 6

请注意,+两次击中a _和a的速度G比击中^一次然后换回的速度更快。

获胜的提交(我将允许至少1w)将是最短的解决方案(以字节为单位)。由于这是我的第一个问题,我希望这是明确的并且不太难。


12
好挑战!仅一点,48小时可能太少了。那是允许赏金需要多长时间,因此应该超过一周左右。
马蒂森(Maltysen)2015年

@Maltysen感谢您的建议,我已经更新了挑战
Tas

1
您也可以垂直包裹还是水平包裹?
亚历克斯·雷肯

2
@AlexReinking很好!是的你可以。
2015年

大!我的实现做到了这一点,所以我只想仔细检查一下。
亚历克斯·雷肯

Answers:


5

Ruby(369字节)

从命令行获取输入。

K="0123456789"+('A'..'Z').to_a.join+" +^="
Q=K.downcase.sub' ','-'
def d x,y
t,s=(x/10-y/10).abs,(x%10-y%10).abs
[t,4-t].min+[s,10-s].min
end
def v s,i,l,a
return l if s.empty?
c,r=s[0],s[1..-1]
j=K.index(c.upcase)||36
return v(r,j,l+d(i,j),a)if a.include?c
s,p=d(i,37)+d(37,j),d(i,38)+d(38,j)
[v(r,j,l+s,a),v(r,j,l+p,a==K ? Q : K)].min
end
puts v("#{ARGV[0]}=",10,0,K)

感谢@Charlie节省了一堆字节:)


j=(K.index(c.upcase) or 36)可以替换为j=K.index(c.upcase)||36以节省4个字节。 def d(x,y)可以替换def d x,y为保存一个字节,也是一样def vv(...) ifv(...)if另一个字节。在最后一行,v(...)可以替换v ...,以节省1个字节,并true!!0保存一个字节。
查理

谢谢!我不太了解Ruby。我是从python翻译
过来的

我还可以替换&&使用&,并|||
Alex Reinking 2015年

您的第一行(K=...)可替换为范围(K='0123456789'+('A'..'Z').to_a.join+' +^='
Charlie

刮胡子再减2!
亚历克斯·雷肯

9

迅速1.2,812个 588 670字节

编辑:通过使用Range替换数字的大型数组并将其转换为Array,从而删除了224个字节。

Edit2:添加了垂直循环

typealias S=String
typealias I=Int
var A:(I)->S={S(UnicodeScalar($0))},B:(I)->(I,I)={a in(a%10,a/10)},a=Array(48...57).map{A($0)},b=[a+(Array(65...90)+[32,43,94,61]).map{A($0)},a+(Array(97...122)+[45,43,94,61]).map{A($0)}],z=Process.arguments
z.removeAtIndex(0)
func C(e:I,f:I)->I{let(a,b)=B(e),(c,d)=B(f)
return min(abs(d-b), abs(4-(d-b)))+min(abs(c-a),abs(10-(c-a)))}
func D(c:S,_ e:I=10,_ f:Bool=false,_ g:Bool=false)->I{if count(c)==0{return C(e,39)}
let h=c.startIndex,i=c.endIndex,j=S(c[h])
if let k=find(b[f ?1:0],j){return C(e,k)+D(c[advance(h,1)..<i],k,(g ?(!f):f),false)}else{return min(C(e,37)+D(c,37,!f,true),C(e,38)+D(c,38,!f,false))}}
print(D(" ".join(z)))

要运行,请将代码放在.swift文件中并使用swift <filename> <your name>


这使用了将两个“键盘”存储为数组的简单方法。

B:(I)->(I,I)={a in(a%10,a/10)} 将索引从数组转换为虚拟键盘上的x,y位置。

func C(e:I,f:I)->I{let(a,b)=B(e),(c,d)=B(f) return abs(d-b)+min(abs(c-a),abs(10-(c-a)))} 取得开始/结束索引,并返回从一次移动到另一个的最小移动量(考虑水平换行)

func D(c:S,_ e:I=10,_ f:Bool=false,_ g:Bool=false)->I是执行大多数计算的主要递归函数。它计算从当前位置到目标字符的距离,除非的情况下应该改变,则它计算两者移位 所述大写锁定的方法和需要的最小。

运行swift codegolf.swift Code Golf打印43


需要考虑垂直包装。
亚历克斯·雷肯

更新为也考虑垂直包装。
David Skrundz

4

的Python 679 661 619 602 589 576 539 520 496 482个字节

运行此命令,它将要求输入(无提示文本)。对于输入,Code Golf它将打印43

a=input()+'=';b=0;c="0123456789abcdefghijklmnopqrstuvwxyz-+^=";d=0;e=[0,1];f='+';g='^';h=[i.isupper()or i==' 'for i in a];i=abs;p=lambda z:all([i==b for i in z]);q=0
def l(z):global s;k=c.index(z.lower().replace(' ','-'));s=[k%10,int(k/10)];m,n=s;return sum([min(i(m-e[0]),i(10-(m-e[0]))),min(i(n-e[1]),i(4-(n-e[1])))])
def o(z):global d,e;d+=l(z);e=s
for r in a:
 if p(h[q:q+3]):o(g);b^=1
 if p(h[q:q+2]):
  if l(f)<l(g):o(f)
  else:o(g);b^=1
 if p([h[q]]):o(f)
 o(r);q+=1
print(d)

完整程序:

input = input() + '='
capsOn = False

keys = "0123456789abcdefghijklmnopqrstuvwxyz-+^="
totalKeys = 0
caret = [0, 1]

shiftKey = '+'
capsKey = '^'

cases = [char.isupper() or char == ' ' for char in input]

def locate(char):
    """
        Find the location of the char on the keyboard
        regardless of case
    """
    location = keys.find(char.replace(' ', '-').lower())
    return [location % 10, int(location / 10)]


def dist(key):
    """
        Calculate the min dist to a char
    """
    nx, ny = locate(key)
    return sum([min(abs(nx - caret[0]), abs(10 - (nx - caret[0]))), min(abs(ny - caret[1]), abs(4 - (ny - caret[1])))])


def moveTo(char):
    """
        Move the caret to the char, ignoring case and
        adds the dist to the tally
    """
    global totalKeys, caret
    totalKeys = totalKeys + dist(char)

    print(keys[caret[0] + caret[1] * 10], '->', char, '=', dist(char))

    caret = locate(char)

diffCase = lambda case: all([i == capsOn for i in case])

for ind, ch in enumerate(input):
    if diffCase(cases[ind:ind + 3]): # use caps
        moveTo(capsKey)
        capsOn ^= 1
    elif diffCase(cases[ind:ind + 2]): # use closest
        if dist(shiftKey) < dist(capsKey):
            moveTo(shiftKey)
        else:
            moveTo(capsKey)
            capsOn ^= 1
    elif diffCase([cases[ind]]): # use shift
        moveTo(shiftKey)

    moveTo(ch) # apply the move

print('Total:', totalKeys)

完整程序的扩展输出:

Code Golf
a -> C = 2
c -> ^ = 6
^ -> o = 5
o -> d = 2
d -> e = 1
e -> + = 5
+ -> _ = 1
- -> + = 1
+ -> G = 3
g -> o = 3
o -> l = 3
l -> f = 5
f -> = = 6
Total: 43

保存一个字节感谢@justin https://codegolf.stackexchange.com/a/18983/42736
4 @xnor https://codegolf.stackexchange.com/a/40791/42736 19感谢@Alex


感谢您的帮助,因为我仍在学习python,这是我的第一个代码高尔夫。
J Atkin 2015年

您可以在内部表中使用空格而不是下划线。
亚历克斯·雷肯

我没想到这一点,谢谢;)
J Atkin

3

C 675字节

从命令行参数获取输入。使用递归主要:

#define Y(_) (!isdigit(_)?!isalpha(_)?3:1+(toupper(_)-65)/10:0)
#define X(_) (!isdigit(_)?!isalpha(_)?_-32&&_-45?_-43?9-(_==94):7:6:(toupper(_)-5)%10:_-48)
x,y,z;char*s;main(a,_,p,q,r){a<2?s[_]?!isdigit(s[_])&&((s[_]-32&&!isupper(s[_]))||!a)&&((s[_]-45&&!islower(s[_]))||a)?q=x,r=y,main(3,43),p=z,x=X(43),y=Y(43),main(3,s[_]),p+=z,x=X(s[_]),y=Y(s[_]),main(a,_+1),p+=z,x=q,y=r,main(3,94),q=z,x=X(94),y=Y(94),main(3,s[_]),q+=z,x=X(s[_]),y=Y(s[_]),main(!a,_+1),q+=z,z=(q<p?q:p):(main(3,s[_]),q=z,x=X(s[_]),y=Y(s[_]),main(a,_+1),z+=q):(main(3,61)):(a<3?s=((char**)_)[1],x=0,y=1,main(1,0),printf("%d",z):(x=X(_)-x,y=Y(_)-y,x+=10*(x<0),y+=4*(y<0),z=(x>5?10-x:x)+(y>2?4-y:y)));}
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.