Wzór naprzemienny

16

W teraz usuniętym pytaniu dotyczącym przepływu stosów ktoś opublikował następujące informacje:

Napisać program lub funkcję do drukowania wzorów zmiennego *i #na podstawie danej liczby całkowitej n. Kilka przykładów:

Wejście: n=1
Wyjście:

*

Dane n=5
wyjściowe:

*####
###**
***##
###**
*####

Wejście: n=8
Wyjście:

*#######
######**
***#####
####****
****####
#####***
**######
#######*

Ponieważ wyglądało to na całkiem fajne wyzwanie do gry w golfa, oto jest.

Jak budowane są te wzorce?

Pierwszy wiersz zaczyna się od pojedynczego *, a po nim n-1końcowy #.
Drugi wiersz zawiera dwa *, z n-2prowadzeniem #.
Trzecia linia zaczyna się od trzech *, po których następuje n-3końcowa liczba #.
itp.

Gdy osiągniemy środek ( n/2), odliczamy ponownie ilość *, co można zobaczyć w powyższych przykładach.

UWAGA: w przypadku nieparzystych liczb wejściowych odwrócona para wierszy (pierwsza i ostatnia; druga i następna ostatnia; itd.) Są dokładnie takie same. W n=5przykładzie pierwsza i ostatnia linia to *####; druga i ostatnia linia to ###**.
Jednak dla parzystych liczb wejściowych odwrócona para linii jest odwrócona. W n=8przykładzie pierwszą i ostatnią linią są *#######i #######*; drugą i ostatnią linią są ######**i **######; itp.

Zasady konkursu:

  • Możesz użyć dowolnych dwóch różnych znaków drukowalnych zamiast *i #. Możesz użyć Ai B; 3i 7; <i >; itp. Podaj w swoich odpowiedziach, czego użyłeś.
  • Możesz założyć n, że będzie dodatnią liczbą całkowitą ( >= 1)
  • Możesz wydrukować listę / tablicę ciągów dla każdej linii lub macierz 2D znaków, zamiast drukować je do STDOUT.

Główne zasady:

  • To jest , więc wygrywa najkrótsza odpowiedź w bajtach.
    Nie pozwól, aby języki kod-golfowe zniechęcały Cię do publikowania odpowiedzi w językach niekodujących golfa. Spróbuj znaleźć możliwie najkrótszą odpowiedź na „dowolny” język programowania.
  • Do odpowiedzi mają zastosowanie standardowe reguły , więc możesz używać STDIN / STDOUT, funkcji / metody z odpowiednimi parametrami i zwracanymi typami, pełnych programów. Twoja decyzja.
  • Domyślne luki są zabronione.
  • Jeśli to możliwe, dodaj link z testem swojego kodu.
  • Zalecane jest również dodanie wyjaśnienia do odpowiedzi.

Przypadki testowe (od pierwszego n=1do drugiego n=10)

*

*#
#*

*##
#**
*##

*###
##**
**##
###*

*####
###**
***##
###**
*####

*#####
####**
***###
###***
**####
#####*

*######
#####**
***####
###****
***####
#####**
*######

*#######
######**
***#####
####****
****####
#####***
**######
#######*

*########
#######**
***######
#####****
*****####
#####****
***######
#######**
*########

*#########
########**
***#######
######****
*****#####
#####*****
****######
#######***
**########
#########*
Kevin Cruijssen
źródło
Możesz użyć dowolnych dwóch różnych znaków zamiast * i #. ” - Czy muszą być drukowalne? Czy możemy używać NUL i SOH (kody ASCII 0 i 1)?
ngn
@ngn Przepraszamy, tylko znaki do wydruku. Wyjaśni w opisie wyzwania.
Kevin Cruijssen

Odpowiedzi:

14

Galaretka , 9 bajtów

>þµoṚUÐeY

Wypróbuj online!

Wyjaśnienie

>þ           Create a table of (x>y) over [1…n]×[1…n]:
               [0 1 1 1 1]
               [0 0 1 1 1]
               [0 0 0 1 1]
               [0 0 0 0 1]
               [0 0 0 0 0]
  µ          Take this array, and...
   oṚ        OR it with its reverse:
               [0 1 1 1 1]
               [0 0 1 1 1]
               [0 0 0 1 1]
               [0 0 1 1 1]
               [0 1 1 1 1]
    UÐe      Apply U (reverse) to even-indexed rows.
       Y     Join by newlines.
Lynn
źródło
17

Python 2 , 62 bajty

lambda n:["%*s"%(i%2*2*n-n,"x"*min(i+1,n-i))for i in range(n)]

Wypróbuj online!

Zastosowania xi przestrzeń.

Wiersze są obliczane w następujący sposób:

"%-5s" % "x"      == "x    "
"%5s"  % "xx"     == "   xx"
"%-5s" % "xxx"    == "xxx  "
"%5s"  % "xx"     == "   xx"
"%-5s" % "x"      == "x    "

Korzystanie ze %*sspecyfikatora do wyboru pomiędzy ni -n.

Lynn
źródło
6

MATL, 34 31 18 bajtów

:t!>tPY|!"@X@oQ&P!

Wypróbuj na MATL Online

Używa 0 dla * i 1 dla #. Na podstawie odpowiedzi Galaretki Lynn .


Starsza odpowiedź, 31 bajtów:

2/tk:wXk:Ph"X@ot~XHh@Gy-hHQ&PY"

Wypróbuj na MATL Online

Używa 1 dla * i 0 dla #.

         % implicit input, say 5
2/       % divide input number by 2 [2.5]
tk       % make a copy and floor that [2.5, 2]
:        % create range 1 to the floored value [2.5, [1, 2]]
wXk      % bring out the division result and this time ceil it
         %  [[1, 2], 3]
:        % create range 1 to that [[1, 2], [1, 2, 3]]
Ph       % flip the last array and concatenate horizontally 
         %  [[1, 2, 3, 2, 1]]
"        % loop through the array
  X@o    % Is the current loop index odd? 1 for odd, 0 for even
  t~     % duplicate and logical negate that
  XH     % copy that value to clipboard H
  h      % and concatenate the values ([1 0] on odd iterations, [0 1] on even) 
  @      % push current value from array (say 2, then stack is [[0 1], 2)
  G      % push input again
  y-     % subtract current array value from input [[0 1], 2, 3]
  h      % concatenate those two [[0 1], [2, 3]]
  H      % get the stored value from clipboard H (1 for even iterations, 0 for odd) 
  Q      % increment that
  &P     % flip the array in that dimension: in even iterations, this flips
         %   across columns and hence inverts the two values. [[0 1], [3, 2]]
         %   in odd iterations, it's a no-op
  Y"     % run-length decoding - repeat the element from first array the number of times
         %  specified in the second array
         % implicit loop end, implicit output
sundar - Przywróć Monikę
źródło
6

APL (Dyalog Classic) , 18 bajtów

a[↑⊢∘⌽\(⊂>⊢⌊⌽)⍳⎕]

Wypróbuj online!

wyjścia ABzamiast*#

oceniane wejście n

⍳⎕ wektor 0 1 ... n-1

⊢⌊⌽min ( ) między sobą ( ) i ich zwrotem ( ) - patrz pociągi

⊂>⊢⌊⌽gdzie wektor jako całość ( ) jest mniejszy od każdego z nich ⊢⌊⌽- zwraca wektor wektorów boolowskich (0/1)

⊢∘⌽\ odwróć co drugi wektor

wymieszać w matrycę

⎕awielkie litery alfabetu angielskiego, 'AB...Z'

⎕a[ ]wymienić 0 1z'A' 'B'

ngn
źródło
Z ciekawości. Ile by to było po prostu wyprowadzić macierz zer i jedynek bez spacji? Zakładam, że ⎕a[...}konwersja ich na spacje Ai Bbez spacji jest krótsza niż zachowanie ich jako spacji 0i 1bez spacji, biorąc pod uwagę, że ich użyłeś, ale po prostu ciekawi mnie, czy istnieje duża różnica w bajtach, jeśli zachowujesz je jako 0i 1.
Kevin Cruijssen
1
@KevinCruijssen O ile mogę grać w golfa, miałaby taką samą długość - albo ⎕d[... ]albo ⊃¨⍕¨... W tym ostatnim wyrażeniu ⍕¨jest „formatuj każdy” - zamienia każdą liczbę w zagnieżdżony wektor znaków , więc potrzebujemy „najpierw każdego” „( ⊃¨), aby uzyskać tylko skalary char (i dlatego nie ma spacji podczas drukowania).
ngn
5

Węgiel drzewny , 21 bajtów

≔⮌…⁰NθEθ⭆蛧⟦μλ⟧κ⌊⟦κι

Wypróbuj online! Używa 0i 1. Link jest do informacji pełnej wersji kodu i obejmuje §*#co przekłada wyjście do *i #w pytaniu. Wyjaśnienie:

    N                   Input number
  …⁰                    Range from 0
 ⮌                      Reversed
≔    θ                  Assign to `q`
      Eθ                Map over reversed range
        ⭆θ              Map over reversed range and join
           §⟦μλ⟧κ       Alternate between range and reversed range column
                 ⌊⟦κι   Minimum of range and reversed range row
          ›             Greater
                        Implicitly print each row on its own line
Neil
źródło
5

Galaretka ,  12  15 bajtów

+3 naprawianie n=1błędu krawędzi :(

R«Ṛ$‘r⁸ṬUÐe0YE?

Pełną programu przyjmującą całkowitą drukowany wyjście, jak zdefiniowano w PO przy użyciu 0i 1do *i #odpowiednio.

Wypróbuj online!

W jaki sposób?

R«Ṛ$‘r⁸ṬUÐe0YE? - Main Link: integer, n
R               - range -> [1,2,3,4,...,n]
   $            - last two links as a monad:
  Ṛ             -   reverse -> [n,...,4,3,2,1]
 «              -   minimum (vectorises) -> [1,2,3,4,...,4,3,2,1]
    ‘           - increment (vectorises) -> [2,3,4,5,...,5,4,3,2]
      ⁸         - chain's left argument, n
     r          - inclusive range (vectorises) -> [[2,3,...,n],[3,4,...n],[4,5,...n],[5,...n],...,[5,...n],[4,5,...n],[3,4,...n],[2,3,...,n]]
       Ṭ        - untruth (vectorises) -> [[0,1,1,...,1],[0,0,1,1,...,1],[0,0,0,1,...,1],[0,0,0,0,1,...,1],...,[0,0,0,0,1,...,1],[0,0,0,1,...,1],[0,0,1,1,...,1],[0,1,1,...,1]]
         Ðe     - apply to entries with even indices:
        U       -   upend              -> [[0,1,1,...,1],[1,1,...,1],[0,0,0,1,...,1],[1,...,1,0,0,0,0],...]
              ? - if...
             E  - ...condition: all equal? (only true when n=1, where we have [1,1])
           0    - ...then: zero
            Y   - ...else: join with newline characters
                - implicit print
Jonathan Allan
źródło
Wygląda na to, że jest to dokładnie mój algorytm, ale inna implementacja, która generuje 0 zamiast 1 i odwrotnie.
Erik the Outgolfer
Tak, faktycznie to samo ... i nie zaktualizowałem mojego postu, aby pokazać poprawkę, którą wprowadziłem.
Jonathan Allan
4

Galaretka , 15 bajtów

r1«RR;ṬṖɗ€‘UÐeY

Wypróbuj online!

Pełny program

*= 1
#=0

Erik the Outgolfer
źródło
4

Java 10, 145 bajtów

n->{var r=new char[n][n];for(int j=0,k;j<n;++j)for(k=0;k<n;)r[j][k]=k++<(j<n/2?j%2<1?j+1:n+~j:j%2>0?j:n-j)?j%2<1?'*':'#':j%2>0?'*':'#';return r;}

Wszystkie trójskładniki sprawiają, że jest nieco niechlujny, ale działa dobrze. Próbowałem spłaszczyć zagnieżdżoną pętlę i różne inne rzeczy, ale tylko zwiększyły liczbę bajtów. Wypróbuj online tutaj .

Nie golfowany:

n -> { // lambda taking an integer as output and returning a char[][]
    var r = new char[n][n]; // the output array; we make use of Java 10's var here (replace with char[][] for another 4 bytes to make this work in Java 8)
    for(int j = 0, k; j < n; ++j) // iterate over the lines
        for(k = 0; k < n; )       // iterate over the j'th line
            r[j][k] = // set the current character
                      k++ < // determine if we're in the first or second portion of the line:
                            (j < n/2 ? // for the first half of the output:
                                 j%2 < 1  // on even lines ...
                                 ? j + 1  // ... print the first symbol j+1 times ...
                                 : n + ~j // ... on odd lines, print it n-j-1 times.
                             : j%2 > 0 ?  // for the second half of the output, on odd lines ...
                                 j :      // ... print the first symbol j times ...
                                 n - j)   // ... on even lines, print it n-j times.
                      ? j%2 < 1 ? '*' : '#'  // for the first part of the line, use '*' on even lines, '#' otherwise
                      : j%2 > 0 ? '*' : '#'; // for the second part of the line, use '*' on odd lines, '#' otherwise
    return r; // return the completed array
}

Java 8 11, 179 127 bajtów

n->{String r="",a,b;for(int j=0;j<n;b="#".repeat(j<n/2?n+~j:j),r+=(j++%2<1?a+b:b+a)+"\n")a="*".repeat(j<n/2?j+1:n-j);return r;}

Wypróbuj online tutaj (TIO nie ma jeszcze Java 11, więc używa niestandardowej metody, która powoduje taką samą liczbę bajtów jak String#repeat()).

Dzięki Kevin Cruijssen za grę w golfa aż 52 bajty!

Nie golfowany:

n -> { // lambda taking an int argument and returning a String
    String r = "", // the output String
           a,      // temporary String containing the '*'s
           b;      // temporary String containing the '#'s
    for(int j = 0; j < n; // loop over the lines
        b = "#".repeat( // repeat the '#' character ...
            j < n/2 ? n + ~j // ... n-j-1 times in the first half of the output ...
            : j), // ... j times in the second half
        r += (j++ % 2 < 1 ? a + b : b + a) + "\n") // assemble the j'th line and append it to the output: on even lines, the '*'s go first; on odd lines, the '#'s go first
        a = "*".repeat( // repeat the '*' character ...
              j < n/2 ? j + 1 // ... j+1 times in the first half of the output ...
              : n - j); // n-j times in the second half
    return r; // return the completed output
}
OOBalance
źródło
3
Jeśli zmienisz język na Java 11, możesz zagrać w golfa do 127 bajtów, używając "*".repeat(...)i "#".repeat(...)(a także zwracając ciąg zamiast bezpośredniego drukowania i gry n-j-1w golfa n+~j):n->{String r="",a,b;for(int j=0;j<n;b="#".repeat(j<n/2?n+~j:j),r+=(j++%2<1?a+b:b+a)+"\n")a="*".repeat(j<n/2?j+1:n-j);return r;}
Kevin Cruijssen
Dzięki, to wielka oszczędność w bajtach. Udało mi się stworzyć 145-bajtową wersję dla Java 10 za pomocą zagnieżdżonych pętli - nie mogę się doczekać wydania Java 11, ta repeat()metoda jest naprawdę fajna do gry w golfa.
OOBalance
4

Lua ,  148  133 bajtów

function(n)t,a,b={},".","#"for i=1,n do r=i<n/2+1 and i or-~n-i s=a:rep(r)..b:rep(n-r)t[i]=i%2<1 and s:reverse()or s end return t end

Wypróbuj online!

-15 bajtów dzięki @KevinCruijssen i @JoKing.

function(n)
   t = {}; a = "."; b = "#"          -- initialize variables, output is in table
                                     -- strings are needed in variables for
                                     --   the str:rep and str:reverse syntax

   for i = 1, n do                          -- build the rows of the table
      r = i<=(n+1)/2 and i or n-i+1         -- logic used to count up then down
      str = a:rep(r)..b:rep(n-r)            -- append correct number of '.'s, fill
                                            --   in the rest with '#'s
      t[i]=i%2==0 and str:reverse() or str  -- logic used to control reversing
   end
   return t                                 -- return table
end
Azure Heights
źródło
2
Nie znam Lui zbyt dobrze, ale wydaje się, że można zaoszczędzić pięć bajtów: (n+1)/2na -~n/2; or n-i+1do or-~n-i; i%2==0do i%2<1; i reverse() ordo reverse()or. Ponadto, zarówno wersja TIO, jak i liczba bajtów zawierają ciągły średnik, który nie wydaje się konieczny. Ładna pierwsza odpowiedź. +1 ode mnie Witamy w PPCG! :)
Kevin Cruijssen
2
Tak naprawdę nie potrzebujesz żadnego średnika. 133 bajty, w tym sugestie Kevina.
Jo King
@KevinCruijssen Thanks! Czy mogę zapytać, co -~nrobi twoja sugestia? To zdecydowanie działa, ale nie rozumiem dlaczego.
Azure Heights
1
@AzureHeights Sure. ~jest jednoargumentowym operatorem negacji bitowej. Jednak ważne dla codegolfing jest to, że ~ima taką samą wartość jak -i-1. Możemy więc użyć -~izamiast i+1i ~-izamiast i-1. Jest to przydatne w dwóch przypadkach, które mogę wykorzystać w twojej odpowiedzi: pozbyć się nawiasów, ponieważ- i ~mają pierwszeństwo nad innymi operatora operacji matematycznych, więc (n+1)/2może zatem być -~n/2. Inną przydatną częścią jest pozbycie się przestrzeni w niektórych przypadkach, tak jak to zrobiłem or-~n-i.
Kevin Cruijssen
1
Oto dwie istotne wskazówki, jeśli chcesz przeczytać więcej na ten temat: Użyj unary ~dla x+1ix-1 i Użyj unary ~dla a-b-1ia+b+1 . Wszystkie ogólne wskazówki, a także wskazówki dotyczące konkretnego języka ( dla języka ( w tym przypadku wskazówki dotyczące gry w golfa w Lua ) mogą być interesujące do przeczytania. :)
Kevin Cruijssen
3

Kotlin , 86 bajtów

{n:Int->for(i in 0..n)println("%${i%2*2*n-n}s".format("x".repeat(Math.min(i+1,n-i))))}

Wypróbuj online!

Zastosowania xi spacja jako symbole wyjściowe. Pochodzi z Lynn Answer

YGolybev
źródło
3

Perl 5 + -pa -MPOSIX -M5.010, 58 bajtów

say+sort{$|--}1x abs,2x("@F"-abs)for(1..ceil$_/=2),-$_..-1

Wypróbuj online!

Dom Hastings
źródło
3

C (gcc) , 118 108 bajtów

Ten nie wygra, ale jest to inne podejście (a przynajmniej tak mi się wydaje!) Zamiast manipulować strunami, wykorzystuję fakt, że 10x-1 nad [1 ..n]={9,99,999,...}, które następnie można pomnożyć, aby uzyskać odpowiedni wzór; printf()następnie uzupełnia zero dla wyrównania do prawej.

Niestety, intma tylko wystarczający zasięg, aby zrobić do 9 cyfr (na platformach 32-bitowych), więc musisz przejść dolong większych wzorów; język, który natywnie wykonuje arytmetykę MP, może być w stanie użyć tego do czegoś.

Dzięki pułapkowi cat za sugestię.

h,j,k;p(h){h=h?10*p(--h):1;}f(i){for(j=0,h=i++;k=++j>i/2?i-j:j,j<i;printf("%0*d\n",h,~-p(k)*p(j%2*(h-k))));}

Wypróbuj online!


Dowód koncepcji, że działa to z arytmetyką MP:

C # (kompilator Mono C #) , 187 165 bajtów

(143 bajty + 22 bajty dla using System.Numerics;nagłówka)

q=>{var r="";for(int j=0,h=q+1,k;j<q;r+=((BigInteger.Pow(10,k)-1)*BigInteger.Pow(10,j%2*(q-k))).ToString("D"+q)+"\n")k=++j>h/2?h-j:j;return r;}

Wypróbuj online!

ErikF
źródło
1
Dowód koncepcji z liczbami poza maksymalnymi natywnymi zakresami liczb całkowitych (przy użyciu C # i BigIntegers): Wypróbuj online!
ErikF
3

Vim, 99 klawiszy

Zawsze interesujące jest wykonanie vima z argumentami wejściowymi. To bardzo nienaturalne, więc nie będzie niesamowicie krótkie. Prawdopodobnie istnieją inne dobre podejścia do tego.

Zakłada się, że dane wejściowe są same w buforze. Przyjmuje się, że rejestry są puste. Zakłada się, że edytor jest wystarczająco wysoki, aby zawierać wynik bez przewijania (można tego technicznie uniknąć kosztem niektórych naciśnięć klawiszy).

"nD@ni<cr><esc>MmaGddM
<c-v>'aI*<esc>qwgvjokoI*<esc>@wq@w<esc>
:set ve=all<cr>@nlh<c-v>@nkr#
:%s/ /#/g<cr>o<esc>
2Gqqdt#$p2j0@qq@q

Wyjaśnienie

 | Buffer state (odd and even case):
 | 5                    6

"nD              read input into register n
@ni<cr><esc>     add n newlines
MmaGddM<c-v>'a   visual block select center row(s)
I*<esc>          prepend a column of *
qw               record macro w
  gvjoko         expand selection up and down
  I*<esc>
  @w             recurse
q
@w<esc>          run macro w and exit visual block select

 | Buffer state:
 | *                    *
 | **                   **
 | ***                  ***
 | **                   ***
 | *                    **
 |                      *

:set ve=all<cr>  move anywhere!
@nlh<c-v>@nkr#   add last column of #s

 | Buffer state:
 | *   #                *    #
 | **  #                **   #
 | *** #                ***  #
 | **  #                ***  #
 | *   #                **   #
 |                      *    #

:%s/ /#/g<cr>      replace spaces with #

 | Buffer state:
 | *####                *#####
 | **###                **####
 | ***##                ***###
 | **###                ***###
 | *####                **####
 |                      *#####

o<esc>2G           prep and jump to line 2
qqdt#$p2j0@qq@q    (effectively) flip every other onward

 | Buffer state:
 | *####                *#####
 | ###**                ####**
 | ***##                ***###
 | ###**                ###***
 | *####                **####
 |                      #####*

I w base64, z rzeczywistymi znakami (wprowadź dane wejściowe inputi naciśnięcia klawiszy keysi uruchom używając vim -u NONE -s keys input)

Im5EQG5pDRtNbWFHZGRNFidhSSobcXdndmpva29JKhtAd3FAdxs6c2V0IHZlPWFsbA1AbmxoFkBua3IjOiVzLyAvIy9nDW8bMkdxcWR0IyRwMmowQHFxQHE=
algmyr
źródło
2

R , 75 bajtów

function(n)outer(1:n,1:n,function(x,y,a=x<y|x>n-y+1)+ifelse(x%%2,a,rev(a)))

Wypróbuj online!

  • Zainspirowany odpowiedzią @Lynn
  • funkcja pobiera njako parametr i zwraca macierz 0/1gdzie 0odpowiada '*'i 1odpowiada'#'
digEmAll
źródło
2

K (ngn / k) , 22 bajty

{"*#"i|:/'i>/:i&|i:!x}

Wypróbuj online!

{ } funkcja z argumentem x

!x Lista (0;1; ...;x-1)

i: Przypisać do i

i&|iminima ( &) ii jego odwrotność (| )

i>/:porównaj z większym niż ( >) iwzględem każdego elementu z listy po prawej stronie (/: ) - zwróć macierz boolowską (listę list)

i|:/'dla każdego ( ') j in i, odwróć ( |:- musimy :wymusić |by być jednością) odpowiedni element j razy (n f/ x stosuje f nczasy na x). Skutecznie odwróć co drugi rząd.

"*#" użyj elementów macierzy jako wskaźników w ciągu "*#"

ngn
źródło