Geben Sie Ihren Namen über ein Steuerkreuz ein

32

Das Puzzle:

Stellen Sie sich ein Konsolen- / Handspiel mit einem Steuerkreuz vor, bei dem Sie eine Art Namen eingeben müssen. Dies trat in vielen älteren Spielen auf, bevor die Verwendung von QWERTY in Konsolen populär wurde (z. B. verwendet die Wii meines Erachtens ein QWERTY-Tastaturlayout für die Eingabe). In der Regel sieht die Bildschirmtastatur wie folgt aus:

Standard:

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

Mit dem Fall geschaltet:

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

Das heißt, alle alphanumerischen Tasten und die folgenden:

_: Ein einzelnes Leerzeichen
-: Ein Bindestrich
+: Groß- / Kleinschreibung nur für den nächsten Buchstaben
^umschalten: Feststelltaste umschalten (dh Groß- / Kleinschreibung aller Buchstaben umschalten)
=: Eingeben, abschließen

* Offensichtlich habe ich Tasten wie "BKSP" und "ENTER" durch kürzere Versionen ersetzt

Und dann würde die Hardware gehört ein D-Pad (oder irgendeine Form der Kontrolle , wohin Sie gehen könnten up, down, leftund right)

Auf dem Bildschirm können Sie in der Regel auch direkt von einer Seite zur anderen wechseln. Wenn Sie sich also auf den Buchstaben konzentrieren J, können Sie durch Drücken rightvon zum Buchstaben wechseln A.

Wann immer ich meinen Namen eingab, versuchte ich immer, den schnellsten Weg zu finden.

Tor:

Ihr Programm übernimmt die Eingabe von Zeichenfolgen, die beliebige alphanumerische Zeichen einschließlich Leerzeichen und Bindestrich enthalten können. Ihr Ziel ist es, die kürzeste Anzahl von Tastendrücken auf dem Steuerkreuz auszugeben, um die erforderliche Zeichenfolge auszugeben.

Überlegungen:

Sie müssen die gedrückte Taste nicht einschließen, um das tatsächliche Zeichen zu drücken .
Fokus beginnt immer bei der A
Enter Taste =muss am Ende gedrückt werden

Beispiel:

input: Code Golf
output: 43

Erklärt:
A -> C= 2
C-> ^= 6 (nach links bewegen)
^-> 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

Beachten Sie, dass es schneller ist, +zweimal für a _und a Gzu schlagen, als ^einmal, und dann zurück zu tauschen.

Die gewinnende Einsendung (ich erlaube mindestens 1 W) ist die kürzeste Lösung (in Bytes). Da dies meine erste Frage ist, hoffe ich, dass dies klar und nicht zu schwer ist.

Tas
quelle
12
Schöne Herausforderung! Nur ein Punkt, 48 Stunden sind wahrscheinlich zu wenig. So lange dauert es, bis Kopfgelder erlaubt sind, also sollte es ungefähr eine Woche länger dauern.
Maltysen
@Maltysen danke für den Vorschlag, ich habe die Herausforderung aktualisiert
Tas
1
Können Sie auch vertikal oder nur horizontal wickeln?
Alex Reinking
2
@ AlexReinking das ist ein toller Punkt! Ja, du kannst.
Tas
Groß! Meine Implementierung macht das, also wollte ich es nur noch einmal überprüfen.
Alex Reinking

Antworten:

5

Ruby (369 Bytes)

Übernimmt Eingaben von der Kommandozeile.

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)

Dank @Charlie eine Menge Bytes gespart :)

Alex Reinking
quelle
j=(K.index(c.upcase) or 36)kann durch ersetzt werden j=K.index(c.upcase)||36, um 4 Bytes zu sparen. def d(x,y)kann mit ersetzt werden def d x,y, um ein Byte zu speichern, und das gilt auch für def v. v(...) ifum v(...)iffür ein weiteres Byte. In der letzten Zeile v(...)kann durch ersetzt werden v ..., um 1 Byte zu speichern, und truedurch !!0, um ein anderes Byte zu speichern.
Charlie
Vielen Dank! Ich kenne Ruby nicht wirklich. Ich übersetzte dies aus Python ...
Alex Reinking
Ich kann auch &&mit &und ||mit ersetzen |.
Alex Reinking
Ihre erste Zeile ( K=...) kann durch eine Range ( K='0123456789'+('A'..'Z').to_a.join+' +^=') ersetzt werden
Charlie
Rasiert noch 2 ab!
Alex Reinking
9

Swift 1.2, 812 588 670 Bytes

Bearbeiten: 224 Bytes wurden entfernt, indem die großen Zahlenfelder durch einen Bereich ersetzt und stattdessen in ein Array konvertiert wurden.

Edit2: Loop vertikal hinzugefügt

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

Fügen Sie zum Ausführen den Code in eine .swiftDatei ein und führen Sie ihn mit ausswift <filename> <your name>


Hierbei wird der einfache Ansatz verwendet, bei dem die beiden 'Tastaturen' als Arrays gespeichert werden.

B:(I)->(I,I)={a in(a%10,a/10)} Konvertiert einen Index aus dem Array in eine x, y-Position auf der virtuellen Tastatur.

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)))} Nimmt einen Start- / Endindex und gibt die minimale Anzahl von Zügen zurück, um von einem zum anderen zu gelangen (Berücksichtigung des horizontalen Umlaufs)

func D(c:S,_ e:I=10,_ f:Bool=false,_ g:Bool=false)->IIst die rekursive Hauptfunktion, die die meisten Berechnungen durchführt. Er berechnet die Entfernung von der aktuellen Position zum Zielzeichen, sofern sich die Groß- / Kleinschreibung nicht ändert. Er berechnet dann sowohl die Verschiebungsmethode als auch die Feststelltaste und verwendet die kleinste.

Laufender swift codegolf.swift Code GolfDruck43

David Skrundz
quelle
Muss für vertikale Wrap berücksichtigen.
Alex Reinking
Aktualisiert, um auch vertikalen Wrap zu berücksichtigen.
David Skrundz
4

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

Führen Sie dies aus und es wird nach einer Eingabe gefragt (ohne Aufforderungstext). Für die Eingabe Code Golfwird gedruckt 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)

Volles Programm:

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)

Erweiterte Ausgabe aus dem vollen Programm:

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

Dank @justin https://codegolf.stackexchange.com/a/18983/42736
4 @xnor https://codegolf.stackexchange.com/a/40791/42736 19 dank @Alex wurde ein Byte gespeichert

J Atkin
quelle
Jede Hilfe ist willkommen, da ich noch Python lerne und dies mein erster Code Golf ist.
J Atkin
Sie können in Ihren internen Tabellen ein Leerzeichen anstelle eines Unterstrichs verwenden.
Alex Reinking
Ich hatte nicht daran gedacht, danke;)
J Atkin
3

C 675 Bytes

Übernimmt die Eingabe vom Befehlszeilenargument. Verwendet rekursives main:

#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
quelle