我有一个ASCII艺术框,需要一个程序来打开它。
例子
输入:
-------
| |
|_____|
输出:
/
/
/
/
/
/
/
| |
|_____|
规格
- 第一行仅包含
-
,其中至少3个 - 中间的行将以
|
空格开头,以|
- 所有中间行将相同
- 最后一行将以
|
have 开头,_
以a结束|
- 所有行的长度将相同
打开盒子:
- 每一个
-
都应由/
升序和位置替换。
我有一个ASCII艺术框,需要一个程序来打开它。
输入:
-------
| |
|_____|
输出:
/
/
/
/
/
/
/
| |
|_____|
-
,其中至少3个|
空格开头,以|
|
have 开头,_
以a结束|
打开盒子:
-
都应由/
升序和位置替换。Answers:
l,{N'/@S*}%W%q
l Read the first line from STDIN.
, Compute the line's length. Result: L
{ }% Map; for each I in [0 ... L-1]:
(implicit) Push I.
N Push a linefeed.
'/ Push a slash.
@ Rotate I on top of the stack.
S* Turn I into a string of I spaces.
W% Reverse the resulting array of strings and characters.
q Read the remaining input from STDIN.
s=>s[r="replace"](/-+/,s=>s[r](/-/g,`
$'/`))[r](/-/g,' ')
输出前导换行符。通过取-
s 的行并将其转换为三角形,然后将-
s 替换为空格来工作。
编辑:由于@ edc65,节省了5个字节。
f=s=>s[R='replace'](/-+/,s=>s[R](/-/g,"\n$'/"))[R](/-/g,' ')
\n
然后再进行转换)。
^w[B!0]{>}w[B!45]{<w[B=10]{t[T+1]b[0]}}v[X]vw[T!0]{vb[124]<[X]b[124]>w[B=0]{>}t[T-1]}w[X!1]{<b[95]}<w[B!0]{^}w[Y!-1]{b[47]>^}
您需要运行此答案的pbi版本比问题新。本来可以在较旧的版本中使用,除非我从来没有允许输入换行符。那好吧。
首先,这通过计算输入中的换行符来确定框的高度。一旦知道了这一点,它就会到达盒子右侧的Y位置,然后下降到需要的位置,然后绘制墙壁和地板,最后盖上盖子。
看看这个有趣的动画!
长时间的停顿是画笔越过输入。
取消高尔夫:
^w[B!0]{>} # Go to the end of the input
w[B!45]{< # Head left until hitting a hyphen
w[B=10]{ # For each newline on the way:
t[T+1] # Count it
b[0] # Delete it
}
}
v[X] # Move down as far as it is right + the number of \n
v # ...plus one
w[T!0]{ # While the counting variable is nonzero:
vb[124] # Go down and draw a pipe
<[X]b[124] # Draw a pipe on the left as well
>w[B=0]{>} # Go back to the right side
t[T-1] # Decrement variable
}
w[X!1]{<b[95]} # Draw the bottom of the box
<w[B!0]{^} # Go up the left wall
w[Y!-1]{b[47]>^} # Go up and right, drawing the lid
j+_m+*;d\/Uz.z
说明
m Uz - [V for d in range(len(input()))]
+*;d\/ - " "*d + "/"
_ - ^[::-1]
j+ .z - "\n".join(^+rest_of_input())
感谢@FryAmTheEggman提供的新算法!
-(?=(-*))¶? $ 1 /¶ --
在第一步中,每个-
变量都用-
其后的,a /
和换行符代替。原始第一行末尾的换行符将被删除。在第二步中,我们将new更改-
为空格,以产生所需的输出。
' /'jnXyPQ)`jt
输入应包含尾随换行符。
' /' % push string (will be indexed into to generate the open lid)
jn % read first line of input and push its length
Xy % identity matrix with that size
P % flip vertically
Q % add 1. Now the matrix contains 1 and 2, to be used as indices
) % index into string. Produces a 2D char array for the lid
` % do-while loop
j % push input line
t % duplicate. Truthy if nonempty
% implicitly end loop. The loop condition is the top of the stack,
% that is, the input line that has just been read.
% This is truthy if non-empty; and in that case another line will
% be read in the next iteration.
% implicitly display stack contents, bottom to top
Ur-@"
{SpUa- -Y}/
输出前导换行符,OP可以接受。
Ur-@ // Replace each hyphen X in the input and its index Y with this function:
" // Start a string that contains a newline.
{ } // Insert here:
Ua- -Y // Take the index of the last hyphen in the input, subtract Y,
Sp // and return that many spaces.
/ // Finish off the string with a slash.
如果允许铰链位于框的右边缘,则该长度将缩短4个字节:
Ur-@"
{SpY}\\
这是我的简短代码:编辑:现在,使用@Dennis的代码编辑可以缩短82个字节!
f=open('f.txt')
d=len(f.readline())-1
a=f.read()
while d:d-=1;print(' '*d+'/')
print(a)
另外,只是为了好玩,您可以使用一种缓慢打开它的方法:
import time
import os
f = open('f.txt', 'r')
e = f.readline()
a = f.read()
d = len(e)
c = 0
t = e + a
g = ''
clear = lambda: os.system('cls')
while c <= d - 1:
clear()
print(("\n" * ((d - 1) - (c))) + t)
c += 1
e1 = e[0:(d - c) -1]
e2 = e[(d - c):len(e)]
e1 += '/'
e2 = ' ' * len(e2)
y = (' ' * len(e1)) + '/' + '\n'
g += y
t = (g + e1 + e2 + '\n' + a)[d:len(g + e1 + e2 + '\n' + a)]
time.sleep(0.2)
f.close()
要使用两者之一,您必须在同一目录中创建一个文本文件,其中包含任意宽度或深度的ascii框,称为“ f.txt”。然后它将打开该框。
(纯Bash版本,不使用任何外部命令。)
r(){
a="${a/-
/
$s/
}"
s+=\
[[ $a = -* ]]&&r
}
mapfile a
r
IFS=
echo "${a[*]}"
输出前导换行符。
样品运行:
bash-4.3$ bash open-the-box.sh <<< $'-------\n| |\n|_____|'
/
/
/
/
/
/
/
| |
|_____|
echo
是外部命令- /usr/bin/echo
;)
echo
可执行文件存在于操作系统的与标准的一致性。如今,仅当可移植性很重要时才使用它,因为它符合标准,但是大多数现代shell都有自己的内置echo
函数,默认情况下会使用它们:pastebin.com/RnxhweBv @Levi,如果您重命名/移动自己的/usr/bin/echo
my代码仍然可以使用。
s^-^" "x(length$')."/\n"^ge&chomp
运行为
perl -ple 's^-^" "x(length${chr 39})."/\n"^ge&chomp' closed_box_file
每个-
在第一行是由一个字符串,它是一些数目的级联的结果代替,
/
和\n
。${chr 39}
评估为perl($'
又名)$POSTMATCH
特殊变量值。最后,chomp摆脱了为最后一个-
字符添加的尾随换行符。
感谢@manatwork节省了7个以上的字符。
奖金 - s^-^" "x$i++."\\\n"^ge&&chop
从右边缘以29 + 3个字符打开框:)。运行为:
gowtham@ubuntu:~$ cat a
----
| |
|__|
gowtham@ubuntu:~$ perl -plE 's^-^" "x$i++."\\\n"^ge&&chop' closed_box_file
\
\
\
\
| |
|__|
-
,所以,我可以打更多的高尔夫球。谢谢!
$.==1
→ $.<2
,&&chop
→ &chop
,删除多余的一对括号length
,将其计{chr 39}
为1,因为由于shell语法的缘故,命令行版本不仅仅需要它:$.<2&&s^-^" "x(length$')."/\n"^ge&chop
+根据我的计数,命令行选项的2个字符= 40。pastebin.com/iDhUs9XX
$.==1
或$.<2
可以删除,因为仅第一行包含-
\n
。
s^-^$'=~y/-/ /r."/\n"^ge&chomp
$d,$b=$args-split"`n";($d.length-1)..0|%{" "*$_+"/"};$b
将输入$args
作为字符串,-split
在换行符s上`n
(参考链接),将第一行存储为$d
(作为字符串),其余存储为$b
(作为字符串数组)。然后,我们从length
第一行的负号(负1)0
循环到,每次迭代输出该数量的空格加a/
。最后,输出$b
(输入字符串的其余部分),默认情况下,每行输出一个。
PS C:\Tools\Scripts\golfing> .\help-me-open-the-box.ps1 "----`n| |`n|__|"
/
/
/
/
| |
|__|
a=>a[b="replace"](/-+/,c=>c[b](d=/-/g,`
$'/`))[b](d,' ')
应该写成的评论@Neil的答案,但我无法创建评论
g'/1.Λ|»»
g'/1.Λ|»» – Full program. Takes input from STDIN.
g - Length. Only takes the first line into account.
'/ – Push a slash character, "/".
1.Λ – And diagonally up-right, draw a line of slashes of the given length.
|» – Push the remaining inputs (all other lines) joined on newlines.
» – Then join the stack on newlines.
↙L§⪪θ¶⁰M→✂⪪θ¶¹
说明:
用换行符分隔输入,获取第一行的长度,并打印从上右至下左的该行:
Print(:DownLeft,Length(AtIndex(Split(q,"\n"),0)))
↙L§⪪θ¶⁰
向右移动一次:
Move(:Right)
M→
再次用换行符分隔输入,并删除第一项,然后隐式打印剩下的内容:
Slice(Split(q,"\n"),1)
✂⪪θ¶¹
(注意:通过换行将输入放入变量中(因为我在上面做了两次),通过使用稍微不同的方法(由于@Neil),长度增加了1个字节,也增加了14个字节:在线(详细)或在线尝试(纯))。
≔⮌⪪θ¶θ↙L⊟θM→⮌θ
需要一个a
带有闭合框的文件,输出到stdout。
for i in $(seq `cat a|awk 'NR==1{print length($1)-1}'` -1 1);{ for j in `seq 1 $i`;{ printf " ";};echo "/";};echo "/";tail -n2 a
It might be possible to make it shorter by using sed
and using stdin and piping.
for i in $(seq `awk 'NR<2&&$0=length-1' a` -1 1);{ for j in `seq 1 $i`;{ printf \ ;};echo /;};echo /;tail -n2 a
$s=$argv[1];$l=strlen(strtok($s,"\n"));for($i=0;$i<$l;$i++)$s=preg_replace("/-/","\n".str_repeat(" ",$l-$i-1)."/",$s,1);echo$s;
Ungolfed version :
$s=$argv[1];
$l=strlen(strtok($s,"\n"));
for($i=0;$i<$l;$i++){
$v="\n".str_repeat(" ",$l-$i-1)."/";
$s=preg_replace("/-/",$v,$s,1);
}
echo $s;
$argv
. There are a couple of minor tricks you could apply: $l=strlen(strtok($s=$argv[1],"↵"));while($l)$s=preg_replace("/-/","↵".str_repeat(" ",--$l-$i)."/",$s,1);echo$s;
(Use a literal newline in your code where is “↵”: pastebin.com/36t2fb0P )