Masukkan nama Anda melalui pad-D

32

Teka-teki:

Pertimbangkan permainan konsol / genggam dengan d-pad di mana Anda diminta memasukkan nama jenis. Ini muncul di banyak game lama sebelum penggunaan QWERTY dipopulerkan di konsol (mis. Saya percaya Wii menggunakan tata letak keyboard QWERTY untuk input). Biasanya, keyboard di layar melihat efek dari *:

Default:

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

Dengan penutup case:

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

Yaitu, semua kunci alfanumerik dan berikut ini:

_: Satu spasi
-: Tanda hubung
+: Alihkan case hanya untuk huruf berikutnya
^: Toggle caps lock (yaitu, alihkan case dari semua huruf)
=: Enter, complete

* Jelas saya mengganti kunci seperti "BKSP" dan "ENTER" dengan versi yang lebih pendek

Dan kemudian hardware akan mencakup d-pad (atau beberapa bentuk kontrol di mana Anda bisa pergi up, down, leftdan right)

Layar juga biasanya memungkinkan Anda bergerak dari satu sisi langsung ke yang lain. Artinya, jika Anda fokus pada surat itu J, menekan rightakan memungkinkan Anda untuk pindah ke surat itu A.

Setiap kali saya memasukkan nama saya, saya selalu berusaha mencari cara tercepat untuk melakukannya.

Tujuan:

Program Anda akan mengambil input string yang dapat menyertakan karakter alfanumerik apa pun termasuk spasi dan tanda hubung, dan tujuan Anda adalah untuk menghasilkan jumlah penekanan tombol terpendek pada d-pad untuk menampilkan string yang diperlukan.

Pertimbangan:

Anda tidak perlu memasukkan tombol yang ditekan untuk menekan karakter yang sebenarnya.
Fokus selalu dimulai pada A
Enter =harus ditekan di akhir

Contoh:

input: Code Golf
output: 43

Dijelaskan:
A -> C= 2
C-> ^= 6 (bergerak ke kiri)
^-> 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

Perhatikan bahwa lebih cepat menekan +dua kali untuk a _dan a Gdaripada menekan ^satu kali, lalu tukar kembali.

Pengajuan yang menang (saya akan mengizinkan setidaknya 1w) akan menjadi solusi terpendek (dalam byte). Karena ini adalah pertanyaan pertama saya, saya harap ini jelas dan tidak terlalu sulit.

Tas
sumber
12
Tantangan yang bagus! Hanya satu poin, 48 jam mungkin terlalu sedikit. Itu berapa lama waktu yang dibutuhkan untuk hadiah diizinkan, jadi harus lebih sekitar seminggu +.
Maltysen
@Maltysen terima kasih atas sarannya, saya telah memperbarui tantangan
Tas
1
Bisakah Anda membungkus secara vertikal juga, atau hanya secara horizontal?
Alex Reinking
2
@AlexReinking itu poin bagus! Ya kamu bisa.
Tas
Besar! Implementasi saya melakukan itu, jadi saya hanya ingin memeriksa ulang.
Alex Reinking

Jawaban:

5

Ruby (369 bytes)

Mengambil input dari baris perintah.

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)

Menyimpan banyak byte berkat @Charlie :)

Alex Reinking
sumber
j=(K.index(c.upcase) or 36)dapat diganti dengan j=K.index(c.upcase)||36untuk menyimpan 4 byte. def d(x,y)dapat diganti dengan def d x,yuntuk menyimpan byte, dan hal yang sama berlaku untuk def v. v(...) ifke v(...)ifuntuk byte lain. Pada baris terakhir, v(...)dapat diganti dengan v ...untuk menyimpan 1 byte, dan truedengan !!0untuk menyimpan byte lain.
Charlie
Terima kasih! Saya tidak begitu kenal Ruby. Saya menerjemahkan ini dari python ...
Alex Reinking
Saya juga bisa mengganti &&dengan &dan ||dengan |.
Alex Reinking
Baris pertama Anda ( K=...) dapat diganti dengan rentang ( K='0123456789'+('A'..'Z').to_a.join+' +^=')
Charlie
Bercukur 2 lagi!
Alex Reinking
9

Swift 1.2, 812 588 670 byte

Sunting: Menghapus 224 byte dengan mengganti array angka yang besar dengan Range dan mengubahnya menjadi Array.

Sunting2: Menambahkan pengulangan secara vertikal

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

Untuk menjalankan, masukkan kode dalam .swiftfile dan jalankan denganswift <filename> <your name>


Ini menggunakan pendekatan sederhana di mana dua 'keyboard' disimpan sebagai array.

B:(I)->(I,I)={a in(a%10,a/10)} Mengubah indeks dari array ke posisi x, y pada keyboard 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)))} Mengambil indeks awal / akhir dan mengembalikan jumlah minimum gerakan untuk berpindah dari satu kali ke yang lain (akuntansi untuk bungkus horizontal)

func D(c:S,_ e:I=10,_ f:Bool=false,_ g:Bool=false)->IMerupakan fungsi rekursif utama yang melakukan sebagian besar perhitungan. Ini menghitung jarak dari posisi saat ini ke karakter target, kecuali kasus ini harus berubah, maka menghitung baik yang pergeseran dan para caps lock metode dan mengambil terkecil.

Menjalankan swift codegolf.swift Code Golfcetakan43

David Skrundz
sumber
Perlu memperhitungkan bungkus vertikal.
Alex Reinking
Diperbarui ke akun untuk bungkus vertikal juga.
David Skrundz
4

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

Jalankan ini dan ia akan meminta input (tanpa teks prompt). Untuk input Code Golfyang dicetak 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)

Program lengkap:

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)

Output yang diperluas dari program lengkap:

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

Menyimpan satu byte berkat @justin https://codegolf.stackexchange.com/a/18983/42736
4 @xnor https://codegolf.stackexchange.com/a/40791/42736 19 terima kasih kepada @Alex

J Atkin
sumber
Setiap bantuan dihargai karena saya masih belajar python dan ini adalah kode golf pertama saya.
J Atkin
Anda bisa menggunakan spasi alih-alih garis bawah di tabel internal Anda.
Alex Reinking
Saya tidak memikirkan itu, terima kasih;)
J Atkin
3

C 675 Bytes

Mengambil input dari argumen baris perintah. Menggunakan utama rekursif:

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