Narysuj sześciokąt ASCII o boku n
Biorąc pod uwagę dodatnią liczbę całkowitą \$n\$wypisz sześciokąt ASCII o przekątnej długości boku \$n\$, jak na zdjęciu (uwaga: są \$2n\$ _
znaki na górnej krawędzi)
Przykłady:
\$n = 1\$
__
/ \
\__/
\$n = 2\$
____
/ \
/ \
\ /
\____/
\$n = 5\$
__________
/ \
/ \
/ \
/ \
/ \
\ /
\ /
\ /
\ /
\__________/
itp.
Wygrywa najkrótszy kod w bajtach. Zastosowanie mają zwykłe metody wejścia / wyjścia .
Odpowiedzi
Płótno , 15 9 bajtów
_;1*⁸/∔╬
Wypróbuj tutaj!
-6 bajtów po naprawieniu programu.
Rysuje ćwiartkę sześciokąta i czwórkę palindromizów.
Python 2 , 92 bajty
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
Wypróbuj online!
Węgiel drzewny , 14 bajtów
←×_θ↖θ→↗θ×_θ‖M
Wypróbuj online!
Poprawka +1 bajta z tylko ASCII.
Rysuje połowę sześciokąta i tworzy jego lustrzane odbicie.
C (gcc) , 119 109 bajtów
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);}
Wypróbuj online!
- uratował 2 dzięki @ceilingcat
Poniższa tabela nie jest aktualizowana, więc wartości mogą się różnić, ale koncepcja jest taka:
- mamy 2 pary równoległych linii
. . _______.______.________ | / \ | . . | / \ | . . | / \ |. | / \ | | \ / |. . | \ / | . . | \ / | __ | ___ \ ________ / ___ | ___ | . .
iterujemy x, y od rozmiaru do 0 i sumujemy je, aby sprawdzić, czy powinno zostać wydrukowane /, odejmujemy, aby sprawdzić \, używamy modulo, aby sprawdzić obie podobieństwa.
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 bajty
s/_+/__$&/g,s/^|$/ /gm,s/^ *\S /$& /gm,s-( +)\\ -$&/ $1 \\ \\ $1 /
- for($\=' __ / \ \__/')x--$_}{
Wypróbuj online!
-p
a }{
na końcu jest sztuczka, aby wydrukować tylko separator rekordów wyjściowych $\
na końcu. Działa tylko dla jednego rekordu wejściowego; nagłówek służy do wydrukowania łącza „wszystko w jednym”.
$\=' __
/ \
\__/' # 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 bajtów
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
Wypróbuj online!
Bardziej rekurencyjna wersja tej odpowiedzi. Arbitralność tego wyzwania sprawia, że jest to dość frustrujące.
Wyjaśnienie
Ta odpowiedź jest trochę trudna do wyjaśnienia. Wyzwanie jest, jak już powiedziałem, arbitralne na kilka sposobów, więc kod jest rodzajem zbioru symboli.
Pomysł
Ideą programu jest tutaj zbudowanie dwóch połówek. Oznacza to, że podczas obliczania n-tego sześciokąta otrzymujemy dwie połówki z n-pierwszego sześciokąta i używamy tego do utworzenia następnego największego.
Są jednak pewne zastrzeżenia. Budujemy górną połowę do góry nogami i tworzymy obie połówki w lustrzanym odbiciu od lewej do prawej. Robimy to, ponieważ jest to wygodne w ten sposób. Nie ma głębokiego powodu, że to po prostu skraca rzeczy, nawet jeśli sprawia, że są one trochę niezrozumiałe.
Detale
Pierwsza linia jest dość prosta, r
to alias dla reverse
. Druga linia nie jest taka prosta. m
to nonsensowna funkcja, istnieje, ponieważ ją lub podobną operację trzeba wykonać w kilku miejscach. Tak naprawdę nie ma znaczenia semantycznego. Najlepszym wyjaśnieniem tego, co robi tutaj, jest kod.
m(o:c:k)=o:c:c:c:k++" "
Od f
tego momentu zaczynamy dochodzić do tego, który obsługuje w zasadzie całą logikę. Pierwszy przypadek f
to podstawa, jest dość standardowy
f 1=[["\\ /","__ "],["/__\\"]]
Zwróć uwagę, że zamiast krotki zwracamy listę dwóch elementów. W każdym rozsądnym programie używalibyśmy krotki, ponieważ jest ona ustalona na 2 elementach. Jednak później zmapujemy oba argumenty tej samej funkcji. Trudno to zrobić z krotką, ale łatwo z listą, a lista nie ma żadnych wad, więc jej używamy.
Następnie mamy przypadek indukcyjny. Najpierw pobieramy poprzedni przypadek i podwójnie mapujemy m
go. To sprawia, że sześciokąt jest o 1 jednostkę szerszy (2 znaki) i przesuwa go o pół jednostki (1 znak) w prawo (chociaż ponieważ całość jest odwrócona, znaki spacji są dodawane po prawej stronie ). Dopasowujemy to do wzorca, [w:i,j]
ponieważ chcemy użyć go w
do późniejszego utworzenia nowych wierszy. Mówiąc o tym, co dalej robimy rzędy. Robimy to za pomocą dopasowania do wzorca:
_:_:k<-r$m w
To rodzaj bzdurnego kodu. Po prostu zderza ze sobą rzeczy, które już mieliśmy, aby wygenerować poprawny wynik. k
a jego odwrotność tworzą nowe wiersze, więc dodajemy je i zwracamy.
Po tym f
, h
co zamienia wyjście z f
na łańcuch. Cofa wszystkie zwariowane transformacje, których użyliśmy podczas tworzenia, i pakuje je do użycia.
Z tym wszystkim po prostu komponujemy f
i h
do ostatecznej funkcji.
Haskell , 100 bajtów
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=' ']
Wypróbuj online!
Gra w golfa Odpowiedź AZTECCO plus kilka nowych technik.
Główną ideą jest to, że sześciokąt jest prostszy, jeśli przeszczepimy pierwsze n
kolumny do końca.
|-|
______
/ \
/ \
/ \
\ /
\ /
\______/
|-|
______
\ /
\ /
\/
/\
/ \
______/ \
Teraz wszystkie /
i \
znajdują się w jednej linii, a _
wszystkie są po lewej stronie. To znacznie ułatwia realizację strategii AZTECCO polegającej na określaniu znaku ze współrzędnych. Aby zaimplementować te zmienione współrzędne, zastępujemy współrzędne x
-współrzędne [1..4*n]
wersją cykliczną i przesuniętą [1..3*n]++[1-n..0]
.
Retina 0.8.2 , 94 bajty
.+
$* ¶$&$* \G ¶$%'/$`$%_$%_$`\
r` \G
$%`\$'$%_$%_$%'/¶ ^¶( *) $1 $.&$*_$.&$*_$& T` `\_` +/$
Wypróbuj online! Link zawiera przypadki testowe. Wyjaśnienie:
.+
$* ¶$&$*
Wstaw dwa rzędy n
spacji.
\G
¶$%'/$`$%_$%_$`\
Przekształć pierwszy rząd w górne boki sześciokąta.
r` \G
$%`\$'$%_$%_$%'/¶
Przekształć drugi rząd w dolne boki sześciokąta.
^¶( *)
$1 $.&$*_$.&$*_$&
Wstaw górną linię.
T` `\_` +/$
Wymień dolną linię.
Python 2 , 119 114 bajtów
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)
Wypróbuj online!
JavaScript (ES6), 109 107 bajtów
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)
Wypróbuj online!
Skomentowano
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 bajty
Zapisano 13 14 19 bajtów dzięki 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;}
Wypróbuj online!
Wyjaśnienie (przed niektórymi golfami)
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 bajtów
-4 ( 7 ) bajtów dzięki Kevinowi Cruijssenowi !
L+<'/úíºI·'_ך»∊¶¡`ðs‡).c
Wypróbuj online!
05AB1E ma polecenie wbudowane płótnie, które mogą być przydatne, ale jest dość skomplikowany, aby dostać pracę, to dopiero builtins lustro º
i ∊
oraz wbudowane Centralizacja .c
.
J , 50 47 bajtów
-3 dzięki Jonah!
' \/_'{~]|."1((0,]+2*|.)@=@i.,.3,3,~0$~<:,])@+:
Wypróbuj online!
((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 (wersja wstępna) , 174 bajty
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")
Wypróbuj online!
-1 bajt dzięki @Duncan
-8 bajtów dzięki @Danis
Haskell , 129 120 bajtów
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=' ']
Wypróbuj online!
uratował 9 dzięki @Wheat Wizard i @xnor.
Sprawdź odpowiedź @xnor i jej duże ulepszenie w podejściu do problemu (unikanie linii modulo i równoległych)!
Odpowiednik mojej odpowiedzi w C.
Tworzymy współrzędne kartezjańskie przy użyciu funkcji list | y <- [0..n * 2], x <- [0..a]
[c | ..., niech c | ... | ... | ...] i potrzebujemy znaku na podstawie xy lub x + y, aby narysować linie.
Używamy modulo do rysowania wielu linii (2)
Specjalny przypadek _
nie wymaga stosunku ax / y, ale zakres, my użył modulo do zrobienia tylko jednego porównania >
zamiast a> x> b jak
Ruby , 141 bajtów
->(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)]}
Wypróbuj online!
Jeśli dozwolone jest górne podkreślenie, zajęłoby to trochę mniej bajtów, podczas gdy sześciokąt jest tak samo ładny jak wcześniej ;-)
Ruby , 114 bajtów
->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]}
Wypróbuj online!
05AB1E , 70 bajtów
ðש'_¹·×«©¶«©¹'/1Λ¹·Ì'.2Λ¹'\3.Λ«©„./`.;©¶¡Â‚€»`s'.ð:,¹3*>(£„._`:„/\‡,
Wypróbuj online!
Perl 5 , 143 bajty
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}
Wypróbuj online!
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 ,
186
168 bajtów
-18 bajtów z poprawkami xnora i usuwaniem niepotrzebnych spacji w ostatniej linii
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]
Wypróbuj online!
Ungolfed:
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) ' '