Это было обсуждалось лет назад (и некоторые имена в этом потоке могут показаться немного знакомыми :-)), но я не знаю о существующей реализации. Я не думаю, что я бы попытался адаптировать std :: string к задаче. Точные требования к типу, по которым std :: basic_string не очень хорошо сформулированы, но стандарт довольно ясен, что он предназначен только для чего-то, что во многом похоже на char
. Для типов, которые существенно различаются, это может все еще работать, но трудно сказать, что произойдет - это никогда не предназначалось и, вероятно, не было проверено со многими типами, кроме маленьких целых чисел.
Когда вы приступите к этому, реализация std::vector
с нуля (даже с небольшой векторной оптимизацией) не будет ужасно сложной.
Все пробелы значимы! Если вы случайно добавите новую строку в конец, в конце вывода будет дополнительный _
~):@,{@\:&-:0' ': *& '/':/+*'\\':~'_':
0*.'|':|\/~ +&*n}%
/+@* ~
+@*n ~+@*
@/ +*n@,{):& *@&-:( ~+*/[
](!=&*.|\~/ +(*n}%
Golfscript - 129 символов
~):@,{@\:&-:0' ': *&' /'*'\\':~'_':
0*.'|'\'/'~ +&*n}%'_/'@* '\_'@*n ~+@*
@'/ '*n@,{):& *@&-:( ~+*'/'[
](!=&*.'|'\~'/ '(*n}%
Golfscript - 133 символа
~):@,{@\:&-:0' ': *&' /'*'\\':~'_':
0*.'|'\'/'~ +&*n}%'_/'@*3 *'\_'@*n' \\'@*3
*@'/ '*n@,{):& *@&-:( ~+*'/''_ '1/(!=&*.'|'\~'/ '(*n}%
n=input()+1;b,f,p,u,s='\/|_ '
a=[s*(n-i)+' /'*i+b+u*(n-i)+p+u*(n-i)+f+'\ '*i+s*(n-i)for
i in range(n)]
print"\n".join(a+['_/'*n+s*3+'\_'*n,' \\'*n+u*3+'/ '*n]+[x[::-1]for
x in a[:0:-1]]+[a[0][::-1].replace(u,s)])
Microsoft Word сообщает 442 символа без пробела
Возможно, можно уменьшить это больше, но это мое последнее обновление ( попробуйте # 2 )
Module z
Sub Main()
Dim i = CInt(Console.ReadLine), j = i + 1, h = j * 2 + 1, w = h * 2, z = "_", b = " "
For y = 0 To h
For x = 0 To w
Dim l = (x + y Mod 2 + i Mod 2) Mod 2, u = j + y, e = j - y, k = h + e, o = x = h Or x = h - 1
Console.Write(If(x = h, If(y = j, b, If(y = j + 1, z, "|")), "") & If(x = w, vbLf, If(y = j, If(x Mod 2 = 0 = (x < h), If(o, b, z), If(x < h, "/", "\")), If(x < k And x > u Or (x < u And x > k Or o) And y < h, z, If(x = k Or (x < u And y < j And x > e Or x > u And y > j And x < w + e) And l = 0, "/", If(x = u Or (x > k And y < j And x < h + u Or x < k And y > j And x > y - j - 1) And l = 1, "\", b))))))
Next
Next
End Sub
End Module
Запускать с ruby -n
n=$_.to_i+1
u,s,c=%w{_ \ \ \\}
z=(1..n).map{|i|k=n-i
s*i+c*k+'/'+u*i+'|'+u*i+"\\"+'/ '*k+s*i}
y=z.reverse.map{|a|a.reverse}
z[-1].tr!u,s
puts y,'_/'*n+s*3+'\_'*n,c*n+u*3+'/ '*n,z
В первой попытке ниже показалось хорошей идеей просто сгенерировать один квадрант (Я выбрал нижний левый), а затем дважды отразить, чтобы получить всю сеть. Но gnibbler получил лучшие результаты, генерируя оба квадранта (верхней половины) и затем генерируя, а не исправляя внутреннюю область. Поэтому я пересмотрел свой, чтобы изначально создать и другой нижний квадрант, зеркало только один раз, а также оставить самый внутренний ряд вне зеркала, который как бы сходится с другой записью.
n=$_.to_i+1
m=2*n+1
u,s,b,f=%w{_ \ \\ /}
z=(0..n).map{|i|s*i+(s+b)*(n-i)+(i==0?u:f)+u*i}
q=z.reverse.map{|a|a.tr f+b,b+b+f}
q[n].gsub!' ','_'
q[n][m-1]=s
z=(q+z).map{|a|a+'|'+a.reverse.tr(f+b,b+b+f)}
z[n][m]=z[n+1][m]=s
z[m].gsub!u,s
puts z
Думаю, все еще есть возможности для улучшения.
s=input()+1
f,b="/ ","\\"
r=range(s)
for i in r:w="_"*(s-i);print" "*(s+(i>=1)-i)+(f*i)[:-1]+b+w+"|"+w+"/"+"\ "*i
print"_/"*s+" "*3+"\_"*s+"\n"+" \\"*s+"_"*3+f*s
for i in r[::-1]:u="_ "[i<1]*(s-i);print" "*(s-i+(i>=1))+("\ "*i)[:-1]+"/"+u+"|"+u+b+f*i
-
s=input()+1;r=range(s);c="/","\\";y="/ ","\\ "
def o(i,r):u="_ "[i<1 and r]*(s-i);print" "*(s+(i>=1)-i)+(y[r]*i)[:-1]+c[r<1]+u+"|"+u+c[r]+(y[r<1]*i)[:-1]
for i in r:o(i,0)
print"_/"*s+" "*3+"\_"*s+"\n"+" \\"*s+"_"*3+"/ "*s
for i in r[::-1]:o(i,1)
n=gets.to_i+1;s=' '
a=0.upto(n-1).map{|i|s*(j=n-i)+' /'*i+?\\+?_*j+'|'+?_*j+?/+'\ '*i+s*j}
d=a.reverse.map{|x|x.reverse};d[-1].tr!?_,s
puts a,'_/'*n+s*3+'\_'*n,' \\'*n+?_*3+'/ '*n,d
Ruby1.8 - 185 символов
Некоторые улучшения от JRL
n=gets.to_i+1;s=' '
u='_';a=0.upto(n-1).map{|i|s*(j=n-i)+' /'*i+'\\'+u*j+'|'+u*j+'/'+'\ '*i+s*j}
d=a.reverse.map{|x|x.reverse}
d[-1].tr!u,s;puts a,'_/'*n+s*3+'\_'*n,' \\'*n+u*3+'/ '*n,d
Ruby - 207 символов
Ruby, кажется, имеет некоторые особенности правила о "\"
n=eval(gets)+1
b,f,p,u,s='\/|_ '.split""
a=0.upto(n-1).map{|i|s*(j=n-i)+' /'*i+b+u*j+"|"+u*j+f+"\\ "*i+s*j}
puts a,'_/'*n+s*3+'\_'*n,' \\'*n+u*3+'/ '*n,a[1..-1].reverse.map{
|x|x.reverse},a[0].reverse.tr(u,s)
195 184 171 167 164
print@o=((map{$z=_ x($x=1+$N-$_);$"x$x." /"x$_."\\$z|$z/".'\ 'x$_.$/}0..($N=<>)),
"_/"x++$N." ".'\_'x$N.$/);
y'/\\'\/',@o||y#_# #,$t++||y#_ # _#,print while$_=pop@o
Первый оператор выводит верх половина паутины. Второй оператор использует операции транслитерации для создания отражения верхней половины.
Следующий весит ближе к 314 символам (продуктивного кода), но больше соответствует духу сезона.
; "
Tr Ic
K| |t
Re aT
", "H
av e
A: -
)H AL LO W
ee N" ," En
jo y_ Yo ur
_ C&& y"; ##
&I (); $N= 1+
<>; $,= $/;@O =(( map
$" x($ X=$N-$_). ${ f}x$_.$
B.${U}x$X.$P.${U}x$X.$
F.${b}x$_,0..$N-1),${g}x$N.(${S}
x3).${c}x$N);sub I{($F,$B,$U, $P)
=qw (/ \\ _ |);; ${
S}= " ";$f=$S.$F;$g=$ U.
$F ;$b=$B.$S;$c=$B.${U};}@{ P}=
@{ O}; while($_=pop@{P} ){ @{
P} || y:_: :;$spooky++ || 0|
0 || y@_ @ _@;y:/:8:; ; ;
; ;; y:\\:/:;y:8:\\:; @O =
( @O ,$_);}print@O; q{
Do !Discuss:Rel ig
io n,Politi cs
,& &T
heG rea
tP ump
ki n}
Подсказка к ] http://www.ascii-art.de/ascii/s/spider.txt
Я создал код в форме паука вручную, но за помощью обратитесь к модулю Acme :: AsciiArtinator на CPAN. с автоматизацией (или хотя бы полуавтоматизацией) задачи.
сокращены за счет встраивания подпрограмм.
perl -E'$"="";($i=<>)++;@r=map{$p=$i-$_;@d=(" "x$_,(" ","\\")x$p,"/","_"x$_);($d="@d")=~y:\\/:/\\:;@d=reverse@d;$d.="|@d"}1..$i;say for reverse@r;$_=$r[0];y: _|:_ :;s:.(.*)\\.*/(.*).:$1_/ \\_$2:;say;y: _\\/:_ /\\:;say;$r[-1]=~y:_: :;say for grep{y:\\/:/\\:}@r;'
Расширен для улучшения читаемости.
perl -E'
$"="";
($i=<>)++;
@r=map{
$p=$i-$_;
@d=(
" "x$_,
(" ","\\")x$p,
"/",
"_"x$_
);
($d="@d")=~y:\\/:/\\:;
@d=reverse@d;
$d.="|@d"
}1..$i;
say for reverse@r;
$_=$r[0];
y: _|:_ :;
s:.(.*)\\.*/(.*).:$1_/ \\_$2:;
say;
y: _\\/:_ /\\:;
say;
$r[-1]=~y:_: :;
say for grep{y:\\/:/\\:}@r;
'
Это код до того, как я его свернул:
#! /opt/perl/bin/perl
use 5.10.1;
($i=<>)++;
$"=""; #" # This is to remove the extra spaces for "@d"
sub d(){
$p=$i-$_;
" "x$_,(" ","\\")x$p,"/","_"x$_
}
sub D(){
@d=d;
($d="@d")=~y:\\/:/\\:; # swap '\' for '/'
@d=reverse@d;
$d.="|@d"
}
@r = map{D}1..$i;
say for reverse@r; # print preceding lines
# this section prints the middle two lines
$_=$r[0];
y: _|:_ :;
s:.(.*)\\.*/(.*).:$1_/ \\_$2:;
say;
y: _\\/:_ /\\:;
say;
$r[-1]=~y:_: :; # remove '_' from last line
say for grep{y:\\/:/\\:}@r; # print following lines
Я бы предпочел продолжить ветку комментариев выше, в которой кратко упоминаются Python и Ruby, но для этого мне нужно форматирование. Smashery, безусловно, классный, но не о чем беспокоиться: оказывается, что Python и Ruby находятся в довольно близкой гонке по одному параметру. Я вернулся и сравнил Python с Ruby в восьми кодах гольфа, которые я ввел.
Challenge Best Python Best Ruby The Wave 161 99 PEMDAS no python entry (default victory?) Seven Segs 160 175 Banknotes 83 (beat Perl!) 87 Beehive 144 164 RPN (no eval) 111 (157) 80 (107) Cubes 249 233 Webs 212 181 Victories 3 4 (5?)
Таким образом, вопрос определенно не решен и стал еще более интересным в последнее время, когда gnibbler начал входить с обеих сторон. : -)
*
Я считал только полнофункциональные записи.
Очевидно, что это даже не в текущем состоянии с учетом количества символов. Число 573 - это просто размер файла на моем компьютере с Windows, так что, вероятно, он насчитывает несколько клавиш Ctrl-M. С другой стороны, возможно, 573 недооценивают его, так как я навлек на себя гнев компилятора, отбросив все # include для экономии места, черт побери, предупреждения!
Но эй, это моя первая попытка сделать одно из них , и, несомненно, будет хорошей практикой попытаться выразить это в более компактном виде.
#define B puts("");
#define K '\\'+'/'
#define F '_'+' '
#define P(s) putchar(s);
#define I int
c(I s,I f){if(s){P(f)c(s-1,f);P(f)}else P('|')}
w(I lw,I s,I k,I f){if(s){P(' ')P(k)w(lw,s-1,k,f);P(K-k)P(' ')}else{P(K-k)c(1+lw,f);P(k)}}
h(I g,I s,I k,I f){I i;for(i=-1;i<g;++i)P(' ')w(g,s,k,f);}
t(I g,I s){if(s)t(g+1,s-1);h(g,s,'/','_');B}
b(I g,I s){h(g,s,'\\',s?'_':' ');B;if(s)b(g+1,s-1);}
m(I s,I k,I f){if(s){P(f)P(k)m(s-1,k,f);P(K-k)P(f)}else{P(F-f)P(F-f)P(F-f)}}
main(I ac,char*av[]){I s;s=atoi(av[1]);t(0,s);m(1+s,'/','_');B;m(1+s,'\\',' ');B;b(0,s);}
n=...s=string r=s.reverse g=s.gsub a="\\|/"j=(" /"):rep(n+1)..a..("\\ "):rep(n+1) k=j o=k l=n*4+7 for i=1,n+1 do k=g(k,"^(.- )/(.-)|(.*)\\(.-)$","%1%2_|_%3%4")o=k..o end o=o..r(o)print((g(g(g(g(r(g(o:sub(1,l),"_"," ")..o:sub(l+1)),j,g(j," ","_")),("."):rep(l),"%1\n"),a," "),r(a),"___")))
Здесь нет ничего сложного; просто выводить построчно - 298 280 271 266 265 261 260 254 240 символов (игнорировать 2 последних разрыва строки)
u,b,f,s,a='_\/ |'
m=input()+1
print'\n'.join([(m-x)*s+x*' /'+b+(m-x)*u+a+(m-x)*u+f+x*'\ 'for x in
range(0,m)]+['_/'*m+s*3+'\_'*m+'\n'+(s+b)*m+u*3+'/ '*m]+[x*s+(m-x)*
' \\'+f+x*u+a+x*u+b+(m-x)*'/ 'for x in range(1,m)] + [s*m+f+s*m+a+s*m+b])
Обратите внимание, что этот код включает в себя начальную сеть в исходном коде. (Двойная обратная косая черта в конце - это позор. В более ранней версии этого не было.)
$_='
\_|_/
_/ \_
\___/
/_|_\\';
for$x(1..<>){
s|(.\S).*([/\\].)|$1$&$2|g;
s|\\(.*)/| \\_$1_/$` /$&\\ |;
s|(\s+)\K/(.*).$| \\$&/$1 /_$2_\\|
}
s|_(?=.*$)| |g;
print
Пробел в $ _
имеет значение (конечно), но все остальное - нет. Если у вас есть незначительное предложение по улучшению этого, пожалуйста, отредактируйте мой код. Например, Kinopiko красиво сбрил 6 символов!
В зависимости от того, как вы подсчитываете переключатели командной строки, это может быть короче (154 по обычным правилам игры в гольф Perl, если я могу правильно подсчитать):
#!perl -ap
$_='
\_|_/
_/ \_
\___/
/_|_\\';
s|(.\S).*([/\\].)|$1$&$2|g,
s|\S(.*).| \\_$1_/$` /$&\\ |,
s|(\s+)\K/(.*).$| \\$&/$1 /_$2_\\|while$F[0]--;
s|_(?=.*$)| |g
(&)=(++) --9
f 0=[" \\_|_/","_/ \\_"," \\___/"," / | \\"] --52
f(n+1)=[s&h&u&"|"&u&g]&w(f n)&[s&g&s&"|"&s&h]where[a,b,c,d,e]=" _/\\|";[g,h]=["/","\\"];y=n+2;[u,s]=[r y b,r y a];p f s n x=let(a,b)=span(/=s)x in a&f b;i=dropWhile(==a);w[]=[];w[x]=[s&h&i(p(map(\x->if x==a then b else x))c d x)&g];w(l:e)|n==y*2-1=x%h:z|n>y=x&" "%" \\":z|n==y="_/"%"\\_":z|n<y=r(y-n)a&"\\ "%" /":z where n=length e;z=w e;x=r(n+1-y)a&g;(%)=(&).(&i l) --367
r=replicate --12
main=interact$unlines.f.read --29
Запись Haskell весит 469 символов. Я уверен, что есть много возможностей для улучшения.
удачи, пытаясь прочитать это :)
вот более читаемая версия. Хотя с этой версии были внесены некоторые изменения
spider 0=[" \\_|_/","_/ \\_"," \\___/"," / | \\"]
spider n=(s++"\\"++u++"|"++u++"/"):w m(spider(n-1))++[s++"/"++s++"|"++s++"\\"]
where
[a,b,c,d,e]=" _/\\|"
[m,y]=[y*2,n+1]
x=r y
[u,s]=[x b,x a]
t a b=map(\x->if x==a then b else x)
p f s n x=let(a,b)=span(/=s)x;(c,d)=span(/=n)b in a++f c++d
i=dropWhile(==a)
w _[]=[]
w _[x]=[s++"\\"++i(p(t a b)c d x)++"/"]
w(a+1)(l:e) |a==m-1=wrapline x l"\\":z
|a>y=wrapline(x++" ")l" \\":z
|a==y=wrapline"_/"l"\\_":z
|a<y=wrapline(r(y-a)' '++"\\ ")l" /":z
where
z=w a e
x=r(a+1-y)' '++"/"
wrapline b l a=b++i l++a
r=replicate
main=interact$unlines.spider.read
«Прямое» решение в dc
(OpenBSD). Не соперник, но это всегда весело. Разрывы строк для «удобочитаемости»
[lcP1-d0<A]sA?sN[lK32sclAxRlNlK-l1scd0!=ARl3PlKl0sclAxRl9PlKlAxRl4PlNlK-
l2scd0!=AAPR]sW95s0124s9[ /]s1[\\ ]s292s347s4lN[dsKlWx1-d0<L]dsLx
[\\_][ ][_/][lN[rdPr1-d0<L]dsLxRRPlNlLxRR]dsBxAP[/ ][_ _][ \\]lBxAP[ \\]s1
[/ ]s247s392s41[dsKlWx1+dlN>L]dsLx32s032s9lNsKlWx
пример вывода
$ dc web.dc
3
\___|___/
/\__|__/\
/ /\_|_/\ \
_/_/_/ \_\_\_
\ \ \_ _/ / /
\ \/_|_\/ /
\/__|__\/
/ \