> <> Keluar Air

20

Ikan tercinta yang berenang melalui kode > <> (bahasa pemrograman esoterik) telah dikeluarkan dari lingkungan alaminya. Perubahan ini telah membuatnya tidak mampu bergerak seperti biasanya: apa yang dulunya adalah gerakan toroidal telah dibatasi pada gerakan kiri-ke-kanan yang sederhana. Tetapi program <> masih ditulis seolah-olah ikan mampu bergerak melalui mereka. Adalah tugas Anda, programmer terkasih, untuk menulis sebuah program untuk membuat linierisasi program>>. Dan lakukan dalam byte sesedikit mungkin; ikan tidak memiliki ingatan yang sangat besar.

Gerakan di> <>

Dalam> <>, gerakan adalah toroidal dan satu karakter pada satu waktu. Ini berarti bahwa ikan (penunjuk) dapat "membungkus" dari ujung garis kembali ke awal. Di> <>, ikan juga mampu bergerak dari atas ke bawah, dari bawah ke atas, dan dari kanan ke kiri, berbeda dengan cara kebanyakan penunjuk bergerak. Jadi pola pergerakan ini akan valid:

>>>^  >>>v
   >>>^  v

dan itu akan berakhir pada loop tak terbatas (looping kembali ke garis atas setelah melewati bagian bawah tanpa batas).

Ikan bergerak dalam kisi panjang sama dengan max (panjang baris) dan tinggi sama dengan jumlah baris.

Bagaimana Anda mengetahui ke arah mana ikan bergerak? Perintah-perintah ini mengubah vektor arah gerakan (mis. (-1,0)Berarti kanan-ke-kiri):

Command | Direction Change
---------------------------
   >    | (1,0) (default)
   <    | (-1,0)
   ^    | (0,1)
   v    | (0,-1)
   /    | (x,y) -> (y,x)
   \    | (x,y) -> (-y,-x)
   |    | (x,y) -> (-x,y)
   _    | (x,y) -> (x,-y)
   #    | (x,y) -> (-x,-y)
   ;    | (0,0)

Sebagaimana dicatat, ikan mulai bergerak dari kiri ke kanan, yaitu dengan vektor arah (1,0) . Ikan mulai menguraikan perintah mulai dengan perintah pertama yang dilihatnya dan mengubah arahnya jika perintah cocok dengan salah satu pengubah arah yang disebutkan di atas.

Ikan berhenti bergerak ketika melihat a ; dan mengakhiri program.

Memasukkan

Input akan menjadi program yang valid (misalnya tidak berulang) yang diberikan melalui STDIN. Anda juga dapat membaca file jika Anda mau. Garis-garis dari setiap program tidak akan harus memiliki panjang yang sama.

Input diberikan sebagai string, dengan baris baru memisahkan setiap baris dalam program.

Program tidak akan berulang, yang juga berarti mereka akan selalu berakhir dengan a ; .

Keluaran

Keluaran akan menjadi program yang dilinearisasi. Artinya, Anda harus mengembalikan semua karakter (termasuk pengubah arah) yang akan dilihat ikan jika menjalankan program "secara normal." Ini semua karakter dalam jalurnya ke; .

Jika input memiliki garis dengan panjang yang tidak sama dan ikan pada akhirnya bergerak sepanjang garis yang lebih pendek dari panjang garis terpanjang, Anda harus memperlakukan itu seolah-olah ikan bergerak di atas ruang (lihat kasus uji).

Mereka yang akrab dengan> <> akan tahu bahwa pengubah arah bukan satu-satunya cara untuk melakukan gerakan di dalamnya, tetapi demi kesederhanaan memperlakukan input seolah-olah mereka adalah satu - satunya cara untuk mempengaruhi gerakan.

Aturan

  1. Celah standar berlaku
  2. Anda dapat menulis program atau fungsi lengkap
  3. Input diberikan melalui STDIN atau file sebagai string berisi baris program yang dipisahkan oleh baris baru ( \n)
    • Anda dapat mengambil input secara berbeda, sesuai alasan (jangan ragu untuk bertanya kepada saya apakah Anda memiliki jenis input tertentu dalam pikiran). Anda mungkin tidak mengisi input dengan spasi sehingga panjang garis cocok.
    • Merujuk ini meta posting tentang masukan fleksibel. Seperti halnya postingan, konsensus umum harus sefleksibel mungkin dengan alasan.
  4. Output adalah string tunggal melalui STDOUT atau dikembalikan oleh fungsi (tergantung pada apa yang Anda pilih untuk dilakukan, lihat Aturan 2)

Uji Kasus

v     >v
>abcv//;
gfed<^ih

v>abcv<defghi^//>v;



v     >v
>abcv//;
gfed<^

v>abcv<defg  ^//>v;


abcdef;

abcdef;


abcd|;

abcd|dcba;


abcd#;

abcd#dcba;


abcd\;
    _

abcd\_\dcba;


^;
>abcde/
 ^jihg<

^ >abcde/ <ghij^a;


;

;
cole
sumber
2
Bisakah kita mengambil input sebagai array string?
Luke
2
Bisakah kita berasumsi bahwa karakter pertama (yang kiri atas) tidak akan menjadi titik koma?
Kritixi Lithos
1
@KritixiLithos pertanyaan bagus, saya akan mengatakan Anda tidak bisa berasumsi itu. Saya akan menambahkan test case.
cole
1
@ Lukas Anda dapat mengambil input sebagai array string jika sangat sulit atau tidak mungkin untuk beroperasi pada format input (string dengan garis yang dipisahkan oleh baris baru). Lihat Peraturan 3. yang sekarang ditambahkan
cole
3
Suara positif wajib untuk alasan yang masuk akal
Patrick Roberts

Jawaban:

13

Röda , 405 393 392 391 371 366 361 236 234 232 230 223 200 byte

F f{L=f()|[#_]|sort|tail
c=""x=0
y=0
X=1
Y=0{l=f[y]l.=[" "]*(L-#l)c=l[x]a=X
[c]
C=indexOf(c,`><v^/\|_#`)X=[1,-1,0,0,-Y,Y,-X,X,-X,X][C]Y=[0,0,1,-1,-a,a,Y,-Y,-Y,Y][C]x+=X
x=x%L
y+=Y
y=y%#f}until[c=";"]}

Cobalah online!

Periksa output!

Penjelasan (kedaluwarsa)

F f{                          /* Declares a function F with parameter f */
                              /* Takes a 2D array of single-char Strings as f */
L =                           /* L contains the value of the length of the longest line*/
    f()                       /* Push the contents each element of f to the stream; this pushes each line*/
        | [#_]                /* Pull a line and push its length to the stream*/
               |sort|tail     /* Sort it and get the last value (the largest one) */
c=""                          /* c contains the value of the current char that is being processed */
x=0; y=0                      /* x and y contain the position of the fish */
X=1; Y=0                      /* X and Y contain the direction of the fish */
{ ... }while [c != ";"]       /* While c is not `;` do: */
l=f[y]                        /*  l is the line (row) the fish is at */
c=" " if [x >= #l]            /*  If x is more than or equal to the line's length, set c to a space (so that we don't need to pad spaces to the array at the beginning)*/
else c = l[x]                 /*  Else set c to the character a position x of l*/
[c]                           /*  Push c to the output stream; ie prints c without a trailing newline*/
a = X                         /*  a preserves the value of X before analysing c */
C = indexOf(c,`><v^/\|_#`)    /*  Simple enough */
X=[1,-1,0,0,-Y,Y,-X,X,-X,X][C]/*  Map each value of C to their respective X-direction in the array */
                              /*  If c cannot be found in `><v^/\|_#` then it will be given the value of -1, or in other words, the -1th element of an array its last element */
Y=[0,0,1,-1,-a,a,Y,-Y,-Y,Y][C]/*  Do the same thing for Y */
x += X                        /*  Change the x-pos by the X-direction */
x = x%L                       /*  Wrap around the right edge */
y += Y                        /*  Do the same for y */
y=y%#f                        /*  But wrap around the bottom instead */
x+=L if[x<0]                  /*  Wrap around the left */
y+=#f if[y<0]                 /*  Wrap around the top */
}

Suntingan

  • 10 byte disimpan berkat @fergusq dengan menggunakan %alih-alih memeriksa apakah x atau y melebihi batas, yang membuka jalan bagi 2 lebih!
  • Digunakan `\`sebagai ganti"\\"
  • Pindah c=""ke baris kedua dan kemudian menghapus baris baru yang mengikutinya
  • Memindahkan konversi baris ke array karakter tunggal ke dalam loop alih-alih di awal (terinspirasi oleh jawaban Python)
  • Digunakan sintaks brace dari while (terima kasih kepada @fergusq untuk mengetahui hal itu)
  • Memindahkan a=X keluar dari pernyataan if
  • Terima kasih kepada @fergusq untuk menemukan cara yang lebih pendek untuk menemukan panjang garis terpanjang
  • Sintaks array yang digunakan sebagai ganti if-statement (seperti jawaban Python) untuk menghemat banyak byte
  • Menghapus kode yang berisi spasi, alih-alih spasi ditambahkan saat> <> bergerak
  • Memperbaiki bug terima kasih dan mengirim satu karakter berkat @fergusq
  • Dihapus +1pada akhir indexOfdan kode yang direstrukturisasi untuk menghemat 2 byte
  • Disimpan 2 byte dengan memindahkan barang-barang (terima kasih kepada @fergusq lagi)
  • Disimpan 1 byte berkat @fergusq dengan menggunakan metode ruang bantalan yang berbeda
  • Disimpan 1 byte dengan menggunakan until[c=";"]bukanwhile[c!=";"]
  • Berkat petunjuk dari @fergusq, saya menghapus loop yang mengisi spasi dan menggantinya dengan l.=[" "]*L
  • Disimpan lebih dari 20 byte dengan menghapus if-statement di akhir yang membungkus program di sekitar tepi kiri dan atas
Kritixi Lithos
sumber
Saya pikir Anda dapat menyimpan beberapa byte dengan menggunakan x=((x+X)%#l)alih-alih x+=X. Sayangnya, (-1)%#lmasih kembali -1.
fergusq
@fergusq Memotong saran Anda :)
Kritixi Lithos
Anda dapat menggunakannya dengan yterlalu: y=y%#f.
fergusq
@fergusq Baru saja akan menambahkan itu :)
Kritixi Lithos
Saya memikirkan hal ini lebih lanjut, berikut adalah dua tips golf lainnya: gunakan keysebagai ganti cmpdan {...}while[...]bukan gunakan while[...]do ... done.
fergusq
10

Python 2, 262 243 237 235 234 233 231 221 219 218 217 byte

Mengambil input sebagai ['<line_1>', '<line_2>', ...]

i=input()
q=max(map(len,i))
i=[k+' '*q for k in i]
x=y=k=0
j=1
o=''
while';'not in o:r=[1,-1,-j,-k,0,0];o+=i[y][x];l='><#\\v^/|_'.find(o[-1]);a=(r+[k,-j,j])[l];k=([k,-k,k,j]+r)[~l];j=a;x=(x+j)%q;y=(y-k)%len(i)
print o

Cobalah secara Online!

-19 byte terima kasih kepada @math_junkie
-6 byte terima kasih kepada @ThisGuy
-2 byte dengan mengekstraksi max(map(L,i))ke variabel (karena secara teori digunakan dua kali).
-1 byte dengan mengurangi berapa kali i[y][x]muncul.
-1 byte dengan menggunakan '\x00'jadi saya tidak perlu melakukan [1:]bagian o[1:]dalam output
-2 byte dengan menggunakan \0bukannya \x00
-10 byte terima kasih kepada @KritixiLithos untuk menyadari bahwa saya dapat memuat sebanyak yang saya inginkan di sisi kanan karena ekstra akan diabaikan
(tidak ada perubahan byte) memperbaiki bug karena variabel yang diekstraksi berada di luar loop
-2 byte karena sekarang saya hanya menggunakan len2 kali jadi menetapkan ulang dibutuhkan 2 byte tambahan
-2 byte dengan menggunakan while';'not in oalih-alihwhile o[-1]!=';', dan menggunakan o=''bukano='\0'. Ini tidak hanya menghemat 2 byte tetapi juga menghilangkan null byte terkemuka yang secara teknis tidak benar-benar valid.

Penjelasan

i = input()                       # Takes input as an array of strings
q = max(map(len,i))               # Finds the width of the longest line
i = [k + ' ' * q for k in i]      # Makes sure everything is at least that width
x = y = k = 0                     # Set the point to (0, 0). Set the vertical motion to 0
j = 1                             # Set the horizontal motion to 1
o = '\0'                          # Initialize the output to a null byte (this is output as nothing, so it doesn't actually affect output)
while o[-1] != ';':               # While the last character in the output is not ';' (this is why the output needs to be initialized with something, otherwise o[-1] gives an index error)
    r = [1,-1,-j,-k,0,0]          # Some of the vertical and horizontal coordinates correspond in opposite order
    o += i[y][x]                  # Add the current character to the output
    l = '><#\\v^/|_'.find(o[-1])  # Find the index of the current character here (or -1 if it's just a regular character)
    a = (r + [k, -j, j])[l]       # The fancy array contains the horizontal movement for each control character
    k = ([k, -k, k, j] + r)[~l]   # The fancy array contains the vertical movement for each control character. Using ~l to get the right index, because r has the values backwards
    j = a                         # a was a placeholder because otherwise k would not be correct
    x = (x + j) % q               # Adjust the pointer position
    y = (y - k) % len(i)          # Adjust the pointer position
print o                           # Print the output after the loop is finished
HyperNeutrino
sumber
Anda dapat bermain golf trysejak findkembali -1jika tidak ditemukan: TIO
pecandu matematika
@math_junkie Oh oke, terima kasih!
HyperNeutrino
Anda dapat menetapkan lenuntuk variabel misalnya Luntuk menyimpan 3 byte dan 4 lainnya dengan mengubah tugas multiline 0menjadi 1 baris x=y=k=0.
caird coinheringaahing
@ ThisGuy Terima kasih!
HyperNeutrino
2
@Cole Dalam golf yang saya sugget, saya menambahkan j dan k di akhir setiap array. Ini agar arahnya tetap dipertahankan
pecandu matematika
5

Ruby, 274 200 187 183

Memotong beberapa karakter lagi dengan menjatuhkan array momentum, d ,.

Saya cukup bangga dengan yang ini. Ini sangat menyenangkan! Dibutuhkan dalam array string dan mengembalikan string yang tepat.

->a{o,x,y='',-1,0
b,m=1,0
(o+=n=a[y=(y+m)%a.size][x=(x+b)%(a.map &:size).max]||' '
b,m=([1]+[0,-1,0]*2+[1,-m]+[-b,m,b]*2+[-m,-b,-m,b,m])[2*('><^v/\\|_#'.index(n)||9),2])until o[?;]
o}

Berkomentar di bawah.

->a{
    o,x,y='',-1,0  # o is the output string, x and y are the positions in the array
    b,m=1,0          # b and m are the direction of momentum
    until o[?;] # until o contains a semicolon
        w=(a.map &:size).max # w is the max width of the arrays
        h=a.size    # h is the height of arrays
        x=x+b % w   # increment cursor position
        y=y+m % h
        o+=n=a[y][x]||' ' # add the new char (or " ") to o
        ix=2*('><^v/\\|_#'.index(n)||9) # find the index new char in the string
        b,m=([1]+[0,-1,0]*2+[1,-m]+[-b,m,b]*2+[-m,-b,-m,b,m])[ix,2] # set momentum to its new value
    end
    o # return output string
}
Bukan itu Charles
sumber
1

PHP 7, 291 260 byte

for($m=max(array_map(strlen,$z=explode("
",$argv[1]))),$y=0,$r=count($z)-$v=1;';'!=$c;[$v,$w]=[[$v,1,-1,0,0,-$w,$w,-$v,$v,-$v][$o=strpos(' ><^v/\|_#',$c)],[$w,0,0,-1,1,-$v,$v,$w,-$w,-$w][$o]],$x+=$m+$v,$x%=$m,$y=0<=($y+=$w)?$r<$y?:$y:$r)echo$c=$z[$y][$x]??' ';
chocochaos
sumber
Saya menghitung 291 byte / karakter.
HyperNeutrino
Anda benar, saya gagal menghitung ternyata = P
chocochaos
Hah Jangan khawatir, aku juga melakukannya.
HyperNeutrino
Saya menemukan beberapa hal untuk golf, mencatat ini turun 25% menjadi 218 byte. Tidak diuji, tapi pasti patut dilihat .
Titus
2
sebuah cacat dalam salah satu golf saya dan enam byte golf lainnya: daftar golf yang diperbarui .
Titus
1

JavaScript, 242 236 235 231 220 byte

a=>{n=a.length;m=x=y=p=0;a.map(g=>m=(w=g.length)<m?m:w);q=1,o="";while((t=a[y][x]||" ")!=";")o+=t,h=q,q=[q,1,0,p,-q][(s=">v\\| <^/_#".indexOf(t)+1)%5]*(r=s>5?-1:1),p=[p,0,1,h,p][s%5]*r,x=(x+q+m)%m,y=(y+p+n)%n;return o+t}

Cobalah online!

fəˈnɛtɪk
sumber
Anda dapat menyimpan 13 char jika Anda menggunakan string sebagai array. Spesifikasi diubah.
Bukan itu Charles