将指数转换为ASCII艺术


28

任务

您的任务是像这样转换字符串:

abc^d+ef^g + hijk^l - M^NO^P (Ag^+)

要这样的字符串:

   d   g       l    N P    +
abc +ef  + hijk  - M O  (Ag )

这是对abc d + ef g + hijk l -M N O P(Ag +)的近似值

换句话说,将字符直接插入到插入符号的上方,抬起一行,一个字符插入一个插入符号。

眼镜

  • 输出中允许多余的尾随空格。
  • 不会提供像这样的链式插入符号m^n^o作为输入。
  • 插入符号不会立即跟随空格或其他插入符号。
  • 尖号之前不会立即有空格。
  • 所有插入符号的前面均应至少包含一个字符,然后至少应包含一个字符。
  • 输入字符串将仅包含可打印的ASCII字符(U + 0020-U + 007E)
  • 代替两行输出,您可以输出两个字符串的数组。

对于那些讲正则表达式的人:输入字符串将与此正则表达式匹配:

/^(?!.*(\^.\^|\^\^|\^ | \^))(?!\^)[ -~]*(?<!\^)$/

排行榜


2
@TimmyD“输入字符串将仅包含可打印的ASCII字符(U + 0020-U + 007E)”
Leaky Nun

3
为什么要停在指数上?我想要处理H_2O的东西!
尼尔

1
@Neil然后提出您自己的挑战,我可以将此挑战作为该挑战的副本来结束。:)
Leaky Nun

1
根据你的榜样我说,他们是superindices,不一定指数
路易斯Mendo

4
那些使用正则表达式的人来自一个高度正规的国家,那里的表达受到严格限制。死亡的主要原因是灾难性的回溯。
戴维·康拉德

Answers:


19

V15 14字节

ÄÒ +òf^xxé kPj

在线尝试!

一个相当简单的解决方案。V 的完美挑战!

说明:

Ä                "Duplicate this current line
 Ò               "Replace this line with spaces
   +             "Move to the beginning of the next line
    ò         ò  "Recursively (The second ò is implicit):
     f^          "  Find a caret
       xx        "  Delete two characters. The second will be saved into the main register
         é       "  Insert a space
           k     "  Move up
            P    "  Paste from the main register
             j   "  Move down

方便地,基于递归的工作方式,此操作将对每个插入符号运行一次。


2
vim是应对这一挑战的完美语言。+1
Downgoat

18

Cheddar,77 72 67字节

l->l.chars.vfuse.replace("^\n"," ").lines.map(j->"%-2s"%j).turn(3)

没有正则表达式!

我喜欢这个答案,因为它很好地证明了切达的能力。主要归功于Conor添加的替换功能。从未开发人员使用PR,因此replace函数仅存在于该分支上(更新:我进行了PR,现在它位于最新的Beta分支上,您可以通过它安装npm install -g cheddar-lang

我找到了打高尔夫球的方法,但是不幸的是,当物品长度不同时,会导致这种疏忽:

["   denifednud   denifednug       denifednul    denifednuN denifednuP    denifednu+ ", "abcdenifednu +efdenifednu  + hijkdenifednu  - Mdenifednu Odenifednu  (Agdenifednu )"]

我可以使用正则表达式节省很多字节,实际上我只是为Cheddar制作了正则表达式...唯一的问题是没有正则表达式函数:/

说明

l->                    // Function take input as `l`
   l.chars             // Get array of chars in input
   .vfuse              // Join with newlines
   .replace("^\n"," ") // Replace `^\n` with a space globally
   .lines              // Get the lines (see below for more details on what this returns)
   .map(j->            // Loop through each "line" `j` is arg
       "%-2s"          // C-like printf format.
                       // think of as: padRight(j, " ", 2)
                       // see below for more details
        % j            // Pass j as the string to insert
   ).turn(3)           // Turn the string 270 degrees (see below)
   .vfuse              // Vertically fuse to get result (this is not needed as we can output an array of the lines)

以获得更好的理解。这就是.lines回报1^2

["1", " 2"]

.turn与旋转这样的:

1
 2

变成:

 2
1

另一个例子将使其更加清晰:

1
 2
2
 2

变成:

 2 2
1 2

为什么要格式化?

%-2s操作非常简单。%指定我们正在开始“格式”,或者此时将在此字符串中插入变量。-表示右击字符串,2为最大长度。默认情况下,它用空格填充。s只是指定它是一个字符串。要查看其功能:

"%-2s" % "a"  == "a "
"%-2s" % " a" == " a"

2
:DI总是支持切达干酪。
DJMcMayhem

@DrGreenEg​​gsandIronMan:D谢谢
Downgoat '16

1
切达干酪有turn串的方法吗?
TuxCrafting '16

6
-1这种语言的名字总是让我饿。

@TùxCräftîñg仅用于2D数组,这就是为什么我使用.lines来获取线的原因。
Downgoat

10

Perl,21 +1 = 22字节

say'';s/\^(.)/♥[A\1↓/

-p标志一起运行。用原始ESC字节(0x1b)和垂直制表符(0x0b)替换。

垂直选项卡是Martin Ender的想法。它节省了两个字节!谢谢。


您是否不需要在开始时将光标向下移动一行,以使指数不与最后一个控制台提示重叠?
Martin Ender

是的,我不确定。我假设要有足够的空间,但这也许有点作弊。(总的来说,我并不以使用光标移动来解决此类问题为荣,但这是我想到的第一件事……)
Lynn

2
我认为这是一个很好的解决方案,但结果在视觉上应与按预期方式打印字符串没有区别。
Martin Ender

1
多么可爱的解决方案
Thomas Weller

7

JavaScript(ES6),56 55字节

s=>[/.(\^(.))?/g,/\^.(())/g].map(r=>s.replace(r,' $2'))

正则表达式当然可以解救。第一个用空格替换所有字符,除非找到了插入符,在这种情况下,它将删除插入符并将字符保留在其后。(保证这些字符存在。)第二个是很明显的一个,用空格替换每个插入号及其后续字符。

编辑:感谢@Lynn节省了1个字节,他设计了一种方法来将替换字符串重用于第二次替换,从而允许替换映射到正则表达式数组上。


2
看起来s=>[/.(\^(.))?/g,/\^.(())/g].map(r=>s.replace(r,' $2'))短了一个字节。
林恩

@Lynn这真是一个绝妙的绝技!
尼尔

7

Python 3中,157个 101 98 85 83 74字节

此解决方案跟踪先前的字符是否为^,然后根据该结果决定是输出到第一行还是第二行。

输出为的数组['firstline', 'secondline']

a=['']*2
l=0
for c in input():x=c=='^';a[l]+=c*x;a[~l]+=' '*x;l=x
print(a)

感谢@LeakyNun,节省了13个 15字节!

感谢@Joffan,节省了7个字节!


1
漂亮的有限状态自动机。
Leaky Nun

将和直接a=['','']连接到and 会更好吗?' 'ca[l]a[~l]
乔芬'16

6

Python 2,73个字节

l=['']*2;p=1
for c in input():b=c!='^';l[p]+=c*b;l[~p]+=' '*b;p=b
print l

没有正则表达式。记住上一个字符是否为^,并根据该字符将当前字符放在顶行或底行中,并在另一个行中插入一个空格。


4

Pyth,17个字节

CcsmX~Z1j;d;cQ\^2

             Q      input string
            c \^    split on '^'
   m                map for sections d:
    X      ;          insert a space at index:
     ~Z1                the old value of Z (initially 0), before setting Z to 1
                      into:
        j;d             the section joined on spaces
  s                 concatenate
 c              2   chop into groups of 2
C                   transpose

返回2个字符串组成的数组。(j建议使用换行符加入他们。)

在线尝试


1
我不禁怀疑您的姓氏如何发音。:D
林恩

4

MATL,18字节

94=t1YSt~&vG*cw~Z)

在线尝试!

94=    % Take input implicitly. Create logical array of the same size that contains
       % true for carets, false otherwise
t      % Push a copy of this array
1YS    % Circularly shift 1 unit to the right. This gives an array that contains true
       % for the elements right after a caret (superindices), and false for the rest 
t~     % Push a copy and negate
&v     % Concatenate vertically. This gives a 2D, 2-row array
G*     % Push the input again, multiply with broadcast. This gives a 2D array in
       % which the first row contains the superindices (characters after a caret)
       % and 0 for the rest; and the second row contains the non-superindices and
       % 0 for the superindices
c      % Convert to char
w      % Swap. Brings to top the array containing true for carets and false otherwise
~      % Negate
Z)     % Use as logical index to remove rows that contain carets. Display implicitly

4

Ruby,47 + 1(-n标志)= 48个字节

puts$_.gsub(/\^(.)|./){$1||" "},gsub(/\^./," ")

像这样运行它: ruby -ne 'puts$_.gsub(/\^(.)|./){$1||" "},gsub(/\^./," ")'


我认为您可以使用$_=$_.gsub(/\^(.)|./){$1||" "}+gsub(/\^./," ")-p代替保存1个字节-n
唐·黑斯廷斯

1
@DomHastings不管它是否工作,您的代码似乎都没有换行符,并且添加+$/意味着它不会保存字节。参数之间存在puts时,会自动为您抛出换行符,
价值墨水

哦...我测试过使用,ruby -p ... <<< 'input'但我同意,如果它缺少换行符,那就不好了!实际上,我可能早些时候在测试中附加了换行符……尽管它在起作用,所以我无法检查!
Dom Hastings

@DomHastings再次查看它,我想这是因为gets大多数时候都包含尾随换行符,但是如果您通过管道传输不包含尾随换行符的文件,那么它将不会出现并且输出将是错误的。使用ruby -p ... inputfileRuby来将代码重定向gets到文件(如果是命令行参数),因此可以测试您的代码。
价值墨水

知道了,这是很有意义的。我猜该文件中的尾随换行符也可以解决此问题。无论如何我都不是一个熟练的Rubyist,所以我觉得我今天已经学到了一些东西。谢谢!
Dom Hastings

3

Python(2),76 68 67字节

-5字节感谢@LeakyNun

-3字节感谢@ KevinLau-notKenny

-1字节感谢@ValueInk

-0个字节,感谢@DrGreenEg​​gsandIronMan

import re
lambda i,s=re.sub:[s("(?<!\^).\^?"," ",i),s("\^."," ",i)]

此匿名Lambda函数将输入字符串作为唯一参数,并返回由换行符分隔的两条输出行。要为其命名,请在其前面加上“ f =“为其命名。

相当简单的正则表达式:第一部分用空格替换以下内容:任何字符和胡萝卜尖号或仅一个字符,但前提是前面没有尖号。第二部分用空格替换字符串中的所有插入符号和字符。


@LeakyNun:我出于某种原因想知道是否1.如果我导入库也成立。当我看到您的评论时,正在将2.复制到此问题中。感谢您和凯文!
KarlKastor '16

您可以使用from re import*
DJMcMayhem删除

@DrGreenEg​​gsandIronMan这似乎使用完全相同的字节数。(参见上文)
KarlKastor '16

保留旧的import语句并lambda i,s=re.sub:[s("(?<!\^).\^?"," ",i),s("\^."," ",i)]为-1字节做
Value Ink


2

视网膜,16字节

S`^
\^(.)
♥[A$1↓

Martin Ender指出了我的Perl答案的一部分。替换为原始ESC字节(0x1b)和垂直标签(0x0b)。


2

shell + TeX + catdvi,51个 43字节

tex '\empty$'$1'$\end'>n;catdvi *i|head -n2

用于tex排版一些精美的数学,然后用于catdvi进行文本表示。head命令可删除原本存在的垃圾(页面编号,结尾换行符)。

编辑:/dev/null当您可以忽略副作用并写入单个字母文件时,为什么要进行冗长,适当的操作并重定向到?


输入: abc^d+ef^g + hijk^l - M^NO^P (Ag^+)

TeX输出(裁剪为等式): “美丽的”数学! 最终输出:

   d   g     l  N P   +
abc +ef +hijk -M O (Ag )

假设:从空目录开始(或者特别是没有名字以“ i”结尾的目录)。输入是shell脚本的单个参数。输入的内容不是空字符串。

有人告诉我这是否是违反规则的行为,尤其是catdvi


2

Haskell,74 56 55字节

g('^':c:r)=(c,' '):g r
g(c:r)=(' ',c):g r
g x=x
unzip.g

返回一对字符串。用法示例:unzip.g $ "abc^d+e:qf^g + hijk^l - M^NO^P: (Ag^+)"->(" d g l N P + ","abc +e:qf + hijk - M O : (Ag )")

g创建一个成对的列表,其中第一个元素是上一行的char,第二个元素是下一行的char。unzip将其变成一对列表。

编辑:@xnor建议unzip节省18个字节。@Laikoni发现还有一个字节要保存。谢谢!


你可以j=unzip.g吗?
xnor

@xnor:哦,我真愚蠢,没看到自己!非常感谢!
nimi

您可以替换g[]=[]使用g x=x,以节省一个字节。
Laikoni'8

@Laikoni:很好发现!谢谢!
nimi

1

Perl,35个字节

34个字节的代码+ 1个 -p

$_=s/\^(.)|./$1||$"/ger.s/\^./ /gr

用法

perl -pe '$_=s/\^(.)|./$1||$"/ger.s/\^./ /gr' <<< 'abc^d+ef^g + hijk^l - M^NO^P (Ag^+)'
   d   g       l    N P    + 
abc +ef  + hijk  - M O  (Ag )

注意:这与我随后发现的Value Ink的答案完全相同。如果需要的话将删除,因为这实际上并没有添加到Ruby解决方案中。


1

爪哇8拉姆达,132个 128 112字符

i->{String[]r={"",""};for(char j=0,c;j<i.length();j++){c=i[j];r[0]+=c==94?i[++j]:32;r[1]+=c==94?32:c;}return r;}

非高尔夫版本如下所示:

public class Q86647 {

    static String[] printExponents(char[] input) {
        String[] result = {"",""};
        for (char j = 0, c; j < input.length(); j++) {
            c = input[j];
            result[0] += c == 94 ? input[++j] : 32;
            result[1] += c == 94 ? 32 : c;
        }
        return result;
    }
}

输出为数组,只需检查是否有插入号,如果是,则将下一个字符放在上一行,否则将有一个空格。


更新

用其ascii值替换字符以保存4个字符。

感谢@LeakyLun指出使用char数组作为输入。

也感谢@KevinCruijssen将切换到intchar以节省更多字符。


您可以尝试输入char[]并使用它for(char c:i)来查看是否可以减少字节数。
Leaky Nun

您可以通过使用高尔夫球下来了一点,以110个字节:i->{String[]r={"",""};for(char j=0,c;j<i.length;j++){c=i[j];r[0]+=c==94?i[++j]:32;r[1]+=c==94?32:c;}return r;}"abc^d+ef^g + hijk^l - M^NO^P (Ag^+)".toCharArray()作为输入。(这些变化Ideone。
凯文Cruijssen

1

椰子122114 96字节

编辑:在Leaky Nun的帮助下,向下压缩了8 26字节。

def e(s,l)=''==l and s or"^"==l[0]and l[1]+e(s+' ',l[2:])or' '+e(s+l[0],l[1:])
f=print..e$('\n')

因此,正如我今天学到Python有一个三元条件运算符,或事实上他们两个:<true_expr> if <condition> else <false_expr><condition> and <true_expr> or <false_expr>去年一个具有一个char少来了。
可以使用python 兼容版本。


第一次尝试:

def e(s,l):
 case l:
  match['^',c]+r:return c+e(s+' ',r)
  match[c]+r:return' '+e(s+c,r)
 else:return s
f=print..e$('\n')

致电f("abc^d+ef^g + hijk^l - M^NO^P (Ag^+)")打印

   d   g       l    N P    +
abc +ef  + hijk  - M O  (Ag )

有人尝试过打椰子吗?它使python具有更多功能性的编程概念,例如上面使用的模式匹配和功能串联(带有..)。因为这是我第一次尝试椰子,所以任何提示都将不胜感激。

绝对可以缩短此时间,因为任何有效的python代码也是有效的椰子,并且发布了较短的python答案,但是我试图找到一种纯粹的功能解决方案。


我认为您可以使用三元运算符(x and y or z)代替case
Leaky Nun

你甚至可以使用s[0]=="^"代替match['^',c]+r in l
漏嫩

@LeakyNun当我更换match['^',c]+r使用s[0]=="^",然后cr不再约束。这将有什么帮助?
Laikoni'7

您可以使用s[1]replace cs[2:]replace r
Leaky Nun

那么您现在就可以使用三元了。
Leaky Nun

0

Dyalog APL,34个字节

{(0 1=⊂b/¯1⌽b){⍺\⍺/⍵}¨⊂⍵/⍨b←⍵≠'∧'}

它返回包含两行的两元素向量

样品运行(前面的向上箭头用于格式化供人类食用的两元向量):

      ↑{(0 1=⊂b/¯1⌽b){⍺\⍺/⍵}¨⊂⍵/⍨b←⍵≠'∧'}'abc∧d+ef∧g + hijk∧l - M∧NO∧P (Ag∧+)'
   d   g       l    N P    + 
abc +ef  + hijk  - M O  (Ag )

就您对我的代码无所作为的问题发表评论:是的,您认为该代码很重要。
haykam

0

PowerShell v2 +,88 83字节

-join([char[]]$args[0]|%{if($c){$_;$b+=' '}elseif($_-94){$b+=$_;' '}$c=$_-eq94});$b

比其他版本略长,但是展示了一些PowerShell魔术和一些不同的逻辑。

本质上与Python回答的概念相同-我们逐个字符地迭代输入的字符,记住前一个字符是否是插入号($c),然后将当前字符放入适当的位置。但是,用于确定输出到何处的逻辑和方法稍有不同,并且没有元组或单独的变量-我们测试前一个字符是否为插入符号,如果是,则将其输出到管道并在其上连接一个空格$b。否则,我们检查当前字符是否为插入符号elseif($_-94),只要不是,我们就将当前字符连接到其上$b并向管道输出一个空格。最后,我们设置当前角色是否是下一个回合的插入符号。

我们将这些字符从管道中收集到一起,并用括号括起来-join,将其转换为字符串,然后将其保留$b在管道中。最后的输出是隐式的,中间有换行符。

为了进行比较,这是@xnor的Python answer的直接端口,为85个字节

$a=,''*2;[char[]]$args[($l=0)]|%{$a[!$l]+="$_"*($c=$_-ne94);$a[$l]+=' '*$c;$l=!$c};$a

0

Gema,42个 41个字符

\^?=?@set{s;$s }
?=\ @append{s;?}
\Z=\n$s

Gema将输入作为流处理,因此您必须一次性解决它:第一行在处理后立即写入,第二行收集在变量$ s中,然后在最后输出。

样品运行:

bash-4.3$ gema '\^?=?@set{s;$s };?=\ @append{s;?};\Z=\n$s' <<< 'abc^d+ef^g + hijk^l - M^NO^P (Ag^+)'
   d   g       l    N P    +  
abc +ef  + hijk  - M O  (Ag )

0

肉桂胶,21个字节

0000000: 5306 6533 bd92 d1db 8899 8381 a2f8 8f8c  S.e3............
0000010: 1230 249e a1                             .0$..

不竞争。在线尝试。

说明

我不是正则表达式高尔夫球手,所以可能有更好的方法来做到这一点。

字符串解压缩为:

S(?<!\^)[^^]& &\^&`S\^.& 

(注意尾随空格)

第一S阶段接收输入,并在后面使用否定的后缀来替换除尖号之外的所有其他字符,且前面没有尖号,并用空格替换,然后删除所有尖号。然后,它立即输出带有换行符的修改后的输入字符串,并删除该S阶段。由于STDIN现在已经用尽,并且上一阶段未提供任何输入,因此下一S阶段再次接收STDIN的最后一行,然后将所有插入符号替换为空格,然后输出任何字符。

在Perl伪代码中:

$first_stage_sub_1 = ($input =~ s/(?<!\^)[^^]/ /gr);
$first_stage_sub_2 = ($first_stage_sub_1 =~ s/\^//gr);
print $first_stage_sub_2, "\n";

$second_stage_sub = ($input =~ s/\^./ /gr);
print $second_stage_sub, "\n";

0

J28 27字节

0|:t#]{."0~_1-_1|.t=.'^'~:]

在线尝试!

                  t=.'^'~:]    0 for ^, 1 for the rest, define t
              _1|.             Shift right, now zeroes are for superscripts         
     ]{."0~_1-                 Prepend that many spaces to each character
   t#                          Remove the rows with carets
0|:                            Transpose

肯定有更好的办法...

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.