게임 보이의 효율적인 타이핑


26

많은 오래된 Game Boy 게임은 종종 사용자의 문자열 입력이 필요했습니다. 그러나 키보드는 없었습니다. 이것은 사용자에게 "키보드 화면"을 다음과 같이 제시함으로써 처리되었습니다.

포켓몬 루비 키보드

'문자 포인터는'사용자는 각각 원하는 문자로 이동 한 것입니다 편지 A.에 시작될 것입니다 D-패드 의 네 개의 버튼 ( UP, DOWN, LEFTRIGHT), 다음을 눌러 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 .

이와 같은 키보드 입력은 매우 느립니다. 따라서 작업을보다 쉽게 ​​수행하려면 주어진 문자열을 입력하는 가장 빠른 방법 을 사용자에게 알려주는 프로그램을 작성해야 합니다. 가장 빠른 방법이 여러 개이면 하나만 표시하면됩니다.

출력 키는 다음과 같아야합니다.

  • > ...에 대한 RIGHT
  • < ...에 대한 LEFT
  • ^ ...에 대한 UP
  • v ...에 대한 DOWN
  • .for BUTTON A(현재 문자를 문자열에 추가)

예를 들어, string 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 바이트의 승자이지만, 더 짧은 솔루션을 찾을 수 있다면 작은 녹색 체크 표시를 이동할 수 있습니다.)


이것은 샌드 박스를 통해 이루어졌으며 유사한 도전 이 발견되었지만 채팅 및 샌드 박스에서 토론은
속박이

나는 그것이 매우 익숙한 듯 생각했지만, 그것은의 중복이 아니다 이것 중 하나.

답변:


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 ) 행렬을 얻습니다.

0, 왼쪽에 0을 붙이십시오

2-/ 인접한 열의 차이점

행렬을 한 쌍의 벡터로 나눕니다

a←⍺| 모듈로 4와 7을 각각 가져 와서 a

b←a⌊⍺-ab더 작게 만들다a 모듈 식을 반대로

'^v' '<>'⌷¨⍨⊂¨a>b위치 에 따라 첫 번째 벡터 또는 두 번째 벡터를 선택 ^하거나v<>a 상이b

b⍴¨¨ 그들 각각을 반복 b 시간을

⍉↑ 두 벡터를 하나의 행렬로 혼합하고 전치하여 n × 2 행렬을 구합니다.

'.',⍨APPEND는 .오른쪽에 -s

반음 낮추다


6

자바 스크립트 (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,?.}}

테스트 프로그램에서 언 골프

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

파이썬 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]의 두 절반 사이의 최소 거리를 찾습니다.

매번 말하지 a=abs않고 할 수 있다고 말 해준 Flp.Tkc에게 감사합니다 abs!


0

자바 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.