Kenar uzunluğu n olan bir ASCII altıgen çizin
Pozitif bir tam sayı verildiğinde \$n\$çapraz kenar uzunluğuna sahip bir ASCII altıgen çıktı \$n\$, resimde gösterildiği gibi (unutmayın \$2n\$ _
üst kenardaki karakterler)
Örnekler:
\$n = 1\$
__
/ \
\__/
\$n = 2\$
____
/ \
/ \
\ /
\____/
\$n = 5\$
__________
/ \
/ \
/ \
/ \
/ \
\ /
\ /
\ /
\ /
\__________/
vb.
Bayt cinsinden en kısa kod kazanır. Genel girdi / çıktı yöntemleri geçerlidir.
Yanıtlar
Tuval , 15 9 bayt
_;1*⁸/∔╬
Burada deneyin!
Programı düzelttikten sonra -6 bayt.
Altıgenin dörtte birini çizer ve dörtlü palindromize eder.
Python 2 , 92 bayt
k=n=input()
while 1:a=k^k>>n;print" "*a+"\/_"[k/n-2]+"_ "[-n<k<n]*2*(2*n+~a)+"\_/"[k/n];k-=1
Çevrimiçi deneyin!
Kömür , 14 bayt
←×_θ↖θ→↗θ×_θ‖M
Çevrimiçi deneyin!
Yalnızca ASCII'den +1 bayt düzeltme.
Altıgenin yarısını çizer ve yansıtır.
C (gcc) , 119109 bayt
a,i,j;f(n){for(i=a+=a=j=n*2;~j;)putchar(!i--?i=a,j--,13:i%(n*3)<n|j%(n*2)?(i-~j-n)%a?(i-j+n)%a?32:92:47:95);}
Çevrimiçi deneyin!
- @ceilingcat sayesinde 2 kurtardı
Değerler farklı olabileceği için aşağıdaki tablo güncellenmemiştir, ancak konsept şu şekildedir:
- 2 çift paralel çizgimiz var
. . _______.______.________ | / \ | . . | / \ | . . | / \ |. | / \ | | \ / |. . | \ / | . . | \ / | __ | ___ \ ________ / ___ | ___ | . .
x'i, y'yi boyuttan 0'a yineleriz ve a / yazdırılması gerekip gerekmediğini kontrol etmek için toplarız, kontrol etmek için çıkarırız, her iki paralelliği kontrol etmek için modulo kullanırız.
i 65432109876543210. j i + jn ________ 8 13 + 7-4 => / \ 7 14 + 6-4 / \ 6 15 + 5-4 / \ 5 / \ 4 \ 1 + 3-4 => / 3 \ 2 + 2-4 / 2 \ 3 + 1-4 / 1 \ ________ / 0
Perl 5 ( -p
), 102 bayt
s/_+/__$&/g,s/^|$/ /gm,s/^ *\S /$& /gm,s-( +)\\ -$&/ $1 \\ \\ $1 /
- for($\=' __ / \ \__/')x--$_}{
Çevrimiçi deneyin!
-p
ve }{
sonunda yalnızca çıktı kaydı ayırıcısını $\
en sonunda yazdırmak için bir numara var . Yalnızca bir giriş kaydı için çalışır; başlık, hepsini tek bir bağlantıda yazdırmak için kullanılır.
$\=' __
/ \
\__/' # output record separator initialized with hexagon (size 1)
s/_+/__$&/g,s/^|$/ /gm,s/^ *\S /$& /gm,s-( +)\\ -$&/ $1 \\ \\ $1 /
- # regexes to increase the hexagon by 1
for .. --$_ # to repeat n-1 times where n is the input
Haskell , 150 bayt
r=reverse
m(o:c:k)=o:c:c:c:k++" "
f 1=[["\\ /","__ "],["/__\\"]]
f n|[w:i,j]<-map m<$>f(n-1),_:_:k<-r$m w=[r k:w:i,k:j]
h[i,j]=unlines$r<$>r i++j
h.f
Çevrimiçi deneyin!
Bu cevabın daha özyinelemeli bir versiyonu. Bu meydan okumanın keyfi olması, bunu oldukça sinir bozucu hale getiriyor.
Açıklama
Bu cevabın açıklaması biraz zor. Zorluk, daha önce de söylediğim gibi, birkaç yönden gelişigüzel, bu yüzden kod bir tür semboller yuvasıdır.
Fikir
Buradaki programın amacı iki yarıyı oluşturmaktır. Bu, n'inci altıgeni hesaplarken n-1'inci altıgenin iki yarısını elde ederiz ve bunu bir sonraki en büyük altıgeni yapmak için kullanırız.
Yine de bazı uyarılar var. Üst yarıyı baş aşağı inşa ediyoruz ve her iki yarıyı da soldan sağa aynalanmış şekilde oluşturuyoruz. Bunu, bu şekilde yapmak uygun olduğu için yapıyoruz. Her şeyi biraz anlaşılmaz hale getirse bile işleri kısaltmasının derin bir sebebi yok.
Detaylar
İlk satır oldukça yalındır r
, için bir takma addır reverse
. İkinci satır o kadar düz değil. m
saçma bir işlevdir, çünkü bu veya benzeri bir işlemin birkaç yerde yapılması gerekir. Gerçekten anlamsal bir anlamı yok. Burada ne yaptığının en iyi açıklaması koddur.
m(o:c:k)=o:c:c:c:k++" "
Buradan f
, temelde tüm mantığı hangi mantığın işlediğini öğrenmeye başlıyoruz . İlk durum f
temel durumdur, oldukça standarttır
f 1=[["\\ /","__ "],["/__\\"]]
Bir tuple yerine iki öğeden oluşan bir liste döndürdüğümüzü unutmayın. Herhangi bir aklı başında programda, 2 öğede sabitlendiği için bir demet kullanırdık. Ancak daha sonra, bunun her iki argümanını da aynı işlevle eşleyeceğiz. Bunu bir tuple ile yapmak zordur, ancak bir liste ile kolaydır ve liste herhangi bir dezavantaj oluşturmaz, bu yüzden onu kullanırız.
O zaman tümevarımlı durumumuz var. İlk önce bir önceki vakayı getiriyoruz ve m
üzerinde çift harita oluşturuyoruz . Bu, altıgen 1 birimini daha geniş yapar (2 karakter) ve onu yarım birim (1 karakter) sağa hareket ettirir (her ne kadar bu şey geriye doğru olduğundan, boşluk karakterleri sağ tarafa eklenir ). Bunu daha sonra yeni satırlar yapmak [w:i,j]
için kullanmak istediğimiz için kalıbı eşleştiriyoruz w
. Bundan sonra sıraları yapacağımızdan bahsetmişken. Bunu bir kalıp eşleşmesi ile yapıyoruz:
_:_:k<-r$m w
Bu bir çeşit saçma kod. Sadece doğru çıktıyı üretmek zorunda olduğumuz şeyleri bir araya getiriyor. k
ve bunun tersi yeni satırları oluşturur, böylece onları ekleriz ve onu döndürürüz.
Sonra f
elimizdeki h
çıktısını döndüğü f
bir dizeye. İnşaat sırasında kullandığımız tüm tuhaf dönüşümleri geri alır ve kullanılmak üzere paketler.
Sadece oluşturduğumuz her şeyle f
ve h
son işlev için.
Haskell , 100 bayt
f n=unlines[q<$>[1..3*n]++[1-n..0]|y<-[-n..n],let q x|abs y==n,x>n='_'|x==y='\\'|x+y==1='/'|1>0=' ']
Çevrimiçi deneyin!
Golf AZTECCO'nun cevabı artı bazı yeni teknikler.
Ana fikir, ilk n
sütunları sonuna kadar nakledersek altıgenin daha basit olmasıdır .
|-|
______
/ \
/ \
/ \
\ /
\ /
\______/
|-|
______
\ /
\ /
\/
/\
/ \
______/ \
Artık tüm /
ve \
tek bir satır vardır ve _
bunlardan sola tümü. Bu, AZTECCO'nun karakteri koordinattan belirleme stratejisini yapmayı çok daha kolaylaştırır. Bu yeniden etiketlenmiş koordinatları uygulamak için, x
koordinatları döngülü [1..4*n]
ve kaydırılmış bir versiyonla değiştiriyoruz [1..3*n]++[1-n..0]
.
Retina 0.8.2 , 94 bayt
.+
$* ¶$&$* \G ¶$%'/$`$%_$%_$`\
r` \G
$%`\$'$%_$%_$%'/¶ ^¶( *) $1 $.&$*_$.&$*_$& T` `\_` +/$
Çevrimiçi deneyin! Bağlantı, test senaryolarını içerir. Açıklama:
.+
$* ¶$&$*
İki satır n
boşluk ekleyin .
\G
¶$%'/$`$%_$%_$`\
İlk sırayı altıgenin üst taraflarına dönüştürün.
r` \G
$%`\$'$%_$%_$%'/¶
İkinci sırayı altıgenin alt kenarlarına dönüştürün.
^¶( *)
$1 $.&$*_$.&$*_$&
En üst satırı ekleyin.
T` `\_` +/$
Alt satırı değiştirin.
Piton 2 , 119 114 bayt
i=n=input()
d=0
exec"k=i/n|d;print' '*i+'\_/'[~k]+'_ '[i-d<n]*2*(2*n+~i)+'\_/'[k]\nif i==d:d=i=-1\ni-=d|1;"*(n-~n)
Çevrimiçi deneyin!
JavaScript (ES6), 109 107 bayt
w=>(x=0,W=w*4,i=g=y=>~y?`
/\\_`[x++-W?y*!i|w/x|x>w*3?(x+~y+w)%W?(x+y)%W-w?1:3:2:4:x=i=0&y--]+g(y):'')(w*2)
Çevrimiçi deneyin!
Yorum yaptı
w => ( // w = input
x = 0, // initialize x to 0
W = w * 4, // W = total width
i = // initialize i to a non-zero value
g = y => // g is a recursive function taking y
~y ? // if y is not equal to -1:
`\n /\\_`[ // list of characters
x++ - W ? // if this is not the end of the row:
y * !i | // if this is neither the first nor the last row
w / x | // or x is less than or equal to w
x > w * 3 ? // or x is greater than w * 3:
(x + ~y + w) % W ? // if (x - y - 1 + w) mod W is not equal to 0:
(x + y) % W - w ? // if (x + y) mod W is not equal to w:
1 // draw a space
: // else:
3 // draw a '\'
: // else:
2 // draw a '/'
: // else:
4 // draw a '_'
: // else:
x = i = 0 & y-- // decrement y, set x and i to 0 and draw a linefeed
] + g(y) // append the result of a recursive call
: // else:
'' // stop the recursion
)(w * 2) // initial call to g with y = w * 2
C (gcc) , 194 \$\cdots\$ 149 144 bayt
Kaydedilen 13 14 19 sayesinde bayt ceilingcat !!!
p(n,c){for(;n--;)printf(L"/\\ _\n"+c);}i;t;f(n){p(n,2);for(i=t=p(2*n,3);i>=p(1,4);t=i/n?--i,1:t)i+=!p(!p(n+i<<!p(!p(n+~i,2),t),t&!i|2),!t)-2*t;}
Çevrimiçi deneyin!
Açıklama (bazı golflerden önce)
p(n,c){for(;n--;) // Helper function to print
putchar("/\\ _\n"[c]);} // one of '/', '\', ' ', '_' , or
// newline n times, this function
// also returns 0
i;t;f(n){ // Main function prints an n hexagon
p(n,2); // Print n leading spaces for the 1st
// line
for( // Main loop
i=t=p(2*n,3); // Set i and t to 0,
// and print 2*n '_'s for the 1st line
i>=p(1,4); // Loop until i goes below 0, and
// print a newline
// At the end of each loop:
i+=1-2*t, // increment i for the 1st half
// and then decrement i in the 2nd
t=i/n?--i,1:t) // keep t as t unless i equals n,
// then make t 1 and decrement i
// In the main loop:
p(n+~i,2), // print n-i-1 leading spaces
p(1,t), // print a '/' in the 1st half and a
// '\' in the 2nd
p(n+i<<1,t&!i|2), // print the 2*(n+i) middle spaces
// unless at the bottom print '_'s
p(1,!t); // print a '\' in the 1st half and a
// '/' in the 2nd
}
05AB1E , 33 29 25 bayt
Kevin Cruijssen sayesinde -4 ( 7 ) bayt !
L+<'/úíºI·'_ך»∊¶¡`ðs‡).c
Çevrimiçi deneyin!
05AB1E , yararlı olabilecek bir tuval yerleşikine sahiptir, ancak çalışması oldukça zordur, bu yalnızca ayna yerleşikleri º
ve ∊
merkezileştirilmiş yerleşiktir .c
.
J , 50 47 bayt
-3 teşekkürler Jonah!
' \/_'{~]|."1((0,]+2*|.)@=@i.,.3,3,~0$~<:,])@+:
Çevrimiçi deneyin!
((0,]+2*|.)@=@i. ,. 3,3,~0$~<:,])@+:
0 0 0 0 3 3 3 3
1 0 0 2 0 0 0 0
0 1 2 0 0 0 0 0
0 2 1 0 0 0 0 0
2 0 0 1 3 3 3 3
]|."1
0 0 3 3 3 3 0 0
0 2 0 0 0 0 1 0
2 0 0 0 0 0 0 1
1 0 0 0 0 0 0 2
0 1 3 3 3 3 2 0
' \/_'{~
____
/ \
/ \
\ /
\____/
Python 3.8 (yayın öncesi) , 174 bayt
n=int(input())
b,a,s="\/ "
z,f=range(n),lambda c,d,t:((n-1-i)*s+c+2*(n+i)*s+d for i in t)
print(f"{'_'*2*n:^{4*n}}",*f(a,b,z),*f(b,a,z[:0:-1]),f"{b:>{n}}{'_'*2*n}/",sep="\n")
Çevrimiçi deneyin!
@Duncan sayesinde -1 bayt
@Danis sayesinde -8 bayt
Haskell , 1229120 bayt
g=mod
f n|a<-n*4=[c|y<-[-n..n],x<-[0..a],let c|x<1='\n'|g x(n*3+1)>n,abs y==n='_'|g(x+y)a==1='/'|g(x-y)a<1='\\'|1>0=' ']
Çevrimiçi deneyin!
@Wheat Wizard ve @xnor sayesinde 9 tasarruf sağladı.
@Xnor cevabını ve soruna yaklaşımdaki büyük gelişimini kontrol edin (modulo ve paralel çizgilerden kaçınarak)!
C cevabımın karşılığı
Listeyi anlama | y <- [0..n * 2], x <- [0..a] kullanarak kartezyen koordinatlar yapıyoruz
[c | ..., let c | ... | ... | ...] ve çizgi çizmek için xy veya x + y'ye göre gerekli karakteri sararız ..
Birden çok çizgi çizmek için modulo kullanırız (2) Ax / y oranına değil, bir aralığa ihtiyaç duyan
özel durum _
, biz >
a> x> b benzeri yerine tek bir karşılaştırma yapmak için modulo kullandı
Ruby , 141 bayt
->(n,g=->c,d{(1..n).map{|i|" "*(n-i)+d+" "*2*(n+i-1)+c}},l=g[?/,e=?\\].reverse){[" "*n+?_*n*2,g[e,?/],l[0..-2],l[-1].sub(/ +(?=\/)/,?_*n*2)]}
Çevrimiçi deneyin!
Bir üst alt çizgiye izin veriliyorsa, bayt biraz daha az alırken, altıgen eskisi kadar güzel ;-)
Ruby , 114 bayt
->n{[" "*n+?_*2*n,(g=->c,d{(1..n).map{|i|" "*(n-i)+c+" "*2*(n+i-1)+d}})[?/,e=?\\],g[e,?/].reverse," "*n+?‾*n*2]}
Çevrimiçi deneyin!
05AB1E , 70 bayt
ðש'_¹·×«©¶«©¹'/1Λ¹·Ì'.2Λ¹'\3.Λ«©„./`.;©¶¡Â‚€»`s'.ð:,¹3*>(£„._`:„/\‡,
Çevrimiçi deneyin!
Perl 5 , 143 bayt
sub f{$n=pop;@b=map{join'',$"x($n-$_),'/',' 'x($n+$_-1),'\\',$/}1..$n;join('',$"x$n,$u=__ x$n,$/,@b,map y|/\\|\\/|r,reverse@b)=~s| +/$|$u/|sr}
Çevrimiçi deneyin!
sub f{
$n=pop; #n = input
@b=map{ #set array @b to line 2 - n+1
join'', #join parts into a line string
$" x ($n-$_), #space times n-1 '/', #char / ' ' x ($n+$_-1), #space times n+iterator minus 1 '\\', #char \ $/ #char newline
} 1..$n; #n lines join('', #return string of these joined: $" x $n, #n spaces $u = __ x$n, #n*2 underscores $/, #char newline
@b, #lines 2 to n+1 constructed above
map y|/\\|\\/|r, #and bottom part which is the same
reverse@b #as top part reversed and /\ rotated
)=~s| +/$|$u/|sr #and change last spaces of last line to _'s
}
Haskell ,
186168
bayt
Xnor'un düzeltmeleriyle ve son satırdaki gereksiz boşlukları kaldırarak -18 bayt
s=' '
(!)=replicate
e=reverse
h n=unlines$(\m->(n!s++(2*n)!'_'++n!s):e(e<$>m)++init m++[(n-1)!s++'\\':(2*n)!'_'++"/"])$(\i->i!s++'\\':(4*n-2*i-2)!s++'/':i!s)<$>[0..n-1]
Çevrimiçi deneyin!
Golfsüz:
hex :: Int -> String
hex n = unlines $ first: middle ++ (init $ reverse (map reverse middle)) ++ [last]
where
first = replicate n ' ' ++ replicate (2*n) '_' ++ replicate n ' '
f i = replicate i ' ' ++ "/" ++ replicate (n-i + 2*n + n-i -2) ' ' ++ "\\" ++ replicate i ' '
middle = map f [n-1,n-2..0]
last = replicate (n-1) ' ' ++ "\\" ++ replicate (2*n) '_' ++ "/" ++ replicate (n-2) ' '