Gambarkan downslash saya

60

Sebagai seorang programmer, Anda mungkin pernah mendengar tentang garis miring ke depan dan garis miring ke belakang. Tetapi apakah Anda pernah mendengar tentang downslash? Saat itulah Anda mengambil banyak garis miring, hubungkan ujungnya dan tarik turun.

Untuk tantangan hari ini, Anda harus menulis sebuah program atau fungsi yang mengambil string yang murni terdiri dari garis miring, dan menampilkan semua garis miring yang ditarik ke bawah dalam garis yang menghubungkannya. Ini akan jauh lebih jelas jika Anda melihat contoh. Mengingat string \\\//\/\\, Anda harus menampilkan:

\
 \
  \
  /
 /
 \
 /
 \
  \

Berikut ini beberapa klarifikasi:

  • Harus ada satu garis miring per baris.

  • Baris pertama akan memiliki 0 spasi utama.

  • Untuk setiap pasang garis miring:

    • Jika mereka berbeda satu sama lain, mereka akan ditarik di kolom yang sama. Misalnya, \/akan memberi:

      \
      /
      
    • Jika mereka memiliki karakter yang sama, yang lebih rendah berada di arah yang ditunjukkan , yaitu bergerak ke kanan untuk backslash, dan bergerak ke kiri untuk tebasan ke depan. Jadi \\//akan memberi

      \
       \
       /
      /
      
  • Setiap baris mungkin memiliki spasi spasi tambahan selama ini tidak mengubah tampilan visual dari output. Hingga satu trailing dan newline terkemuka juga dapat diterima. Ruang pemimpin tambahan tidak diizinkan !

Agar lebih sederhana, Anda dapat mengasumsikan bahwa string tidak akan pernah mengandung terlalu banyak garis miring ke depan. Dengan kata lain, tidak ada awalan input yang akan mengandung garis miring yang lebih maju dari garis miring terbalik, sehingga input seperti \\////atau //tidak akan pernah diberikan. Ini juga berarti bahwa setiap input akan mulai dengan garis miring terbalik.

Jika input Anda diambil sebagai string literal, Anda dapat lolos dari garis miring terbalik jika ini diperlukan. Anda juga tidak perlu menangani input yang kosong, atau mengandung karakter selain garis miring.

Anda dapat menampilkan dengan format apa pun yang masuk akal .

Seperti biasa, ini adalah tantangan , jadi cobalah membuat solusi sesingkat mungkin, bahkan jika Anda memilih bahasa yang agak sulit. Poin bonus untuk menjelaskan teknik menarik yang Anda gunakan untuk melepas byte!

Contohnya

#Input
\\\\\\\\\\\

#Output
\
 \
  \
   \
    \
     \
      \
       \
        \
         \
          \

#Input
\\\//\\/\//\\///

#Output
\
 \
  \
  /
 /
 \
  \
  /
  \
  /
 /
 \
  \
  /
 /
/


#Input
\/\/\/

#Output
\
/
\
/
\
/
DJMcMayhem
sumber
9
The backslash membuat jumlah yang luar biasa dari lolos ...
totallyhuman
Apakah metode formfeed / backslash untuk memindahkan kursor yang diberikan dalam jawaban saya diizinkan untuk pertanyaan ini?
Digital Trauma

Jawaban:

20

GNU Sed, 20

s|\\|&^L|g
s|/|^H/^L^H|g

Catat itu ^Ldan ^Hmerupakan karakter formfeed dan backspace literal (0x12 dan 0x8).

Jawaban ini berfungsi dengan menggerakkan kursor menggunakan karakter backspace dan formfeed. Garis miring / garis miring terbalik tidak diberi spasi - Tidak yakin akan mendiskualifikasi jawaban ini. Ini tidak berfungsi di TIO, tetapi terlihat baik di bawah terminal umum seperti xtermdan gnome-terminal.

Buat kembali skrip sed ini sebagai berikut:

base64 -d <<< c3xcXHwmDHxnCnN8L3wILwwIfGc= > downslash.sed

Jalankan sebagai berikut:

$ echo '\\\//\/\\' | sed -f downslash.sed
\ 
 \ 
  \ 
  /
 /
 \ 
 /
 \ 
  \ 

$ 

Penjelasan:

s|\\|&^L|g     # move cursor down after every "\"
s|/|^H/^L^H|g  # move cursor left before every "/", then after, down and left again
Trauma Digital
sumber
14

Arang , 13 12 11 byte

FS¿⁼ι/↓¶/↘ι

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Mendukung ekstra //s. Penjelasan:

 S              Input string
F               Loop over each character
  ¿             If
    ι           Current character
   ⁼            Equals
     /          Literal /
      ↓¶        Move left
      ↓ /       Print a / downwards
         ↘ι     Else it's a \ so print that down and right
Neil
sumber
Saya pikir ↓¶= "Bergerak ke kiri" dalam deskripsi tidak benar.
Jonathan Allan
@ JonathanAllan Itu benar (baris baru dicetak = bergerak ke kiri), meskipun mungkin akan lebih jelas untuk mengatakan "cetak \n/"
hanya ASCII
Saya tidak mengatakannya print \n/ downkarena saya merasa lebih membantu untuk menggambarkan efek kode daripada terjemahan literalnya.
Neil
1
(Lidah di pipi: Menjelaskan efek = MyCode - Do the spec). Saya mengerti sekarang meskipun pengaruhnya adalah bergerak ke kiri; mungkin layak dikatakan "Bergerak ke kiri (dengan mencetak baris baru dengan arah pencetakan ke bawah)".
Jonathan Allan
Paling ringkas dan jelas dari semuanya!
j4hangir
14

Python 2 , 55 54 51 57 53 byte

-3 byte (dan perbaikan bug) berkat Felipe Nardi Batista

i=0
for c in input():i-=c<'<'*i;print' '*i+c;i+=c>'<'

Cobalah online!

tongkat
sumber
56 bytes
Mr. Xcoder
10

/// , 119 byte

/// tidak memiliki perintah input, jadi input harus disematkan dalam program. Untuk yang ini, string input hanya ditambahkan, tanpa perlu melarikan diri.

/=/\/\///M/
|%%=N/%|||=C/BA=\/\\/\/C\\=C\\/CbC=B\A\=CfC=AB=/A/%Mxy=B/|z%N|x|y% %N%x|y%%% |fzN%M%b|zN|M|%
=|/AB\\=%/|=AC

Bagaimana itu bekerja

  • Berikut ini, input dari \\/\//akan ditambahkan ke program untuk demonstrasi.
  • digunakan untuk mewakili baris baru dalam kode inline.

Singkatan

Awal /=/\/\///M/␤|%%=N/%|||=C/BA=program berisi pergantian singkatan golf.

  • =meluas ke //, Mke ␤|%%, Nke %|||dan Cke BA.
  • Setelah ini, program saat ini menjadi

    /\/\\/\/BA\\//BA\\/BAbBA//B\A\//BAfBA//AB///A/%
    |%%xy//B/|z%%||||x|y% %%|||%x|y%%% |fz%|||%
    |%%%b|z%||||
    |%%|%
    //|/AB\\//%/|//ABA\\/\//
    

Pengodean ulang input

Tahap selanjutnya mengubah string input yang ditambahkan ke bentuk yang lebih bermanfaat. Karena sepenuhnya terdiri dari dua karakter perintah ///, ini membutuhkan perhatian untuk menghindari penyusunan program dasar.

  • Substitusi substansial pertama /\/\\/\/BA\\/,, menggantikan string /\dengan /BA\.
    • Program dasar tidak mengandung /\pada saat ini, sehingga substitusi ini tidak mempengaruhinya.
    • Namun, ini membagi string input yang ditambahkan ke dalam urutan \s diikuti oleh urutan /s, yang bersama-sama dengan ABApada akhir program dasar memungkinkan untuk beralih melalui itu dengan penggantian berikut.
    • Termasuk ABAawalan sebelumnya, contoh string input sekarang menjadi ABA\\/BA\//.
  • Substitusi berikutnya /BA\\/BAbBA/,, digantikan BA\oleh BAbBA.
    • Karena /// pergantian diulang sampai tidak cocok lagi, ini berganti melalui semua \s dari string input, yang dengan awalan sekarang menjadiABAbBAbBA/BAbBA//
  • Demikian pula, /B\A\//BAfBA/perubahan BA/untuk BAfBA, iterasi melalui /s.
    • Pelarian \dalam substitusi ini diperlukan karena jika tidak maka akan hancur oleh yang sebelumnya.
    • Input sekarang telah berubah menjadi ABAbBAbBAfBABAbBAfBAfBA.
  • Selanjutnya /AB//menghapus beberapa bagian berlebihan dari pengkodean, mengubahnya menjadi AbBAbBAfBAbBAfBAfBA.
    • Ini juga menghilangkan suatu ABdari /|/AB\\/substitusi nanti dalam program, yang diperlukan untuk melindunginya dari /\manipulasi di atas .
    • Pada titik ini setiap \string input asli telah menjadi AbB, dan setiap /telah menjadi AfB. ( bdan fberdiri untuk maju dan mundur.) Ada yang tersesat Adi akhir.
  • Dua pergantian berikutnya menggantikan semua Adan Bdengan fragmen program untuk dijalankan pada tahap akhir. Dalam string pengganti, %s dan |s mengkode apa yang akan menjadi /dan \masing-masing. Ini memiliki dua manfaat:
    • Tidak seperti /dan \, %dan |tidak perlu melarikan diri untuk disalin.
    • String pengganti menghindari mengandung substring /\, yang seharusnya telah hancur oleh manipulasi sebelumnya.
  • Setelah ini, substitusi /|/\\/(sebelumnya /|/AB\\/) sekarang menerjemahkan kode |s, setelah yang berikut /%/|//ini menjadi /%/\//dan menerjemahkan kode %s.

Struktur program pada tahap akhir

Pada titik ini, program dasar telah menjalankan semua substitusinya, dan yang tersisa hanyalah program-pengkodean dari string input.

  • Setiap karakter input telah menjadi subprogram

    /
    \//xy*\z//\\\\x\y/ //\\\/x\y/// \fz/\\\/
    \///b\z/\\\\
    \//\/
    

    (trailing newline), di mana *mewakili funtuk dokumen asli /, atau buntuk dokumen asli \.

  • Ada juga perintah substitusi yang tidak lengkap /␤\//xydi akhir program, yang tidak akan berpengaruh kecuali untuk memberikan yang diperlukan /untuk penggantian subprogram sebelumnya.

Substring bersama

Sebelum iterasi terakhir melalui subprogram dimulai, ada substring yang melintasi batas setelah setiap subprogram karakter dari formulir \/␤/.

  • Substring ini digunakan sebagai negara global bersama. Semua substitusi yang tersisa dalam program akan memanipulasinya secara identik dan paralel, sehingga pada akhir setiap subprogram karakter input, salinan substring bersama ini (kecuali final /, yang menopang substitusi) akan dijalankan untuk mencetak baris untuk itu. karakter.
  • Versi awal dari substring mewakili pencetakan baris yang berisi just /, yang merupakan "baris sebelumnya" imajiner yang tepat untuk menyebabkan karakter input pertama dicetak pada awal barisnya.
  • Secara umum, selama langkah-langkah pencetakan, substring bersama terdiri dari sejumlah spasi, \\atau \/, baris baru, dan berikut ini /.

Menjalankan subprogram karakter

Beberapa dari pergantian berikut ini mengandung lebih banyak \bagian dalam untuk mencegah agar tidak dicocokkan dan dihancurkan satu sama lain (termasuk salinan lain dalam subprogram lain). Pencapaian ini juga merupakan alasan mengapa kedua xdan ydibutuhkan.

  • Substitusi karakter pertama, /␤\//xyf\z/atau /␤\//xyb\z/, menyebabkan ␤/substring bersama di akhir menjadi xyfzatau xybz, segera setelah \/atau \\.
  • Substitusi /\\\\x\y/ /diganti \\xydengan spasi, dan subtitusi tidak /\\\/x\y//diganti \/xyoleh apa pun.
    • Mereka berlaku ketika karakter input sebelumnya yang dicetak masing-masing adalah \atau /.
    • Substring bersama sekarang berisi jumlah ruang yang tepat untuk mencetak \berikutnya, diikuti oleh fzatau bz.
  • Substitusi / \fz/\\\/␤\//diganti ​ fzoleh \/␤/, dan /b\z/\\\\␤\//diganti bzoleh \\␤/.
    • Mereka berlaku ketika karakter input saat ini adalah /atau \, masing-masing.
    • Yang pertama memakan ruang ekstra untuk ditempatkan /dengan benar.
      • Jika ruang ini tidak ada (yaitu input yang melanggar kondisi awalan), pergantian berikut disalahartikan, mencetak banyak sampah dan biasanya mengenai a ///, yang merupakan infinite loop.
    • Masing-masing menambahkan perintah yang benar untuk mencetak karakternya sendiri, dan mengembalikan yang asli ␤/di akhir substring bersama.
  • Subprogram karakter sekarang telah mencapai salinan substring bersama, yang siap untuk mencetak barisnya.

Setelah subprogram karakter terakhir dijalankan, apa yang tersisa dari program ini adalah /␤\//xy. Karena ini merupakan substitusi yang tidak lengkap dengan final yang hilang /, program akan melewatinya dan berhenti secara normal.

Ørjan Johansen
sumber
1
Bahasa yang tepat untuk pekerjaan itu! Lol
DJMcMayhem
6

Jelly , 14 byte

=”\ðḤ’+\_⁸⁶ẋżY

Program lengkap mencetak hasilnya.

Cobalah online!

Bagaimana?

=”\ðḤ’+\_⁸⁶ẋżY - Link: list of characters, s    e.g. "\\\//\\/"
 ”\            - literal '\'                         '\'
=              - equal? (call this e)                [1, 1, 1, 0, 0, 1, 1, 0]
   ð           - new dyadic chain f(e, s)
    Ḥ          - double                              [2, 2, 2, 0, 0, 2, 2, 0]
     ’         - decrement                           [1, 1, 1,-1,-1, 1, 1,-1]
      +\       - cumulative reduce with addition     [1, 2, 3, 2, 1, 2, 3, 2]
         ⁸     - chain's left argument, e            [1, 1, 1, 0, 0, 1, 1, 0]
        _      - subtract (# of leading spaces)      [0, 1, 2, 2, 1, 1, 2, 2]
          ⁶    - literal ' '                         ''
           ẋ   - repeat                              [""," ","  "," "," "," ","  ","  "]
            ż  - zip with s                          [["",'\'],[" ",'\'],["  ",'\'],["  ",'/'],[" ",'/'],[" ",'\'],["  ",'\'],["  ",'/']]
             Y - join with newlines                  ["",'\','\n'," ",'\','\n',"  ",'\','\n',"  ",'/','\n'," ",'/','\n'," ",'\','\n',"  ",'\','\n',"  ",'/']
               - implicit print - this smashes the lists (shown as "..." above) and the characters (shown as '...' above) together.
Jonathan Allan
sumber
6

Haskell , 49 byte

scanl(\x c->drop(sum[1|'/'<-c:x])(' '<$x)++[c])[]

Cobalah online!

dianne
sumber
5

JavaScript (ES8), 66 59 63 byte

7 byte disimpan berkat Justin Mariner
+4 byte untuk diperbaiki /\\/\\/(diperhatikan oleh Neil )

f=([a,...z],b=a<'0')=>a?a.padStart(b+=k=a>'/')+`
`+f(z,b-!k):''

Cobalah online!


sumber
5

MATL , 23 19 18 byte

1 byte off berkat @Sanchises

fGqoEq1yd~h*YsGZ?c

Input adalah string yang dilampirkan dalam tanda kutip tunggal.

Cobalah online! Atau verifikasi kasus uji: 1 , 2 , 3 .

Penjelasan

Pertimbangkan input '\\\//\/\\'sebagai contoh.

f      % Implicit input. Array of indices of nonzeros. Since all chars in the input
       % have nonzero code point, this gives [1 2 ... n] where n is input length
       % STACK: [1 2 3 4 5 6 7 8 9]
G      % Push input again
       % STACK: [1 2 3 4 5 6 7 8 9], '\\\//\/\\'
qo     % Subtract 1 from (the code-point) of each char and then compute modulo 2.
       % This transforms '\' into 1 and '/' into 0
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 0 0 1 0 1 1]
Eq     % Double, subtract 1. This transforms 0 into -1
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 -1 -1 1 -1 1 1]
1y     % Push 1 and duplicate from below
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 -1 -1 1 -1 1 1], 1, [1 1 1 -1 -1 1 -1 1 1]
d~     % Consecutive differences, logical negation: gives 1 if consecutive entries
       % are equal, 0 otherwise
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 -1 -1 1 -1 1 1], 1, [1 1 0 1 0 0 0 1]
h      % Horizontally concatenate
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 -1 -1 1 -1 1 1], [1 1 1 0 1 0 0 0 1]
*      % Element-wise multiplication
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 0 -1 0 0 0 1]
Ys     % Cumulative sum
       % STACK: [1 2 3 4 5 6 7 8 9], [1 2 3 3 2 2 2 2 3]
G      % Push input again
       % STACK: [1 2 3 4 5 6 7 8 9], [1 2 3 3 2 2 2 2 3], '\\\//\/\\'
Z?     % Build sparse matrix with those row indices, column indices, and values
       % STACK: [92  0  0;
                  0 92  0;
                  0  0 92;
                  0  0 47;
                  0 47  0;
                  0 92  0;
                  0 47  0;
                  0 92  0;
                  0  0 92]
c      % Convert to char. Char 0 is shown as space. Implicitly display
       % STACK: ['\  ';
                 ' \ ';
                 '  \';
                 '  /';
                 ' / ';
                 ' \ ';
                 ' / ';
                 ' \ ';
                 '  \']
Luis Mendo
sumber
Satu byte off oleh algoritma yang sedikit berbeda untuk mendapatkan indeks Anda: Cobalah online!
Sanchises
@Sanchises Terima kasih atas hasil edit Anda yang sangat tepat!
Luis Mendo
5

C # (.NET Core) , 74 88 82 78 77 76 + 18 byte

-1 byte terima kasih kepada Kevin Cruijssen

s=>s.Select((x,i)=>$"{x}".PadLeft((x-s[0])/45-~s.Take(i).Sum(y=>y<92?-1:1)))

Menghasilkan kumpulan string, satu untuk setiap baris. Hitungan byte juga mencakup:

using System.Linq;

Cobalah online!

Penjelasan untuk jawaban 77 byte:

s =>                              // Take input, a string
    s.Select((x, i) =>            // Replace every character with:
        $"{x}"                    //     The character as string
        .PadLeft(                 //     Pad with this many spaces:
            s.Take(i)             //         Take characters, in the input string, preceding current one
            .Sum(y =>             //         Sum them by:
                y < 92 ? -1 : 1   //             If it's a \ add 1, if / subtract 1
            )
            + (x - s[0]) / 45 + 1 //         If first slash is a / add one more space, if current slash is a \ add one more space (I got this through power of MATHS!)
                                  //         How I arrived at this function:
                                  //         + x / 48        If current slash is a \ add one more space
                                  //         - s[0] / 48 + 1 If the first slash is a / add one more space
        )
    )
Grzegorz Puławski
sumber
3
Tidak berhasil /\\/\\/.
Neil
@Neil terima kasih telah menunjukkan itu! Tetap.
Grzegorz Puławski
1
Saya tahu ini sudah lama, tetapi Anda dapat menyimpan byte dengan mengubah s.Take(i).Sum(y=>y<92?-1:1)+(x-s[0])/45+1ke(x-s[0])/45-~s.Take(i).Sum(y=>y<92?-1:1)
Kevin Cruijssen
Bagus sekali @KevinCruijssen!
Grzegorz Puławski
4

05AB1E , 14 byte

ÇÈx<ηOs-W-ISú»

Cobalah online!

Penjelasan

Ç                # convert input string to a list of ascii codes
 È               # check each for evenness
  x              # push a doubled copy
   <             # decrement
    η            # compute prefixes
     O           # sum each prefix
      s          # swap the unaltered copy of evenness to the top
       -         # subtract from the prefix-sum list
        W-       # subtract the minimum value
          IS     # push input split to a list of chars
            ú    # pad each with the number of spaces computed
             »   # join on newline
Emigna
sumber
1
Tidak berhasil /\\/\\/.
Neil
Ç¥.¥0<.SηOv¹Nèy<ú, terisak dalam biner
Magic Gurita Guci
3

R , 122 121 byte

-1 byte terima kasih kepada Giuseppe

x=el(strsplit(scan(,""),""));n=seq(x);y=x>"/";for(i in n)cat(rep(" ",diffinv(y[n[-1]-1]+y[n[-1]]-1)[i]),x[i],"\n",sep="")

Cobalah online!

Dengan spasi ekstra:

x = el(strsplit(scan(,""),""))
n = seq(x)
y = x>"/"
for(i in n) {
  cat(rep(" ", diffinv(y[n[-1]-1]+y[n[-1]]-1)[i]), x[i], "\n", sep="")
}

Penjelasan: Jawaban ini didasarkan pada pengamatan bahwa jumlah spasi memimpin mengubah setiap baris dengan -1, ditambah jumlah /pada baris sebelumnya dan saat ini.

Jika kita memiliki garis miring N, variabelnya yadalah vektor dengan panjang N, dengan 1 untuk setiap posisi dengan \, 0 sebaliknya. Oleh karena itu, untuk mendapatkan perubahan dalam jumlah spasi utama per baris, kami menghitung y[1:(N-1)] + y[2:N] - 1. Fungsi diffinvmengubah perbedaan-perbedaan ini menjadi suatu urutan, dimulai dengan 0. Selebihnya hanyalah masalah merakit setiap baris sebagai jumlah ruang trailing yang diperlukan, diikuti oleh garis miring yang relevan dan baris baru.

pengguna2390246
sumber
1
Hah. Saya mengambil pendekatan yang sangat berbeda untuk 119 byte yang membuat saya bertanya-tanya apakah kita bisa menggabungkan pendekatan kami. (penggunaan yang bagus dari diffinv;) Anda juga dapat mengatur y=x>")"untuk -1 byte
Giuseppe
@ Giuseppe Anda harus memposting itu sebagai jawaban terpisah, itu pendekatan yang cukup berbeda. Milikmu adalah cara yang bagus untuk menghindari keharusan melakukannya strsplit, yang selalu merupakan pembunuh. Anda juga dapat memanfaatkan yang terkenal diffinv!
user2390246
1
Saya juga berpikir jika Anda memasukkan library(methods)header (yang seharusnya OK tanpa penalti karena paket itu adalah bagian basis R), Anda dapat menggunakan el. Juga, diffinvternyata hanya selama cumsum! :)
Giuseppe
Ya, saya baru menyadari itu juga, itu tidak berfungsi dalam konteks itu
user2390246
baik, saya datang dengan solusi , tapi ya, itu *Smengacaukan semuanya.
Giuseppe
3

Brain-Flak , 175 byte (174 karakter + 1 bendera)

Jalankan dengan -cbendera.

{(({})<(())>){({}[()]<([{}])>)}{}(({}<>{}<><({}<>)((()()()()()){})>)<{({}[()]<((((()()()()){}){}){})>)}>{})<>}<>{}{({}<>)(({})(())){({}[()]<([{}]())>)}{}{<>{}<>(<{}>)}{}<>}<>

Cobalah online!

Penjelasan

{ for each char in the input...
  (({})<(())>){({}[()]<([{}])>)}{} push 1/-1 for backslash/slash
  ((
   {}<>{}<> add the 1/-1 to a running total
   <
    ({}<>) move slash/backslash to other stack
    ((()()()()()){}) newline
   >
  )<{({}[()]<((((()()()()){}){}){})>)}>{}) spaces
  <>
}<>{} end for
reverse data order, removing one space before backslash
{({}<>)(({})(())){({}[()]<([{}]())>)}{}{<>{}<>(<{}>)}{}<>}<>
MegaTom
sumber
Saya selalu menegakkan otak. : D
DJMcMayhem
3

Ruby , 80 76 byte

-4 byte berkat manatwork

puts"\\";$*[i=0].chars.each_cons 2{|b,c|puts" "*(b==c ?b==?/?i-=1:i+=1:i)+c}

Cobalah online!

Penjelasan:

puts "\\"           # Output the first backslash
$*[i=0].            # Get the first argument and set i to 0
chars.              # Go through every individual character,
each_cons 2 { |b,c| # In pairs to compare easily
                    #
    puts " " *      # Decide how many padding spaces to use based on the value
                    # of i. The expression inside the parenthesis will return
                    # i but before that, it will increment/decrement i based
                    # on what the previous character was.
                        #
    ( b==c ?            # if b == c
        b==?/ ?         #   if b == "/" (Going to the left)
            i-=1        #       return decremented i
            :           #   else        (Going to the right)
            i+=1        #       return incremented i
        :               # else
        i) +            #   return i
                    #
                c   # Finally, write the second of the characters that we're
}                   # iterating through.
Pazzaz
sumber
1
Versi Ruby yang mana? The 2.3.3 saya harus menuntut tanda kurung di sekitar parameter ketika blok kode berikut: .each_cons(2){…}. Sebagai gantinya Anda dapat menyimpan dengan mengganti .each_char.chars.
manatwork
@manatwork Versi ruby ​​saya adalah 2.4.1. Terima kasih atas saran tentang karakter, saya tidak tahu tentang itu.
Pazzaz
Anda bisa menyimpan dua byte lagi dengan pindah i+=ke awal ekspresi ternary bersarang, dan akhiri dengan -1:1:0.
benj2240
3

Java 8, 121 118 110 109 102 byte

a->{String r="";int s=0,p=0,i;for(char c:a){for(i=s+=p+(p=c-63)>>5;i-->0;r+=" ");r+=c+"\n";}return r;}

-7 byte berkat sihir bit-wise @Nevay . :)

Penjelasan:

Coba di sini.

a->{                    // Method with char-array parameter and String return-type
  String r="";          //  Return-String
  int s=0,              //  Amount of spaces
      p=0,              //  Previous characters (starting at 0)
      i;                //  Index-integer
  for(char c:a){        //  Loop over the input
    for(i=s+=p+(p=c-63)>>5;
                        //   If the current does not equals the previous character
                        //    Leave `s` the same
                        //   Else-if it's a '\':
                        //    Increase `s` by 1
                        //   Else (it's a '/'):
                        //    Decrease `s` by 1
                        //   And set the previous character to the current in the process
        i-->0;r+=" ");  //   Append `r` with `s` amount of spaces               
    r+=c+"\n";          //   Append the character + a new-line to the result
  }                     //  End of loop
  return r;             //  Return result-String
}                       // End of method
Kevin Cruijssen
sumber
1
102 byte:a->{String r="";int s=0,p=0,i;for(char c:a){for(i=s+=p+(p=c-63)>>5;i-->0;r+=" ");r+=c+"\n";}return r;}
Nevay
@Tidak, Terima kasih. Saya tahu itu bisa dipersingkat dengan beberapa operasi bitwise, tetapi tidak bisa mengetahuinya. Terutama karena saya lupa tentang mencoba efek dari >>/ >>>/ <<... Saya hanya memeriksa beberapa hal dengan &/ |/ ~/ ^..>.>
Kevin Cruijssen
3

C (GCC), 137 134 97 byte

Cobalah online!

• 3 byte terima kasih ATaco

• 37 byte berkat Digital Trauma & ThePirateBay

i,d;f(char*s){char c=s[i],n=s[++i];if(c){printf("%*c%c\n",d+1,c);(c-n)?d:(c==47)?--d:++d;f(s);}}

Tidak ada yang terlalu mewah hanya fungsi rekursif sederhana yang mengambil string dan mencetak garis miring, perhatikan bahwa input harus lolos dari garis miring terbalik terlebih dahulu.

Pemakaian

f("\\\\\\//\\/\\\\",0,0);

Tidak disatukan

Ini untuk jawaban lama, lihat tautan coba online untuk yang diperbarui!

f(char *s, i, d) {
    char c=s[i], n=s[++i];
    if(!c) return;
    for(int j=0; j<d; j++) printf(" ");
    printf("%c\n",c);
    f(s, i, (c!=n)?d:(c=='/')?d-1:d+1);
}

Keluaran

masukkan deskripsi gambar di sini

Tertidur
sumber
Anda dapat mengganti c=='\0'dengan !cuntuk efek yang sama.
ATaco
Luar biasa terima kasih baru saja memperbarui solusinya!
Asleepace
Dapatkah Anda menggunakan printf("%*s%c", n, "", c)untuk mencetak karakter c dengan n spasi terkemuka?
Digital Trauma
Aku cukup yakin Anda dapat menyimpan beberapa byte dengan mengganti (c!=n)dengan c-ndan menata ulang ekspresi ternary. Sama dengan (c=='/'). Anda juga dapat mengganti '/'dengan angka literal 47. Saya pikir totalnya adalah 7 byte.
1
78 byte
ASCII
3

C, 60 byte

i;f(char*s){for(i=1;*s;s++)printf("%*c\n",*s%2?--i:i++,*s);}

Cobalah online!

orlp
sumber
-1 tanpa tautan TIO: P
ASCII-saja
TIO
ASCII-only
@ ASCII-satunya saja, selamat datang
Stan Strum
3

Retina , 47 byte

^|\\
 $&
+m`^( *)( /|\\)(/| \\)
$1$2¶$1$3
m`^ 

Cobalah online! Tautan termasuk kasus uji. Penjelasan:

^|\\
 $&

Tambahkan spasi di awal setiap baris dan sebelum masing-masing \.

+m`^( *)( /|\\)(/| \\)
$1$2¶$1$3

Pertimbangkan dua karakter pertama dari string. Jika yang pertama adalah /maka indentasi perlu dikurangi; ini dicapai dengan memasukkan ruang sebelumnya dalam tangkapan (yang selalu ada karena tahap pertama menambahkannya); jika yang kedua adalah a \\maka perlu ditambah; ini dicapai dengan memasukkan ruang yang ditambahkan tahap pertama dalam tangkapan. Setelah memberi indentasi yang benar pada karakter kedua, stage diulang untuk karakter kedua dan ketiga, dll.

m`^ 

Hapus indentasi ekstra.

Saya telah menulis versi 94-byte yang (seperti jawaban Arang saya) memungkinkan setiap kombinasi garis miring: Coba online! Penjelasan:

.$
¶$.`$* $&

Dapatkan bola bergulir dengan mengambil tebasan terakhir dan indentasi ke posisi yang sama pada garisnya sendiri.

/
 /

Awali spasi untuk semua garis miring maju sehingga dapat ditangkap.

+`^(.*)( /|\\)¶( *)( \\|/)
$1¶$3$2¶$3$4

Berulang kali ambil tebasan terakhir dari input dan sejajarkan pada jalurnya sendiri dengan garis miring di bawah.

+ms`^(?<!^[\\/].*) (?!.*^[\\/])

Hapus indentasi sisa apa pun.

G`.

Hapus input yang sekarang kosong.

Neil
sumber
2

Lua , 96 byte

c=0 for s in(...):gmatch(".")do c=c+(p==s and(s=="/"and-1or 1)or 0)p=s print((" "):rep(c)..s)end

Cobalah online!

Yang terpendek yang bisa saya dapatkan di Lua. Input diambil dari baris perintah.

Ini memang menggunakan beberapa trik:

  1. (...):gmatch(
    Ini harus menjadi bentuk terpendek dari memasukkan string tunggal ke dalam program Lua dari baris perintah. The ...berekspresi di Lua menangkap kelebihan parameter ke fungsi yang tidak ditentukan dalam deklarasi fungsi dan digunakan untuk varargs. Karena tubuh utama dari program Lua dipanggil sebagai fungsi dengan argumen baris perintah sebagai parameternya, argumen baris perintah akan berakhir di ....
    Tanda kurung di sekitarnya mengubah ...ekspresi yang berpotensi bernilai banyak menjadi ekspresi bernilai tunggal. Pertimbangkan contoh (agak mengejutkan) ini:
    function multipleReturnValues()
        return "abc", "def"
    end
    print(  multipleReturnValues()  ) --This prints: abc    def
    print( (multipleReturnValues()) ) --This prints: abc
  2. Pengurai Lua tidak memerlukan terminator garis apa pun, atau bahkan spasi kosong di antara pernyataan, selama token kedua pernyataan dapat dipisahkan dengan jelas dan hanya ada satu interpretasi teks yang kode Lua yang valid.
  3. Menyalahgunakan and/ oruntuk "jika x maka logika value1 else value2".
    Operator Lua andmengembalikan argumen pertamanya jika salah; jika tidak, ia mengembalikan argumen kedua. The orOperator mengembalikan argumen pertama jika truthy; kalau tidak, argumen kedua.
  4. ptidak perlu inisialisasi.
    p==sselalu salah dalam menjalankan loop pertama, terlepas dari input. Tidak menetapkan pke nilai apa pun sebelum memasukkan loop (meninggalkannya nil) akan membuat itu terjadi dan menyimpan byte juga.

Adakah yang bisa bermain golf ini (di Lua)?

Jonathan S.
sumber
Saya dapat menyimpan dua byte dengan menggunakan gsub daripada menggunakan gmatch. c=0(...):gsub(".",function(s)c=c+(p==s and(s=="/"and-1or 1)or 0)p=s print((" "):rep(c)..s)end)
QuertyKeyboard
Ya, itu tidak penting. Anda bisa saja dengan mudah diselamatkan dua byte dengan mengubah gmatch(".")ke gmatch"."seperti yang Anda lakukan dalam jawaban Anda berikutnya.
QuertyKeyboard
@QuertyKeyboard Aneh ... Saya sebenarnya menggunakan gsub persis seperti ini di versi pertama dari kode ini, tetapi kemudian beralih ke gmatch sebagai gantinya karena entah bagaimana ternyata lebih pendek. Saya tidak tahu apa yang saya lakukan berbeda, sayangnya file tersebut ditimpa.
Jonathan S.
2

R , 119 byte

function(s)for(i in 1:nchar(s))cat(rep(" ",cumsum(c(0,!diff(S<-(utf8ToInt(s)>48)*2-1))*S)[i]),substr(s,i,i),"
",sep="")

Cobalah online!

Ini agak berbeda dari jawaban user2390246 . Mereka masing-masing mengulangi string, mencetak sejumlah karakter spasi dan kemudian /\karakter yang sesuai .

Namun, saya menghindari pemisahan string, sebagai gantinya memilih untuk mengganti karakter dengan nilai pengkodean UTF-8 sebagai gantinya, yang kemudian memungkinkan saya untuk melakukan aritmatika pada angka secara langsung, yang menyelamatkan saya hanya beberapa byte.

Giuseppe
sumber
Baru saja merenungkan ini lagi, saya pikir ada kesalahan dalam algoritma Anda: TIO
user2390246
@ user2390246 saya memperbaikinya! Saya memiliki beberapa tanda kurung salah tempat, tetapi sekarang diffinvpasti tidak akan berfungsi di sini.
Giuseppe
bagaimana dengan tio.run/##HYy7DsIwEAR/…
JayCe
2

C # (.NET Core) , 60/65 byte

Saya mencoba versi C # yang lebih pendek

s=>{int i=0;return s.Select(x=>"".PadLeft(x<92?--i:i++)+x);}

seperti yang dinyatakan: "Ini juga berarti bahwa setiap input akan mulai dengan garis miring terbalik." Atau agak lama yang menyelesaikan awal "/"

s=>{int i=s[0]&1;return s.Select(x=>"".PadLeft(x<92?--i:i++)+x);}

Cobalah online!

Dan
sumber
Selamat datang di situs ini! :)
DJMcMayhem
2

Lua , 88 84 byte

Versi yang ditingkatkan (-4 bytes berkat QuertyKeyboard)

s=""g=s.gsub g(...,".",function(c)s=g(g(g(s,"\\"," "),"/?$",c)," /","/")print(s)end)

Cobalah online!

Versi asli (88 byte)

Upaya lain di Lua, kali ini dengan pendekatan yang sama sekali berbeda menggunakan manipulasi string, bukan variabel counter.

s=""for c in(...):gmatch"."do s=s:gsub("\\"," "):gsub("/?$",c):gsub(" /","/")print(s)end

Tidak Disatukan:

s = ""
for c in string.gmatch((...), ".") do --for each character in the input
  --s contains the output from the previous iteration
  s = s:gsub("\\", " ") --Replace backslash with space -> indent by 1
  s = s:gsub("/?$", c) --Remove any / at the end of the string and append c to the string
  s = s:gsub(" /", "/") --Remove a single space in front of any / -> un-indent by 1
  print(s)
end

Ada satu hal yang menarik dalam kode: (...):gmatch"."
Ini menggunakan beberapa kebiasaan dalam Lua parser. Ketika Lua menemukan sepotong kode dalam formulir func "string", itu akan mengubahnya menjadi func("string"). Ini agar seseorang dapat menulis print "string"untuk mencetak string konstan dan hanya bekerja dengan string tunggal literal setelah fungsi. Yang lain akan memberikan kesalahan sintaksis. Namun, gula sintaksis ini juga berfungsi dengan pemanggilan fungsi di tengah ekspresi, dan yang lebih mengejutkan, :gula itu bekerja dengan baik bersama-sama dengan metode pemanggilan gula sintaksis. Jadi pada akhirnya, Lua akan menginterpretasikan kode seperti ini:

(...):gmatch"."
-> (...):gmatch(".")
-> string.gmatch((...), ".")

Jika ada yang bisa memikirkan cara untuk menghapus salah satu dari tiga panggilan gsub, tolong katakan padaku.

Jonathan S.
sumber
1
Saya kecewa menemukan bahwa trik gsub saya yang saya komentari pada jawaban Anda yang lain tidak cukup berhasil untuk yang satu ini. Sebenarnya akhirnya menambahkan satu byte. Namun, saya tidak akan menyerah begitu saja. Pertama, saya mencoba menyimpan gsub sebagai variabel untuk mempersingkat kode. Yang mengejutkan saya, kode saya jumlah byte yang sama - 88. Namun, saya menyadari bahwa dengan gsub disimpan, trik gsub saya sekarang bisa berfungsi! Inilah kode saya yang mencukur 4 byte:s=""g=s.gsub g(...,".",function(c)s=g(g(g(s,"\\"," "),"/?$",c)," /","/")print(s)end)
QuertyKeyboard
@QuertyKeyboard Yup, saya juga mencoba menyimpan gsub di variabel sebelum loop dan kemudian menggunakannya alih-alih menulis gsub tiga kali, dan saya sama terkejutnya melihatnya sama sekali tidak membuat perbedaan. Menggabungkan trik "gsub bukan loop" dan "store gsub" benar-benar rapi, tidak memikirkan yang itu! Terima kasih! :)
Jonathan S.
1

Perl, 40 + 2 byte

/\//&&$.--,say($"x$.,$_),/\\/&&$.++for@F

Anda membutuhkan -Fbenderanya.


sumber
1

Perl, 34 38 +1 byte

untuk menangani dua kasus

s,(/)|.,$"x($1?$c&&--$c:$c++).$&.$/,ge

untuk dijalankan dengan -popsi

s,(/)|.,$"x($1?--$c:$c++).$&.$/,ge

Sunting: komentar berikut tidak berfungsi saat karakter pertama /

s,(/)|.,$"x($1?$c--:++$c).$&.$/,ge

namun output akan digeser satu karakter di sebelah kanan jika karakter pertama adalah \

Nahuel Fouilleul
sumber
1
Tidak berhasil /\\/\\/.
Neil
Dengan pertanyaan yang diperbarui, 34solusi awal Anda kini benar-benar valid
Ton Hospel
1

VBA (Excel), 181 byte

Sub q()
a = Cells(1, 1)
For x = 1 To Len(a)
c = Mid(a, x, 1)
If c = "\" Then: Debug.Print b & c: b = b + " "
If c = "/" Then: b = Left(b, Len(b) - 1): Debug.Print b & c
Next
End Sub
remoel
sumber
1
Anda dapat menurunkan ini secara signifikan tanpa mengubah algoritme Anda dengan mengambil keuntungan dari sifat autoformatting dari Excel VBA dan dengan menggunakan [...]notasi: Saya mendapatkannya hingga 128 Bytes Sub q For x=1To[Len(A1)] c=Mid([A1],x,1) If c="\"Then Debug.?b;c:b=b+" " If c="/"Then b=Left(b,Len(b)-1):Debug.?b;c Next End Sub
Taylor Scott
Terima kasih telah bermain golf skrip saya. Saya belajar sesuatu dari ini dan akan berlaku di masa depan. :) Tidak tahu saya bisa menggunakannya untuk mengambil data langsung ke sel. Terima kasih lagi :)
remoel
1

Pyth , 24 21 byte

Port dari jawaban Rod .

VQ=-Z<N\<+*ZdN=+Z>N\<

Cobalah online!

Felipe Nardi Batista
sumber
Tidak valid, mencetak [spasi tambahan di baris pertama jika string dimulai dengan \. BTW di mana kode Anda?
Tn. Xcoder
@Mr. Xcoder diperbaiki
Felipe Nardi Batista
1

Dyalog APL, 31 byte

{↑⍵,¨⍨' '/¨⍨{⍵-⍨+1+2×⍵}⍵='\'}

Coba di sini!

dzaima
sumber
{↑⍵↑¨⍨a-1-+\¯1*a←⍵='\'}
ngn