对游戏男孩的有效打字


26

许多旧的Game Boy游戏经常需要用户输入字符串。但是,没有键盘。这是通过向用户显示“键盘屏幕”来解决的,如下所示:

口袋妖怪红宝石键盘

该“字符指针”将开始于字母A的用户将导航到与所需的字符d-垫的四个按钮(UPDOWNLEFTRIGHT),然后按BUTTON A将其追加到最终字符串。

请注意:

  • 网格环绕,因此UP在字母A上同时按下可将您带到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字节的获胜者,但是如果有人可以找到更短的解决方案,则可以移动绿色的小勾号;)


请注意,这是通过沙盒进行的,并且发现了类似的挑战,但是在聊天和沙盒中的讨论得出的结论是,它不是
骗子

我认为这似乎很熟悉,但它不是一个重复这一任。

Answers:


4

Dyalog APL,61 字节

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

假设 ⎕IO←0

⎕a,'.' 字母后跟句号

⍵⍳⍨在那里找到参数的字符作为索引0..26(' '所有其他字符将为27)

⍺⊤以7为底进行编码(注意左侧arg 绑定到4 7),得到2×n矩阵

0, 向左添加零

2-/ 相邻列之间的差异

将矩阵拆分为一对向量

a←⍺| 分别取4和7为模,分配给 a

b←a⌊⍺-a使其b较小,a并且其模数逆

'^v' '<>'⌷¨⍨⊂¨a>b根据不同之处选择^或选择v第一个向量,<>选择第二个向量ab

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

Ruby,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 返回键盘上字符的位置。

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.