Zbuduj pół-zygzak


29

NJako dane wejściowe otrzymasz dodatnią liczbę całkowitą . Twoim zadaniem jest zbudowanie pół-zygzaka, o Nbokach o długości każdej N. Ponieważ stosunkowo trudno jest jasno opisać to zadanie, oto kilka przykładów:

  • N = 1:

    O
    
  • N = 2:

    O
     OO
    
  • N = 3:

    OO
     OO
      OOO
    
  • N = 4:

    OOOOO
     OO
      OO
       OOOO
    
  • N = 5:

    OOOOOO
     OOO
      OOO
       OOO
        OOOOOO
    
  • N = 6:

    OOOOOOO
     OOO
      OOO
       OOO
        OOO
         OOOOOOOOOOOO
    
  • N = 7:

    OOOOOOOOO
     OOOO
      OOOO
       OOOO
        OOOO
         OOOO
          OOOOOOOOOOOOOO
    
  • Większy przypadek testowy z N = 9

Jak widać, pół-zygzak składa się z naprzemiennych linii ukośnych i poziomych, i zawsze zaczyna się od górnej linii od lewej do prawej dolnej. Zwróć uwagę, że znaki na poziomych liniach są oddzielone spacją.

Zasady

  • Można wybrać dowolną non-białymi charakter zamiast O, może to być nawet sprzeczne.

  • Możesz wyprowadzić / zwrócić wynik jako ciąg znaków lub listę ciągów znaków, z których każdy reprezentuje jedną linię .

  • Możesz mieć końcowy lub wiodący znak nowej linii.

  • Obowiązują domyślne luki .

  • Możesz przyjmować dane wejściowe i dostarczać dane wyjściowe dowolnym standardowym środkiem .

  • Jeśli to możliwe, dodaj link testowy do swojego zgłoszenia. Będę głosować za każdą odpowiedzią, która pokazuje wysiłki w golfa i zawiera wyjaśnienie.

  • To jest , więc wygrywa najkrótszy kod w bajtach w każdym języku !



Czy musimy umieszczać odstępy między O, które są poziome?
HatsuPointerKun

1
@HatsuPointerKun Zwróć uwagę, że znaki na poziomych liniach są oddzielone spacją. - Tak, musisz wstawić spacje.
Pan Xcoder

1
O tak. Powinienem nauczyć się czytać. Dzięki
HatsuPointerKun

1
@JohnHamilton odpowiedź powinna teoretycznie działa dla dowolnej liczby podanej jako wejście. Nie mogą się martwić o to, co może pomieścić ekran.
Pan Xcoder,

Odpowiedzi:


10

Węgiel drzewny , 24 bajty

FN«↶§7117ι×⁺#× ﹪ι²⁻Iθ¹»#

Wypróbuj online!

-5 dzięki Neilowi .

AST:

Program
├F: For
│├N: Input number
│└Program
│ ├↶: Pivot Left
│ │└§: At index
│ │ ├'7117': String '7117'
│ │ └ι: Identifier ι
│ └Print
│  └×: Product
│   ├⁺: Sum
│   │├'#': String '#'
│   │└×: Product
│   │ ├' ': String ' '
│   │ └﹪: Modulo
│   │  ├ι: Identifier ι
│   │  └2: Number 2
│   └⁻: Difference
│    ├I: Cast
│    │└θ: Identifier θ
│    └1: Number 1
└Print
 └'#': String '#'

Dla Węgla było to zbyt łatwe :)
Pan Xcoder

@ Mr.Xcoder To naprawdę nie jest golfem ... nie jestem pewien, jak to zagrać w golfa.
Erik the Outgolfer

OP powiedział, że postać może być dowolna i nie musi być konsekwentna, więc szukałem czegoś podobnego do FN§⟦↘→↗→⟧ι⁻Iθ¹→(tylko 15 bajtów), ale listy kierunków wydają się nie działać poprawnie w Charcoal. Szkoda.
Charlie

@CarlosAlejo Próbowałem też, ale niestety to nie działa.
Erik the Outgolfer

1
@CarlosAlejo FN✳§⟦↘→↗→⟧ι⁻θ¹Obędzie działać po tym, jak Dennis pociągnie, będąc skierowanym w kierunku
tylko ASCII

7

Python 2 , 157 153 bajtów

n=input()
o,s=q='O '
def p(k,t=q*n+s*(4*n-6)):print(t*n)[k*~-n:][:n*3/2*~-n+1]
p(2)
for i in range(n-2):p(0,i*s+s+o+s*(4*n-7-2*i)+o+s*(2*n+i-2))
n>1>p(5)

Wypróbuj online!

  • n*3/2*~-n+1 jest szerokością każdej linii: ⌊3n / 2⌋ · (n − 1) + 1 znaki.
  • Ciąg q*n+s*(4*n-6)reprezentuje górny i dolny rząd. Jeśli powtórzymy i pokroimy [2*(n-1):], otrzymamy górny rząd; jeśli kroimy [5*(n-1):], otrzymujemy dolny rząd. Stąd definicja pi wywołania p(2)i p(5). Ale ponieważ i tak potrzebujemy powtórzeń i odcinania długości linii dla wszystkich innych linii, ponownie używamy pw pętli.
  • To i*s+s+o+…tylko nudne wyrażenie dla środkowych rzędów.
  • n>1>p(5)spowoduje zwarcie, jeśli nie n≯1spowoduje p(5)to oceny. Stąd jest to skrót if n>1:p(5).

Wow, niesamowite rozwiązanie, takie sprytne. Zasłużyłeś na moją opinię
Mr. Xcoder

Wow, nigdy nie wiedziałem, że w takich porównaniach Python miał zwarcie +1.
Zacharý

6

Mathematica, 126 125 121 112 104 89 86 bajtów

(m=" "&~Array~{#,#^2-#+1};Do[m[[1[i,#,-i][[j~Mod~4]],j#-#+i+1-j]]="X",{j,#},{i,#}];m)&
  • #to numer wejściowy dla funkcji anonimowej (zakończony końcowym &).
  • m=" "&~Array~{#,#^2-#+1};tworzy macierz znaków spacji o odpowiednim rozmiarze, wypełniając tablicę podanych wymiarów #,#^2-#+1wyjściami stałej funkcji anonimowej „wypisz spację” " "&.
  • Do[foo,{j,#},{i,#}]to para zagnieżdżonych pętli do, w których jzakresy od 1do #i wewnątrz tych izakresów od 1do #.
  • m[[1[i,#,-i][[j~Mod~4]],j#-#+i+1-j]]="X"ustawia odpowiednią część macierzy na znak Xna podstawie ji i. -iWykorzystuje negatywne indeksowanie aby zapisać bajty od #-i+1. (Zapomniałem napisać Mod[j,4]jak j~Mod~4w oryginalnej wersji tego kodu.) Jenny_mathy zwróciła uwagę, że możemy użyć modułowej reszty do bezpośredniego indeksowania listy (zamiast używania Switch) w celu zaoszczędzenia 9 bajtów, a JungHwan Min wskazał, że nie T trzeba użyć, ReplacePartponieważ możemy ustawić część tablicy, która 1[i,#,-i][[j~Mod~4]]wykorzystuje dziwne zachowanie i ogólność, [[foo]]aby zaoszczędzić bajty{1,i,#,-i}[[j~Mod~4+1]]
  • Ponieważ meta ustaliło, że lista znaków jest łańcuchem (jak wskazał JungHwan Min ), nie musimy mapować żadnej funkcji w wierszach matrycy znaków, ponieważ jest to już lista „łańcuchów”.

Możesz to przetestować w piaskownicy Wolfram Cloud , wklejając poniższy kod i naciskając Shift + Enter lub Numpad Enter:

(m=" "&~Array~{#,#^2-#+1};Do[m[[1[i,#,-i][[j~Mod~4]],j#-#+i+1-j]]="X",{j,#},{i,#}];m)&@9//MatrixForm

1
Bardzo dobrze! możesz zastąpić StringJoin ciągiem „” <> # &, aby zapisać 4 bajty
J42161217,

@Jenny_mathy Dzięki za wskazówkę! To wydaje się całkiem przydatne.
Mark S.

2
Możesz także zamienić Switch [...] na {1, i, #, - i} [[j ~ Mod ~ 4 + 1]] i zaoszczędzić 9 bajtów!
J42161217,

1
Tak naprawdę nie potrzebujesz ReplaceParttutaj. m=ReplacePart[...]może być m[[{1,i,#,-i}[[j~Mod~4+1]],j#-#+i+1-j]]="X"- można z listy. Pozbywa się 15 bajtów. SetPart
JungHwan Min

1
{1,i,#,-i}[[j~Mod~4+1]]może być również 1[i,#,-i][[j~Mod~4]]. Ta sztuczka działa, ponieważ [[0]]zwraca Headwyrażenie.
JungHwan Min

4

C ++, 321 234 bajty

-87 bajtów dzięki Zacharýowi

#include<vector>
#include<string>
auto z(int n){std::vector<std::string>l;l.resize(n,std::string(n*n+n/2*(n-1),32));l[0][0]=79;int i=0,j,o=0;for(;i<n;++i)for(j=1;j<n;++j)l[i%4?i%4-1?i%4-2?0:n-j-1:n-1:j][i*n+j-i+(o+=i%2)]=79;return l;}

Zwraca wektor ciągów


Sprowadziłem to do 318 bajtów: repl.it/JpJ2
Zacharý

Korekta, zmniejszyłem ją do 239 bajtów : repl.it/JpJ2/1
Zacharý

Przepraszamy za spam, 234 bajty: repl.it/JpJ2/3
Zacharý

1
Co mogę powiedzieć, chyba że jesteś mile widziany!
Zacharý

@ Zacharý bardzo dziękuje panu
HatsuPointerKun

4

Mathematica, 179 bajtów

Rotate[(c=Column)@(t=Table)[{c@(a=Array)[" "~t~#<>(v="o")&,z,0],c@t[t[" ",z-1]<>v,z-1],c@a[t[" ",z-2-#]<>v&,z-1,0],c@t[v,z-Boole[!#~Mod~4<1]-1]}[[i~Mod~4+1]],{i,0,(z=#)-1}],Pi/2]&

edycja dla @JungHwanMin


Nie spodziewałem się, że będzie tak krótki, dobrze zrobiony!
Pan Xcoder

Tylko pytanie: czy można Mod[z,4]==0go zastąpić Mod[z,4]<1?
Pan Xcoder

tak, mogę trochę
pograć w

3
Naprawdę nie znam Matematyki, ale czy możesz zastąpić Mod[#,4]#~Mod~4dla -1 bajtów?
Pan Xcoder

1
Ups ... przypadkowo przegłosowano. Czy możesz edytować odpowiedź, abym mógł odwrócić ją do góry nogami?
JungHwan Min

4

05AB1E , 21 20 19 bajtów

Kod

Używa nowego trybu płótna:

Fx<)Nè'ONÉúR3212NèΛ

Wykorzystuje kodowanie 05AB1E . Wypróbuj online!

Wyjaśnienie:

F                      # For N in range(0, input)
 x<)                   #   Push the array [input, 2 × input - 1]
    Nè                 #   Retrieve the Nth element
      'ONÉúR           #   Push "O" if N is odd, else "O "
            3212Nè     #   Retrieve the Nth element of 3212
                  Λ    #   Write to canvas

Dla wejścia 6 daje to następujące argumenty (w tej samej kolejności) dla obszaru roboczego:

[<num>, <fill>, <patt>]
[6,     'O',     3]
[11,    'O ',    2]
[6,     'O',     1]
[11,    'O ',    2]
[6,     'O',     3]
[11,    'O ',    2]

Aby wyjaśnić, co robi płótno, wybieramy pierwszy zestaw argumentów z powyższej listy.

Liczba 6 określa długość ciągu, który zostanie zapisany na płótnie. Wypełniacz służy do pisania na płótnie, którym w tym przypadku jest O. Cyklicznie przebiega przez łańcuch wypełniający. Kierunek łańcucha jest określony przez ostatni argument, kierunek. Kierunki są następujące:

7  0  1
 \ | /
6- X -2
 / | \
5  4  3

Oznacza to, że 3 ustawia kierunek na południowy wschód , co można również wypróbować online .


zauważ również, że tryb płótna jest w fazie rozwoju i jest bardzo niestabilny
Adnan

: O 05AB1E mutuje się w węgiel drzewny (to także bije węgiel drzewny O_o)
tylko ASCII

@ Tylko ASCII Tak, widziałem wzrost wszystkich języków opartych na ASCII (węgiel drzewny, SOGL, V itp.) I widziałem, jak 05AB1E tonie w tle, więc musiałem coś z tym zrobić: p
Adnan

więc skopiowałeś węgiel? : P 05ab1e ma nawet płótno i druk kierunkowy (chociaż węgiel drzewny obsługuje tylko ten styl drukowania za pomocą pytona)
tylko ASCII

2

SOGL V0.12 , 36 bajtów

╝.H∫2\?.╝}F2%?№@.┌Ο};1w⁄Hh1ž}.4%1>?№

Wypróbuj tutaj!

Podstawową ideą jest, aby dla każdej liczby zakresu wejściowego wybrać dodanie przekątnej lub poziomej kropkowanej części, w którym to przypadku obróci tablicę, aby ułatwić dodawanie. Wyjaśnienie:

╝                                     get a diagonal from the bottom-left corner with the length of the input - the starting canvas
 .H∫                        }         for each number in the range [1,inp-1] do, pushing counter
    2\?  }                              if it divides by 2, then
       .╝                                 create another diagonal of the input
          F2%                           push counter % 2
             ?     }                    if that [is not 0]
              №                           reverse the current canvas upside down
               @.┌Ο                       get an alternation of spaces and dashes with the dash amount of the input length
                    ;                   get the canvas on top of the stack
                     1w⁄                get its 1st element length
                        H               decrease it
                         h              swap the bottom 2 items - the canvas is now at the bottom and the current addition ontop
                          1             push 1
                           ž            at 1-indexed coordinates [canvasWidth-1, 1] in the canvas insert the current part made by the Ifs
                             .4%1>?   if input%4 > 1
                                   №    reverse the array vertically

Gdyby wprowadzenie 1 nie było dozwolone, również ο.∫2%?.╝}F2\?№@.┌Ο};1w⁄Hh1ž}.4%1>?№by działało. Gdyby dozwolone były pływające liczby losowe, również .∫2%?.╝}F2\?№@.┌Ο};1w⁄Hh1ž}.4%1>?№by działały. Gdybym nie był leniwy i zaimplementowany , }F2%?mógłby zostać zastąpiony przez -4 bajty


2

Mathematica, 106 87 bajtów

SparseArray[j=i=1;k=#-1;Array[{j+=Im@i;k∣#&&(i*=I);j,#+1}->"o"&,l=k#+1,0],{#,l}," "]&

Zwraca SparseArrayobiekt Strings. Aby zwizualizować dane wyjściowe, możesz dołączyć Grid@. Zgłasza błąd w przypadku 1, ale można go zignorować.

Wyjaśnienie

j=i=1

Ustaw ii jna 1.

k=#-1

Ustaw kna wejście - 1.

l=k#+1

Ustaw lnak*input + 1

Array[ ..., l= ...,0]

Powtarzaj lczasy, zaczynając od 0, zwiększając za 1każdym razem ...


j+=Im@i

Dodaj urojoną część ido j...

k∣#&&(i*=I)

Jeśli bieżąca iteracja jest podzielna przez k, pomnóż iprzez urojoną jednostkę ...

{... j,#+1}->"o"

Utwórz Ruleobiekt, który zmienia element w pozycji {j, current iteration + 1}na"o"


SparseArray[ ...,{#,l}," "]

Stwórz SparseArray obiekt, używając wygenerowanych Ruleobiektów, z wymiarem {input, l}, używając " "jako pusty.

Wypróbuj na Wolfram Sandbox!


1
coś jest nie tak z przypadkiem n = 3
J42161217

1
n = 2, 4,5,6 ma również problemy z poprawnością, ale myślę, że działa to dla 7 i więcej. Jestem ciekawy: czy istnieje precedens, czy SparseArrayliczenie liczy się jako tablica? Można to wizualizować za pomocą Gridlub MatrixForm, ale normalnie nie liczyłbym go tutaj jako „listy ciągów”. Jeśli wystarcza tablica 2D, to na przykład odcina 8 bajtów od mojego rozwiązania (12 przed pomocą Jenny_mathy).
Mark S.

1
@Znaki. Również tablica ciągów znaków jest zgodna z meta-konsensusem . Jeśli coś jest niejasne, zapytaj PO (ponieważ on / ona ustala zasady, a nie my). Proste wyszukiwanie „SparseArray” na tej stronie daje mnóstwo SparseArrayodpowiedzi, więc zakładam, że jest w porządku.
JungHwan Min

1
@Znaki. Również ta strona ma wiele sztuczek w golfa Mathematica.
JungHwan Min

1
@JungHwanMin Edytowałem moją odpowiedź, tak jak prosiłeś
J42161217,

2

Python 3 , 228 226 224 215 197 195 bajtów

-11 bajtów Dzięki @Mr. Xcoder

-2 bajty Dzięki @Mr. Xcoder

def f(n,s=range):
 x=y=t=c=0;z=[]
 for i in s(n*n-n+2):c+=i%(n-(2<=n))<1;z+=[[x,y]];t=max(t,x);x+=2-c%2;y+=[-1,1][c%4<3]*(c%2)
 return'\n'.join(''.join(' O'[[k,j]in z]for k in s(t))for j in s(n))

Wypróbuj online!

Objaśnienie i mniej golfowy kod:

def f(n):
 x=y=t=c=0;z=[]                       #initialize everything
 for i in range(n*n-n+2):             #loop n*n-n+2 times which is the numberr of 'o's expected
    c+=i%[~-n,n]<n-1                  #if one cycle has been completed, increase c by 1, if n>1.                                            
    z+=[[x,y]]                        #add [x,y] to z(record the positions of 'o')
    t=max(t,x)                        #trap maximum value of x-coordinate(to be used later while calculatng whole string)
    r=[[2,0],[1,1],[2,0],[1,-1]][c%4] #r gives direction for x and y to move, adjust it as per c i.e. cycles
    x+=r[0];y+=r[1]                   #yield newer values of x and y 
 return '\n'.join(''.join(' o'[[k,j]in z]for k in range(t))for j in range(n)) #place space or 'o' accordingly as per the recorded posititons in z

1
Bardzo dobra robota. Gratulacje!
Pan Xcoder

@ Mr.Xcoder Dziękujemy. Muszę powiedzieć, że ten był trudny, szczególnie miał problemy z identyfikacją prawidłowego zasięgu.
officialaimm


1
215 bajtów , if 2>n:return'o'jest dość zbędny. Zrobiłem obejście c+=i%[~-n,n][2>n]<1zamiast z c+=i%~-n<1.
Pan Xcoder,

1
Przepraszam za bardzo późną poprawę, 195 bajtów
Mr. Xcoder

1

Haskell , 197 bajtów

a n c=take(2*n)$cycle$c:" "
r i n x y=take(div(3*n)2*(n-1)+1)$(' '<$[1..i])++(cycle$"O "++(a(2*n-i-3)y)++"O "++(a(n+i-2)x))
z n=take n$(r 0 n 'O' ' '):[r i n ' ' ' '|i<-[1..n-2]]++[r(n-1)n ' ' 'O']

Wypróbuj online!

Dzięki @Lynn: naprawiono odstępy między O s na poziomych segmentach zygzaka, ale kosztowało to dużo bajtów!

Kilka wyjaśnień:

  • rjest wierszem wyniku: ma 0 y y y y y 0 x x x 0 y ...format, liczbę xiy zależnie od wiersza i inicjałun
  • dla górnego rzędu x='0'iy=' '
  • dla środkowych rzędów x=' 'iy=' '
  • dla dolnego rzędu x=' 'iy='0'
  • take(div(3*n)2*(n-1)+1) tnie nieskończony rząd we właściwym miejscu
  • każde wyjście ma jeden górny wiersz i jeden dolny wiersz, z wyjątkiem gdy n=1: take nobsługuje tę skrzynkę.

Ładnie grał w golfa! Myślę, że możesz upuścić kilka takich miejsc. I replicate n xmoże być zastąpiony przez x<$[1..n]. Ponadto w Twojej odpowiedzi nie ma odstępów między Os na poziomych segmentach zygzaka.
Lynn

@ Lynn dzięki! z odstępami na segmentach poziomych moja metoda staje się nieporęczna, ale i tak chciałem naprawić kod ...
Jferard

Możesz sporo zaoszczędzić, używając operatorów i usuwając niepotrzebne spacje, patrz tutaj .
ბიმო

1

Python 2 , 155 151 146 137 bajtów

m=input()
n=m-1
r=range(n+2)
for L in zip(*[' '*i+'O'+n*' 'for i in(r+[n,m]*~-n+r[-2::-1]+([m,0]*n)[:-1])*m][:1+3*m/2*n]):print''.join(L)

Wypróbuj online!


@ Mr.Xcoder Ahh. Teraz widzę.
TFeld

@ Mr.Xcoder Naprawiono teraz.
TFeld

Jestem spóźniony o rok na imprezę golfową, ale `L`[2::5]oszczędzam bajt''.join(L)
Mr. Xcoder
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.