Efektywne pisanie na Game Boyu

26

Wiele starych gier Game Boy często wymagało od użytkownika wprowadzania ciągów. Nie było jednak klawiatury. Zostało to rozwiązane poprzez przedstawienie użytkownikowi „ekranu klawiatury” w następujący sposób:

Pokemon Ruby Keyboard

W „wskaźnik znak” rozpocznie się na literę A. Użytkownik może nawigować do każdego żądanego znaku z D-Pad „s cztery przyciski ( UP, DOWN, LEFTi RIGHT), a następnie naciśnij BUTTON A, aby dołączyć go do końcowego łańcucha.

Proszę zanotować:

  • Siatka owija się , więc naciśnięcieUPna literę A zabierze Cię do T.
  • „Wskaźnik znaków” pozostaje wstawiany po dodaniu litery

Wyzwanie

Powyższa klawiatura ma opcje zmiany wielkości liter i ma nieregularny kształt. Dla uproszczenia w tym wyzwaniu użyjemy następującej klawiatury (prawy dolny róg to ASCII char 32, spacja):

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 .

Pisanie na klawiaturze takiej jak ta jest bardzo wolne - więc aby to ułatwić, Twoim zadaniem jest napisanie programu, który poinformuje użytkownika o najszybszym możliwym sposobie wpisania danego ciągu. Jeśli istnieje wiele najszybszych sposobów, wystarczy tylko jeden z nich.

Klucz wyjściowy powinien być:

  • > dla RIGHT
  • < dla LEFT
  • ^ dla UP
  • v dla DOWN
  • .dla BUTTON A(dodaj bieżącą literę do ciągu)

Na przykład po podaniu ciągu DENNISrozwiązanie wyglądałoby tak:

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

Zasady / Szczegóły

  • Pamiętaj, że siatka się zawija!
  • Możesz przesłać pełny program lub funkcję, o ile zajmie to ciąg początkowy i wygeneruje ciąg rozwiązania. Białe znaki / końcowe znaki nowej linii są nieistotne, o ile wynik jest poprawny.
  • Możesz założyć, że dane wejściowe będą składały się wyłącznie ze znaków, które można wpisać na określonej klawiaturze, ale mogą być puste.
  • To jest , więc wygrywa najkrótszy kod. Obowiązują standardowe luki w kodzie golfowym.

Przypadki testowe

Zwykle istnieje wiele rozwiązań o tej samej długości. Do każdego przypadku testowego podałem optymalną długość i przykład. Nie musisz drukować długości w odpowiedzi, tylko rozwiązanie.

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)

Możesz wyświetlić mój generator testów na Rep.it - powiadom mnie, jeśli są jakieś błędy.

Dziękujemy wszystkim za zgłoszenia! Użytkownik ngn jest obecnie zwycięzcą z 61 bajtami, ale jeśli ktoś może znaleźć krótsze rozwiązanie, można przesunąć mały zielony znaczek;)

FlipTack
źródło
Zauważ, że to przeszło przez piaskownicę i znaleziono podobne wyzwanie , ale dyskusja na czacie i piaskownicy doprowadziła do wniosku, że to nie jest dupek, tylko ściśle powiązany :)
FlipTack
Myślałem, że to wydaje się bardzo znajome, ale to też nie jest duplikat tego .

Odpowiedzi:

4

Dyalog APL , 61 bajtów

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

zakłada ⎕IO←0

⎕a,'.' alfabet, po którym następuje kropka

⍵⍳⍨znajdź tam znaki argumentu jako wskaźniki 0..26 ( ' 'a wszystkie pozostałe będą mieć 27)

⍺⊤zakoduj w bazie 7 (zwróć uwagę, że lewy arg jest związany 4 7), uzyskaj macierz 2 × n

0, wstaw zera w lewo

2-/ różnice między sąsiednimi kolumnami

podziel macierz na parę wektorów

a←⍺| weź je odpowiednio modulo 4 i 7, przypisz do a

b←a⌊⍺-auczynić bmniejszym ai jego modułową odwrotnością

'^v' '<>'⌷¨⍨⊂¨a>bwybierz ^lub vdla pierwszego wektora i <lub >dla drugiego, w zależności od tego, gdzie się aróżnib

b⍴¨¨powtarzaj każdy z tych bczasów

⍉↑ zmieszaj dwa wektory w jedną matrycę i przetransponuj, uzyskaj macierz n × 2

'.',⍨dołącz .-s po prawej stronie

spłaszczyć

ngn
źródło
6

JavaScript (ES6), 147 bajtów

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)

Ciekawym zachowaniem substringjest to, że wymienia argumenty, jeśli drugi jest mniejszy niż pierwszy. Oznacza to, że jeśli obliczę optymalną liczbę lewych / prawych pras jako liczbę od -3 do 3, mogę dodać 3 i wziąć podłańcuch <<<>>>zaczynając od 3 i otrzymam prawidłową liczbę strzałek. Tymczasem naciśnięcia w dół / w górę są obsługiwane po prostu przez wyszukiwanie tablicy za pomocą bitów i różnicy w wierszach za pomocą 3; ten sposób jest nieco krótszy, ponieważ elementów tablicy jest mniej.

Neil
źródło
4

Rubin, 107 bajtów

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

Niegolfowany w programie testowym

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
źródło
1

Mathematica, 193 bajty

Golf

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

Czytelny

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
źródło
1

Python 2, 298 bajtów

To jest dłuższe niż powinno, ale ...

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

Każda pomoc byłaby bardzo mile widziana!

Wprowadza dane w cudzysłowie.

l zwraca położenie znaku na klawiaturze.

Dwie ifinstrukcje pośrodku dsłużą do sprawdzenia, czy optymalne byłoby „owinięcie” klawiatury.

Dane wejściowe szostały wcześniej "A"dodane, ponieważ początkowa pozycja kursora to A.

Pętlujemy sznurkiem parami, odrzucając ostatnią (która nie jest parą:) [:-1], znajdując minimalną odległość między dwiema połówkami pary.

Dzięki Flp.Tkc za powiedzenie mi, że mogę to zrobić a=abszamiast mówić za abskażdym razem!

Daniel
źródło
0

Java 8, 1045 bajtów

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

Czytelny

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

Wyjaśnienie

Rozwiązaniem jest bezpośrednie podejście: źle zoptymalizowana brutalna siła. Ta metoda g(...)jest podstawowym wyszukiwaniem głębokości w pierwszej kolejności, przeprowadzanym przez każdą permutację (w górę, w dół, w lewo, w prawo). Po drobnych modyfikacjach przy zamawianiu przypadków testowych otrzymuję wynik:

<<.v<.v<<<.v<<<.^.^<<.^<.
v<<.v>>.v>>>.^^>.^.^<<.
<<.<..^^<.>.>>.^<.
v<<.^<.>>.^^>.
.^<.v>>>.<<.^^<<.
>.^^<.^^>.
^<.
// new line for the last
Bobas_Pett
źródło