ゲームボーイでの効率的な入力


26

多くの古いGame Boyゲームでは、ユーザーからの文字列入力が必要になることがよくありました。しかし、キーボードはありませんでした。これは、次のような「キーボード画面」をユーザーに提示することで処理されました。

ポケモンRubyキーボード

「文字ポインタ」は、ユーザが各所望の文字に移動なる文字Aで始まるであろうD-パッドの4つのボタン(UPDOWNLEFTおよびRIGHT)を押しBUTTON A、最終的な文字列に追加します。

ご注意ください:

  • グリッドが回り込むのでUP、文字Aを押しながら押すとTに移動します。
  • 「文字ポインタ」は、文字を追加した後もそのままになります

チャレンジ

上記のキーボードには、大文字と小文字を変更するオプションがあり、不規則な形状です。そのため、簡単にするために、この課題では次のキーボードを使用します(右下はASCII文字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 .

このようなキーボードでの入力は非常に遅いため、これを簡単にするために、与えられた文字列を入力するための最速の方法をユーザーに伝えるプログラムを書くことがタスクです。最速の方法が複数ある場合、表示する必要があるのは1つだけです。

出力キーは次のとおりです。

  • > ために RIGHT
  • < ために LEFT
  • ^ ために UP
  • v ために DOWN
  • .for 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

私はそれが非常に精通見えたと思ったが、それはの重複はありませんこの1どちらか。

回答:


4

Dyalog 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時間を繰り返す

⍉↑ 2つのベクトルを単一の行列に混ぜて転置し、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、2番目の引数が1番目の引数よりも小さい場合に引数を交換することです。これは、-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,?.}}

テストプログラムでゴルフをしていない

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バイト

ゴルフ

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 キーボードの文字の位置を返します。

中央の2つのifステートメントはd、キーボードを「ラップ」するのが最適かどうかを確認するためのものです。

カーソルの初期位置はであるため、入力s"A"先頭に追加されていますA

文字列をペアでループし、最後のペア(ペアではない)を破棄し、ペア[:-1]の2つの半分の間の最小距離を見つけます。

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.