画我的斜线


60

作为程序员,您可能听说过正斜杠和反斜杠。但是您听说过减斜线吗?那是当您采取一堆斜线,连接它们的末端并使其下降时。

对于今天的挑战,您必须编写一个程序或函数,该程序或函数采用一个纯粹由斜杠组成的字符串,并输出在连接它们的直线中向下绘制的所有斜杠。如果您看到一个示例,这将更加清楚。给定字符串\\\//\/\\,您应该输出:

\
 \
  \
  /
 /
 \
 /
 \
  \

以下是一些说明:

  • 每行必须有一个斜线。

  • 第一行将有0个前导空格。

  • 对于每对斜杠:

    • 如果它们彼此不同,则将它们绘制在同一列中。例如,\/将给出:

      \
      /
      
    • 如果它们是相同字符,则下一个字符指向的方向,即向右移动一个反斜杠,向左移动一个正斜杠。所以\\//会给

      \
       \
       /
      /
      
  • 每行可能会有多余的尾随空白,只要这不会改变输出的视觉外观。最多也可以使用一个尾随且领先的换行符。不允许有多余的前导空格!

为了简化操作,您可以假设该字符串永远不会包含太多的正斜杠。换句话说,输入的前缀不会包含比反斜杠更多的正斜杠,因此永远不会给出类似\\////或的输入//。这也意味着每个输入都将以反斜杠开头。

如果将输入作为字符串文字使用,则必要时可以转义反斜杠。您也将永远不需要处理空的输入或包含除斜杠以外的字符的输入。

您可以采用任何合理的格式输出。

像往常一样,这是一个挑战挑战,因此即使您选择的语言很难,也请尝试提供最短的解决方案。奖励积分,用于解释您曾经剥夺字节数的任何有趣技术!

例子

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

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

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

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


#Input
\/\/\/

#Output
\
/
\
/
\
/

9
反斜杠导致令人讨厌的大量转义……
全人类,2013年

Answers:


20

GNU Sed,20岁

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

请注意,^L^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码,仅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%|||CBA
  • 此后,当前程序变为

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

输入重新编码

下一阶段将附加的输入字符串转换为更可用的形式。由于它完全由///的两个命令字符组成,因此要格外小心,以避免损坏基础程序。

  • 第一个实质性替代,/\/\\/\/BA\\/取代了串/\/BA\
    • 基本程序此时不包含/\,因此此替换不会影响它。
    • 但是,这会将附加的输入字符串分成\s 序列和s序列,再/ABA基础程序末尾的s 序列一起使用,可以通过以下替换对其进行迭代。
    • 包括ABA前面的前缀在内,示例输入字符串现在变为ABA\\/BA\//
  • 下一个替换/BA\\/BAbBA/替换BA\BAbBA
    • 因为重复///直到替换不再匹配为止\,所以它将遍历输入字符串的所有s,其前缀现在变为ABAbBAbBA/BAbBA//
  • 同样,/B\A\//BAfBA/改变BA/BAfBA通过迭代/秒。
    • 逃逸\是必要的,这种替代,否则它就会由前一个被截断。
    • 输入现已变为ABAbBAbBAfBABAbBAfBAfBA
  • 接下来,/AB//删除一些多余的编码部分,将其变成AbBAbBAfBAbBAfBAfBA
    • 这也将在程序的后面AB/|/AB\\/替换中删除一个,这是保护它免受上述/\操作所需要的。
    • 此时\,原始输入字符串中的AbB每个字符串都已变为,并且每个字符串/都已变为AfB。(bf代表前进和后退。)A结尾处有一个流浪。
  • 接下来的两个替换将所有As和Bs 替换为要在最后阶段运行的程序片段。在替换字符串中,%s和|s分别编码将变成/s和\s的内容。这有两个好处:
    • /和不同\%s和|s不需要转义即可复制。
    • 替换字符串应避免包含子字符串/\,否则该子字符串会被先前的操作所破坏。
  • 此后,替换/|/\\/(以前称为/|/AB\\/)现在对|s进行解码,此后,后面的内容/%/|//变为/%/\//并对%s进行解码。

最后阶段的计划结构

此时,基本程序已经运行了所有替换项,剩下的只是输入字符串的程序编码。

  • 每个输入字符已成为一个子程序

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

    (换行符),其中,*表示要么f为原始/,或b为原始\

  • /␤\//xy在程序的末尾还有一个不完整的替换命令,该命令将不起作用,除非/为替换先前的子程序提供了必要的命令。

共享子串

在子程序的最终迭代开始之前,在形式的每个字符的子程序之后都有一个跨越边界的子字符串\/␤/

  • 这些子字符串用作共享的全局状态。程序中所有剩余的替换将相同且并行地操作它们,以便在每个输入字符的子程序末尾,该共享子字符串的副本(除final之外/,它将锚定替换)将运行以打印该行字符。
  • 子字符串的初始版本表示打印包含just的行/,该行是正确的假想“上一行”,以​​使第一个输入字符打印在其行的开头。
  • 通常,在打印步骤中,共享子字符串由多个空格\\\/,换行符和跟随符组成/

运行一个字符子程序

以下几种替换\在内部包含多余的,以防止它们彼此匹配和修饰(包括其他子程序中的其他副本)。实现这一点也是同时需要x和的原因y

  • 在字符子程序第一取代,/␤\//xyf\z/或者/␤\//xyb\z/,使␤/在共享子串的端部成为xyfzxybz,紧随\/\\
  • 取代/\\\\x\y/ /替换\\xy一个空格,以及替代/\\\/x\y//取代\/xy的什么都没有。
    • 当打印的先前输入字符分别为a \或时/,它们将适用。
    • 共享子字符串现在包含适当数量的空格,用于打印\下一个空格,后跟fzbz
  • 取代/ \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: ['\  ';
                 ' \ ';
                 '  \';
                 '  /';
                 ' / ';
                 ' \ ';
                 ' / ';
                 ' \ ';
                 '  \']

通过稍微不同的算法减去一个字节即可获取索引:在线尝试!
Sanchises

@Sanchises感谢您的适当修改!
路易斯·门多

5

C#(.NET Core)74 88 82 78 77 76 + 18字节

-1字节感谢Kevin Cruijssen

s=>s.Select((x,i)=>$"{x}".PadLeft((x-s[0])/45-~s.Take(i).Sum(y=>y<92?-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
不适用于/\\/\\/
尼尔

@Neil感谢您指出!固定。
GrzegorzPuławski17年

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)
Kevin Cruijssen,

好一个@KevinCruijssen!
GrzegorzPuławski,18年

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<ú, 抽泣二进制
魔术章鱼缸

3

[R 122个 121字节

-1个字节,感谢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="")

在线尝试!

带有额外的空格:

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。因此,为了获得每行前导空格数的变化,我们计算y[1:(N-1)] + y[2:N] - 1。该函数diffinv将这些差异转换为以0开头的序列。其余的只是将每一行组装为所需的尾随空格数,然后是相关的斜杠和换行符。


1
嗯 我对119个字节采用了一种完全不同的方法,这使我想知道是否可以组合使用我们的方法。(很好的使用diffinv;)您也可以设置y=x>")"-1个字节
Giuseppe

@Giuseppe您应该将其发布为单独的答案,这是一种足够不同的方法。您的方法是避免做某事的好方法strsplit,它始终是杀手er。您还可以利用著名diffinv
user2390246

1
我也认为,如果您放入library(methods)标题(由于该软件包是基于R的部分,应该没有罚金),您可以使用el。而且,diffinv竟然只要cumsum!:)
Giuseppe

是的,我也意识到了这一点,在这种情况下还
行不通

好吧,我想出了一种解决方法,但是,是的,这*S搞砸了。
Giuseppe

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字节归功于manatwork

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 17/09/14

@manatwork我的红宝石版本是2.4.1。感谢您对字符的建议,我不知道那个。
Pazzaz

您可以通过移动i+=到嵌套三元表达式的开头并以结束来节省另外两个字节-1:1:0
benj2240 '18

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

•37字节归功于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);}}

仅仅是一个简单的递归函数就可以了,该函数需要一个字符串并打印出斜杠,请注意,输入必须先转义反斜杠。

用法

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了同样的效果。
ATaco

太感谢了,刚刚更新了解决方案!
Asleepace

您可以使用printf("%*s%c", n, "", c)n个前导空格打印字符吗?
Digital Trauma

我敢肯定,你可以通过更换节省几个字节,(c!=n)c-n和清理三元表达式。与相同(c=='/')。另外,您可以'/'用文字数字代替47。我认为总共是7个字节。



3

视网膜,47字节

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

在线尝试!链接包括测试用例。说明:

^|\\
 $&

在每行的开头和每行之前添加一个空格\

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

考虑字符串的前两个字符。如果第一个是a,/则需要减少缩进量;这是通过在捕获中包括前面的空间来实现的(该空间一直存在,因为第一级添加了它);如果第二个是a,\\那么它需要增加;这是通过在捕获中包括第一阶段添加的空间来实现的。给第二个字符正确的缩进量后,对第二个和第三个字符等重复该步骤。

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中的表达式捕获函数声明中未指定的函数的任何多余参数,并用于varargs。由于Lua程序的主体是使用命令行参数作为其参数的函数调用的,因此命令行参数将以结尾...
    它周围的括号将潜在的多值...表达式转换为单值表达式。考虑以下示例(有点令人惊讶):
    function multipleReturnValues()
        return "abc", "def"
    end
    print(  multipleReturnValues()  ) --This prints: abc    def
    print( (multipleReturnValues()) ) --This prints: abc
  2. Lua解析器不需要任何行终止符,甚至不需要语句之间的空格,只要可以清楚地分隔两个语句的标记并且对有效Lua代码的文本只有一种解释即可。
  3. 滥用and/ or表示“如果x则为value1,否则为value2”逻辑。
    如果Lua的and运算符错误,则返回其第一个参数;否则,返回第二个参数。如果or运算符为真,则运算符返回其第一个参数。否则,第二个参数。
  4. p不需要任何初始化。
    p==s无论输入如何,在循环的第一次运行中始终必须为false。p在进入循环之前不设置任何值(保留nil)将使这种情况发生并节省字节。

有人可以在卢阿(Lua)打高尔夫球吗?


我能够通过使用gsub而不是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

好吧,那并不重要。通过更改gmatch(".")gmatch"."下一个答案中的操作,您可以轻松保存两个字节。
QuertyKeyboard

@QuertyKeyboard太奇怪了……在此代码的第一个版本中,我实际上确实像这样使用gsub,但是后来改用gmatch了,因为它以某种方式变短了。我不知道我做了什么不同,不幸的是文件被覆盖了。
Jonathan 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编码值,然后允许我直接对数字进行算术,这仅节省了几个字节。


只是
想了一下

@ 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的另一种尝试,这一次是使用完全不同的方法使用字符串操作而不是计数器变量。

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

代码中有一件有趣的事情:(...):gmatch"."
这在Lua解析器中使用了一些怪癖。当Lua遇到形式的代码时func "string",它将转换为func("string")。这样就可以写出print "string"一个常量字符串,并且只能在该函数之后使用单个字符串文字。其他任何内容都会产生语法错误。但是,这种语法糖也可以与表达式中间的函数调用一起使用,更令人惊讶的是,它与:方法语法糖一起可以很好地工作。所以最后,Lua将解释如下代码:

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

如果有人能想到删除三个gsub调用之一的方法,请告诉我。


1
我很失望地发现我在您的其他答案中评论的gsub技巧不适用于此答案。它实际上最终增加了一个字节。但是,我不会轻易放弃。首先,我尝试将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三次,而我惊讶地发现它完全没有区别。结合使用“ gsub而不是循环”和“存储gsub”这两种技巧确实很巧妙,没想到这一点!谢谢!:)
乔纳森·


1

Perl,40 + 2字节

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

您需要-F标志。


1

Perl,34 38 +1字节

处理这两种情况

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

-p选项一起运行

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

编辑:当第一个字符是时,以下注释不起作用 /

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

但是,如果第一个字符为,则输出将向右移一个字符 \


1
不适用于/\\/\\/
尼尔于2009年

有了更新的问题,您的原始34解决方案现在完全有效
Ton Hospel

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
Taylor Scott 2009年

感谢您打高尔夫球。我从中学到了一些知识,并将在将来应用。:)不知道我可以用它直接将数据获取到单元格中。再次感谢:)
取消



By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.