Sekolah Pesawat Marshalling

8

Diberikan string yang mewakili serangkaian sinyal tangan yang mengatur pesawat , tulis fungsi atau program untuk menghitung posisi akhir pesawat terbang mengikuti sinyal-sinyal ini.

NB: Co-koordinat dalam tantangan ini direpresentasikan sebagai sepasang koordinat Cartesian, ditambah arah kompas pos: (x, y, h)mana xadalah koordinat x, yadalah koordinat y, dan hmerupakan salah satu dari N, E, S, atau W.

Anda mulai dengan pesawat terbang di (0, 0, N)grid imajiner, dengan mesin mati. Input Anda adalah string yang berisi pasangan karakter yang dipisah koma, di mana setiap pasangan mewakili satu sinyal marshalling. Anda harus mengikuti setiap sinyal marshalling secara bergantian, dan mengeluarkan koordinat dalam (x, y, h)bentuk posisi akhir pesawat.

Jika suatu sinyal mengharuskan pesawat Anda untuk bergerak, anggap itu bergerak satu unit ke arah yang diperlukan untuk setiap sinyal dari jenis yang diterimanya. Jika suatu sinyal mengharuskan pesawat Anda berputar, anggap ia berputar 90 derajat ke arah yang diperlukan untuk setiap sinyal dari jenis yang diterimanya.

Sebuah pesawat tidak bisa bergerak jika mesinnya mati. Jika mesin pesawat Anda mati dan Anda menerima sinyal gerakan / belok, jangan menerapkan gerakan / belokan.

Sinyal

Setiap sinyal marshalling diwakili oleh sepasang karakter. Yang pertama dari pasangan mewakili posisi lengan kiri marshaller, dari sudut pandang pesawat , dan yang kedua lengan kanan dari POV yang sama. Grafik sinyal yang berguna ini dapat membantu.

o/  —  START ENGINES (no movement, no turn)
-/  —  CUT ENGINES   (no movement, no turn)
-~  —  TURN LEFT     (no movement, left turn)
~-  —  TURN RIGHT    (no movement, right turn)
~~  —  COME FORWARD  (forward movement, no turn)
::  —  MOVE BACK     (backward movement, no turn)
/\  —  NORMAL STOP   (no movement, no turn)

Ini bukan daftar lengkap sinyal marshalling, tetapi hanya itu yang Anda perlukan untuk mendukungnya.

Memasukkan

Input adalah string yang dipisahkan koma yang berisi pasangan karakter. String ini akan selalu valid - Anda tidak harus memvalidasi input.

Keluaran

Keluaran adalah seperangkat koordinat seperti dijelaskan di atas. Anda dapat mengembalikan ini dalam format apa pun yang nyaman - jika bahasa Anda mendukung beberapa nilai pengembalian, Anda dapat menggunakannya; sebagai alternatif, Anda dapat menggunakan string (tanda kurung di sekitar koordinat tidak wajib), array, tuple, daftar, atau apa pun yang menurut Anda nyaman. Satu-satunya aturan adalah bahwa hal itu harus berisi x, ydan hnilai-nilai, dalam urutan itu.

Uji Kasus

Input  —  Output
o/,~~,~~,~-,::  —  (-1, 2, E)
::,~-,o/,/\,~~,-~,~~,~~,~~  —  (-3, 1, W)
o/,::,-/,~~,o/,~-,~~,~~,~-  —  (2, -1, S)
o/,~-,~-,::,::,~-,~~,-~  —  (-1, 2, S)
~-,~-,o/,::,::,-/,~~,-~  —  (0, -2, N)
ArtOfCode
sumber
1
Apa yang sebenarnya dilakukan mesin mulai dan mesin potong? Apakah hanya perpindahan antara mesin mulai dan mesin potong yang dijalankan? Kalau tidak, saya gagal melihat relevansinya.
Level River St
@LevelRiverSt "Pesawat tidak bisa bergerak jika mesinnya mati." Saya sudah membahasnya dalam teks.
ArtOfCode
jika kita menulis suatu fungsi, dapatkah kita mengambil input sebagai daftar instruksi?
FlipTack
@ Flp.Tkc Bisakah Anda mengubah tantangan agar lebih mudah? Tidak :)
ArtOfCode
Saya tidak menyadari bahwa menggunakan fungsi "split" bawaan sangat menantang. Memiliki format input yang kaku pada kode-golf tidak disarankan; standarnya adalah "ambil input dalam format apa pun yang nyaman".
FlipTack

Jawaban:

2

Java 8, 505 byte

Golf (dengan bantuan dari @ masterX244 untuk mencukur potongan besar)

class f{static boolean T(String u,String v){return u.equals(v);}public static void main(String[]a){java.util.Scanner q=new java.util.Scanner(System.in);String s=q.nextLine();int x=0;int y=0;int d=0;int[][]v={{0,1},{-1,0},{0,-1},{1,0}};int b=1;for(String r:s.split(",")){if(T(r,"o/")||T(r,"-/"))b=~1;if(b<0){if(T(r,‌​"~-"))d=(d+3)%4;if(T‌​(r,"-~"))d=(d+1)%4;i‌​f(T(r,"~~")){x+=v[d]‌​[0];y+=v[d][1];}if(T‌​(r,"::")){x-=v[d][0]‌​;y-=v[d][1];}}}Syste‌​m.out.println("("+x+‌​","+y+","+"NWSE".cha‌​rAt(d)+")");}}

Lebih mudah dibaca

class f {
    static boolean T(String u,String v){return u.equals(v);}
    public static void main(String[] a) {
        java.util.Scanner q=new java.util.Scanner(System.in);
        String s=q.nextLine();
        int x=0;
        int y=0;
        int d=0;
        int[][] val = {
                {0,1},  // N
                {-1,0}, // W
                {0,-1}, // S
                {1,0}   // E
        };
        int b=1;
        for (String r: s.split(",")) {
            // toggle b if either start or stop engine
            if(T(r,"o/") || T(r,"-/"))
                b=~1;
            if(b<0){
                // right
                if(T(r,"~-")) d=(d+3)%4;
                // left
                if(T(r,"-~")) d=(d+1)%4;
                // come forward
                if(T(r,"~~")) {
                    x+=val[d][0];
                    y+=val[d][1];
                }
                // move back
                if(T(r,"::")) {
                    x-=val[d][0];
                    y-=val[d][1];
                }
            }
        }
        System.out.print("("+x+","+y+","+"NWSE".charAt(d)+")");
    }
}
Bobas_Pett
sumber
beberapa byte gratis: kelas yang mengandung main () tidak harus publik (lihat tips golf untuk java di sini) dan cukup banyak ruang kosong yang dapat dioptimalkan (apa pun di sebelah simbol nonalphanumeric dapat dilucuti). juga false dapat ditulis sebagai 0> 1
masterX244
Juga: mengganti bool dengan int dan membandingkannya menjadi lebih besar atau lebih kecil dari nol, juga membuat beberapa byte mati. (menggunakan * = - 1 untuk menghidupkannya) kode dalam komentar berikutnya. Dan selalu gunakan print () di atas println ketika Anda hanya perlu satu baris di
output
class f{static boolean T(String u,String v){return u.equals(v);}public static void main(String[]a){java.util.Scanner q=new java.util.Scanner(System.in);String s=q.nextLine();int x=0;int y=0;int d=0;int[][]v={{0,1},{-1,0},{0,-1},{1,0}};int b=1;for(String r:s.split(",")){if(T(r,"o/")||T(r,"-/"))b*=-1;if(b<0){if(T(r,"~-"))d=(d+3)%4;if(T(r,"-~"))d=(d+1)%4;if(T(r,"~~")){x+=v[d][0];y+=v[d][1];}if(T(r,"::")){x-=v[d][0];y-=v[d][1];}}}System.out.print("("+x+","+y+","+"NWSE".charAt(d)+")");}}
masterX244
@ masterX244 thx saya jelas tahu sedikit tentang ini. Saya akan menambahkan hasil edit untuk dicetak
Bobas_Pett
impor juga merupakan tempat untuk mengoptimalkan. untuk satu atau 2 menyebutkan referensi yang sepenuhnya memenuhi syarat pada keduanya lebih pendek daripada mengimpor. (kode yang saya tempelkan di komentar berisi semua optimisasi yang saya temukan)
masterX244
1

Befunge, 201 185 byte

p10p2p3pv
~/3-*95~<v:+-"/"
  v!:-*53_v
 #_7-:v v0-1
vv!:-3_100>p
 _69*-:v NESW v+g01g
v v-*93_g10g\->4+4%10p
v<_100g >*:10g:1\-\2%!**03g+03p10g:2\-\2%**02g+02p
>>~65*`#v_2g.3g.10g9+5g,@

Cobalah online!

Befunge tidak memiliki tipe string seperti itu, sehingga untuk membuat sinyal lebih mudah untuk dibandingkan, setiap pasangan karakter dikonversi menjadi integer menggunakan rumus (c1 - 45)/3 + c2 - 47. Ini bisa berarti kami akan mendapatkan kecocokan salah pada input yang tidak valid, tetapi itu tidak masalah jika input tersebut dijamin valid.

Sisa kode didasarkan pada manipulasi empat "variabel": status engine (1 atau 0), heading (0 hingga 3 untuk NESW), dan posisi x dan y . Perhitungan untuk masing-masing sinyal adalah sebagai berikut:

Start engine: engine = 1
Cut engine: engine = 0
Belok kiri: heading = (heading - engine + 4) % 4
Belok kanan: heading = (heading + engine) % 4
Gerakan: (di mana dir adalah 1 untuk maju dan -1 untuk mundur)
y += dir*engine*(1-heading)*!(heading%2)
x += dir*engine*(2-heading)*(heading%2)

Setelah kita mencapai akhir dari urutan input, maka itu hanya masalah keluaran x , y , dan heading (dikonversi ke char dengan pencarian tabel sederhana).

James Holderness
sumber
1

Python 2.7.12, 295 byte

from operator import*
l=[0,0]
m=[['N',[0,1]],['E',[1,0]],['S',[0,-1]],['W',[-1,0]]]
n=0
x=raw_input()
for c in x.split(','):
 if'o/'==c:n=1
 if'-/'==c:n=0
 if n:
    if'-~'==c:m=m[-1:]+m[:-1]
    if'~-'==c:m=m[1:]+m[:1]
    if'~~'==c:l=map(add,l,m[0][1])
    if'::'==c:l=map(sub,l,m[0][1])
print l+[m[0][0]]

Lekukan tingkat pertama setelah formenggunakan satu \s. Lekukan tingkat kedua menggunakan satu \t. (wysiwyg menggantikan \tdengan beberapa spasi jadi harap diingat saat menguji ukuran)

Eric
sumber
3
Ada banyak spasi kosong yang bisa Anda hapus di sini.
ArtOfCode
Bukan hanya ruang putih tetapi lainnya mudah untuk memperbaiki ketidakefisienan. Cobalah kiat untuk bermain golf dengan python untuk contoh tertentu.
Ad Hoc Garf Hunter
Perhatikan bahwa dalam kode-golf Anda tidak harus memiliki prompt input: cukup lakukan raw_input().
FlipTack
Kesalahan kode ini untuk saya di baris 15: TypeError: Argument to map() must support iteration(Saya menggunakan Python 2.7.12).
clismique
@ Qwerp-Derp, saya yakin saya memperbaiki kesalahan peta ().
Eric
1

Python 2, 142 byte

s=raw_input()
e=p=0;d=1
while s:exec'd-=e d+=e p+=1j**d*e e=0 0 e=1 p-=1j**d*e 0'.split()[ord(s[0])+ord(s[1])*2&7];s=s[3:]
print p,'ESWN'[d%4]

Contoh:

% python2.7 ams.py <<<'o/,~~,~~,~-,::'
(-1+2j) E

Ini mencetak bilangan kompleks, yang seharusnya oke, saya kira? The x, y, hagar masih ada, dan 'j'tidak menyebabkan kebingungan. Katakan padaku apakah aku harus mengubahnya.

Lynn
sumber