Ingrese su nombre a través de un D-pad

32

El rompecabezas:

Considere un juego de consola / de mano con un d-pad donde se le requiere ingresar un tipo de nombre. Esto apareció en muchos juegos anteriores antes de que el uso de QWERTY se popularizara en las consolas (por ejemplo, creo que la Wii usa un diseño de teclado QWERTY para la entrada). Por lo general, el teclado en pantalla tiene el efecto de *:

Defecto:

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 _ + ^ =

Con el caso cambiado:

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 - + ^ =

Es decir, todas las claves alfanuméricas y lo siguiente:

_: Un solo espacio
-: Un guión
+: Cambiar mayúsculas y minúsculas solo para la siguiente letra
^: Alternar bloqueo de mayúsculas (es decir, cambiar mayúsculas y minúsculas)
=: Entrar, completar

* Obviamente reemplacé teclas como "BKSP" y "ENTER" con versiones más cortas

Y luego el hardware incluiría un d-pad (o alguna forma de control donde se podía ir up, down, lefty right)

La pantalla también te permite moverte de un lado a otro directamente. Es decir, si se concentrara en la letra J, presionar rightle permitiría moverse a la letra A.

Cada vez que ingresaba mi nombre, siempre intentaba encontrar la forma más rápida de hacerlo.

Gol:

Su programa tomará una entrada de cadena que puede incluir cualquier carácter alfanumérico, incluido un espacio y un guión, y su objetivo es generar la menor cantidad de pulsaciones de teclas en el d-pad para generar la cadena requerida.

Consideraciones:

No necesita incluir la tecla presionada para presionar el carácter real.
El foco siempre comienza en A
Enter, =debe presionarse al final

Ejemplo:

input: Code Golf
output: 43

Explicado:
A -> C= 2
C-> ^= 6 (moviéndose hacia la izquierda)
^-> 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

Tenga en cuenta que es más rápido presionar +dos veces para a _y a Gque presionar ^una vez, luego cambiar de nuevo.

La presentación ganadora (permitiré al menos 1w) será la solución más corta (en bytes). Como esta es mi primera pregunta, espero que sea clara y no demasiado difícil.

Tas
fuente
12
Buen desafío! Solo un punto, 48 horas es probablemente muy poco. Ese es el tiempo que se tarda en permitir las recompensas, por lo que debería ser más de una semana o más.
Maltysen
@ Maltysen gracias por la sugerencia, he actualizado el desafío
Tas
1
¿Puedes envolver también verticalmente o solo horizontalmente?
Alex Reinking
2
@AlexReinking ese es un gran punto! Sí tu puedes.
Tas
¡Excelente! Mi implementación hace eso, así que solo quería verificar dos veces.
Alex Reinking

Respuestas:

5

Rubí (369 bytes)

Toma información de la línea de comando.

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)

Ahorré un montón de bytes gracias a @Charlie :)

Alex Reinking
fuente
j=(K.index(c.upcase) or 36)se puede reemplazar con j=K.index(c.upcase)||36para guardar 4 bytes. def d(x,y)puede reemplazarse con def d x,ypara guardar un byte, y lo mismo ocurre con def v. v(...) ifpara v(...)ifpor otro byte. En la última línea, v(...)se puede reemplazar con v ...para guardar 1 byte y truecon !!0para guardar otro byte.
Charlie
¡Gracias! Realmente no conozco a Ruby. Traduje esto de Python ...
Alex Reinking
También puedo reemplazar &&con &y ||con |.
Alex Reinking
Su primera línea ( K=...) se puede reemplazar con un rango ( K='0123456789'+('A'..'Z').to_a.join+' +^=')
Charlie
¡Afeita otros 2!
Alex Reinking
9

Swift 1.2, 812 588 670 bytes

Editar: Se eliminaron 224 bytes al reemplazar las grandes matrices de números con un Rango y convertirlo en una Matriz.

Edit2: Agregado bucle verticalmente

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)))

Para ejecutar, coloque el código en un .swiftarchivo y ejecútelo conswift <filename> <your name>


Esto utiliza el enfoque simple donde los dos 'teclados' se almacenan como matrices.

B:(I)->(I,I)={a in(a%10,a/10)} Convierte un índice de la matriz en una posición x, y en el teclado virtual.

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)))} Toma un índice de inicio / fin y devuelve el número mínimo de movimientos para pasar de una a otra (teniendo en cuenta el ajuste horizontal)

func D(c:S,_ e:I=10,_ f:Bool=false,_ g:Bool=false)->IEs la principal función recursiva que realiza la mayoría de los cálculos. Se calcula la distancia desde la posición actual al carácter objetivo, a menos que el caso debe cambiar, entonces se calcula tanto el desplazamiento y las tapas de bloqueo métodos y toma el más pequeño.

Ejecutando swift codegolf.swift Code Golfimpresiones43

David Skrundz
fuente
Necesita dar cuenta de la envoltura vertical.
Alex Reinking
Actualizado para tener en cuenta la envoltura vertical también.
David Skrundz
4

Python 679 661 619 602 589 576 539 520 496 482 Bytes

Ejecute esto y solicitará una entrada (sin texto de solicitud). Para la entrada Code Golfque imprime 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)

Programa completo:

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)

Salida extendida del programa completo:

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

Guardado un byte gracias a @justin https://codegolf.stackexchange.com/a/18983/42736
4 @xnor https://codegolf.stackexchange.com/a/40791/42736 19 gracias a @Alex

J Atkin
fuente
Cualquier ayuda es apreciada ya que todavía estoy aprendiendo Python y este es mi primer código de golf.
J Atkin
Puede usar un espacio en lugar de un guión bajo en sus tablas internas.
Alex Reinking
No había pensado en eso, gracias;)
J Atkin
3

C 675 bytes

Toma información del argumento de la línea de comando. Utiliza recursivo principal:

#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)));}
LambdaBeta
fuente