Mengetik dengan Efisien di Game Boy


26

Banyak game Game Boy lama seringkali membutuhkan input string dari pengguna. Namun, tidak ada keyboard. Ini ditangani dengan menghadirkan pengguna dengan "layar keyboard" seperti:

Keyboard Pokemon Ruby

The 'karakter pointer' akan dimulai pada huruf A. Pengguna akan menavigasi ke masing-masing karakter yang diinginkan dengan D-Pad 's empat tombol ( UP, DOWN, LEFTdan RIGHT), lalu tekan BUTTON Auntuk menambahkan ke string akhir.

Tolong dicatat:

  • Grid membungkus , sehingga menekanUPsementara pada huruf A akan membawa Anda ke T.
  • 'Penunjuk karakter' tetap diletakkan setelah menambahkan huruf

Tantangan

Keyboard di atas memiliki opsi untuk mengubah huruf besar-kecil dan bentuknya tidak beraturan. Jadi, untuk kesederhanaan, dalam tantangan ini kita akan menggunakan keyboard berikut (kanan bawah adalah ASCII char 32, spasi):

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 .

Mengetik pada keyboard seperti ini sangat lambat - jadi, untuk membuatnya lebih mudah, tugas Anda adalah menulis sebuah program yang memberi tahu pengguna cara tercepat yang mungkin untuk mengetik string yang diberikan. Jika ada beberapa cara tercepat, Anda hanya perlu menunjukkan satu.

Kunci output harus:

  • > untuk RIGHT
  • < untuk LEFT
  • ^ untuk UP
  • v untuk DOWN
  • .untuk BUTTON A(tambahkan huruf saat ini ke string)

Misalnya, ketika diberi string DENNIS, solusinya akan terlihat seperti ini:

>>>.>.>>v..>>.>>>v.

Aturan / Detail

  • Tolong ingat, kisi-kisi membungkus!
  • Anda dapat mengirimkan program atau fungsi lengkap, selama itu mengambil string awal dan menghasilkan string solusi. Baris putih / trailing baris baru tidak relevan selama outputnya benar.
  • Anda dapat mengasumsikan input hanya terdiri dari karakter yang dapat diketik pada keyboard yang ditentukan, tetapi mungkin kosong.
  • Ini , jadi kode terpendek menang. Lubang kode standar golf berlaku.

Uji Kasus

Biasanya ada beberapa solusi dengan panjang yang sama. Untuk setiap test case, saya telah memasukkan panjang optimal, dan sebuah contoh. Anda tidak perlu mencetak panjang jawaban Anda, hanya solusinya.

FLP.TKC  ->  25 steps:  <<.<v.<<<v.<<<v.^.<<^.<^.
MOYLEX   ->  23 steps:  <<v.>>v.>>>v.>^^.^.<<^.
FEERSUM  ->  18 steps:  <<.<..<vv.>.>>.<^.
MEGO     ->  14 steps:  <<v.<^.>>.>vv.

A CAT    ->  17 steps:  .<^.>>>v.<<.<<vv.
BOB      ->  10 steps:  >.<vv.>^^.

(space)  ->  3 steps:   <^.
(empty)  ->  0 steps:   (empty)

Anda dapat melihat generator testcase saya di repl.it - tolong beri tahu saya jika ada bug.

Terima kasih semuanya atas kirimannya! Pengguna ngn saat ini adalah pemenang dengan 61 byte, tetapi jika ada yang bisa menemukan solusi yang lebih pendek, centang hijau kecil dapat dipindahkan;)


Perhatikan bahwa ini telah melalui kotak pasir, dan tantangan serupa ditemukan, tetapi diskusi dalam obrolan dan kotak pasir mengarah pada kesimpulan bahwa itu bukan penipuan, hanya terkait erat :)
FlipTack

Saya pikir itu tampak sangat akrab, tetapi itu juga bukan duplikat dari yang ini .

Jawaban:


4

Dyalog APL , 61 byte

4 7∘{∊'.',⍨⍉↑b⍴¨¨'^v' '<>'⌷¨⍨⊂¨a>b←a⌊⍺-a←⍺|↓2-/0,⍺⊤⍵⍳⍨⎕a,'.'}

mengasumsikan ⎕IO←0

⎕a,'.' alfabet diikuti dengan berhenti penuh

⍵⍳⍨temukan karakter argumen di sana sebagai indeks 0..26 ( ' 'dan semua yang lain akan menjadi 27)

⍺⊤encode di basis 7 (perhatikan arg kiri terikat ke 4 7), dapatkan 2 × n matriks

0, angka nol di sebelah kiri

2-/ perbedaan antara kolom yang berdekatan

membagi matriks menjadi sepasang vektor

a←⍺| bawa masing-masing modulo 4 dan 7, tetapkan ke a

b←a⌊⍺-amembuat byang lebih kecil adan terbalik modularnya

'^v' '<>'⌷¨⍨⊂¨a>bpilih ^atau vuntuk vektor pertama dan <atau >untuk yang kedua, berdasarkan dari mana aberbedab

b⍴¨¨ulangi setiap bwaktu itu

⍉↑ campurkan dua vektor menjadi satu matriks dan transposkan, dapatkan matriks n × 2

'.',⍨tambahkan .-s di sebelah kanan

meratakan


6

JavaScript (ES6), 147 byte

s=>s.replace(/./g,c=>(q=p,p="AHOVBIPWCJQXDKRYELSZFMY.GNU ".indexOf(c),"<<<>>>".substring(3,((p>>2)+10-(q>>2))%7)+["","v","vv","^"][p-q&3]+"."),p=0)

Perilaku yang menarik substringadalah bahwa ia bertukar argumen jika yang kedua kurang dari yang pertama. Ini berarti bahwa jika saya menghitung jumlah optimal dari penekanan kiri / kanan sebagai angka antara -3 dan 3, saya dapat menambahkan 3, dan mengambil substring <<<>>>mulai dari 3 dan saya akan mendapatkan jumlah panah yang benar. Sementara itu tekan ke bawah / atas hanya ditangani dengan mencari array menggunakan bitwise dan selisih baris dengan 3; cara ini sedikit lebih pendek karena ada lebih sedikit elemen array.


4

Ruby, 107 byte

->s{c=0
s.tr(". ","[\\").bytes{|b|b-=65
print ["","^","^^","v"][c/7-b/7],(d=(c-c=b)%7)>3??>*(7-d):?<*d,?.}}

Tidak digabungkan dalam program uji

f=->s{                                 #Input in s.
  c=0                                  #Set current position of pointer to 0.
  s.tr(". ","[\\").                    #Change . and space to the characters after Z [\
  bytes{|b|                            #For each byte b,
    b-=65                              #subtract 65 so A->0 B->1 etc.
    print ["","^","^^","v"][c/7-b/7],  #Print the necessary string to move vertically.
    (d=(c-c=b)%7)>3?                   #Calculate the horizontal difference c-b (mod 7) and set c to b ready for next byte.
       ?>*(7-d):?<*d,                  #If d>3 print an appropriate number of >, else an appropriate number of <.
    ?.                                 #Print . to finish the processing of this byte.
  }
}

#call like this and print a newline after each testcase
f["FLP.TKC"];puts  
f["MOYLEX"];puts   
f["FEERSUM"];puts  
f["MEGO"];puts     
f["A CAT"];puts    
f["BOB"];puts      

1

Mathematica, 193 byte

Golf

StringJoin@@(StringTake[">>><<<",Mod[#〚2〛,7,-3]]<>StringTake["vv^",Mod[#〚1〛,4,-1]]<>"."&/@Differences[FirstPosition[Partition[ToUpperCase@Alphabet[]~Join~{"."," "},7],#]&/@Characters["A"<>#]])&

Dapat dibaca

In[1]:= characters = ToUpperCase@Alphabet[]~Join~{".", " "}

Out[1]= {"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", ".", " "}

In[2]:= keyboard = Partition[characters, 7]

Out[2]= {{"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", ".", " "}}

In[3]:= characterPosition[char_] := FirstPosition[keyboard, char]

In[4]:= xToString[x_] := StringTake[">>><<<", Mod[x, 7, -3]]

In[5]:= yToString[y_] := StringTake["vv^", Mod[y, 4, -1]]

In[6]:= xyToString[{y_, x_}] := xToString[x] <> yToString[y] <> "."

In[7]:= instructionsList[input_] := xyToString /@ Differences[characterPosition /@ Characters["A" <> input]]

In[8]:= instructions[input_] := StringJoin @@ instructionsList[input]

In[9]:= instructions["DENNIS"]

Out[9]= ">>>.>.>>v..>>.>>>v."

1

Python 2, 298 byte

Ini lebih lama dari yang seharusnya, tapi ...

def l(c):i="ABCDEFGHIJKLMNOPQRSTUVWXYZ. ".index(c);return[i%7,i/7]
def d(f,t,a=abs):
 v,h=l(t)[1]-l(f)[1],l(t)[0]-l(f)[0]
 if a(h)>3:h=h-7*h/a(h)
 if a(v)>2:v=v-4*v/a(v)
 return'^v'[v>0]*a(v)+'<>'[h>0]*a(h)
s="A"+input()
print''.join([d(p[0],p[1])+'.'for p in[s[n:n+2]for n in range(len(s))][:-1]])

Bantuan apa pun akan sangat dihargai!

Mengambil input dalam tanda kutip.

l mengembalikan lokasi karakter di keyboard.

Dua ifpernyataan di tengah dadalah untuk memeriksa apakah akan optimal untuk 'membungkus' keyboard.

Input, stelah "A"ditambahkan sebelumnya karena posisi awal kursor adalah A.

Kami loop melalui string berpasangan, membuang yang terakhir (yang bukan pasangan:) [:-1], menemukan jarak minimum antara dua bagian dari pasangan.

Terima kasih kepada Flp.Tkc karena memberi tahu saya bahwa saya dapat melakukan a=absalih - alih mengatakannya abssetiap waktu!


0

Java 8, 1045 byte

Golf

staticchar[][]a={{'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','.',''}};staticintm=Integer.MAX_VALUE;staticStringn="";staticboolean[][]c(boolean[][]a){boolean[][]r=newboolean[4][];for(inti=0;i<4;i)r[i]=a[i].clone();returnr;}staticvoidg(inti,intj,boolean[][]v,chard,Stringp){v[i][j]=true;if(a[i][j]==d&&p.length()<m){m=p.length();n=p;}if(i-1<0){if(!v[3][j])g(3,j,c(v),d,p"^");}elseif(!v[i-1][j])g(i-1,j,c(v),d,p"^");if(i1>3){if(!v[0][j])g(0,j,c(v),d,p"v");}elseif(!v[i1][j])g(i1,j,c(v),d,p"v");if(j-1<0){if(!v[i][6])g(i,6,c(v),d,p"<");}elseif(!v[i][j-1])g(i,j-1,c(v),d,p"<");if(j1>6){if(!v[i][0])g(i,0,c(v),d,p">");}elseif(!v[i][j1])g(i,j1,c(v),d,p">");}publicstaticvoidmain(String[]args){boolean[][]v=newboolean[4][7];Scannerx=newScanner(System.in);Strings=x.next();Stringpath="";intp=0;intq=0;for(inti=0;i<s.length();i){chart=s.charAt(i);g(p,q,c(v),t,"");path=n".";n="";m=Integer.MAX_VALUE;for(intj=0;j<4;j){for(intk=0;k<7;k){if(a[j][k]==t){p=j;q=k;}}}}System.out.println(path);}

Dapat dibaca

static char[][] a = {
        {'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','.',' '}
};
static int m = Integer.MAX_VALUE;
static String n="";


static boolean[][] c(boolean[][] a){
    boolean [][] r = new boolean[4][];
    for(int i = 0; i < 4; i++)
        r[i] = a[i].clone();
    return r;
}

static void g(int i, int j,boolean[][] v,char d,String p) {

    v[i][j] = true;
    if (a[i][j]==d && p.length()<m){
        m=p.length();
        n=p;
    }

    if (i-1<0) {
        if(!v[3][j])
            g(3, j, c(v), d, p + "^");
    }
    else if (!v[i-1][j])
        g(i-1, j, c(v), d, p + "^");


    if (i+1>3) {
        if(!v[0][j])
            g(0, j, c(v), d, p + "v");
    }
    else if(!v[i+1][j])
        g(i+1, j, c(v), d, p + "v");


    if (j-1<0) {
        if(!v[i][6])
            g(i, 6, c(v), d, p + "<");
    }
    else if (!v[i][j-1])
        g(i, j-1, c(v), d, p + "<");


    if (j+1>6) {
        if (!v[i][0])
            g(i, 0, c(v), d, p + ">");
    }
    else if (!v[i][j+1])
        g(i, j+1, c(v), d, p + ">");

}

public static void main(String[] args) {
    boolean[][] v = new boolean[4][7];
    Scanner x = new Scanner(System.in);
    String s = x.next();
    String path="";
    int p=0;
    int q=0;
    for(int i=0;i<s.length();i++){
        char t=s.charAt(i);
        g(p,q,c(v),t,"");
        path+=n+".";
        n="";
        m=Integer.MAX_VALUE;
        for(int j=0;j<4;j++){
            for(int k=0;k<7;k++){
                if(a[j][k]==t) {
                    p=j;
                    q=k;
                }
            }
        }

    }
    System.out.println(path);
}

Penjelasan

Solusinya adalah pendekatan langsung: brute force yang dioptimalkan dengan buruk. Metode g(...)ini adalah pencarian dasar kedalaman pertama melalui setiap permutasi (atas, bawah, kiri, kanan). Dengan sedikit modifikasi dalam pemesanan untuk test case saya mendapatkan output:

<<.v<.v<<<.v<<<.^.^<<.^<.
v<<.v>>.v>>>.^^>.^.^<<.
<<.<..^^<.>.>>.^<.
v<<.^<.>>.^^>.
.^<.v>>>.<<.^^<<.
>.^^<.^^>.
^<.
// new line for the last
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.