การพิมพ์ที่มีประสิทธิภาพบน Game Boy


26

เกมบอยเก่าหลายเกมมักจะต้องมีการป้อนสตริงจากผู้ใช้ อย่างไรก็ตามไม่มีแป้นพิมพ์ สิ่งนี้ได้รับการจัดการโดยการนำเสนอผู้ใช้ด้วย "หน้าจอคีย์บอร์ด" ดังนี้:

คีย์บอร์ดโปเกมอนรูบี้

'การชี้ตัวอักษร' จะเริ่มที่ตัวอักษร A. ผู้ใช้จะต้องไปที่ตัวละครแต่ละตัวต้องการด้วยD-Pad 's สี่ปุ่ม ( UP, DOWN, LEFTและ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 .

การพิมพ์บนแป้นพิมพ์แบบนี้ช้ามากดังนั้นเพื่อให้ง่ายขึ้นงานของคุณคือการเขียนโปรแกรมที่บอกผู้ใช้ถึงวิธีที่เร็วที่สุดในการพิมพ์สตริงที่กำหนด หากมีวิธีที่เร็วที่สุดหลายวิธีคุณจะต้องแสดงวิธีเดียวเท่านั้น

คีย์เอาต์พุตควรเป็น:

  • > สำหรับ RIGHT
  • < สำหรับ LEFT
  • ^ สำหรับ UP
  • v สำหรับ DOWN
  • .สำหรับBUTTON A(ต่อท้ายจดหมายปัจจุบันถึงสตริง)

ตัวอย่างเช่นเมื่อได้รับสตริงDENNISการแก้ปัญหาจะมีลักษณะเช่นนี้:

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

กฎ / รายละเอียด

  • โปรดจำไว้ว่ากริดล้อมรอบ!
  • คุณสามารถส่งโปรแกรมหรือฟังก์ชั่นเต็มรูปแบบตราบใดที่มันใช้สตริงเริ่มต้นและสร้างสตริงโซลูชัน การขึ้นบรรทัดใหม่ของ whitespace / trailing ไม่เกี่ยวข้องตราบใดที่เอาต์พุตถูกต้อง
  • คุณสามารถสมมติว่าการป้อนข้อมูลจะประกอบด้วยอักขระที่พิมพ์ได้บนแป้นพิมพ์ที่ระบุเท่านั้น
  • นี่คือดังนั้นรหัสที่สั้นที่สุดชนะ มีช่องโหว่ของรหัสมาตรฐานสำหรับกอล์ฟ

กรณีทดสอบ

โดยปกติจะมีวิธีแก้ปัญหาที่หลากหลายที่มีความยาวเท่ากัน สำหรับกรณีทดสอบแต่ละรายการฉันได้รวมความยาวที่เหมาะสมและตัวอย่างไว้ คุณไม่จำเป็นต้องพิมพ์ความยาวในคำตอบของคุณเพียงแค่ทางออก

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)

คุณสามารถดูเครื่องกำเนิด testcase ของฉันใน repl.it - โปรดแจ้งฉันหากมีข้อบกพร่องใด ๆ

ขอบคุณทุกคนสำหรับการส่ง! ขณะนี้ผู้ใช้ ngn เป็นผู้ชนะที่มี 61 ไบต์ แต่ถ้าใครสามารถหาวิธีแก้ปัญหาที่สั้นกว่าก็สามารถย้ายเห็บสีเขียวเล็กน้อยได้)


หมายเหตุที่ว่านี้ได้รับการผ่าน Sandbox ที่และความท้าทายที่คล้ายกันก็พบ แต่การอภิปรายในการแชทและ sandbox ที่นำไปสู่ข้อสรุปที่ว่ามันไม่ได้เป็นล่อเพียงเกี่ยวข้องอย่างใกล้ชิด :)
FlipTack

ฉันคิดว่ามันดูเหมือนคุ้นเคยมาก แต่ก็ไม่ซ้ำกับคนนี้อย่างใดอย่างหนึ่ง

คำตอบ:


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สำหรับเวกเตอร์แรกและ<หรือ>สำหรับวินาทีขึ้นอยู่กับตำแหน่งที่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 และฉันจะได้ลูกศรจำนวนที่ถูกต้อง ในขณะเดียวกันการกดขึ้น / ลงนั้นทำได้ง่าย ๆ เพียงแค่ค้นหาอาเรย์โดยใช้ bitwise และความแตกต่างของแถวด้วย 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

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.