Pertanyaan ini memiliki pasang surut

33

Input akan terdiri dari karakter berikut:

  • ^: Naik satu
  • v: Turun satu
  • atau k: Naik dua
  • atau j: Turun dua

Misalnya, input berikut:

^^▲^v▼▲^^v

akan menghasilkan output berikut:

        ^
   ^   ^ v
  ▲ v ▲

 ^   ▼
^

Urutan melarikan diri yang menggerakkan kursor seperti \e[Btidak diizinkan. Anda harus menghasilkan output menggunakan spasi dan baris baru.

Berikut adalah beberapa kasus uji lagi.

▲v^v^v^v^v^v^v^v▲

                ▲
▲ ^ ^ ^ ^ ^ ^ ^ 
 v v v v v v v v

^^^^^^^▲▲▲▼▼▼vvvvvv

         ▲

        ▲ ▼

       ▲   ▼

      ^     ▼
     ^       v
    ^         v
   ^           v
  ^             v
 ^               v
^                 v

v^^vv^^vvv^v^v^^^vvvv^^v^^vv

  ^   ^         ^
 ^ v ^ v       ^ v       ^
v   v   v ^ ^ ^   v   ^ ^ v
         v v v     v ^ v   v
                    v
Absinth
sumber
1
Apakah ruang trailing diperbolehkan? Baris kosong?
xnor
2
Bagaimana dengan bahasa yang tidak mendukung Unicode? Bisakah karakter alternatif digunakan?
Gagang Pintu
1
@ xnor Anda diizinkan untuk mengekor spasi dan / atau baris kosong.
absinthe
2
@ Doorknob saya akan mengizinkan juntuk turun dua kali dan kuntuk naik dua kali juga.
absinthe
1
@ xnor Kesalahan saya: / Komentar sudah benar dan saya salah mengedit aturan. Akan diperbaiki sekarang.
absinthe

Jawaban:

9

Pyth, 27 byte

jCm.<.[*5lzd\ =+Ztx"v ^k"dz

Cobalah online: Demonstrasi atau Test Suite

Saya menggunakan kdan jbukannya dan . Ada banyak baris kosong terkemuka dan tertinggal. Anda harus mencari sedikit untuk menemukan gambar. Berikut ini adalah versi 34 byte , yang menghapus semua baris kosong awal dan akhir.

j.sCm.<.[*5lzd\ =+Ztx"v ^k"dz]*lzd

Cobalah online: Demonstrasi atau Test Suite

Penjelasan:

jCm.<.[*5lzd\ =+Ztx"v ^k"dz  implicit: Z = 0
  m                       z  map each char d from input string z to:
                  x"v ^k"d     find d in the string "v ^k", -1 if not found
                 t             -1, that gives -2 for j, -1 for v, 1 for ^ and 2 for k
              =+Z              add this number to Z
     .[*5lzd\                  append spaces on the left and on the right of d, 
                               creating a 5*len(input_string) long string
   .<           Z              rotate this string to the left by Z chars
jC                           transpose and print on lines
Jakube
sumber
16

Tidak dapat dibaca , 2199 2145 2134 2104 2087 2084 byte

Mendukung baik k/ jmaupun / sintaksis.

Dalam tradisi Unreadable yang baik, berikut adalah program yang diformat dalam font proporsional, untuk mengaburkan perbedaan antara tanda kutip dan tanda kutip ganda:

'"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "'" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "'"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " '"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "'" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""'" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" '"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""'"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """'" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "'" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "'"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "'" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" '"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " '"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "'"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " '"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""'"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " '"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "'" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " '"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "'" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " '"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """'" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " '"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" ""

Ini adalah tantangan yang luar biasa. Terima kasih telah mengirim!

Penjelasan

Untuk memahami apa yang bisa dan tidak bisa dilakukan Unreadable, bayangkan Brainfuck dengan pita tak terbatas di kedua arah, tetapi alih-alih penunjuk memori yang memindahkan satu sel pada satu waktu, Anda dapat mengakses sel memori apa pun dengan mendereferensikan penunjuk. Ini sangat berguna dalam solusi ini, meskipun operasi aritmatika lainnya - termasuk modulo - harus dilakukan dengan tangan.

Berikut adalah program sebagai kodesemu dengan komentar sutradara:

// Initialize memory pointer. Why 5 will be explained at the very end!
ptr = 5

// FIRST PASS:
// Read all characters from stdin, store them in memory, and also keep track of the
// current line number at each character.

// We need the +1 here so that EOF, which is -1, ends the loop. We increment ptr by 2
// because we use two memory cells for each input character: one contains the actual
// character (which we store here); the other will contain the line number at which the
// character occurs (updated at the end of this loop body).
while ch = (*(ptr += 2) = read) + 1:

    // At this point, ch will be one more than the actual value.
    // However, the most code-economical way for the following loop is to
    // decrement inside the while condition. This way we get one fewer
    // iteration than the value of ch. Thus, the +1 comes in handy.

    // We are now going to calculate modulo 4 and 5. Why? Because
    // the mod 4 and 5 values of the desired input characters are:
    //
    //  ch  %5  %4
    //  ^   1
    //  v   2
    //  k   3
    //  j   4
    //  ▲   0   2
    //  ▼   0   0
    //
    // As you can see, %5 allows us to differentiate all of them except ▲/▼,
    // so we use %4 to differentiate between those two.

    mod4 = 0      // read Update 2 to find out why mod5 = 0 is missing
    while --ch:
        mod5 = mod5 ? mod5 + 1 : -4
        mod4 = mod4 ? mod4 + 1 : -3

    // At the end of this loop, the value of mod5 is ch % 5, except that it
    // uses negative numbers: -4 instead of 1, -3 instead of 2, etc. up to 0.
    // Similarly, mod4 is ch % 4 with negative numbers.

    // How many lines do we need to go up or down?
    // We deliberately store a value 1 higher here, which serves two purposes.
    // One, as already stated, while loops are shorter in code if the decrement
    // happens inside the while condition. Secondly, the number 1 ('""") is
    // much shorter than 0 ('""""""""'""").
    up = (mod5 ? mod5+1 ? mod5+3 ? 1 : 3 : 2 : mod4 ? 3 : 1)
    dn = (mod5 ? mod5+2 ? mod5+4 ? 1 : 3 : 2 : mod4 ? 1 : 3)

    // As an aside, here’s the reason I made the modulos negative. The -1 instruction
    // is much longer than the +1 instruction. In the above while loop, we only have
    // two negative numbers (-3 and -4). If they were positive, then the conditions in
    // the above ternaries, such as mod5+3, would have to be mod5-3 etc. instead. There
    // are many more of those, so the code would be longer.

    // Update the line numbers. The variables updated here are:
    // curLine = current line number (initially 0)
    // minLine = smallest linenum so far, relative to curLine (always non-positive)
    // maxLine = highest linenum so far, relative to curLine (always non-negative)
    // This way, we will know the vertical extent of our foray at the end.

    while --up:
        curLine--
        minLine ? minLine++ : no-op
        maxLine++

    while --dn:
        curLine++
        minLine--
        maxLine ? maxLine-- : no-op

    // Store the current line number in memory, but +1 (for a later while loop)
    *(ptr + 1) = curLine + 1

// At the end of this, minLine and maxLine are still relative to curLine.
// The real minimum line number is curLine + minLine.
// The real maximum line number is curLine + maxLine.
// The total number of lines to output is maxLine - minLine.

// Calculate the number of lines (into maxLine) and the real minimum
// line number (into curLine) in a single loop. Note that maxLine is
// now off by 1 because it started at 0 and thus the very line in which
// everything began was never counted.
while (++minLine) - 1:
  curLine--
  maxLine++

// Make all the row numbers in memory positive by adding curLine to all of them.
while (++curLine) - 1:
  ptr2 = ptr + 1
  while (ptr2 -= 2) - 2:    // Why -2? Read until end!
    *ptr2++

// Finally, output line by line. At each line, we go through the memory, output the
// characters whose the line number is 0, and decrement that line number. This way,
// characters “come into view” in each line by passing across the line number 0.
while (--maxLine) + 2:    // +2 because maxLine is off by 1
  ptr3 = 5
  while (ptr -= 2) - 5:
    print (*((ptr3 += 2) + 1) = *(ptr3 + 1) - 1) ? 32 : *ptr3   // 32 = space
  ptr = ptr3 + 2
  print 10  // newline

Begitu banyak untuk logika program. Sekarang kita perlu menerjemahkan ini ke Tidak Dapat Dibaca dan menggunakan beberapa trik golf yang lebih menarik.

Variabel selalu direferensikan secara numerik dalam Unreadable (misalnya a = 1menjadi sesuatu seperti *(1) = 1). Beberapa literal numerik lebih panjang dari yang lain; yang terpendek adalah 1, diikuti oleh 2, dll. Untuk menunjukkan seberapa jauh angka negatif itu, inilah angka dari -1 hingga 7:

-1  '""""""""'""""""""'"""  22
 0  '""""""""'"""           13
 1  '"""                     4
 2  '""'"""                  7
 3  '""'""'"""              10
 4  '""'""'""'"""           13
 5  '""'""'""'""'"""        16
 6  '""'""'""'""'""'"""     19
 7  '""'""'""'""'""'""'"""  22

Jelas, kami ingin mengalokasikan variabel # 1 ke variabel yang paling sering muncul dalam kode. Di loop sementara pertama, ini pasti mod5, yang muncul 10 kali. Tapi kita tidak perlu mod5lagi setelah loop sementara pertama, sehingga kita dapat mengalokasikan kembali lokasi memori yang sama ke variabel lain yang kita gunakan nanti. Ini ptr2dan ptr3. Sekarang variabel direferensikan 21 kali secara total. (Jika Anda mencoba menghitung sendiri jumlah kemunculannya, ingatlah untuk menghitung sekitar a++dua kali, satu kali untuk mendapatkan nilai dan satu kali untuk menetapkannya.)

Hanya ada satu variabel lain yang bisa kita gunakan kembali; setelah kami menghitung nilai modulo, chtidak lagi diperlukan. updan dnmuncul jumlah yang sama kali, jadi tidak masalah. Merge Mari kita chdengan up.

Ini menyisakan total 8 variabel unik. Kita dapat mengalokasikan variabel 0 hingga 7 dan kemudian memulai blok memori (berisi karakter dan nomor baris) pada 8. Tapi! Karena 7 panjang kode yang sama dengan −1, kita juga bisa menggunakan variabel −1 hingga 6 dan memulai blok memori pada 7. Dengan cara ini, setiap referensi ke posisi awal blok memori sedikit lebih pendek dalam kode! Ini memberi kita tugas-tugas berikut:

-1    dn
 0                      ← ptr or minLine?
 1    mod5, ptr2, ptr3
 2    curLine
 3    maxLine
 4                      ← ptr or minLine?
 5    ch, up
 6    mod4
 7... [data block]

Sekarang ini menjelaskan inisialisasi di bagian paling atas: itu 5 karena itu 7 (awal dari blok memori) minus 2 (kenaikan wajib dalam kondisi sementara pertama). Hal yang sama berlaku untuk dua kejadian lainnya dari 5 di loop terakhir.

Perhatikan bahwa, karena 0 dan 4 memiliki panjang kode yang sama, ptrdan minLinedapat dialokasikan dengan cara apa pun. ... Atau bisakah mereka?

Bagaimana dengan 2 misterius di loop kedua-terakhir sementara? Bukankah ini seharusnya 6? Kami hanya ingin mengurangi angka dalam blok data, bukan? Begitu kita mencapai 6, kita berada di luar blok data dan kita harus berhenti! Ini akan menjadi kerentanan kesalahan kegagalan buffer overflow kesalahan keamanan!

Nah, pikirkan apa yang terjadi jika kita tidak berhenti. Kami menurunkan variabel 6 dan 4. Variabel 6 adalah mod4. Itu hanya digunakan di loop sementara pertama dan tidak lagi diperlukan di sini, jadi tidak ada salahnya dilakukan. Bagaimana dengan variabel 4? Bagaimana menurut Anda, seharusnya variabel 4 ptratau seharusnya minLine? Itu benar, minLinetidak lagi digunakan pada saat ini juga! Dengan demikian, variabel # 4 adalah minLinedan kita dapat dengan aman mengurangi dan tidak merusak!

PEMBARUAN 1! Golfed 2199-2145 byte dengan menyadari bahwa dnbisa juga digabung dengan mod5, meskipun mod5masih digunakan dalam perhitungan nilai untuk dn! Tugas variabel baru sekarang:

 0    ptr
 1    mod5, dn, ptr2, ptr3
 2    curLine
 3    maxLine
 4    minLine
 5    ch, up
 6    mod4
 7... [data block]

PEMBARUAN 2! Ditarik dari 2145 hingga 2134 byte dengan menyadari bahwa, karena mod5sekarang berada dalam variabel yang sama dengan dn, yang dihitung hingga 0 dalam loop sementara, mod5tidak perlu lagi diinisialisasi secara eksplisit ke 0.

UPDATE 3! Bermain golf dari 2134 hingga 2104 byte dengan menyadari dua hal. Pertama, meskipun ide "modulo negatif" tidak sia-sia mod5, alasan yang sama tidak berlaku mod4karena kami tidak pernah menguji terhadap mod4+2dll. Oleh karena itu, mengubah mod4 ? mod4+1 : -3untuk mod4 ? mod4-1 : 3membawa kami ke 2110 byte. Kedua, karena mod4selalu 0 atau 2, kita dapat menginisialisasi mod4ke 2 bukannya 0 dan membalikkan dua terner ( mod4 ? 3 : 1bukan mod4 ? 1 : 3).

PEMBARUAN 4! Ditarik dari 2104 hingga 2087 byte dengan menyadari bahwa loop sementara yang menghitung nilai modulo selalu berjalan setidaknya sekali, dan dalam kasus seperti itu, Unreadable memungkinkan Anda untuk menggunakan kembali nilai pernyataan terakhir dalam ekspresi lain. Jadi, alih-alih while --ch: [...]; up = (mod5 ? mod5+1 ? [...]sekarang kita miliki up = ((while --ch: [...]) ? mod5+1 ? [...](dan di dalam loop sementara itu, kita menghitung mod4dulu, jadi itulah mod5pernyataan terakhir).

UPDATE 5! Ditarik dari 2087 hingga 2084 byte dengan menyadari bahwa alih-alih menuliskan konstanta 32dan 10(spasi dan baris baru), saya dapat menyimpan angka 10 dalam variabel (sekarang tidak digunakan) variabel # 2 (sebut saja ten). Alih-alih ptr3 = 5kita menulis ten = (ptr3 = 5) + 5, maka 32menjadi ten+22dan print 10menjadi print ten.

Timwi
sumber
Ini ... mengerikan ... +1
kirbyfan64sos
6

CJam, 37 byte

r_,2*:L3*S*f{\_iImd8-g\8>)*L+:L\t}zN*

Ini mencetak baris kosong sebelum dan sesudah output yang diinginkan, yang telah diizinkan oleh OP .

Cobalah online di juru bahasa CJam .

Bagaimana itu bekerja

r_     e# Read a token from STDIN and push a copy.
,2*:L  e# Compute its length, double it and save it in L.
3*S*   e# Push a string of 6L spaces.
f{     e# For each character C in the input, push C and the string of spaces; then
  \    e#   Swap C with the string of spaces.
  _i   e#   Push a copy of C and cast it to integer.
  Imd  e#   Push quotient and remainder of its division by 18.
  8-g  e#   Push the sign((C%18) - 8). Gives -1 for ^ and ▲, 1 for v and ▼.
  \    e#   Swap the result with the quotient.
  8>)  e#   Push ((C/18) > 1) + 1. Gives 2 for ▲ and ▼, 1 for ^ and v.
  *    e#   Multiply both results. This pushes the correct step value.
  L+:L e#   Add the product to L, updating L.
  \t   e#   Replace the space at index L with C.
}      e# We've built the columns of the output.
z      e# Zip; transpose rows with columns.
N*     e# Join the rows, separating by linefeeds.
Dennis
sumber
Saya pikir itu hanya akan adil untuk secara eksplisit menyatakan sebagai peringatan bahwa solusi Anda menghasilkan jumlah baris baru yang berlebihan sebelum dan setelah hasil yang diinginkan ...
Timwi
Ditambahkan. (Saya pikir itu tidak perlu karena OP secara eksplisit mengizinkan jalur kosong.)
Dennis
3

Python 2, 102

s=input()
j=3*len(s)
exec"w='';i=j=j-1\nfor c in s:i-='kv_^j'.find(c)-2;w+=i and' 'or c\nprint w;"*2*j

Mencetak baris demi baris.

Loop melalui karakter dalam input dan melacak ketinggian saat ini. Ketinggian diperbarui oleh salah satu +2, +1, -1, -2seperti yang dihitung oleh 'kv_^j'.find(c)-2. Mungkin ada rantai mod yang lebih pendek

Ketika ketinggian saat ini sama dengan nomor baris (yang bisa negatif), kami menambahkan karakter saat ini ke garis, dan jika tidak menambahkan spasi. Kemudian, kami mencetak garis. Sebenarnya, ini lebih pendek untuk memulai ketinggian pada nomor baris saat ini dan mengurangi perubahan tinggi, menambahkan karakter ketika nilainya menyentuh 0.

Nomor garis mencakup rentang yang cukup besar sehingga urutan naik-dua atau turun-dua akan tetap di dalamnya. Sebenarnya, ada jumlah berlebih yang baik. Jika kita memiliki batas atas pada panjang input, akan lebih pendek untuk menulis, katakanlah j=999.

Anehnya, i and' 'or clebih pendek dari biasanya [' ',c][i==0]. Catatan yang ibisa negatif, yang memotong beberapa trik biasa.

Tidak
sumber
2

MATLAB, 116

function o=u(a)
x=0;y=1;o='';for c=a b=find(c=='j^ vk')-3;y=y+b;if y<1 o=[zeros(1-y,x);o];y=1;end
x=x+1;o(y,x)=c;end

Ini awal. The jdan kmembuat rasa sakit di leher karena saya tidak dapat menemukan cara untuk matematis peta dari j^vkke [-2 -1 1 2]dan dengan MATLAB tidak mengakui Unicode (rupanya kedua atas dan bawah memiliki nilai 26 pada gambar MATLAB. Go!), Ada banyak byte yang terbuang untuk melakukan pemetaan.

Dengan menggambar inspirasi dari solusi @xnors, kode dapat dikurangi dengan 14 karakter lain dengan memetakan karakter kontrol di dalam for loop.

Ada juga banyak byte yang terbuang untuk mencoba menghitung jika string input mengirim pola kembali ke bawah indeks di mana ia mulai (mungkin jika ada batas pada panjang string saya bisa menyederhanakan bit itu).

Dan dalam bentuk yang mudah dibaca:

function o=u(a)
%We start in the top left corner.
x=0; %Although the x coordinate is 1 less than it should be as we add one before storing the character
y=1;
o=''; %Start with a blank array
for c=a
    %Map the current character to [-2 -1 1 2] for 'j^vk' respectively.
    b=find(c=='j^ vk')-3;
    y=y+b; %Offset y by our character
    if y<1 %If it goes out of range of the array
        o=[zeros(1-y,x); o]; %Add enough extra lines to the array. This is a bit of a hack as 0 prints as a space in MATLAB.
        y=1; %Reset the y index as we have now rearranged the array
    end
    x=x+1; %Move to the next x coordinate (this is why we start at x=0
    o(y,x)=c; %Store the control character in the x'th position at the correct height.
end
Tom Carpenter
sumber
Akan b=[-2 -1 1 2](a==[106 107 94 118])bekerja Ia bekerja di oktaf. Atau bahkan b=[-2 -1 1 2](a-94==[12 13 0 24])jika Anda ingin memotong satu byte lagi!
wchargin
@WChargin tidak berfungsi di MATLAB. Sayangnya perilaku ==berhenti yang berfungsi, dan juga di MATLAB Anda tidak dapat menempatkan ()setelah [].
Tom Carpenter
Hmm ... Anda bisa mengubah bahasa menjadi Oktaf! :) (Octave juga punya +=, fwiw.)
wchargin
@WChargin Itu curang = P Tapi saya setuju, Octave memiliki banyak cara pintas yang tidak dimiliki Matlab.
flawr
2

JavaScript (ES6), 140

Tes menjalankan cuplikan di bawah ini di peramban yang mendukung EcmaScript 6 (diuji pada Firefox).

f=s=>[...s].map(c=>{for(t=r[y+=c>'▲'?2:c>'v'?-2:c>'^'?1:-1]||x;y<0;y++)r=[,...r];r[y]=t+x.slice(t.length)+c,x+=' '},y=0,r=[x=''])&&r.join`
`

// Less golfed

f=s=>(
  y=0,
  x='',
  r=[],
  [...s].forEach( c =>
    {
      y += c > '▲' ? 2 : c > 'v' ? -2 : c > '^' ? 1 : -1;
      t = r[y] || x;
      while (y < 0)
      {
        y++;
        r = [,...r]
      }  
      r[y] = t + x.slice(t.length) + c;
      x += ' '
    }
  ),
  r.join`\n`
)  


//Test

;[
  '^^▲^v▼▲^^v'
, '▲v^v^v^v^v^v^v^v▲'
, '^^^^^^^▲▲▲▼▼▼vvvvvv'
, 'v^^vv^^vvv^v^v^^^vvvv^^v^^vv'  
].forEach(t=>document.write(`${t}<pre>${f(t)}</pre>`))
pre { border:1px solid #777 }

edc65
sumber
1

GS2, 34 byte

Yang ini dengan benar menghitung batas output sehingga tidak ada spasi kosong yang dihasilkan. Inilah solusi saya dalam hex

5e 20 76 6a 05 3e 26 ea 30 e0 6d 40 28 26 cf d3
31 e9 d0 4d 42 5e e2 b1 40 2e e8 29 cf d3 5c e9
9a 54

Ada sedikit penjelasan. Pada stack kita memiliki input pengguna sebagai array kode ascii. Program dimulai dalam string literal karena 05. Kita mulai.

  5e 20 76 6a      # ascii for "^ vj"
  05               # finish string literal and push to stack
  3e               # index - find index in array or -1 if not found
  26               # decrement
ea                 # map array using block of 3 instructions (indented)

  30               # add 
e0                 # create a block of 1 instruction
6d                 # scan (create running total array of array using block)
40                 # duplicate top of stack
28                 # get minimum of array
26                 # decrement
cf                 # pop from stack into register D (this is the "highest" the path goes)

  d3               # push onto stack from register D
  31               # subtract
e9                 # map array using block of 2 instructions

d0                 # push onto stack from register A (unitialized, so it contains stdin)

  4d               # itemize - make singleton array (also is single char string)
  42               # swap top two elements in stack
  5e               # rjust - right justify string
e2                 # make block from 3 instructions
b1                 # zipwith - evaluate block using parallel inputs from two arrays
40                 # duplicate top of stack

  2e               # get length of array/string
e8                 # map array using block of 1 instruction
29                 # get maximum of array
cf                 # pop from stack into register D (this is the "lowest" the path goes)

  d3               # push from register D onto stack
  5c               # ljust - left justify string
e9                 # map array using block of two instructions
9a                 # transpose array of arrays
54                 # show-lines - add a newline to end of each element in array

GS2, 24 byte

Saya juga memiliki solusi 24 byte yang tidak terlalu peduli menghitung ukuran output, dan berakhir dengan spasi tambahan. Saya lebih suka yang dengan spasi putih tetap minimum.

5e 20 76 6a 05 3e 26 ea 30 e0 6d d0 08 4d 42 d1
30 5e d1 5c 09 b1 9a 54
rekursif
sumber
1

Crayon , 13 byte (tidak bersaing)

O"^ vj"\CynIq

Cobalah online! Gunakan panah asli karena mengapa tidak.

Non-bersaing karena Crayon jauh lebih baru daripada tantangan ini.

Bagaimana itu bekerja

Crayon adalah bahasa berbasis tumpukan yang dirancang untuk menjadi pembunuh di tantangan ASCII-art. Itu dibangun di sekitar dasar "kanvas" keluaran 2-dimensi, dan "krayon", kursor yang bergerak di sekitar kanvas ini. Apa pun yang dikirim ke output digambar di atas kanvas di posisi krayon, dan ke arah krayon menghadap. Secara default, krayon menunjuk ke Timur (ke kanan).

O"^ v▼"\CynIq   Implicit: input string is on top of the stack
O               For each char I in the input string:
 "^ v▼"          Push this string.
       \         Swap the top two items (so I is on top).
        C        Take the index of I in the string.
                 This returns 3 for ▼, 2 for v, 0 for ^, and -1 for ▲.
         y       Move the crayon by this number of spaces on the Y-axis (south).
          n      Move the crayon one position north.
                 The crayon has now been translated 2 positions south for ▼,
                 1 south for v, 1 north for ^, and 2 north for ▲.
           Iq    Draw I at the crayon. This automatically moves the crayon forward
                 by the length of I, which is 1 in this case.
Produksi ETH
sumber
0

pb - 136 byte

^w[B!0]{>}v[3*X]<[X]<b[1]^[Y]^>w[B!0]{t[B]<vw[B=0]{v}>w[T=107]{^^b[T]t[0]}w[T=94]{^b[T]t[0]}w[T=118]{vb[T]t[0]}w[T!0]{vvb[T]t[0]}^[Y]^>}

Penggunaan kdan jbukan dan .

Beberapa catatan:

  • Escape sequences that move the cursor such as \e[B are not allowed. You must produce the output using spaces and newlines.Saya mengikuti aturan ini! pb menggunakan konsep "kuas" untuk menghasilkan karakter. Kuas bergerak di sekitar "kanvas" dan dapat mencetak karakter tepat di bawahnya. Namun, implementasi aktual mencetak karakter menggunakan spasi dan baris baru.
  • Saya tidak akan repot dengan tantangan ini walaupun saya pikir akan menyenangkan dengan pb sampai saya melihat putusan itu You are allowed trailing spaces and/or empty lines . Ini karena beberapa alasan:
    • pb tidak bisa tidak telah spasi. Itu selalu menghasilkan keluaran persegi panjang, padding dengan spasi jika perlu.
    • Program ini menghasilkan banyak baris kosong. Tidak tahu seberapa tinggi output ketika mulai membuatnya, jadi untuk input panjang nmulai dari Y=3n+1. Ini -1karena turun 3ndari Y=-1, dan mulai Y=2n-1gagal untuk input semua k.

Anda dapat menonton program ini beraksi di YouTube! Versi ini sedikit dimodifikasi sehingga hanya turun ke n-1. Ini berfungsi untuk input ini, tetapi akan gagal untuk orang lain. Namun, hasilnya jauh lebih bagus.

Dengan komentar:

^w[B!0]{>}             # Go to the end of the input
v[3*X]                 # Go down 3 times the current X value
<[X]<                  # Go to X=-1 (off screen, won't be printed)
b[1]                   # Leave a non-zero value to find later
^[Y]^>                 # Back to the beginning of the input
w[B!0]{                # For every byte of input:
    t[B]                 # Copy it to T
    <vw[B=0]{v}>         # Go 1 to the right of the character to the left
                         # (either the last one printed or the value at X=-1)
                         # Move the correct amount for each character and print it:
    w[T=107]{^^b[T]t[0]} # k
    w[T=94]{^b[T]t[0]}   # ^
    w[T=118]{vb[T]t[0]}  # v
    w[T!0]{vvb[T]t[0]}   # j (Every other possibility sets T to 0, so if T is not 0
                         #    it must be j. T!0 is shorter than T=106)
    ^[Y]^>               # To the next byte of input to restart the loop
}
monmon bawah tanah
sumber
0

Ceylon, 447 byte

import ceylon.language{o=null,v=variable,s=shared}s void y(){v L c;v L f;v L l;v Integer i=0;class L(v L?p,v L?n){s v String t="";s L u=>p else(f=p=L(o,this));s L d=>n else(l=n=L(this,o));s void a(Character c)=>t=t+" ".repeat(i-t.size)+c.string;}f=l=c=L(o,o);for(x in process.readLine()else""){switch(x)case('^'){c=c.u;}case('v'){c=c.d;}case('▲'|'k'){c=c.u.u;}case('▼'|'j'){c=c.d.d;}else{}c.a(x);i++;}print(f.t);while(f!=l){f=f.d;print(f.t);}}

Atau dengan jeda baris untuk "keterbacaan": import ceylon.language{o=null,v=variable,s=shared}s void y(){v L c;v L f;v L l;v Integer i=0;class L(v L?p,v L?n){s v String t="";s L u=>p else(f=p=L(o,this));s L d=>n else(l=n=L(this,o));s void a(Character c)=>t=t+" ".repeat(i-t.size)+c.string;}f=l=c=L(o,o);for(x in process.readLine()else""){switch(x)case('^'){c=c.u;}case('v'){c=c.d;}case('▲'|'k'){c=c.u.u;}case('▼'|'j'){c=c.d.d;}else{}c.a(x);i++;}print(f.t);while(f!=l){f=f.d;print(f.t);}}

Ini berfungsi baik dengan input ▲ / ▼ dan j / k (Jika kita harus mendukung salah satunya saja, program akan lebih pendek 8 byte). Baris keluaran terakhir kosong ketika posisi awal berada di atasnya (yaitu input pertama adalah a dan ^dan kami tidak pernah mendapatkan di bawah itu lagi nanti). Input yang bukan merupakan salah satu karakter yang ditentukan hanya akan dicetak apa adanya, tanpa beralih baris:

v^^vv^^vvv^v^v^^^Hellovvvv^^v^^vv

  ^   ^         ^Hello
 ^ v ^ v       ^      v       ^
v   v   v ^ ^ ^        v   ^ ^ v
         v v v          v ^ v   v
                         v

Ini adalah versi yang diformat (753 bytes):

shared void y() {
    variable L c;
    variable L f;
    variable L l;
    variable Integer i = 0;
    class L(variable L? p, variable L? n) {
        shared variable String t = "";
        shared L u => p else (f = p = L(null, this));
        shared L d => n else (l = n = L(this, null));
        shared void a(Character c) => t = t + " ".repeat(i - t.size) + c.string;
    }
    f = l = c = L(null, null);
    for (x in process.readLine() else "") {
        switch (x)
        case ('^') { c = c.u; }
        case ('v') { c = c.d; }
        case ('▲' | 'k') { c = c.u.u; }
        case ('▼' | 'j') { c = c.d.d; }
        else {}
        c.a(x);
        i++;
    }
    print(f.t);
    while (f != l) {
        f = f.d;
        print(f.t);
    }
}

Ini adalah program "berorientasi objek" yang hampir langsung ... kelas (lokal) L(penyangga baris) menyimpan satu baris teks (dalam t), dan juga (nullable) pointer ke penunjuk berikutnya ( n) dan sebelumnya ( p) baris. Atribut (tidak nullable) u(untuk atas) dan d(untuk turun) menginisialisasi mereka jika diperlukan (dengan pointer terbalik ke dirinya sendiri), dan dalam hal ini juga melacak keseluruhan baris pertama dan terakhir (dalam fdan lvariabel).

Metode a(tambahkan) menambahkan karakter ke baris ini, termasuk beberapa ruang yang pada akhirnya diperlukan.

cadalah baris saat ini. Kami mengurai string input (menggunakan readLinesebagai input harus pada satu baris) menggunakan pernyataan switch yang memperbarui baris saat ini, dan kemudian memanggil metode append.

Setelah penguraian selesai, kita beralih pada garis dari yang pertama hingga yang terakhir, mencetak masing-masing. (Ini menghancurkanf pointer, jika diperlukan setelah itu, kita harus menggunakan variabel terpisah untuk ini.)

Beberapa trik yang digunakan untuk bermain golf:

  • Beberapa hal yang dalam bahasa lain akan menjadi kata kunci sebenarnya hanya pengidentifikasi dalam ceylon.languagepaket, dan dapat diubah namanya dengan impor alias - kami menggunakan ini untuk anotasi shared(digunakan 5 ×) dan variable(digunakan 6 ×), serta untuk objek null(digunakan 4 ×):

    import ceylon.language{o=null,v=variable,s=shared}
    

    (Trivia: Formatter dalam Ceylon IDE memformat beberapa anotasi bahasa bawaan, di antara mereka variabledan shared, dengan menempatkannya pada baris yang sama dengan deklarasi beranotasi, berbeda dengan anotasi khusus, yang diletakkan pada baris terpisah di atas deklarasi. Ini membuat versi program golf yang diformat tidak dapat dibaca, oleh karena itu saya mengubah alias-impor kembali untuk versi ini.)

    this, void, case, elseAdalah kata kunci yang sebenarnya dan tidak dapat diganti dengan cara ini, dan Integer, Stringdan Charactermuncul hanya sekali masing-masing, sehingga tidak ada yang bisa diperoleh dengan mengimpor.

  • Awalnya saya juga memiliki kelas ScreenBuffer yang terpisah (yang melacak daftar buffer baris yang terhubung, indeks saat ini, dan sebagainya), tetapi karena hanya ada satu objek saja, itu dioptimalkan jauh.

  • Itu kelas Screenbuffer juga memiliki updan downmetode, yang dipanggil dari parser (dan hanya melakukan currentLine = currentLine.upmasing - masing currentLine = currentLine.down). Ini menunjukkan bahwa melakukan hal ini secara langsung di sakelar pengurai lebih pendek. Itu juga diizinkan untuk menulis currentLine = currentLine.up.up(yang kemudian menjadi c = c.u.u) alih-alih currentLine = currentLine.up;currentLine = currentLine.up.

  • Awalnya kami memang melewatkan indeks saat ini sebagai argumen ke dalam metode append (dan bahkan ke parser dari loop) - memiliki variabel dalam fungsi yang berisi lebih pendek.

  • Awalnya metode printAll saya menggunakan pointer saat ini dan memindahkannya terlebih dahulu sampai baris saat ini kosong, dan kemudian turun saat mencetak setiap baris. Ini pecah ketika menggunakan ▲ dan ▼ untuk melompati garis, jadi kami harus secara eksplisit menambahkan sesuatu di garis melompat itu. Melacak baris pertama / terakhir terbukti lebih mudah (meskipun perlu menggunakan dua pernyataan cetak, karena tidak ada loop do-while-do di Ceylon).

  • Awalnya saya punya sesuatu seperti ini:

      String? input = process.readLine();
      if(exists input) {
         for(x in input) {
             ...
         }
      }
    

    process.readLinekembali nulljika tidak ada baris yang dapat dibaca (karena input telah ditutup), dan kompiler Ceylon mengharuskan saya untuk memeriksa sebelum saya mengakses input. Seperti dalam kasus ini saya tidak ingin melakukan apa-apa, saya bisa menggunakan elseoperator yang mengembalikan argumen pertama jika bukan nol, dan sebaliknya argumen kedua, menyimpan variabel dan pernyataan-if. (Ini juga akan memungkinkan kami untuk mengkodekan input default untuk menguji: for (x in process.readLine() else "^^▲^v▼▲^^v") {)

Paŭlo Ebermann
sumber
0

JavaScript (ES6), 228 byte

E=(r,p=(' '[M='repeat'](Z=r.length)+',')[M](Z*4),i=Z*2,k=0)=>Z>k?E(r,(p.split(',').map((o,q)=>q==i?o.slice(0,k)+r[k]+o.slice(k++):o)).join`,`,i+(H={'^':-1,k:-2,j:2,v:1})[r[k]],k):p.split(',').join`
`.replace(/\s+\n$|^\s+\n/g,'')

Nah, berikut ini adalah solusi rekursif (agak panjang) yang melewati semua test case yang diberikan. Itu tantangan yang bagus. Ini menggunakan kdanj menggantikan dan .

Cuplikan Tes

Meskipun pengiriman itu sendiri hanya dapat menangani k,j, cuplikan berikut dapat menangani keduanya k,jdan ▼,▲.

E=(r,p=(' '[M='repeat'](Z=r.length)+',')[M](Z*4),i=Z*2,k=0)=>Z>k?E(r,(p.split(',').map((o,q)=>q==i?o.slice(0,k)+r[k]+o.slice(k++):o)).join`,`,i+(H={'^':-1,k:-2,j:2,v:1})[r[k]],k):p.split(',').join`
`.replace(/\s+\n$|^\s+\n/g,'')
Input: <input type="text" oninput=o.textContent=E(this.value.replace(/▲/g,'k').replace(//g,'j'))></input>
<pre id='o'></pre>

R. Kap
sumber