Ефективне друкування на ігровому хлопчику


26

У багатьох старих іграх Game Boy часто потрібні строкові введення від користувача. Однак клавіатури не було. Це вдалося вирішити, подавши користувачеві такий "екран клавіатури", як:

Клавіатура Ruby Pokemon

«Покажчик на символ» буде починатися на букву А. користувача буде переміщатися до кожного потрібного символу з D-Pad «s чотири кнопки ( UP, DOWN, LEFTі RIGHT), потім натисніть кнопку , BUTTON Aщоб додати його в кінцеву рядок.

Будь ласка, запиши:

  • Сітка обертається навколо , тому натисканняUPна літери А переведе вас до T.
  • "Покажчик символів" залишається після додавання листа

Змагання

На наведеній вище клавіатурі є параметри для зміни регістру та неправильної форми. Отже, для простоти в цьому виклику ми будемо використовувати таку клавіатуру (праворуч внизу - ASCII char 32, пробіл):

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 .

Введення на клавіатурах на кшталт цього відбувається надзвичайно повільно - тому, щоб полегшити це, ваше завдання - написати програму, яка розповість користувачеві про найшвидший спосіб ввести заданий рядок. Якщо існує декілька найшвидших способів, вам потрібно показати лише один.

Вихідним ключем має бути:

  • > для RIGHT
  • < для LEFT
  • ^ для UP
  • v для DOWN
  • .для BUTTON A(додавання поточного листа до рядка)

Наприклад, якщо дано рядок DENNIS, рішення виглядатиме так:

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

Правила / подробиці

  • Пам'ятайте, сітка обертається!
  • Ви можете подати повну програму або функцію, якщо вона займає початкову рядок і створює рядок рішення. Пробіли / прокладки нових рядків не мають значення, якщо вихідний результат правильний.
  • Ви можете припустити, що введення складається лише з символів, які можна вводити на вказаній клавіатурі, але може бути порожнім.
  • Це , тому виграє найкоротший код. Застосовуються стандартні лазівки з кодовим гольфом.

Випробування

Зазвичай існує кілька рішень однакової довжини. Для кожного тестового випадку я включив оптимальну довжину та приклад. Вам не потрібно друкувати довжину у своїй відповіді, просто рішення.

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)

Ви можете переглянути мій генератор тестових шапок на repl.it - будь ласка, повідомте мене про наявність помилок.

Дякую всім за подані матеріали! Наразі користувач ngn є переможцем із 61 байтом, але якщо хтось може знайти коротше рішення, маленьку зелену галочку можна перемістити;)


Зауважте, що це було через пісочницю, і подібний виклик був знайдений, але обговорення в чаті та пісочниці призвело до висновку, що це не обман, просто тісно пов’язані :)
FlipTack

Я думав, що це здається дуже знайомим, але це теж не дублікат цього .

Відповіді:


4

Діалог APL , 61 байт

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

передбачає ⎕IO←0

⎕a,'.' алфавіт з подальшим повним зупинкою

⍵⍳⍨знайдіть знаки аргументу там як індекси 0..26 ( ' 'а всі інші будуть 27)

⍺⊤кодувати в базі 7 (зверніть увагу на лівий аргумент , пов'язаний з 4 7), отримайте матрицю 2 × n

0, подати нулі вліво

2-/ відмінності між сусідніми стовпцями

розділити матрицю на пару векторів

a←⍺| прийняти їх за модулем 4 та 7 відповідно, призначити a

b←a⌊⍺-aзробити bменший aі його модульний зворотний

'^v' '<>'⌷¨⍨⊂¨a>bвибираємо ^або vдля першого вектора, <або >для другого, виходячи з того, де aвідрізняється відb

b⍴¨¨повторюйте кожен із цих bчасів

⍉↑ змішують два вектори в одну матрицю і переносять її, отримуючи матрицю n × 2

'.',⍨додати .–s справа

сплющити


6

JavaScript (ES6), 147 байт

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)

Цікавою поведінкою компанії substringє те, що він обмінюється аргументами, якщо другий менше першого. Це означає, що якщо я обчислюю оптимальну кількість натискань ліворуч / праворуч як число між -3 і 3, я можу додати 3 і взяти підрядку <<<>>>починаючи з 3, і я отримаю правильну кількість стрілок. Тим часом преси вниз / вгору просто обробляються, шукаючи масив, використовуючи побіжно та різницю рядків з 3; цей спосіб трохи коротший, оскільки є менше елементів масиву.


4

Рубін, 107 байт

->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 в тестовій програмі

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

Математика, 193 байт

Гольф

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

Читабельна

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 байт

Це довше, ніж має бути, але ...

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

Будь-яка допомога буде дуже вдячна!

Здійснює введення в лапки.

l повертає розташування символу на клавіатурі.

Два ifтвердження в середині d- для перевірки того, чи було б оптимально «обернутись» навколо клавіатури.

Вхід, який sбув "A"попереджений для нього, оскільки початкове положення курсоруA .

Проводимо цикл через рядок парами, відкидаючи останню (яка не є парою:) [:-1], знаходячи мінімальну відстань між двома половинами пари.

Дякую Flp.Tkc за те, що він сказав мені, що можу робити, a=absа не говорити absкожен раз!


0

Java 8, 1045 байт

Гольф

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

Читабельна

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

Пояснення

Рішення - це прямий підхід: погано оптимізована груба сила. Метод g(...)- це базовий глибинний перший пошук, що проходить через кожну перестановку (вгору, вниз, вліво, вправо). З деякими незначними модифікаціями для замовлення тестових випадків я отримую вихід:

<<.v<.v<<<.v<<<.^.^<<.^<.
v<<.v>>.v>>>.^^>.^.^<<.
<<.<..^^<.>.>>.^<.
v<<.^<.>>.^^>.
.^<.v>>>.<<.^^<<.
>.^^<.^^>.
^<.
// new line for the last
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.