Digitazione efficiente su un Game Boy


26

Molti vecchi giochi per Game Boy spesso richiedono l'immissione di stringhe da parte dell'utente. Tuttavia, non c'era la tastiera. Ciò è stato gestito presentando all'utente una "schermata della tastiera" in questo modo:

Tastiera Pokemon Ruby

Il 'puntatore carattere' comincerebbe sulla lettera A. L'utente dovrebbe spostarsi su ogni carattere desiderato con il D-Pad s' quattro tasti ( UP, DOWN, LEFTe RIGHT), quindi premere BUTTON Aper aggiungere alla stringa finale.

Notare che:

  • La griglia si avvolge , quindi premendoUPmentre sulla lettera A ti porteresti a T.
  • Il "puntatore di caratteri" rimane inserito dopo aver aggiunto una lettera

La sfida

La tastiera sopra ha opzioni per cambiare la custodia ed è di forma irregolare. Quindi, per semplicità, in questa sfida useremo la seguente tastiera (in basso a destra è il carattere ASCII 32, uno spazio):

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 .

Digitare su tastiere come questa è estremamente lento - quindi, per facilitare questa operazione, il tuo compito è scrivere un programma che dica all'utente il modo più veloce possibile di digitare una determinata stringa. Se ci sono più modi più veloci, devi solo mostrarne uno.

La chiave di output dovrebbe essere:

  • > per RIGHT
  • < per LEFT
  • ^ per UP
  • v per DOWN
  • .per BUTTON A(aggiungi la lettera corrente alla stringa)

Ad esempio, quando viene data la stringa DENNIS, la soluzione dovrebbe apparire così:

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

Regole / Dettagli

  • Ricorda, la griglia si avvolge!
  • È possibile inviare un programma completo o una funzione, purché richieda la stringa iniziale e produca una stringa di soluzione. Gli spazi vuoti / le nuove righe finali sono irrilevanti purché l'output sia corretto.
  • Puoi supporre che l'input consisterà solo di caratteri digitabili sulla tastiera specificata, ma potrebbe essere vuoto.
  • Questo è , quindi vince il codice più corto. Si applicano scappatoie standard per il golf da codice.

Casi test

Di solito ci sono più soluzioni della stessa lunghezza. Per ogni caso di test, ho incluso la lunghezza ottimale e un esempio. Non è necessario stampare la lunghezza nella risposta, solo la soluzione.

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)

Puoi vedere il mio generatore di testcase su repl.it - per favore avvisami se ci sono dei bug.

Grazie a tutti per le osservazioni! L'utente ngn è attualmente il vincitore con 61 byte, ma se qualcuno riesce a trovare una soluzione più breve, il piccolo segno di spunta verde può essere spostato;)


Si noti che questo è stato attraverso la sandbox e una sfida simile è stata trovata, ma la discussione in chat e sandbox ha portato alla conclusione che non è un duplicato, ma strettamente correlato :)
FlipTack

Ho pensato che sembrasse molto familiare, ma non è neanche un duplicato di questo .

Risposte:


4

Dyalog APL , 61 byte

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

assume ⎕IO←0

⎕a,'.' l'alfabeto seguito da un punto

⍵⍳⍨trova i caratteri dell'argomento lì come indici 0..26 ( ' 'e tutti gli altri saranno 27)

⍺⊤codifica in base 7 (nota che l'arg di sinistra è legata a 4 7), ottieni una matrice 2 × n

0, anteporre zeri a sinistra

2-/ differenze tra colonne adiacenti

dividere la matrice in una coppia di vettori

a←⍺| prendili rispettivamente modulo 4 e 7, assegnali a a

b←a⌊⍺-arendere bil più piccolo di ae il suo inverso modulare

'^v' '<>'⌷¨⍨⊂¨a>bscegliere ^o vper il primo vettore e <o >per il secondo, in base a dove adifferisceb

b⍴¨¨ripeti ognuna di quelle bvolte

⍉↑ mescola i due vettori in una singola matrice e trasponila, ottieni una matrice n × 2

'.',⍨append .-s sulla destra

appiattire


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)

Un comportamento interessante substringè che scambia gli argomenti se il secondo è inferiore al primo. Ciò significa che se calcolo il numero ottimale di pressioni sinistra / destra come un numero compreso tra -3 e 3, posso aggiungere 3 e prendere la sottostringa di <<<>>>partenza da 3 e otterrò il numero corretto di frecce. Nel frattempo le presse su / giù vengono semplicemente gestite guardando in alto un array usando un bit per bit e della differenza nelle righe con 3; in questo modo è leggermente più breve in quanto vi sono meno elementi dell'array.


4

Rubino, 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,?.}}

Non registrato nel programma di test

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"<>#]])&

Leggibile

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

Questo è più lungo di quanto dovrebbe essere, ma ...

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

Qualsiasi aiuto sarebbe molto apprezzato!

Accetta le virgolette.

l restituisce la posizione di un personaggio nella tastiera.

Le due ifaffermazioni nel mezzo di dsono per verificare se sarebbe ottimale "avvolgere" attorno alla tastiera.

L'input sè stato "A"anteposto perché la posizione iniziale del cursore è A.

Attraversiamo la stringa in coppie, scartando l'ultima (che non è una coppia [:-1]:), trovando la distanza minima tra le due metà della coppia.

Grazie a Flp.Tkc per avermi detto che posso fare a=absinvece di dire absogni volta!


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

Leggibile

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

Spiegazione

La soluzione è un approccio diretto: forza bruta scarsamente ottimizzata. Il metodo g(...)è una prima ricerca di profondità di base che passa attraverso ogni permutazione (su, giù, sinistra, destra). Con alcune lievi modifiche all'ordine per i casi di test ottengo l'output:

<<.v<.v<<<.v<<<.^.^<<.^<.
v<<.v>>.v>>>.^^>.^.^<<.
<<.<..^^<.>.>>.^<.
v<<.^<.>>.^^>.
.^<.v>>>.<<.^^<<.
>.^^<.^^>.
^<.
// new line for the last
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.