Entrez votre nom via un D-pad

32

Le puzzle:

Considérez un jeu console / portable avec un d-pad où vous devez entrer un nom en quelque sorte. Cela est apparu dans de nombreux jeux plus anciens avant que l'utilisation de QWERTY ne soit popularisée dans les consoles (par exemple, je pense que la Wii utilise une disposition de clavier QWERTY pour la saisie). En règle générale, le clavier à l'écran ressemble à l'effet de *:

Défaut:

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

Avec le boîtier basculé:

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

Autrement dit, toutes les clés alphanumériques et les éléments suivants:

_: Un seul espace
-: Un tiret
+: Changer la casse pour la lettre suivante uniquement
^: Basculer le verrouillage des majuscules (c'est-à-dire, changer la casse de toutes les lettres)
=: Entrer, terminer

* Évidemment, j'ai remplacé des clés comme "BKSP" et "ENTER" par des versions plus courtes

Et puis le matériel comprendrait un d-pad (ou une certaine forme de contrôle où vous pouvez aller up, down, leftet right)

L'écran vous permet également généralement de passer d'un côté directement à l'autre. Autrement dit, si vous étiez concentré sur la lettre J, appuyer sur rightvous permettrait de passer à la lettre A.

Chaque fois que je saisissais mon nom, j'essayais toujours de trouver le moyen le plus rapide de le faire.

Objectif:

Votre programme prendra une entrée de chaîne qui peut inclure n'importe quel caractère alphanumérique, y compris un espace et un trait d'union, et votre objectif est de produire le plus petit nombre de touches sur le pavé numérique pour sortir la chaîne requise.

Considérations:

Vous n'avez pas besoin d'inclure la touche enfoncée pour appuyer sur le caractère réel.
La mise au point commence toujours à la toucheA
Entrée =doit être enfoncée à la fin

Exemple:

input: Code Golf
output: 43

Expliqué:
A -> C= 2
C-> ^= 6 (se déplaçant vers la gauche)
^-> 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

Notez qu'il est plus rapide de frapper +deux fois pour a _et a Gque de frapper ^une fois, puis de revenir en arrière.

La soumission gagnante (je vais autoriser au moins 1w) sera la solution la plus courte (en octets). Comme c'est ma première question, j'espère que c'est clair et pas trop difficile.

Tas
la source
12
Beau défi! Juste un point, 48 heures, c'est probablement trop peu. C'est le temps qu'il faut pour que les primes soient autorisées, donc cela devrait être plus autour d'une semaine +.
Maltysen
@Maltysen merci pour la suggestion, j'ai mis à jour le défi
Tas
1
Pouvez-vous envelopper verticalement aussi, ou simplement horizontalement?
Alex Reinking
2
@AlexReinking c'est un bon point! Oui, vous pouvez.
Tas
Génial! Mon implémentation fait cela, donc je voulais juste revérifier.
Alex Reinking

Réponses:

5

Rubis (369 octets)

Prend l'entrée de la ligne de commande.

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)

Sauvegardé un tas d'octets grâce à @Charlie :)

Alex Reinking
la source
j=(K.index(c.upcase) or 36)peut être remplacé par j=K.index(c.upcase)||36pour économiser 4 octets. def d(x,y)peut être remplacé par def d x,ypour enregistrer un octet, et il en va de même def v. v(...) ifà v(...)ifun autre octet. Sur la dernière ligne, v(...)peut être remplacé par v ...pour enregistrer 1 octet et truepar !!0pour enregistrer un autre octet.
Charlie
Merci! Je ne connais pas vraiment Ruby. J'ai traduit ça de python ...
Alex Reinking
Je peux également remplacer &&par &et ||par |.
Alex Reinking
Votre première ligne ( K=...) peut être remplacée par une plage ( K='0123456789'+('A'..'Z').to_a.join+' +^=')
Charlie
Rase encore 2 de plus!
Alex Reinking
9

Swift 1.2, 812 588 670 octets

Edit: Suppression de 224 octets en remplaçant les grands tableaux de nombres par une plage et en le convertissant à la place en tableau.

Edit2: Ajout d'une boucle verticale

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

Pour l'exécuter, placez le code dans un .swiftfichier et exécutez-le avecswift <filename> <your name>


Cela utilise l'approche simple où les deux «claviers» sont stockés sous forme de tableaux.

B:(I)->(I,I)={a in(a%10,a/10)} Convertit un index du tableau en position x, y sur le clavier virtuel.

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)))} Prend un index de début / fin et renvoie le nombre minimum de mouvements pour passer d'une fois à l'autre (en tenant compte de l'habillage horizontal)

func D(c:S,_ e:I=10,_ f:Bool=false,_ g:Bool=false)->IEst la fonction récursive principale qui effectue la plupart des calculs. Il calcule la distance entre la position actuelle au caractère cible, à moins que le cas devrait changer, il calcule à la fois le déplacement et les bouchons de verrouillage des méthodes et prend la plus petite.

swift codegolf.swift Code GolfImpressions en cours d'exécution43

David Skrundz
la source
Doit tenir compte de l'enroulement vertical.
Alex Reinking
Mis à jour pour tenir compte de l'enroulement vertical également.
David Skrundz
4

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

Exécutez ceci et il demandera une entrée (sans texte d'invite). Pour l'entrée, Code Golfil 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)

Programme complet:

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)

Sortie étendue du programme complet:

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

Un octet enregistré grâce à @justin https://codegolf.stackexchange.com/a/18983/42736
4 @xnor https://codegolf.stackexchange.com/a/40791/42736 19 grâce à @Alex

J Atkin
la source
Toute aide est appréciée car j'apprends toujours le python et c'est mon premier golf de code.
J Atkin
Vous pouvez utiliser un espace au lieu d'un trait de soulignement dans vos tables internes.
Alex Reinking
Je n'y avais pas pensé, merci;)
J Atkin
3

C 675 octets

Prend l'entrée de l'argument de ligne de commande. Utilise récursif 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
la source