Digitação eficiente em um Game Boy


26

Muitos jogos antigos do Game Boy frequentemente exigiam a entrada de strings do usuário. No entanto, não havia teclado. Isso foi tratado ao apresentar ao usuário uma "tela do teclado" da seguinte forma:

Pokemon Ruby Keyboard

O 'ponteiro caráter' iria começar na letra A. O usuário navegar para cada caractere desejado com o D-Pad 's quatro botões ( UP, DOWN, LEFTe RIGHT) e pressione BUTTON Apara anexá-lo para a cadeia final.

Observe:

  • A grade se quebra , pressionandoUPa letra A o levaria até T.
  • O 'ponteiro de caractere' permanece colocado após o anexo de uma letra

O desafio

O teclado acima tem opções para mudar de maiúsculas e minúsculas e tem uma forma irregular. Portanto, para simplificar, neste desafio, usaremos o seguinte teclado (o canto inferior direito é ASCII char 32, um espaço):

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 .

Digitar em teclados como esse é extremamente lento - portanto, para facilitar isso, sua tarefa é escrever um programa que informe ao usuário a maneira mais rápida possível de digitar uma determinada string. Se houver várias maneiras mais rápidas, você só precisará mostrar uma.

A chave de saída deve ser:

  • > para RIGHT
  • < para LEFT
  • ^ para UP
  • v para DOWN
  • .for BUTTON A(acrescente a letra atual à string)

Por exemplo, quando recebida a string DENNIS, a solução seria assim:

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

Regras / Detalhes

  • Por favor, lembre-se, a grade envolve!
  • Você pode enviar um programa completo ou uma função, desde que ela pegue a cadeia inicial e produza uma cadeia de solução. As novas linhas de espaço em branco / à direita são irrelevantes desde que a saída esteja correta.
  • Você pode assumir que a entrada será composta apenas por caracteres digitáveis ​​no teclado especificado, mas pode estar vazia.
  • Isso é , então o código mais curto vence. Aplicam-se lacunas de código-golfe padrão.

Casos de teste

Geralmente existem várias soluções do mesmo comprimento. Para cada caso de teste, incluí o comprimento ideal e um exemplo. Você não precisa imprimir o comprimento da sua resposta, apenas a solução.

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)

Você pode ver meu gerador de caixa de teste em repl.it - notifique-me se houver algum erro.

Obrigado a todos pelos envios! Atualmente, o usuário ngn é o vencedor com 61 bytes, mas se alguém encontrar uma solução mais curta, o pequeno tique verde pode ser movido;)


Note-se que esta tem sido através da caixa de areia, e um desafio semelhante foi encontrado, mas a discussão no chat e caixa de areia levou à conclusão de que é que não é um ingênuo, apenas intimamente relacionada :)
FlipTack

Eu pensei que parecia muito familiar, mas não é uma duplicata de um presente também.

Respostas:


4

Dyalog APL , 61 bytes

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

assume ⎕IO←0

⎕a,'.' o alfabeto seguido de um ponto final

⍵⍳⍨encontre os caracteres do argumento como índices 0..26 ( ' 'e todos os outros terão 27)

⍺⊤codificar na base 7 (observe que o argumento esquerdo está vinculado 4 7), obtenha uma matriz 2 × n

0, Anexar zeros à esquerda

2-/ diferenças entre colunas adjacentes

dividir a matriz em um par de vetores

a←⍺| tomam os módulos 4 e 7 respectivamente, atribuem a a

b←a⌊⍺-afazer bo menor ae seu inverso modular

'^v' '<>'⌷¨⍨⊂¨a>bescolha ^ou vpara o primeiro vetor e <ou >para o segundo, com base em onde adifereb

b⍴¨¨repita cada um desses bmomentos

⍉↑ misture os dois vetores em uma única matriz e transponha, obtenha uma matriz n × 2

'.',⍨acrescente .-s à direita

aplainar


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)

Um comportamento interessante substringé que ele troca os argumentos se o segundo for menor que o primeiro. Isso significa que, se eu calcular o número ideal de pressionamentos esquerdo / direito como um número entre -3 e 3, posso adicionar 3 e pegar a substring de <<<>>>começar em 3 e obter o número correto de setas. Enquanto isso, as prensas para baixo / para cima são tratadas simplesmente procurando uma matriz usando um bit a bit e a diferença nas linhas com 3; dessa forma, é um pouco mais curto, pois há menos elementos da 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,?.}}

Ungolfed in program program

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

Golfe

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

Legível

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

Isso é mais longo do que deveria ser, mas ...

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

Qualquer ajuda seria muito apreciada!

É inserido entre aspas.

l retorna a localização de um caractere no teclado.

As duas ifinstruções no meio dsão para verificar se seria o melhor para 'envolver' o teclado.

A entrada sfoi "A"anexada a ela porque a posição inicial do cursor é A.

Passamos a corda em pares, descartando a última (que não é um par [:-1]:), encontrando a distância mínima entre as duas metades do par.

Agradeço ao Flp.Tkc por me dizer que posso fazer em a=absvez de dizer abstodas as vezes!


0

Java 8, 1045 bytes

Golfe

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

Legível

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

Explicação

A solução é uma abordagem direta: força bruta pouco otimizada. O método g(...)é uma primeira pesquisa básica de profundidade, passando por cada permutação (para cima, para baixo, esquerda, direita). Com algumas pequenas modificações no pedido para os casos de teste, recebo a saída:

<<.v<.v<<<.v<<<.^.^<<.^<.
v<<.v>>.v>>>.^^>.^.^<<.
<<.<..^^<.>.>>.^<.
v<<.^<.>>.^^>.
.^<.v>>>.<<.^^<<.
>.^^<.^^>.
^<.
// new line for the last
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.