スラッシュを描く


60

プログラマーとして、あなたはおそらくスラッシュとバックスラッシュを聞いたことがあるでしょう。しかし、あなたはダウンスラッシュを聞いたことがありますか?それは、あなたがたくさんのスラッシュを取り、それらの端をつなぎ、それらを引き下ろすときです。

今日の課題では、純粋にスラッシュで構成される文字列を受け取り、それらを結ぶ線で下向きに描かれたすべてのスラッシュを出力するプログラムまたは関数を作成する必要があります。例を見ると、これはより明確になります。文字列を指定すると\\\//\/\\、次を出力する必要があります。

\
 \
  \
  /
 /
 \
 /
 \
  \

いくつかの説明を次に示します。

  • 行ごとに1つのスラッシュが必要です。

  • 最初の行には、先頭に0個のスペースがあります。

  • スラッシュの各ペアに対して:

    • それらが互いに異なる場合、それらは同じ列に描画されます。たとえば、次のように\/なります。

      \
      /
      
    • それらが同じ文字である場合、下の方が指す方向にあり、バックスラッシュの場合は右に移動し、スラッシュの場合は左に移動します。だから\\//与える

      \
       \
       /
      /
      
  • 出力の視覚的な外観が変わらない限り、各行には余分な末尾の空白があります。最大1つの末尾および先頭の改行も使用できます。余分な先行スペースは使用できません

これをより簡単に保つために、文字列に含まれるスラッシュが多すぎることはないと想定できます。言い換えると、入力のプレフィックスにはバックスラッシュよりも多くのスラッシュが含まれないため、\\////またはのような入力//は与えられません。これは、すべての入力がバックスラッシュで始まることも意味します。

入力が文字列リテラルとして取得される場合、必要に応じて円記号をエスケープできます。また、空の入力や、スラッシュ以外の文字を含む入力を処理する必要はありません。

妥当な形式で出力できます

いつものように、これは挑戦なので、これがかなり難しい言語を選んだとしても、最短の解決策を可能にするようにしてください。バイトを削除するために使用した興味深いテクニックを説明するためのボーナスポイント!

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

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

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

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


#Input
\/\/\/

#Output
\
/
\
/
\
/

9
バックスラッシュは...笑脱出の迷惑な量のために作る
totallyhuman

回答:


20

GNU Sed、20

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

^Land ^Hはリテラルのフォームフィードおよびバックスペース文字(0x12および0x8)であることに注意してください。

この答えは、バックスペースとフォームフィード文字を使用してカーソルを移動することで機能します。スラッシュ/バックスラッシュはスペースで左詰めされていません-この答えが不適格であることは確かではありません。これはTIOでは機能しませんが、xtermやなどの一般的な端末では正常に見えgnome-terminalます。

このsedスクリプトを次のように再作成します。

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

次のように実行します。

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

$ 

説明:

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

13 12 11バイト

FS¿⁼ι/↓¶/↘ι

オンラインでお試しください!リンクは、コードの詳細バージョンです。余分なをサポートします//。説明:

 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

↓¶説明の「左に移動」は正しくないと思います。
ジョナサンアラン

おそらく、「印刷と言って明確になりますが、それは、(改行は=が左に移動ダウン印刷)そうです@JonathanAllan \n/ダウン」
ASCIIのみ

私は言っprint \n/ downたのは、文字通りの翻訳よりもコードの効果を説明する方が有益だと感じたからです。
ニール

1
(頬の舌:効果の説明= MyCode - Do the spec)。私はかかわらず、今それを得る効果が左に移動することです。「左に移動する(印刷方向を下にして改行を印刷することにより)」と言う価値があるかもしれません。
ジョナサンアラン

最も簡潔でわかりやすい説明です!
j4hangir


10

///、119バイト

///には入力コマンドがないため、入力をプログラムに埋め込む必要があります。この場合、入力文字列は単純に追加され、エスケープする必要はありません。

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

使い方

  • 以下では\\/\//、デモ用にプログラムの入力が追加されます。
  • インラインコードで改行を表すために使用されます。

略語

/=/\/\///M/␤|%%=N/%|||=C/BA=プログラムの冒頭には、ゴルフの略語の代わりが含まれています。

  • =展開//M␤|%%N%|||CしますBA
  • この後、現在のプログラムは

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

入力記録

次の段階では、追加された入力文字列をより使いやすい形式に変換します。完全に///の2つのコマンド文字で構成されているため、これは基本プログラムをマングルすることを避けるためにいくらか注意を払っています。

  • 最初の実質的な置換/\/\\/\/BA\\/は、文字列/\をに置き換えます/BA\
    • /\現時点では基本プログラムは含まれていないため、この置換は影響しません。
    • ただし、これにより、追加された入力文字列が\sのシーケンスに分割され、その後にsのシーケンスが続きます/。これABAは、ベースプログラムの最後で、次の置換を使用して反復できます。
    • そのABA前にプレフィックスを含めると、入力文字列の例はになりABA\\/BA\//ます。
  • 次の置換は/BA\\/BAbBA/、に置き換えBA\られBAbBAます。
    • ///置換は、一致しなくなるまで繰り返されるため\、入力文字列のすべてのsを反復処理します。ABAbBAbBA/BAbBA//
  • 同様に、に/B\A\//BAfBA/変更BA/BAfBA/sを反復処理します。
    • \それ以外の場合は前の置換によって破壊されるため、この置換でのエスケープが必要です。
    • 入力はに変わりましたABAbBAbBAfBABAbBAfBAfBA
  • 次に/AB//、エンコーディングの余分な部分を削除して、に変換しAbBAbBAfBAbBAfBAfBAます。
    • また、これは削除さABから/|/AB\\/、後で上からそれを保護するために必要とされたプログラム、で置換/\操作。
    • この時点\で、元の入力文字列のAbBすべて/がになり、すべてがになりましたAfB。(bそしてf後方と前方を表します。)A最後に迷いがあります。
  • 次の2つの置換により、すべてのAsとBsがプログラムフラグメントに置き換えられ、最終段階で実行されます。置換文字列では、%sおよび|sがどうなるのかエンコード/sおよび\それぞれです。これには2つの利点があります。
    • /およびとは異なり\%sおよび|sはコピーするためにエスケープする必要はありません。
    • 置換文字列は/\、さもなければ以前の操作によって破壊されていたサブストリングを含むことを避けます。
  • この後、置換/|/\\/(以前は/|/AB\\/)が|sをデコードし、その後、以下/%/|//がsになり/%/\//、デコードされ%ます。

最終段階のプログラム構造

この時点で、基本プログラムはすべての置換を実行し、残っているのは入力文字列のプログラムエンコーディングだけです。

  • 各入力文字はサブプログラムになりました

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

    (改行)、ここで、*いずれかを表しf、オリジナルのために/、またはbオリジナルのために\

  • また/␤\//xy、プログラムの最後に不完全な置換コマンドがあり/ます。これは、前のサブプログラムの置換に必要なものを提供する以外は効果がありません。

共有部分文字列

サブプログラムの最後の反復が始まる前に、各文字のフォームのサブプログラムの後に境界を横切るサブストリングがあり\/␤/ます。

  • これらの部分文字列は、共有グローバル状態として使用されます。プログラムの残りのすべての置換は、それらを同じように並行して操作し、各入力文字のサブプログラムの最後に/、この共有部分文字列のコピー(置換をアンカーするfinalを除く)が実行され、その行を印刷しますキャラクター。
  • 部分文字列の初期バージョンは、justを含む行の印刷を表します/。これは、最初の入力文字を行の先頭に印刷するための右の想像上の「前の行」です。
  • 一般に、印刷ステップ中、共有部分文字列は、複数のスペース、\\または\/、改行、それに続くで構成されます/

キャラクターサブプログラムの実行

次の置換のいくつかには、\他のサブプログラム内の他のコピーを含め、互いに一致したりマングルされたりすることを防ぐために、追加のs が含まれています。これを達成することも、両方の理由であるxとがy必要とされています。

  • 最初の文字のサブプログラムで置換、/␤\//xyf\z/または/␤\//xyb\z/、原因と␤/共有ストリングの終わりになるxyfzxybz、直後の\/\\
  • 置換/\\\\x\y/ /\\xyスペースで/\\\/x\y//置き換え\/xyられ、置換は何も置き換えられません。
    • 印刷される前の入力文字がそれぞれ\またはの場合に適用され/ます。
    • 共有部分文字列には、\次を印刷するための適切な数のスペースが含まれ、その後にfzまたはが続きbzます。
  • 置換/ \fz/\\\/␤\//​ fzによって置換され\/␤/、によって/b\z/\\\\␤\//置換bzされ\\␤/ます。
    • 現在の入力文字がある場合には適用され/たり\、それぞれ。
    • 最初のものは余分なスペースを消費して/正しく配置します。
      • このスペースが欠落している(つまり、入力がプレフィックス条件に違反している)場合、次の置換は誤って解釈され、大量のジャンクを出力し、通常///無限ループであるをヒットします。
    • それぞれが正しいコマンドを追加して独自の文字を印刷し␤/、共有部分文字列の最後に元の文字を復元します。
  • これで、文字サブプログラムは共有サブストリングのコピーに到達し、その行を印刷する準備ができました。

最後の文字サブプログラムが実行された後、プログラムの残りは/␤\//xyです。これはfinalが欠落している不完全な置換であるため/、プログラムはそれをスキップして通常どおり停止します。


1
仕事にふさわしい言語!笑
DJMcMayhem

6

ゼリー、14 バイト

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

結果を印刷する完全なプログラム。

オンラインでお試しください!

どうやって?

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

MATL23 19 18バイト

@Sanchisesのおかげで1バイトオフ

fGqoEq1yd~h*YsGZ?c

入力は、単一引用符で囲まれた文字列です。

オンラインでお試しください!あるいは、テストケースを確認します。 1 2 3

説明

'\\\//\/\\'例として入力を検討してください。

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

インデックスを取得するためのわずかに異なるアルゴリズムによる1バイトのオフ:オンラインで試してみてください!
Sanchises

@Sanchises非常に適切な編集をありがとう!
ルイスメンドー

5

C#(.NET Core)74 88 82 78 77 76 + 18バイト

Kevin Cruijssenのおかげで1バイト

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

各行に1つずつ、文字列のコレクションを出力します。バイト数には以下も含まれます。

using System.Linq;

オンラインでお試しください!

77バイトの回答の説明:

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
では機能しません/\\/\\/
ニール

@ニールはそれを指摘してくれてありがとう!一定。
グルゼゴルツプワフスキ

1
私はそれがしばらくしている知っていますが、変更することで、バイトを保存することができますs.Take(i).Sum(y=>y<92?-1:1)+(x-s[0])/45+1(x-s[0])/45-~s.Take(i).Sum(y=>y<92?-1:1)
ケビンCruijssen

@KevinCruijssenいいね!
グルゼ

4

05AB1E、14バイト

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

オンラインでお試しください!

説明

Ç                # 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
では機能しません/\\/\\/
ニール

Ç¥.¥0<.SηOv¹Nèy<ú, バイナリですすり泣く
マジックタコのUr

3

R122 121バイト

ジュゼッペのおかげで-1バイト

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

オンラインでお試しください!

余分な空白がある場合:

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

説明:この回答は、先頭のスペースの数が各行に-1ずつ変化するという観察に基づいており/、前の行と現在の行の数に加えています。

N個のスラッシュがある場合、変数yは長さNのベクトルであり、各位置に1があり\、それ以外の場合は0です。したがって、1行あたりの先頭スペースの数の変化を取得するには、を計算しy[1:(N-1)] + y[2:N] - 1ます。この関数は、diffinvこれらの違いを0から始まるシーケンスに変換します。残りは、各行を必要な数の後続スペースとして組み立て、その後に関連するスラッシュと改行が続くだけです。


1
ハァッ 私は119バイトに対してまったく異なるアプローチを取りましたが、これはアプローチを組み合わせることができるのかと思います。(diffinv;の適切な使用)またy=x>")"、-1バイトに設定できます
ジュゼッペ

@Giuseppe別の回答として投稿する必要があります。これは十分に異なるアプローチです。あなたのやり方は、やらなければならないことを避ける良い方法ですstrsplit。これは常にキラーです。有名なものを利用することもできますdiffinv
user2390246

1
またlibrary(methods)、ヘッダーに入れると(そのパッケージは部分ベースRであるためペナルティーなしで問題ありません)、を使用できますel。また、diffinv同じくらい長いことが判明しましたcumsum!:)
ジュゼッペ

はい、私はあまりにも、それはその文脈ではなく、かなりの作業を行うことを実現しました
user2390246

まあ、私は回避策を思いつきましたが、ええ、それは*S物事を台無しにします。
ジュゼッペ

3

Brain-Flak、175バイト(174文字+ 1フラグ)

-cフラグ付きで実行します。

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

オンラインでお試しください!

説明

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

私は常に頭脳を支持します。:D
DJMcMayhem

3

ルビー80 76バイト

マナトワークのおかげで-4バイト

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

オンラインでお試しください!

説明:

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
どのRubyバージョンですか?2.3.3コードブロックが続く場合、パラメーターの周りに括弧が必要です.each_cons(2){…}。変更では、.each_char→ を置き換えることで保存できます.chars
マナトワーク

@manatwork私のルビーバージョンは2.4.1です。文字についての提案をありがとう、私はそれについて知りませんでした。
Pazzaz

i+=ネストされた3項式の先頭に移動し、で終わることにより、さらに2バイトを保存できます-1:1:0
benj2240

3

Java 8、121 118 110 109 102バイト

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のビット単位の魔法のおかげで、-7バイトになりました。:)

説明:

ここで試してみてください。

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バイト: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ありがとう。ビット単位の操作で短縮できることは知っていましたが、理解できませんでした。私はの効果を試して忘れてしまった主な理由>>/ >>>/ <<...私だけでいくつかのことを確認していた&/ |/ ~/ ^..>>
ケビンCruijssen

3

C(GCC)、137 134 97バイト

オンラインでお試しください!

•3バイトのおかげでATaco

•Digital TraumaおよびThePirateBayのおかげで37バイト

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

文字列を取得してスラッシュを出力する単純な再帰関数だけを考えてみてください。入力は最初にバックスラッシュをエスケープする必要があることに注意してください。

使用法

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

非ゴルフ

これは古い回答用です。更新されたリンクについては、オンラインで試してみてください。

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

出力

ここに画像の説明を入力してください


あなたは置き換えることができc=='\0'!c、同じ効果のために。
アタコ

解決策を更新しただけで、本当に感謝しています!
Asleepace

printf("%*s%c", n, "", c)n個の先行スペースを使用してchar cを印刷できますか?
デジタル外傷

三項式に置き換え(c!=n)c-n再配置することで、数バイト節約できると確信しています。と同じ(c=='/')。また、'/'リテラル数に置き換えることができます47。合計で7バイトだと思います。



3

網膜、47バイト

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

オンラインでお試しください!リンクにはテストケースが含まれます。説明:

^|\\
 $&

各行の先頭と各行の前にスペースを追加します\

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

文字列の最初の2文字を考慮してください。最初の値がaの/場合、インデントを減らす必要があります。これは、キャプチャに先行スペースを含めることで実現されます(最初のステージで追加されたため、常に存在します)。2番目がaである場合、\\インクリメントする必要があります。これは、最初の段階でキャプチャに追加したスペースを含めることで実現されます。2番目の文字に正しいインデントを指定すると、2番目と3番目の文字などについてステージが繰り返されます。

m`^ 

余分なインデントを削除します。

(私の炭の答えのように)スラッシュの任意の組み合わせを許可する94バイトのバージョンを作成しました:オンラインで試してみてください!説明:

.$
¶$.`$* $&

最後のスラッシュを取得し、独自の行の同じ位置にインデントすることにより、ボールを転がします。

/
 /

キャプチャできるように、すべてのスラッシュの前にスペースを付けます。

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

入力の最後のスラッシュを繰り返し取得し、それを下の行のスラッシュと独自の行に揃えます。

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

残っているインデントを削除します。

G`.

空になった入力を削除します。


2

Lua、96バイト

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

オンラインでお試しください!

Luaで思いついた最も短いもの。入力はコマンドラインから取得されます。

これはいくつかのトリックを使用します:

  1. (...):gmatch(
    これは、コマンドラインからLuaプログラムに単一の文字列を取得する最短の形式である必要があります。...Lua の式は、関数宣言で指定されておらず、可変引数に使用される関数への余分なパラメーターをキャプチャします。Luaプログラムの本体は、パラメーターとしてコマンドライン引数を使用して関数として呼び出されるため、コマンドライン引数はになり...ます。
    その周りの括弧は、潜在的に複数値の...式を単一値の式に変えます。次の(多少驚くべき)例について考えてみましょう:
    function multipleReturnValues()
        return "abc", "def"
    end
    print(  multipleReturnValues()  ) --This prints: abc    def
    print( (multipleReturnValues()) ) --This prints: abc
  2. Luaパーサーは、2つのステートメントのトークンを明確に分離でき、有効なLuaコードであるテキストの解釈が1つしかない限り、行末記号やステートメント間の空白さえも必要としません。
  3. 「if x then value1 else value2」ロジックのand/の乱用or
    Luaのand演算子は、偽である場合、最初の引数を返します。それ以外の場合は、2番目の引数を返します。orそれはtruthyであれば、オペレータは、最初の引数を返します。それ以外の場合、2番目の引数。
  4. p初期化は必要ありません。
    p==s入力に関係なく、ループの最初の実行では常にfalseでなければなりません。pループに入る前に値を設定しない(終了するnil)と、ループが発生してバイトも節約されます。

誰でもこれをゴルフできますか(ルアで)?


gmatchを使用する代わりにgsubを使用することで2バイトを節約できました。c=0(...):gsub(".",function(s)c=c+(p==s and(s=="/"and-1or 1)or 0)p=s print((" "):rep(c)..s)end)
QuertyKeyboard

まあ、それは重要ではありません。次の回答で行ったように変更gmatch(".")することで、2バイトを簡単に保存できgmatch"."ます。
QuertyKeyboard

@QuertyKeyboardそれは奇妙です...私は実際にこのコードの最初のバージョンでこれとまったく同じようにgsubを使用しましたが、それがどういうわけか短くなったので代わりにgmatchに切り替えました。私が何を変更したかはわかりませんが、残念ながらファイルは上書きされます。
ジョナサンS.


2

R、119バイト

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

オンラインでお試しください!

これは、user2390246の回答とは多少異なります。これらはそれぞれ、文字列を反復処理し、一定数のスペース文字と適切な/\文字を出力します。

ただし、文字列を分割せず、代わりに文字をUTF-8エンコード値に置き換えることを選択したため、数値を直接計算でき、数バイトしか節約できませんでした。


ちょうど私があなたのアルゴリズムに誤りがあると思い、いくつかのより多くの本を熟考されて:TIO
user2390246

@ user2390246修正しました!かっこが間違っていましたが、今はdiffinv間違いなく動作しません。
ジュゼッペ


2

C#(.NET Core)、60/65バイト

短いC#バージョンを試しました

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

述べられているように:「これはまた、すべての入力がバックスラッシュで始まることを意味します。」または「/」の開始を解決する少し長い

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

オンラインでお試しください!


サイトへようこそ!:)
DJMcMayhem

2

Lua88 84バイト

改善されたバージョン(QuertyKeyboardのおかげで4バイト)

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

オンラインでお試しください!

元のバージョン(88バイト)

Luaでのもう1つの試み。今回は、カウンター変数の代わりに文字列操作を使用したまったく異なるアプローチです。

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

ゴルフをしていない:

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

コードには興味深いことが1つあります。(...):gmatch"."
これは、Luaパーサーでいくつかの癖を使用しています。Luaがフォーム内のコードに遭遇するとfunc "string"、これをに変換しfunc("string")ます。これはprint "string"、定数文字列を出力するために書くことができ、関数の後に単一の文字列リテラルでのみ機能するようにするためです。それ以外のものは構文エラーになります。ただし、この構文シュガーは、式の途中で関数呼び出しを使用しても機能し、さらに驚くべきことに、:メソッド呼び出しのシンタックスシュガーと一緒に機能します。最終的に、Luaは次のようにコードを解釈します。

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

3つのgsub呼び出しのうちの1つを削除する方法を考えている人がいたら教えてください。


1
私はあなたの他の答えでコメントした私のgsubのトリックがこの1つに対してはうまくいかなかったことに失望しました。実際には1バイトが追加されました。しかし、私は簡単にそれをあきらめません。最初に、コードを短縮するためにgsubを変数として保存しようとしました。驚いたことに、私のコードはまったく同じバイト数-88でした。しかし、gsubが保存されると、gsubトリックが機能するようになりました。ここでは4バイト削ら私のコードは次のとおりです。s=""g=s.gsub g(...,".",function(c)s=g(g(g(s,"\\"," "),"/?$",c)," /","/")print(s)end)
QuertyKeyboard

@QuertyKeyboardうん、ループの前にgsubを変数に保存してから、gsubを3回書く代わりにそれを使用してみましたが、まったく違いが見られないことに驚きました。「ループの代わりにgsub」と「store gsub」のトリックを組み合わせるのは本当にすてきです、それは考えていませんでした!ありがとう!:)
ジョナサンS.

1

パイス-33バイト

最初の試みは、ゴルフになります。

jsMC,*L;+ZsM._*VqVtzztMxL"/ \\"zz

こちらからオンラインでお試しください





pingを実行 @maltysen
スタン・ストラム

@StanStrumこの時点で、あなたはあなた自身の答えとしてそれを投稿することができます
マルティセン

1

Perl、40 + 2バイト

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

-Fフラグが必要です。


1

Perl、34 38 + 1バイト

2つのケースを処理する

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

-pオプションで実行する

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

編集:最初の文字が次の場合、次のコメントは機能しません /

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

ただし、最初の文字が次の場合、出力は右に1文字シフトされます \


1
では機能しません/\\/\\/
ニール

更新された質問により、元の34ソリューションは完全に有効になりました
トンホスペル

1

VBA(Excel)、181バイト

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
Excel VBAのオートフォーマットの性質を活用し、[...]表記法を使用することにより、アルゴリズムを変更せずにこれを大幅に減らすことができます。128バイトに減らしました 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
テイラースコット

私の脚本をゴルフしてくれてありがとう。私はこれから何かを学び、将来的に適用されます。:)セルに直接データを取得するためにそれを使用できることを知りませんでした。再びありがとう:)
リモール



弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.