Escritura eficiente en un Game Boy


26

Muchos juegos antiguos de Game Boy a menudo requerían una entrada de cadena del usuario. Sin embargo, no había teclado. Esto se manejó presentando al usuario una "pantalla de teclado" como esta:

Pokemon Ruby Keyboard

El 'puntero del carácter' comenzaría en letra A. El usuario navegar a cada carácter deseado con el D-Pad 's cuatro botones ( UP, DOWN, LEFTy RIGHT), a continuación, pulse BUTTON Apara anexar a la cadena final.

Tenga en cuenta:

  • La cuadrícula se enrolla , por lo que presionarUPmientras está en la letra A lo llevaría a T.
  • El 'puntero de caracteres' permanece fijo después de agregar una letra

El reto

El teclado anterior tiene opciones para cambiar mayúsculas y minúsculas y tiene una forma irregular. Entonces, por simplicidad, en este desafío usaremos el siguiente teclado (la parte inferior derecha es ASCII char 32, un espacio):

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 .

Escribir en teclados como este es extremadamente lento, por lo tanto, para facilitar esto, su tarea es escribir un programa que le diga al usuario la forma más rápida posible de escribir una cadena dada. Si hay varias formas más rápidas, solo necesita mostrar una.

La clave de salida debe ser:

  • > para RIGHT
  • < para LEFT
  • ^ para UP
  • v para DOWN
  • .para BUTTON A(agregar la letra actual a la cadena)

Por ejemplo, cuando se le da la cadena DENNIS, la solución se vería así:

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

Reglas / Detalles

  • Por favor, recuerde, la cuadrícula se envuelve!
  • Puede enviar un programa completo o una función, siempre que tome la cadena inicial y produzca una cadena de solución. Los espacios en blanco / las nuevas líneas finales son irrelevantes siempre que la salida sea correcta.
  • Puede suponer que la entrada solo consistirá en caracteres que se pueden escribir en el teclado especificado, pero puede estar vacío.
  • Este es el , por lo que gana el código más corto. Se aplican las lagunas de código estándar de golf.

Casos de prueba

Por lo general, hay múltiples soluciones de la misma longitud. Para cada caso de prueba, he incluido la longitud óptima y un ejemplo. No necesita imprimir la longitud en su respuesta, solo la solución.

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)

Puede ver mi generador de casos de prueba en repl.it ; notifíqueme si hay algún error.

¡Gracias a todos por las presentaciones! El usuario ngn es actualmente el ganador con 61 bytes, pero si alguien puede encontrar una solución más corta, se puede mover la pequeña marca verde;)


Tenga en cuenta que esto ha pasado por el sandbox, y se encontró un desafío similar , pero la discusión en el chat y el sandbox llevó a la conclusión de que no es un engaño, solo está estrechamente relacionado :)
FlipTack

Pensé que me parecía muy familiar, pero tampoco es un duplicado de este .

Respuestas:


4

Dyalog APL , 61 bytes

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

asume ⎕IO←0

⎕a,'.' el alfabeto seguido de un punto final

⍵⍳⍨encuentre los caracteres del argumento allí como índices 0..26 ( ' 'y todos los demás serán 27)

⍺⊤codificar en la base 7 (tenga en cuenta que el argumento izquierdo está vinculado 4 7), obtenga una matriz 2 × n

0, anteponer ceros a la izquierda

2-/ diferencias entre columnas adyacentes

dividir la matriz en un par de vectores

a←⍺| tomarlos módulo 4 y 7 respectivamente, asignar a a

b←a⌊⍺-ahacer bel más pequeño de ay su inverso modular

'^v' '<>'⌷¨⍨⊂¨a>belija ^o vpara el primer vector y / <o >para el segundo, según dónde adifiere deb

b⍴¨¨repetir cada uno de esos bmomentos

⍉↑ mezclar los dos vectores en una sola matriz y transponerla, obtener una matriz n × 2

'.',⍨agregar .-s a la derecha

aplanar


6

JavaScript (ES6), 147 bytes

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 comportamiento interesante substringes que intercambia los argumentos si el segundo es menor que el primero. Esto significa que si calculo el número óptimo de presiones izquierda / derecha como un número entre -3 y 3, puedo sumar 3, y tomar la subcadena de <<<>>>comenzar en 3 y obtendré el número correcto de flechas. Mientras tanto, las prensas hacia abajo / arriba se manejan simplemente buscando una matriz usando un bit y la diferencia en filas con 3; de esta manera es un poco más corto ya que hay menos elementos de matriz.


4

Ruby, 107 bytes

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

Sin golf en el programa de prueba

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 bytes

Golf

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

Legible

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 bytes

Esto es más largo de lo que debería ser, pero ...

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

Cualquier ayuda sería muy apreciada!

Toma entrada entre comillas.

l devuelve la ubicación de un personaje en el teclado.

Las dos ifdeclaraciones en el medio dson para verificar si sería óptimo 'envolver' el teclado.

La entrada se sha "A"antepuesto a ella porque la posición inicial del cursor es A.

Recorremos la cadena en pares, descartando la última (que no es un par [:-1]:), encontrando la distancia mínima entre las dos mitades del par.

¡Gracias a Flp.Tkc por decirme que puedo hacer en a=abslugar de decir abscada vez!


0

Java 8, 1045 bytes

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

Legible

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

Explicación

La solución es un enfoque directo: fuerza bruta mal optimizada. El método g(...)es una primera búsqueda de profundidad básica que pasa por cada permutación (arriba, abajo, izquierda, derecha). Con algunas ligeras modificaciones al ordenar los casos de prueba, obtengo el resultado:

<<.v<.v<<<.v<<<.^.^<<.^<.
v<<.v>>.v>>>.^^>.^.^<<.
<<.<..^^<.>.>>.^<.
v<<.^<.>>.^^>.
.^<.v>>>.<<.^^<<.
>.^^<.^^>.
^<.
// new line for the last
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.