Vẽ dấu gạch chéo của tôi


60

Là một lập trình viên, có lẽ bạn đã nghe nói về dấu gạch chéo về phía trước và dấu gạch chéo ngược. Nhưng bạn đã nghe nói về dấu gạch chéo? Đó là khi bạn lấy một loạt các dấu gạch chéo, nối đầu của chúng và kéo chúng xuống.

Đối với thử thách ngày nay, bạn phải viết một chương trình hoặc hàm lấy một chuỗi hoàn toàn là các dấu gạch chéo và xuất ra tất cả các dấu gạch chéo được kéo xuống dưới trong một đường nối chúng. Điều này sẽ rõ ràng hơn rất nhiều nếu bạn nhìn thấy một ví dụ. Đưa ra chuỗi \\\//\/\\, bạn nên xuất ra:

\
 \
  \
  /
 /
 \
 /
 \
  \

Dưới đây là một số làm rõ:

  • Phải có một dấu gạch chéo trên mỗi dòng.

  • Dòng đầu tiên sẽ có 0 không gian hàng đầu.

  • Đối với mỗi cặp dấu gạch chéo:

    • Nếu chúng khác nhau, chúng sẽ được vẽ trong cùng một cột. Ví dụ: \/sẽ cho:

      \
      /
      
    • Nếu chúng là cùng một ký tự, thì phần dưới nằm theo hướng được chỉ vào, đó là di chuyển sang bên phải cho dấu gạch chéo ngược và di chuyển sang bên trái để chém về phía trước. Vậy \\//sẽ cho

      \
       \
       /
      /
      
  • Mỗi dòng có thể có thêm khoảng trắng theo sau miễn là điều này không làm thay đổi giao diện trực quan của đầu ra. Lên đến một dấu vết và dòng mới hàng đầu cũng được chấp nhận. Không gian hàng đầu thêm không được phép !

Để giữ cho điều này đơn giản hơn, bạn có thể giả định rằng chuỗi sẽ không bao giờ chứa quá nhiều dấu gạch chéo về phía trước. Nói cách khác, không có tiền tố của đầu vào sẽ chứa nhiều dấu gạch chéo về phía trước hơn dấu gạch chéo ngược, do đó, một đầu vào giống \\////hoặc //sẽ không bao giờ được đưa ra. Điều này cũng có nghĩa là mọi đầu vào sẽ bắt đầu bằng dấu gạch chéo ngược.

Nếu đầu vào của bạn được lấy dưới dạng chuỗi ký tự, bạn có thể thoát khỏi dấu gạch chéo ngược nếu điều này là cần thiết. Bạn cũng sẽ không bao giờ cần xử lý một đầu vào trống hoặc chứa các ký tự không phải là dấu gạch chéo.

Bạn có thể xuất ra bởi bất kỳ định dạng hợp lý .

Như thường lệ, đây là một thử thách , vì vậy hãy cố gắng đưa ra giải pháp ngắn nhất có thể, ngay cả khi bạn chọn một ngôn ngữ mà điều này khá khó khăn. Điểm thưởng cho việc giải thích bất kỳ kỹ thuật thú vị nào bạn đã sử dụng để loại bỏ byte!

Ví dụ

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

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

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

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


#Input
\/\/\/

#Output
\
/
\
/
\
/

9
Các dấu gạch chéo ngược tạo ra một số lượng khó chịu khi thoát lol ...
hoàn toàn là

Câu trả lời:


20

GNU Sed, 20

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

Lưu ý rằng ^L^Hlà các ký tự định dạng và backspace bằng chữ (0x12 và 0x8).

Câu trả lời này hoạt động bằng cách di chuyển con trỏ xung quanh bằng cách sử dụng các ký tự backspace và formfeed. Dấu gạch chéo / dấu gạch chéo ngược không được đệm trái với khoảng trắng - Không chắc chắn về điều này không đủ điều kiện trả lời này. Điều này không hoạt động trong TIO, nhưng nó có vẻ tốt trong các thiết bị đầu cuối phổ biến như xtermgnome-terminal.

Tái tạo kịch bản sed này như sau:

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

Chạy nó như sau:

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

$ 

Giải trình:

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

14

Than , 13 12 11 byte

FS¿⁼ι/↓¶/↘ι

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Hỗ trợ thêm //s. Giải trình:

 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

Tôi nghĩ ↓¶= "Di chuyển sang trái" trong mô tả không đúng.
Jonathan Allan

@Jonathan ALLan Điều đó đúng (dòng mới được in xuống = di chuyển sang trái), mặc dù có thể rõ ràng hơn khi nói "in \n/xuống"
ASCII-chỉ

Tôi đã không nói print \n/ downbởi vì tôi cảm thấy rằng nó hữu ích hơn để mô tả hiệu ứng của mã hơn là bản dịch theo nghĩa đen của nó.
Neil

1
(Lưỡi trong má: Mô tả hiệu ứng = MyCode - Do the spec). Tôi hiểu ngay bây giờ mặc dù hiệu quả là di chuyển sang trái; có thể đáng nói "Di chuyển sang trái (bằng cách in một dòng mới với hướng in xuống)".
Jonathan Allan

Ngắn gọn nhất và tự giải thích của tất cả!
j4hangir


10

/// , 119 byte

/// không có lệnh đầu vào, vì vậy đầu vào phải được nhúng trong chương trình. Đối với điều này, chuỗi đầu vào chỉ đơn giản là được nối thêm, không cần thoát.

/=/\/\///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

Làm thế nào nó hoạt động

  • Sau đây, một đầu vào của \\/\//sẽ được thêm vào chương trình để trình diễn.
  • được sử dụng để thể hiện các dòng mới trong mã nội tuyến.

Các từ viết tắt

Phần đầu /=/\/\///M/␤|%%=N/%|||=C/BA=của chương trình chứa các phần thay thế cho chữ viết tắt chơi gôn.

  • =mở rộng đến //, Mđến ␤|%%, Nđến %|||Cđến BA.
  • Sau đó, chương trình hiện tại trở thành

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

Mã hóa đầu vào

Giai đoạn tiếp theo biến đổi chuỗi đầu vào được nối vào thành một dạng có thể sử dụng nhiều hơn. Vì nó bao gồm hoàn toàn hai ký tự lệnh của ///, điều này cần cẩn thận để tránh xáo trộn chương trình cơ sở.

  • Sự thay thế đáng kể đầu tiên /\/\\/\/BA\\/, thay thế chuỗi /\bằng /BA\.
    • Chương trình cơ sở không chứa /\tại thời điểm này, vì vậy sự thay thế này không ảnh hưởng đến nó.
    • Tuy nhiên, điều này phân tách chuỗi đầu vào được nối vào thành chuỗi \s theo sau là chuỗi /s, cùng với ABAphần cuối của chương trình cơ sở, có thể lặp lại qua chuỗi đó với các thay thế sau.
    • Bao gồm ABAtiền tố trước nó, chuỗi đầu vào ví dụ bây giờ trở thành ABA\\/BA\//.
  • Sự thay thế tiếp theo /BA\\/BAbBA/, thay thế BA\bởi BAbBA.
    • Bởi vì /// thay thế được lặp lại cho đến khi chúng không còn khớp nữa, điều này lặp lại qua tất cả các \chuỗi của chuỗi đầu vào, với tiền tố giờ trở thànhABAbBAbBA/BAbBA//
  • Tương tự như vậy, /B\A\//BAfBA/những thay đổi BA/để BAfBA, lặp qua /s.
    • Việc thoát \trong sự thay thế này là cần thiết vì nếu không nó sẽ bị sai lệch bởi cái trước đó.
    • Đầu vào bây giờ đã biến thành ABAbBAbBAfBABAbBAfBAfBA.
  • Tiếp theo /AB//loại bỏ một số phần thừa của mã hóa, biến nó thành AbBAbBAfBAbBAfBAfBA.
    • Đây cũng loại bỏ một ABtừ /|/AB\\/thay thế sau này trong chương trình, đó là cần thiết để bảo vệ nó khỏi trên /\thao tác.
    • Tại thời điểm này, mọi \chuỗi trong đầu vào ban đầu đã trở thành AbBvà mọi thứ /đã trở thành AfB. ( bfđứng cho lùi và tiến.) Có một đi lạc Aở cuối.
  • Hai sự thay thế tiếp theo thay thế tất cả các As và Bs bằng các đoạn chương trình để chạy trong giai đoạn cuối cùng. Trong các chuỗi thay thế, %s và |s mã hóa những gì sẽ trở thành /s và \s tương ứng. Điều này có hai lợi ích:
    • Không giống như /\, %s và |s không cần thoát để được sao chép.
    • Các chuỗi thay thế tránh chứa chuỗi con /\, nếu không sẽ bị xáo trộn bởi các thao tác trước đó.
  • Sau này, sự thay thế /|/\\/(trước đây /|/AB\\/) bây giờ giải mã |s, sau đó phần sau /%/|//đã trở thành /%/\//và giải mã %s.

Cấu trúc chương trình ở giai đoạn cuối

Tại thời điểm này, chương trình cơ sở đã chạy tất cả các thay thế của nó và tất cả những gì còn lại là mã hóa chương trình của chuỗi đầu vào.

  • Mỗi ký tự đầu vào đã trở thành một chương trình con

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

    (theo dõi dòng mới), trong đó *đại diện fcho một bản gốc /hoặc bcho một bản gốc \.

  • Ngoài ra còn có một lệnh thay thế không đầy đủ /␤\//xyvào cuối chương trình, sẽ không có hiệu lực ngoại trừ việc cung cấp một sự cần thiết /cho các thay thế của chương trình con trước đó.

Chuỗi con được chia sẻ

Trước khi lần lặp cuối cùng thông qua các chương trình con bắt đầu, có một chuỗi con vượt qua ranh giới sau mỗi chương trình con của mỗi ký tự của biểu mẫu \/␤/.

  • Những chất nền này được sử dụng như một trạng thái chung. Tất cả các thay thế còn lại trong chương trình sẽ thao tác chúng một cách đồng nhất và song song, sao cho ở cuối mỗi chương trình con của ký tự đầu vào, bản sao của chuỗi con chung này (ngoại trừ cuối cùng /, neo các thay thế) sẽ được chạy để in dòng cho nó tính cách.
  • Phiên bản ban đầu của chuỗi con đại diện cho việc in một dòng chỉ chứa /, đó là "dòng trước" tưởng tượng đúng để làm cho ký tự đầu vào đầu tiên được in ở đầu dòng.
  • Nói chung, trong các bước in, chuỗi con được chia sẻ bao gồm một số khoảng trắng \\hoặc \/, một dòng mới và sau đây /.

Chạy chương trình con nhân vật

Một số thay thế sau có chứa thêm \s bên trong để ngăn chúng khớp và xáo trộn lẫn nhau (bao gồm các bản sao khác trong các chương trình con khác). Đạt được điều này cũng là lý do tại sao cả hai xycần thiết.

  • Sự thay thế đầu tiên trong chương trình con ký tự, /␤\//xyf\z/hoặc /␤\//xyb\z/, làm cho ␤/phần cuối của chuỗi con được chia sẻ trở thành xyfzhoặc xybz, ngay sau dấu \/hoặc \\.
  • Sự thay /\\\\x\y/ /thế thay thế \\xybằng một khoảng trắng, và sự thay /\\\/x\y//thế thay thế \/xybởi không có gì.
    • Chúng được áp dụng khi ký tự đầu vào trước đó được in tương ứng \hoặc /.
    • Chuỗi con được chia sẻ hiện chứa số lượng không gian thích hợp để in \tiếp theo, theo sau là fzhoặc bz.
  • Sự thay / \fz/\\\/␤\//thế thay thế ​ fzbởi \/␤/, và /b\z/\\\\␤\//thay thế bzbởi \\␤/.
    • Chúng áp dụng khi ký tự đầu vào hiện tại tương ứng /hoặc \.
    • Cái đầu tiên ăn thêm một khoảng trống để đặt /chính xác.
      • Nếu không gian này bị thiếu (tức là đầu vào vi phạm điều kiện tiền tố), các thay thế sau đây sẽ bị hiểu sai, in rất nhiều rác và thường nhấn a ///, đó là một vòng lặp vô hạn.
    • Mỗi lệnh thêm lệnh chính xác để in ký tự của chính nó và khôi phục bản gốc ␤/ở cuối chuỗi con được chia sẻ.
  • Chương trình con ký tự hiện đã đạt đến bản sao của chuỗi con được chia sẻ, nó đã sẵn sàng để in dòng của nó.

Sau khi chương trình con ký tự cuối cùng chạy, phần còn lại của chương trình là gì /␤\//xy. Vì đây là một sự thay thế không hoàn toàn với thiếu cuối cùng /, chương trình bỏ qua nó và tạm dừng bình thường.


1
Ngôn ngữ phù hợp cho công việc! Lol
DJMcMayhem

6

Thạch , 14 byte

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

Một chương trình đầy đủ in kết quả.

Hãy thử trực tuyến!

Làm sao?

=”\ðḤ’+\_⁸⁶ẋż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.



5

JavaScript (ES8), 66 59 63 byte

7 byte được lưu nhờ Justin Mariner
+4 byte để sửa /\\/\\/(được chú ý bởi Neil )

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

Hãy thử trực tuyến!


5

MATL , 23 19 18 byte

Giảm 1 byte nhờ @Sanchises

fGqoEq1yd~h*YsGZ?c

Đầu vào là một chuỗi được bao trong các dấu ngoặc đơn.

Hãy thử trực tuyến! Hoặc xác minh các trường hợp kiểm tra: 1 , 2 , 3 .

Giải trình

Hãy xem xét đầu vào '\\\//\/\\'là một ví dụ.

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: ['\  ';
                 ' \ ';
                 '  \';
                 '  /';
                 ' / ';
                 ' \ ';
                 ' / ';
                 ' \ ';
                 '  \']

Một byte tắt bởi một thuật toán hơi khác nhau để có được các chỉ số của bạn: Hãy thử trực tuyến!
Sanchise

@Sanchises Cảm ơn bạn đã chỉnh sửa rất phù hợp!
Luis Mendo

5

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

-1 byte nhờ Kevin Cruijssen

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

Xuất ra một tập hợp các chuỗi, một cho mỗi dòng. Số lượng byte cũng bao gồm:

using System.Linq;

Hãy thử trực tuyến!

Giải thích cho câu trả lời 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
        )
    )

3
Không làm việc cho /\\/\\/.
Neil

@Neil cảm ơn bạn đã chỉ ra điều đó! Đã sửa.
Grzegorz Puławski

1
Tôi biết đã được một lúc, nhưng bạn có thể tiết kiệm một byte bằng cách thay đổi s.Take(i).Sum(y=>y<92?-1:1)+(x-s[0])/45+1thành(x-s[0])/45-~s.Take(i).Sum(y=>y<92?-1:1)
Kevin Cruijssen

Đẹp một @KevinCruijssen!
Grzegorz Puławski

4

05AB1E , 14 byte

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

Hãy thử trực tuyến!

Giải trình

Ç                # 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

1
Không làm việc cho /\\/\\/.
Neil

Ç¥.¥0<.SηOv¹Nèy<ú, khóc nức nở trong nhị phân
Bạch tuộc ma thuật Urn

3

R , 122 121 byte

-1 byte nhờ 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="")

Hãy thử trực tuyến!

Có thêm khoảng trắng:

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="")
}

Giải thích: Câu trả lời này dựa trên quan sát rằng số lượng khoảng trắng hàng đầu thay đổi mỗi dòng bằng -1, cộng với số lượng /trong các dòng trước đó và hiện tại.

Nếu chúng ta có N dấu gạch chéo, biến ylà một vectơ có độ dài N, với 1 cho mỗi vị trí với \, 0 nếu không. Do đó, để có được sự thay đổi về số lượng khoảng trắng hàng đầu trên mỗi dòng, chúng tôi tính toán y[1:(N-1)] + y[2:N] - 1. Hàm diffinvchuyển đổi các khác biệt này thành một chuỗi, bắt đầu bằng 0. Phần còn lại chỉ là vấn đề lắp ráp mỗi dòng là số lượng khoảng trắng theo yêu cầu, tiếp theo là dấu gạch chéo có liên quan và dòng mới.


1
Huh. Tôi đã sử dụng một cách tiếp cận khá khác nhau cho 119 byte khiến tôi tự hỏi liệu chúng ta có thể kết hợp các cách tiếp cận của mình không. (sử dụng tốt diffinv;) Ngoài ra, bạn có thể đặt y=x>")"cho -1 byte
Giuseppe

@Giuseppe Bạn nên đăng nó như một câu trả lời riêng biệt, đó là một cách tiếp cận đủ khác. Của bạn là một cách tốt đẹp để tránh phải làm strsplit, mà luôn luôn là một kẻ giết người. Bạn cũng có thể tận dụng sự nổi tiếng diffinv!
dùng2390246

1
Ngoài ra tôi nghĩ rằng nếu bạn đặt library(methods)tiêu đề (sẽ không bị phạt vì gói đó là một phần cơ sở R), bạn có thể sử dụng el. Ngoài ra, diffinvhóa ra chỉ là miễn là cumsum! :)
Giuseppe

Vâng, tôi cũng đã nhận ra điều đó, nó không hoạt động hoàn toàn trong bối cảnh đó
user2390246

tốt, tôi đã đưa ra một cách giải quyết , nhưng vâng, điều đó làm *Shỏng mọi thứ.
Giuseppe

3

Brain-Flak , 175 byte (174 ký tự + 1 cờ)

Chạy với -ccờ.

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

Hãy thử trực tuyến!

Giải trình

{ 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
{({}<>)(({})(())){({}[()]<([{}]())>)}{}{<>{}<>(<{}>)}{}<>}<>

Tôi luôn luôn nâng cao tinh thần. : D
DJMcMayhem

3

Ruby , 80 76 byte

-4 byte nhờ thao tác

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

Hãy thử trực tuyến!

Giải trình:

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.

1
Phiên bản nào của Ruby? 2.3.3 Tôi có yêu cầu ngoặc đơn xung quanh tham số khi khối mã theo sau : .each_cons(2){…}. Thay đổi, bạn có thể lưu bằng cách thay thế .each_char.chars.
manatwork

@manatwork Phiên bản ruby ​​của tôi là 2.4.1. Cảm ơn lời đề nghị về ký tự, tôi không biết về cái đó.
Pazzaz

Bạn có thể lưu hai byte khác bằng cách di chuyển i+=đến phần đầu của biểu thức ternary lồng nhau và kết thúc nó bằng -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 nhờ vào phép thuật khôn ngoan của @Nevay . :)

Giải trình:

Hãy thử nó ở đây.

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

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

@Nevay Cảm ơn. Tôi biết nó có thể được rút ngắn với một số thao tác bitwise, nhưng không thể tìm ra nó. Chủ yếu là vì tôi quên mất việc thử các hiệu ứng của >>/ >>>/ <<... Tôi chỉ kiểm tra một số thứ với &/ |/ ~/ ^..>.>
Kevin Cruijssen

3

C (GCC), 137 134 97 byte

Hãy thử trực tuyến!

• 3 byte cảm ơn ATaco

• 37 byte nhờ 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);}}

Không có gì quá lạ mắt chỉ là một hàm đệ quy đơn giản lấy một chuỗi và in ra các dấu gạch chéo, lưu ý rằng đầu vào cần phải thoát khỏi dấu gạch chéo ngược trước.

Sử dụng

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

Ung dung

Đây là câu trả lời cũ, xem liên kết thử trực tuyến để cập nhật!

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

Đầu ra

nhập mô tả hình ảnh ở đây


Bạn có thể thay thế c=='\0'bằng !ccho tác dụng tương tự.
ATaco

Tuyệt vời cảm ơn chỉ cần cập nhật các giải pháp!
Ngủ

Bạn có thể sử dụng printf("%*s%c", n, "", c)để in char c với n khoảng trắng không?
Chấn thương kỹ thuật số

Tôi khá chắc chắn rằng bạn có thể tiết kiệm vài byte bằng cách thay thế (c!=n)với c-nvà sắp xếp lại các biểu ternary. Tương tự với (c=='/'). Ngoài ra, bạn có thể thay thế '/'bằng số chữ 47. Tôi nghĩ rằng nó là 7 byte trong tổng số.



3

Võng mạc , 47 byte

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

Hãy thử trực tuyến! Liên kết bao gồm các trường hợp thử nghiệm. Giải trình:

^|\\
 $&

Thêm một khoảng trắng ở đầu mỗi dòng và trước mỗi dòng \.

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

Hãy xem xét hai ký tự đầu tiên của chuỗi. Nếu đầu tiên là một /thì thụt lề cần phải được giảm; điều này đạt được bằng cách bao gồm không gian trước trong bản chụp (luôn tồn tại vì giai đoạn đầu tiên đã thêm nó); nếu cái thứ hai là một \\thì nó cần phải tăng lên; điều này đạt được bằng cách bao gồm không gian mà giai đoạn đầu tiên được thêm vào trong bản chụp. Khi đã cho nhân vật thứ hai thụt lề chính xác, giai đoạn được lặp lại cho nhân vật thứ hai và thứ ba, v.v.

m`^ 

Loại bỏ thụt lề thêm.

Tôi đã viết một phiên bản 94 byte (như câu trả lời Char than của tôi) cho phép mọi sự kết hợp của dấu gạch chéo: Hãy thử trực tuyến! Giải trình:

.$
¶$.`$* $&

Nhận bóng lăn bằng cách lấy dấu gạch chéo cuối cùng và thụt nó vào cùng một vị trí trên đường thẳng của chính nó.

/
 /

Không gian tiền tố cho tất cả các dấu gạch chéo về phía trước để chúng có thể được chụp.

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

Liên tục lấy dấu gạch chéo cuối cùng của đầu vào và căn chỉnh nó trên dòng riêng của nó với dấu gạch chéo trên dòng bên dưới.

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

Xóa mọi vết lõm còn sót lại.

G`.

Xóa đầu vào trống bây giờ.


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

Hãy thử trực tuyến!

Ngắn nhất tôi có thể đến với Lua. Đầu vào được lấy từ dòng lệnh.

Điều này không sử dụng một vài thủ thuật:

  1. (...):gmatch(
    Đây phải là hình thức ngắn nhất để nhận một chuỗi đơn vào chương trình Lua từ dòng lệnh. Các ...biểu hiện trong Lua chụp bất kỳ thông số dư thừa để một chức năng không được chỉ định trong phần khai báo hàm và được sử dụng cho varargs. Do phần chính của chương trình Lua được gọi là một hàm với các đối số dòng lệnh làm tham số của nó, nên các đối số dòng lệnh sẽ kết thúc bằng ....
    Các dấu ngoặc đơn xung quanh nó biến ...biểu thức có giá trị tiềm năng thành biểu thức có giá trị đơn. Xem xét ví dụ này (hơi ngạc nhiên):
    function multipleReturnValues()
        return "abc", "def"
    end
    print(  multipleReturnValues()  ) --This prints: abc    def
    print( (multipleReturnValues()) ) --This prints: abc
  2. Trình phân tích cú pháp Lua không cần bất kỳ trình kết thúc dòng nào, hoặc thậm chí khoảng trắng giữa các câu lệnh, miễn là hai mã thông báo của câu lệnh có thể được phân tách rõ ràng và chỉ có một cách giải thích văn bản là mã Lua hợp lệ.
  3. Lạm dụng and/ orcho logic "nếu x thì value1 khác value2". Toán tử
    của Lua andtrả về đối số đầu tiên của nó nếu nó sai; mặt khác, nó trả về đối số thứ hai của nó. Các ornhà điều hành trả về đối số đầu tiên của nó nếu nó là truthy; mặt khác, đối số thứ hai.
  4. pkhông cần bất kỳ sự khởi tạo nào.
    p==sluôn luôn phải sai trong lần chạy đầu tiên của vòng lặp, bất kể đầu vào là gì. Không đặt pthành bất kỳ giá trị nào trước khi vào vòng lặp (bỏ nó nil) sẽ khiến điều đó xảy ra và cũng lưu byte.

Bất cứ ai có thể chơi golf này (ở Lua)?


Tôi đã có thể lưu hai byte bằng cách sử dụng gsub thay vì sử dụng gmatch. c=0(...):gsub(".",function(s)c=c+(p==s and(s=="/"and-1or 1)or 0)p=s print((" "):rep(c)..s)end)
QuertyPal

Vâng, không phải là vấn đề. Bạn có thể dễ dàng lưu hai byte bằng cách thay đổi gmatch(".")thành gmatch"."như bạn đã làm trong câu trả lời tiếp theo.
QuertyPal

@QuertyPal Thật kỳ lạ ... Tôi thực sự đã sử dụng gsub chính xác như thế này trong phiên bản đầu tiên của mã này, nhưng sau đó chuyển sang gmatch thay vì vì nó bằng cách nào đó hóa ra ngắn hơn. Tôi không biết những gì tôi đã làm khác nhau, tập tin bị ghi đè không may.
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="")

Hãy thử trực tuyến!

Điều này khác một chút so với câu trả lời của user2390246 . Mỗi người lặp lại chuỗi, in ra một số ký tự khoảng trắng nhất định và sau đó là /\ký tự thích hợp .

Tuy nhiên, tôi đã tránh chia chuỗi, thay vào đó chọn thay thế các ký tự bằng giá trị mã hóa UTF-8 của chúng, điều này cho phép tôi trực tiếp thực hiện số học trên các số, giúp tôi chỉ tiết kiệm được một vài byte.


Chỉ cần suy nghĩ thêm về điều này, tôi nghĩ rằng có một lỗi trong thuật toán của bạn: TIO
user2390246

@ user2390246 Tôi đã sửa nó! Tôi đã có một số dấu ngoặc sai, nhưng bây giờ diffinvchắc chắn sẽ không hoạt động ở đây.
Giuseppe


2

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

Tôi đã thử phiên bản C # ngắn hơn

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

như đã nói: "Điều này cũng có nghĩa là mọi đầu vào sẽ bắt đầu bằng dấu gạch chéo ngược." Hoặc dài hơn một chút để giải quyết bắt đầu "/"

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

Hãy thử trực tuyến!


Chào mừng đến với trang web! :)
DJMcMayhem

2

Lua , 88 84 byte

Phiên bản được cải tiến (-4 byte nhờ QuertyPal)

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

Hãy thử trực tuyến!

Phiên bản gốc (88 byte)

Một nỗ lực khác ở Lua, lần này với cách tiếp cận hoàn toàn khác bằng cách sử dụng thao tác chuỗi thay vì biến đếm.

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

Ung dung:

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

Có một điều thú vị trong mã: (...):gmatch"."
Điều này sử dụng một số quirks trong trình phân tích cú pháp Lua. Khi Lua gặp một đoạn mã trong biểu mẫu func "string", nó sẽ chuyển đổi mã này thành func("string"). Điều này là để người ta có thể viết print "string"để in một chuỗi không đổi và nó chỉ hoạt động với một chuỗi ký tự duy nhất sau hàm. Bất cứ điều gì khác sẽ cung cấp một lỗi cú pháp. Tuy nhiên, đường cú pháp này cũng hoạt động với các lệnh gọi hàm ở giữa một biểu thức, và đáng ngạc nhiên hơn, nó hoạt động tốt chỉ với :phương pháp gọi đường cú pháp. Vì vậy, cuối cùng, Lua sẽ diễn giải mã như thế này:

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

Nếu bất cứ ai có thể nghĩ ra một cách để loại bỏ một trong ba cuộc gọi gsub, xin vui lòng cho tôi biết.


1
Tôi đã thất vọng khi thấy rằng thủ thuật gsub của tôi, tôi đã nhận xét trong câu trả lời khác của bạn không hoàn toàn hiệu quả cho câu hỏi này. Nó thực sự đã kết thúc việc thêm một byte. Tuy nhiên, tôi sẽ không từ bỏ dễ dàng. Đầu tiên, tôi đã cố gắng lưu trữ gsub như một biến để rút ngắn mã. Thật ngạc nhiên, mã của tôi chính xác là cùng một lượng byte - 88. Tuy nhiên, tôi nhận ra rằng với gsub được lưu, thủ thuật gsub của tôi giờ có thể hoạt động! Đây là mã của tôi đã loại bỏ 4 byte:s=""g=s.gsub g(...,".",function(c)s=g(g(g(s,"\\"," "),"/?$",c)," /","/")print(s)end)
QuertyPal

@QuertyPal Yup, tôi cũng đã thử lưu trữ gsub trong một biến trước vòng lặp và sau đó sử dụng nó thay vì viết gsub ba lần, và tôi rất ngạc nhiên khi thấy nó hoàn toàn không có gì khác biệt. Kết hợp các thủ thuật "gsub thay vì loop" và "store gsub" thực sự rất gọn gàng, bạn đã không nghĩ đến điều đó! Cảm ơn! :)
Jonathan S.


1

Perl, 40 + 2 byte

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

Bạn cần -Fcờ.


1

Perl, 34 38 + 1 byte

để xử lý hai trường hợp

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

được chạy với -ptùy chọn

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

EDIT: bình luận sau không hoạt động khi ký tự đầu tiên là /

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

tuy nhiên đầu ra sẽ được dịch chuyển một ký tự bên phải nếu char đầu tiên là \


1
Không làm việc cho /\\/\\/.
Neil

Với câu hỏi được cập nhật, 34giải pháp ban đầu của bạn hiện hoàn toàn hợp lệ
TonMedel

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

1
Bạn có thể giảm đáng kể thuật toán này mà không cần thay đổi thuật toán của mình bằng cách tận dụng tính năng tự động định dạng của Excel VBA và bằng cách sử dụng [...]ký hiệu: Tôi đã giảm xuống còn 128 Byte 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

Cảm ơn bạn đã chơi golf kịch bản của tôi. Tôi đã học được điều gì đó từ điều này và sẽ áp dụng trong tương lai. :) Không biết tôi có thể sử dụng điều đó để lấy dữ liệu trực tiếp đến các ô. Cảm ơn một lần nữa :)
làm lại



Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.