Inserisci il tuo nome tramite un D-pad


32

Il puzzle:

Prendi in considerazione una console / un gioco portatile con un d-pad in cui ti viene richiesto di inserire un nome. Questo è apparso in molti vecchi giochi prima che l'uso di QWERTY fosse reso popolare nelle console (ad esempio, credo che Wii utilizzi un layout di tastiera QWERTY per l'input). In genere, la tastiera su schermo osserva l'effetto di *:

Predefinito:

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 il caso acceso:

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

Cioè, tutte le chiavi alfanumeriche e le seguenti:

_: Un singolo spazio
-: un trattino
+: cambia maiuscole e minuscole solo per la lettera successiva
^: attiva il blocco maiuscole (ovvero cambia maiuscole e minuscole)
=: inserisci, completa

* Ovviamente ho sostituito chiavi come "BKSP" e "ENTER" con versioni più brevi

E poi l'hardware dovrebbe includere un d-pad (o una qualche forma di controllo in cui si poteva andare up, down, lefte right)

Lo schermo in genere consente anche di spostarsi da un lato direttamente all'altro. Cioè, se tu fossi concentrato sulla lettera J, premendo rightti permetterebbe di passare alla lettera A.

Ogni volta che inserivo il mio nome, provavo sempre a trovare il modo più rapido per farlo.

Obbiettivo:

Il tuo programma prenderà l'input di stringa che può includere qualsiasi carattere alfanumerico incluso uno spazio e un trattino, e il tuo obiettivo è quello di produrre il minor numero di pressioni di tasti sul tasto direzionale per produrre la stringa richiesta.

considerazioni:

Non è necessario includere il tasto premuto per premere il carattere reale.
La messa a fuoco inizia sempre A
all'Invio =deve essere premuto alla fine

Esempio:

input: Code Golf
output: 43

Spiegato:
A -> C= 2
C-> ^= 6 (spostandosi a sinistra)
^-> 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

Nota che è più veloce colpire +due volte per a _e a Gche colpire ^una volta, quindi scambia indietro.

L'invio vincente (consentirò almeno 1w) sarà la soluzione più breve (in byte). Dato che questa è la mia prima domanda, spero che sia chiaro e non troppo difficile.


12
Bella sfida! Solo un punto, 48 ore è probabilmente troppo poco. Ecco quanto ci vuole per ottenere i doni, quindi dovrebbe essere più di una settimana +.
Maltysen,

@Maltysen grazie per il suggerimento, ho aggiornato la sfida
Tas

1
Puoi avvolgere anche verticalmente o solo orizzontalmente?
Alex Reinking,

2
@AlexReinking è un ottimo punto! Si, puoi.
Tas

Grande! La mia implementazione lo fa, quindi volevo solo ricontrollare.
Alex Reinking,

Risposte:


5

Rubino (369 byte)

Riceve input dalla riga di 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)

Ho salvato un sacco di byte grazie a @Charlie :)


j=(K.index(c.upcase) or 36)può essere sostituito con j=K.index(c.upcase)||36per salvare 4 byte. def d(x,y)può essere sostituito con def d x,yper salvare un byte, e lo stesso vale per def v. v(...) ifa v(...)ifper un altro byte. Nell'ultima riga, v(...)può essere sostituito con v ...per salvare 1 byte e truecon !!0per salvare un altro byte.
Charlie,

Grazie! Non conosco davvero Ruby. L'ho tradotto da Python ...
Alex Reinking,

Posso anche sostituire &&con &e ||con |.
Alex Reinking,

La tua prima riga ( K=...) può essere sostituita con un intervallo ( K='0123456789'+('A'..'Z').to_a.join+' +^=')
Charlie

Rade altri 2!
Alex Reinking,

9

Swift 1.2, 812 588 670 byte

Modifica: rimossi 224 byte sostituendo le grandi matrici di numeri con un intervallo e convertendolo invece in un array.

Edit2: aggiunto loop in 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)))

Per eseguire, inserire il codice in un .swiftfile ed eseguirlo conswift <filename> <your name>


Questo utilizza il semplice approccio in cui le due 'tastiere' sono memorizzate come array.

B:(I)->(I,I)={a in(a%10,a/10)} Converte un indice dall'array in una posizione x, y sulla tastiera virtuale.

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)))} Prende un indice di inizio / fine e restituisce il numero minimo di mosse da passare da una volta all'altra (tenendo conto dell'involucro orizzontale)

func D(c:S,_ e:I=10,_ f:Bool=false,_ g:Bool=false)->IÈ la principale funzione ricorsiva che esegue la maggior parte dei calcoli. Calcola la distanza dalla posizione corrente al personaggio bersaglio, a meno che il caso non cambi, quindi calcola sia il metodo di spostamento che il blocco maiuscole e prende il minimo.

Esecuzione di swift codegolf.swift Code Golfstampe43


Deve tenere conto dell'involucro verticale.
Alex Reinking,

Aggiornato per tenere conto anche dell'involucro verticale.
David Skrundz,

4

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

Esegui questo e ti chiederà un input (senza testo di richiesta). Per l'input Code Golfche stampa 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)

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

Uscita estesa dal programma 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

Salvataggio di un byte grazie a @justin https://codegolf.stackexchange.com/a/18983/42736
4 @xnor https://codegolf.stackexchange.com/a/40791/42736 19 grazie a @Alex


Qualsiasi aiuto è apprezzato perché sto ancora imparando Python e questo è il mio primo codice golf.
J Atkin,

È possibile utilizzare uno spazio anziché un carattere di sottolineatura nelle tabelle interne.
Alex Reinking,

Non ci avevo pensato, grazie;)
J Atkin,

3

C 675 byte

Prende input dall'argomento della riga di comando. Utilizza principale ricorsivo:

#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)));}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.