Answers:
j_+t.iJ*R"/ "SQ+L\\J*Q"/\
j_+t.iJ*R"/ "SQ+L\\J*Q"/\ implicit: Q = input number
SQ create the list [1, 2, ..., Q]
*R"/ " repeat "/ " accordingly to this numbers
J assign this list of strings to J
+L\\J create a 2nd list, which contains the same strings
as in J, just with a "\" prepended
.i interleave these two lists
t remove the first element
*Q"/\ repeat the string "/\" Q times
+ append it to the list
_ reverse it
j print each string on a separate line
ri_"/\ /"2/f*)@,\f>+_z..e>N*
我试图帮助Reto打他的CJam答案,但最终得到了一个与他无关的解决方案,所以我认为自己也可以发布它。
这利用了输出的对称性。特别是输出与转置相同的事实。
首先,我们生成第一N+1
行,但没有左边缘:
ri e# Read input and convert to integer N.
_ e# Duplicate.
"/\ /"2/ e# Push an array with two strings: ["/\" " /"]
f* e# Repeat each of the two strings N times. That gives the first two rows.
) e# Detach the second row.
@, e# Pull up the other copy of N and turn into range [0 1 ... N-1].
\f> e# For each element i in that range, discard the first i characters of
e# the second row.
+ e# Add all those lines back to the first row.
现在,我们有了一个表示以下网格的字符串数组:
/\/\/\/\
/ / / /
/ / / /
/ / /
/ / /
的转置如下所示:
/ / /
\/ /
/ / /
\/ /
/ / /
\/ /
/ /
\/
这些一起具有我们需要的所有非空格字符。现在,我们可以利用丹尼斯(Dennis)的rad技巧,通过获取每个对应字符对的最大值,将两个ASCII网格合并为一个。在两个网格不同的所有位置上,一个将有一个空格(或根本没有),而另一个将具有我们要查找的字符。当矢量化操作中的一个列表比另一个更长时,更长的列表中的其他元素将被简单保留,这正是我们要寻找的。在其他情况下,非空格字符将始终是两个字符中的最大值:
_z e# Duplicate the grid and transpose it.
..e> e# For each pair of characters in corresponding positions, pick the maximum.
N* e# Join the lines by linefeed characters.
Uo-U £Y?"\\/"sYv)+" /"pU-Y/2 :"/\\"pU} ·
Uo-U mXYZ{Y?"\\/"sYv)+" /"pU-Y/2 :"/\\"pU} qR
该程序的核心是列出U * 2
项目,将每个项目映射到模式的一行,然后将它们与换行符连接起来:
Uo-U // Build an array of all integers in the range [-U, U).
mXYZ{ // Map each item X and index Y in this array with the following function.
...
} qR // Join the resulting array with newlines.
至于模式本身,这是我将其分解的方式:
/\/\/\/\
\/ / / /
/ / / /
\/ / /
/ / /
\/ /
/ /
\/
如您在这里看到的,这现在演变为三个简单的模式。第一个是最简单的,使用以下代码生成:
Y? ... : // If Y, the current index, is 0,
"/\\"pU // return the pattern "/\" repeated U*2 times.
现在为左半部分。奇数索引应该映射到\/
,甚至映射到,/
因此我们使用以下代码:
"\\/"s // Otherwise, slice the pattern "\/" at
Yv) // if Y is even, 1; otherwise, 0.
这使得右半部分更容易;我们需要做的就是重复 /
几次:
" /"p // Repeat the pattern " /"
U-Y/2 // floor(U - (Y/2)) times.
建议欢迎!
ri_"/\\"*N@,W%{'\'/@" /"*+_N\N}/;;
感谢@NinjaBearMonkey指出额外的内容;
。
虽然这看起来不太优雅,但我尝试了其他一些选择,但最终并没有缩短。
说明:
ri_ Get input, convert to integer, and copy.
"/\\" Pattern for first line.
*N Repeat N times, and add a newline.
@, Rotate N to top, and create [0 .. N-1] sequence.
W% Invert sequence to [N-1 .. 0].
{ Loop over counts, creating two lines for each.
'\ Leading character for first in pair of lines. Rest will be the same
for both lines.
'/ First character for repeated part.
@ Rotate count to top.
" /" Repetitive pattern.
* Replicate it by count.
+ Concatenate with '/.
_ Copy whole thing for use as second in pair of lines.
N\ Put a newline between the pair of lines.
N Add a newline after second line.
}/ End of loop over counts.
;; Created an extra line, get rid of it.
""<>(#<>"
"&/@Normal@SparseArray[{{i_,j_}/;2∣(i+j)&&i+j<2#+3->"/",{i_,j_}/;i~Min~j<2&&2∣i~Max~j->"\\"},{2#,2#}," "])&
可能会打得更远。
当然,这不是最短的,但是拥有Java解决方案很高兴:
String a(int a){String s="";int b=-1,c,e;for(a*=2;++b<a;){for(c=-1;++c<a;)s+=(e=b+c)>a?" ":e%2==0?"/":b==0||c==0?"\\":" ";s+="\n";}return s;}
String a(int a){
String s ="";
int b=-1,c,e;
for (a*=2;++b < a;){
for (c = -1 ; ++c < a ;)
s+= (e=b+c)>a?" ": e%2==0? "/" : b==0||c==0? "\\" : " ";
s+="\n";
}
return s;
}
System.out.println(a(5));
/\/\/\/\/\
\/ / / / /
/ / / / /
\/ / / /
/ / / /
\/ / /
/ / /
\/ /
/ /
\/
n=>{r='';for(i=0;i<n;i++)r+='/\\';for(j=0;j<2*n-1;j++){r+='\n'+(j%2?'':'\\');for(i=n-j/2;i>0;i--)r+='/ '}return r}
去高尔夫(也转换为ES5)+演示:
function c(n) {
r = '';
for (i = 0; i < n; i++) r += '/\\';
for (j = 0; j < 2 * n - 1; j++) {
r += '\n' + (j % 2 ? '' : '\\');
for (i = n - j / 2; i > 0; i--) r += '/ '
}
return r
}
alert(c(prompt()));
->n{s='/\\'*n
n.times{|i|puts s,?\\+s='/ '*(n-i)}}
在测试程序中:
f=->n{s='/\\'*n
n.times{|i|puts s,?\\+s='/ '*(n-i)}}
f[gets.to_i]
循环为从i = 0到i = n-1的每次迭代打印2行。
第二行'\'
之后总是出现ni个'/ '
。
第一行与上一次迭代的第二行相同,但是'\'
缺少(因此,s
当我们打印上一次迭代的第二行时,将存储此值。)
唯一的例外是迭代零,可通过初始化s
为来处理'/\'*n
。
p=>{s=`/\\`.repeat(p++)+`
`;for(i=p;i>2;s+='\\'+o+o)o=`/ `.repeat(--i)+`
`;return s+'\\/'}
首先发布在这里!
曾经使用 但现在使用,类似于Ruby的。Array(len)
.
join(str)
String.repeat(len)
operator*(str,len)
取消高尔夫:
len => {
var str = `/\\`.repeat(len++) + '\n';
for (var i = len, mid; i > 2; str += '\\' + mid + mid) {
mid = `/ `.repeat(--i) + '\n';
}
return str + '\\/';
}
感谢:
107 => 104字节:@insertusername此处
97 => 90字节:@ user81655
p=>{s=Array(++p).join('/\\')+'\n';for(i=p;i>2;i--,s+='\\'+o+o)o=Array(i).join('/ ')+'\n';return s+'\\/'}
。
repeat
方法。
n=input();b=1
print'/\\'*n
while~-n+b:print'\\'*b+'/ '*n;b^=1;n-=b
非常简单。该值n
是行上的数字/
,b
表示行是否以开头\
。alter的值b
在0和1之间交替,n
每隔第二步减小一次。丑陋的终止条件在时停止n=1, b=0
。exec
循环的替代方案将存在需要大量转义的问题"'\\\\'"
。
我惊讶地发现这种方法比使用单个数字更短k=2*n+b
。这是68个字节:
k=2*input()+1
print k/2*"/\\"
while k>2:print k%2*'\\'+k/2*'/ ';k-=1
一种替代策略可以避免print
为顶行单独设置,但我没有找到一种简洁的方法。
我敢肯定这可以打高尔夫球,但是现在是凌晨四点,我需要去睡觉。
n$z"/\"z$D$OlOz[" /"zi-$Dlr$d"\"zi1+-3&5$X$O].
n$z Take number from input (n) and store it in the register (z)
"/\" Push these characters (in reverse)
z$D Push register value and duplicate the whole stack that many times
$O Output whole stack as characters
lO Output newline
z Push n from register
[ Open for loop that repeats n times
" /" Push these characters (in reverse)
zi- n - loop counter
$D Pop k and duplicate whole stack k times
l Push 10 (for newline)
r Reverse stack
$d Duplicate whole stack
"\" Push this character
zi1+- 0 if n = loop counter + 1, truthy otherwise
3& Do the next three characters if top of stack is 0
5$X Dump the bottom-most five items of the stack
$O Output whole stack as characters
]. Close for loop and stop
f=g.(*2)
g m=unlines$t m(c"/\\"):[t n l|(n,l)<-zip[m,m-1..2]$c['\\':p,p]]
p=c"/ "
c=cycle
t=take
与现有的Haskell解决方案相比,这实际上没有竞争力,因为它通过返回而不是打印字符串来节省5个字符。我发布它只是为了展示无限模式方法与基于坐标的方法相比。笔记:
p
可以内联,长度不变。[t n l|(n,l)<-...]
保存2个以上(map(uncurry t)$...)
。String s(Integer n)=>"\n".join{"/\\".repeat(n),for(i in 2*n+1..3)"\\".repeat(i%2)+"/ ".repeat(i/2)};
它具有一个“命名实参列表” join
(没有任何命名实参,而是可迭代的理解),并具有多种用途String.repeat
(其中之一实际上意味着“仅包含奇数i
”)。
格式:
String s(Integer n) =>
"\n".join{
"/\\".repeat(n),
for (i in 2*n + 1 .. 3)
"\\".repeat(i % 2)
+ "/ ".repeat(i / 2)
};
<?$n=$argv[1];$r=str_repeat;echo$r("/\\",$n);for(;$i++<$n*2-1;)echo"\n".($i%2?"\\":'').$r("/ ",$n-floor(($i-1)/2));?>
假设通知已关闭,并且输入来自命令行。
取消高尔夫:
<?php
error_reporting(E_ALL & ~E_NOTICE);
$n = $argv[1];
$r='str_repeat';
echo $r("/\\",$n);
for(;$i++<$n*2-1;){
echo"\n".(($i%2)?"\\":'') . $r("/ ",$n-floor(($i-1)/2));
}
?>
欢迎评论:)
;
s即可。