Taper efficacement sur un Game Boy

26

Beaucoup de vieux jeux Game Boy nécessitaient souvent une entrée de chaîne de la part de l'utilisateur. Cependant, il n'y avait pas de clavier. Cela a été géré en présentant à l'utilisateur un "écran de clavier" comme ceci:

Pokemon Ruby Keyboard

Le « pointeur de caractère » commencerait sur la lettre A. L'utilisateur naviguerait à chaque caractère désiré avec le D-Pad quatre boutons de ( UP, DOWN, LEFTet RIGHT), puis appuyez sur BUTTON Apour ajouter à la chaîne finale.

Notez s'il vous plaît:

  • La grille s'enroule , donc appuyerUPsur la lettre A vous amènera à T.
  • Le 'pointeur de caractère' reste en place après avoir ajouté une lettre

Le défi

Le clavier ci-dessus a des options pour changer la casse et a une forme irrégulière. Donc, pour plus de simplicité, dans ce défi, nous utiliserons le clavier suivant (le coin inférieur droit est le caractère ASCII 32, un espace):

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 .

Taper sur des claviers comme celui-ci est extrêmement lent - donc, pour rendre cela plus facile, votre tâche consiste à écrire un programme qui indique à l'utilisateur le moyen le plus rapide possible de taper une chaîne donnée. S'il existe plusieurs moyens les plus rapides, il vous suffit d'en afficher un.

La clé de sortie doit être:

  • > pour RIGHT
  • < pour LEFT
  • ^ pour UP
  • v pour DOWN
  • .pour BUTTON A(ajouter la lettre actuelle à la chaîne)

Par exemple, une fois donnée la chaîne DENNIS, la solution ressemblerait à ceci:

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

Règles / Détails

  • N'oubliez pas, la grille s'enroule!
  • Vous pouvez soumettre un programme complet ou une fonction, tant qu'il prend la chaîne initiale et produit une chaîne de solution. Les espaces blancs / sauts de ligne ne sont pas pertinents tant que la sortie est correcte.
  • Vous pouvez supposer que la saisie se composera uniquement de caractères saisissables sur le clavier spécifié, mais elle peut être vide.
  • C'est le , donc le code le plus court l'emporte. Les échappatoires de code-golf standard s'appliquent.

Cas de test

Il existe généralement plusieurs solutions de même longueur. Pour chaque cas de test, j'ai inclus la longueur optimale et un exemple. Vous n'avez pas besoin d'imprimer la longueur dans votre réponse, juste la solution.

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)

Vous pouvez voir mon générateur de testcase sur repl.it - veuillez m'informer s'il y a des bugs.

Merci à tous pour les soumissions! L'utilisateur ngn est actuellement le gagnant avec 61 octets, mais si quelqu'un peut trouver une solution plus courte, la petite coche verte peut être déplacée;)

FlipTack
la source
Notez que cela a été fait dans le bac à sable, et un défi similaire a été trouvé, mais la discussion dans le chat et le bac à sable a conduit à la conclusion que ce n'est pas un dupe, juste étroitement lié :)
FlipTack
Je pensais que cela semblait très familier, mais ce n'est pas un double de celui-ci non plus.

Réponses:

4

Dyalog APL , 61 octets

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

suppose ⎕IO←0

⎕a,'.' l'alphabet suivi d'un point

⍵⍳⍨trouver les caractères de l'argument en tant qu'indices 0..26 ( ' 'et tous les autres seront 27)

⍺⊤encoder en base 7 (notez que l'argument de gauche est lié à 4 7), obtenez une matrice 2 × n

0, ajouter des zéros à gauche

2-/ différences entre les colonnes adjacentes

diviser la matrice en une paire de vecteurs

a←⍺| les prendre respectivement modulo 4 et 7, assigner à a

b←a⌊⍺-afaire ble plus petit de aet son inverse modulaire

'^v' '<>'⌷¨⍨⊂¨a>bchoisissez ^ou vpour le premier vecteur et <ou >pour le second, en fonction de l'endroit où adiffère deb

b⍴¨¨répéter chacune de ces bfois

⍉↑ mélanger les deux vecteurs dans une seule matrice et la transposer, obtenir une matrice n × 2

'.',⍨ajouter .-s à droite

aplatir

ngn
la source
6

JavaScript (ES6), 147 octets

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 comportement intéressant de substringest qu'il échange les arguments si le second est inférieur au premier. Cela signifie que si je calcule le nombre optimal de pressions gauche / droite comme un nombre compris entre -3 et 3, je peux ajouter 3 et prendre la sous-chaîne de <<<>>>départ à 3 et j'obtiendrai le nombre correct de flèches. Pendant ce temps, les pressions vers le bas / haut sont simplement gérées en recherchant un tableau en utilisant un bit à bit et de la différence dans les lignes avec 3; cette façon est légèrement plus courte car il y a moins d'éléments de tableau.

Neil
la source
4

Rubis, 107 octets

->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 testé dans le programme de 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      
Level River St
la source
1

Mathematica, 193 octets

Le golf

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

Lisible

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."
ngenisis
la source
1

Python 2, 298 octets

C'est plus long qu'il ne devrait l'être, mais ...

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

Toute aide serait grandement appréciée!

Prend la saisie entre guillemets.

l renvoie l'emplacement d'un caractère sur le clavier.

Les deux ifinstructions au milieu de dsont pour vérifier s'il serait optimal de «boucler» autour du clavier.

L'entrée y sa été "A"ajoutée car la position initiale du curseur estA .

Nous parcourons la chaîne par paires, en éliminant la dernière (qui n'est pas une paire [:-1]:), en trouvant la distance minimale entre les deux moitiés de la paire.

Merci à Flp.Tkc de m'avoir dit que je peux faire a=absau lieu de le dire à abschaque fois!

Daniel
la source
0

Java 8, 1045 octets

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

Lisible

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

Explication

La solution est une approche directe: une force brute mal optimisée. La méthodeg(...) est une première recherche de profondeur de base passant par chaque permutation (haut, bas, gauche, droite). Avec quelques légères modifications dans la commande des cas de test, j'obtiens la sortie:

<<.v<.v<<<.v<<<.^.^<<.^<.
v<<.v>>.v>>>.^^>.^.^<<.
<<.<..^^<.>.>>.^<.
v<<.^<.>>.^^>.
.^<.v>>>.<<.^^<<.
>.^^<.^^>.
^<.
// new line for the last
Bobas_Pett
la source