Bir Oyun Çocuğuna Verimli Yazma


26

Birçok eski Game Boy oyunu sıklıkla kullanıcıdan dize girişi gerektiriyordu. Ancak klavye yoktu. Bu, kullanıcıya şöyle bir "klavye ekranı" sunmak suretiyle gerçekleştirildi:

Pokemon Ruby Klavye

'Karakteri işaretçisi' kullanıcı her istenilen karaktere gidin olacağını A harfinin başlayacağını D-Pad 'in dört düğme ( UP, DOWN, LEFTve RIGHT), sonra basına BUTTON Anihai dizeye eklenecek.

Lütfen aklınızda bulundurun:

  • Izgara etrafına sarılır , böyleceUPA harfi üzerinebastığınızdasizi T'ye götürürdünüz.
  • Bir harf ekledikten sonra 'karakter işaretçisi' kalmaya devam ediyor

Meydan okuma

Yukarıdaki klavyenin büyük / küçük harf değiştirme seçenekleri vardır ve düzensiz bir şekildir. Bu nedenle, basit olması için, bu zorlu görevde aşağıdaki klavyeyi kullanacağız (sağ alt ASCII karakter 32, boşluk):

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 .

Bunun gibi klavyelere yazmak oldukça yavaştır - bu yüzden bunu kolaylaştırmak için göreviniz, kullanıcıya belirli bir dize yazmanın en hızlı yolunu söyleyen bir program yazmaktır . Birden çok hızlı yol varsa, yalnızca birini göstermeniz gerekir.

Çıkış anahtarı şöyle olmalıdır:

  • > için RIGHT
  • < için LEFT
  • ^ için UP
  • v için DOWN
  • .için BUTTON A(geçerli harfi dizeye ekle )

Örneğin, dize verildiğinde DENNIS, çözüm şöyle görünecekti:

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

Kurallar / Detaylar

  • Unutma, ızgara etrafını sardı!
  • İlk dizgeyi aldığı ve bir çözüm dizgisi ürettiği sürece, tam bir program veya işlev gönderebilirsiniz. Boşluk / izleyen yeni satırlar çıktı doğru olduğu sürece ilgisizdir.
  • Girişin yalnızca belirtilen klavyede yazılabilir karakterlerden oluşacağını varsayabilirsiniz, ancak boş olabilir.
  • Bu , yani en kısa kod kazanır. Standart kod-golf boşlukları uygulanır.

Test Kılıfları

Genellikle aynı uzunlukta birden fazla çözüm vardır. Her test durumu için optimum uzunluğu ve bir örneği dahil ettim. Cevabınızdaki uzunluğu, yalnızca çözümü yazdırmanız gerekmez.

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 jeneratörümü repl.it adresinde görebilirsiniz - lütfen herhangi bir hata varsa bana bildirin .

Gönderdiğiniz için herkese teşekkür ederim! Kullanıcı ngn şu anda 61 bayt ile kazananı kazanıyor, ancak eğer daha kısa bir çözüm bulabilirse, küçük yeşil onay işareti hareket ettirilebilir;)


Bunun kum havuzundan geçtiğini ve benzer bir mücadelenin bulunduğunu not edin, ancak sohbet ve kum havuzundaki tartışmalar, bunun yakın bir ilişki olduğu sonucuna yol açtı. :)
FlipTack

Ben çok tanıdık gibiydi, ama bunun bir kopyası değil bu bir ya.

Yanıtlar:


4

Dyalog APL , 61 bayt

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

varsayar ⎕IO←0

⎕a,'.' alfabenin ardından tam bir durak

⍵⍳⍨Argümanın karakterini orada indeks 0..26 olarak bulun ( ' 've diğerleri 27 olacak)

⍺⊤üs 7'de kodlayın (sol argümanın bağlı olduğunu unutmayın 4 7), 2 × n'lik bir matris elde edin

0, sıfırları sola doğru çevir

2-/ bitişik sütunlar arasındaki farklar

matrisi bir çift vektöre bölmek

a←⍺| sırasıyla sırasıyla 4 ve 7 modulo al a

b←a⌊⍺-ayapmak bdaha küçük ave modüler tersini

'^v' '<>'⌷¨⍨⊂¨a>btercih ^ya da vbirinci vektör ve <ya >yere göre, ikincisi için adeğişmesidirb

b⍴¨¨bu bzamanların her birini tekrarla

⍉↑ iki vektörü tek bir matris halinde karıştırın ve transpoze edin, bir nx2 matris elde edin

'.',⍨.sağa eklemek

düzleştirmek


6

JavaScript (ES6), 147 bayt

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)

İlginç bir davranış substring, ikincisi birinciden küçükse argümanları değiştirmesidir. Bu, optimal sol / sağ pres sayısını -3 ile 3 arasında bir sayı olarak hesaplarsam, 3 ekleyebilirim ve 3'ten <<<>>>başlayarak alt dizini alabilirim ve doğru ok sayısını alacağım anlamına gelir. Bu arada, aşağı / yukarı presleri, basitçe bit kullanarak bir dizi kullanarak ve 3'teki sıralardaki farkları kullanarak kolayca idare edilir; daha az dizi elemanı olduğundan bu yol biraz daha kısa.


4

Ruby, 107 bayt

->s{c=0
s.tr(". ","[\\").bytes{|b|b-=65
print ["","^","^^","v"][c/7-b/7],(d=(c-c=b)%7)>3??>*(7-d):?<*d,?.}}

Test programında 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 bayt

Golf

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

Okunabilir

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 bayt

Bu olması gerekenden daha uzun, ama ...

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

Herhangi bir yardım çok takdir edilecektir!

Tırnak işareti içinde giriş yapar.

l karakterin konumunu klavyede döndürür.

ifOrtasındaki iki ifade d, klavyenin etrafında 'kaydırmanın' uygun olup olmadığını kontrol etmek içindir.

Giriş, solan "A"imleç başlangıç pozisyonu olduğu için değerin başına A.

Sonuncuyu (bir çift değil:) atarak, çiftin [:-1]iki yarısı arasındaki minimum mesafeyi bularak ipler arasında dolaşıyoruz .

Her seferinde a=abssöylemek yerine yapabileceğimi söylediğin için Flp.Tkc'ye teşekkürler abs!


0

Java 8, 1045 bayt

Golf

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

Okunabilir

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

açıklama

Çözüm doğrudan bir yaklaşımdır: düşük düzeyde optimize edilmiş kaba kuvvet. Yöntem g(...), her permütasyona (yukarı, aşağı, sola, sağa) giden temel bir derinlik araştırmasıdır. Test durumları için bazı küçük değişiklikler yapıldıktan sonra çıktıyı alıyorum:

<<.v<.v<<<.v<<<.^.^<<.^<.
v<<.v>>.v>>>.^^>.^.^<<.
<<.<..^^<.>.>>.^<.
v<<.^<.>>.^^>.
.^<.v>>>.<<.^^<<.
>.^^<.^^>.
^<.
// new line for the last
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.