Padrão alternado

16

Em uma pergunta de stackoverflow agora excluída, alguém postou o seguinte:

Escreva um programa ou função para imprimir padrões alternados *e com #base em um número inteiro n. Alguns exemplos:

Entrada: n=1
Saída:

*

Entrada n=5
Saída de :

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

Entrada: n=8
Saída:

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

Uma vez que parecia um desafio muito legal de código de golfe, aqui está.

Como esses padrões são construídos?

A primeira linha começa com uma única *, seguida pela n-1quantidade de final #.
A segunda linha contém duas *, com n-2quantidade de liderança #.
A terceira linha começa com três *, seguidas pela n-3quantidade de# .
etc.

Quando chegamos ao meio (n/2 ), contamos novamente com a quantidade de *, que pode ser vista nos exemplos acima.

Observe que, para números de entrada ímpares, o par de linhas inversas (portanto, a primeira e a última; a segunda e a penúltima; etc.) são exatamente iguais. No n=5exemplo, a primeira e a última linha são *####; a segunda e a penúltima linha são ###**.
Para números de entrada pares, no entanto, o par de linhas inversas é invertido. No n=8exemplo, a primeira e a última linha são *#######e #######*; a segunda e a penúltima linha são######** e **######; etc.

Regras do desafio:

  • Você pode usar dois caracteres distintos para impressão em vez de *e #. Você pode usar Ae B; 3e 7;<e >; etc. Por favor, indique em suas respostas o que você usou.
  • Você pode assumir nque será um número inteiro positivo ( >= 1)
  • Você tem permissão para produzir uma lista / matriz de cadeias para cada linha ou uma matriz 2D de caracteres, em vez de imprimi-las em STDOUT.

Regras gerais:

  • Isso é , então a resposta mais curta em bytes vence.
    Não permita que idiomas com código de golfe o desencorajem a postar respostas com idiomas que não sejam codegolf. Tente encontrar uma resposta o mais curta possível para 'qualquer' linguagem de programação.
  • As regras padrão se aplicam à sua resposta, para que você possa usar STDIN / STDOUT, funções / método com os parâmetros adequados e programas completos do tipo retorno. Sua chamada.
  • As brechas padrão são proibidas.
  • Se possível, adicione um link com um teste para o seu código.
  • Além disso, é altamente recomendável adicionar uma explicação para sua resposta.

Casos de teste (primeiro n=1a n=10)

*

*#
#*

*##
#**
*##

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

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

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

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

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

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

*#########
########**
***#######
######****
*****#####
#####*****
****######
#######***
**########
#########*
Kevin Cruijssen
fonte
" Você pode usar dois caracteres distintos em vez de * e #. " - Eles precisam ser imprimíveis? Podemos usar NUL e SOH (códigos ASCII 0 e 1)?
ngn 27/07
Desculpe, apenas caracteres imprimíveis. Esclarecerá na descrição do desafio.
Kevin Cruijssen 27/07/2018

Respostas:

14

Geléia , 9 bytes

>þµoṚUÐeY

Experimente online!

Explicação

>þ           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
fonte
17

Python 2 , 62 bytes

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

Experimente online!

Usos xe espaço.

As linhas são calculadas assim:

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

Usando o %*sespecificador para escolher entre ne -n.

Lynn
fonte
6

MATL, 34 31 18 bytes

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

Experimente no MATL Online

Usa 0 para * e 1 para #. Baseado na resposta de Lynn's Jelly .


Resposta mais antiga, 31 bytes:

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

Experimente no MATL Online

Usa 1 para * e 0 para #.

         % 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 - Restabelecer Monica
fonte
6

APL (Dyalog Classic) , 18 bytes

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

Experimente online!

saídas em ABvez de*#

entrada avaliada f—

⍳⎕ o vetor 0 1 ... n-1

⊢⌊⌽min ( ) entre si ( ) e o reverso ( ) - ver trens

⊂>⊢⌊⌽onde o vetor como um todo ( ) é menor que cada um de seus ⊢⌊⌽- retorna um vetor de vetores booleanos (0/1)

⊢∘⌽\ reverter todos os outros vetores

misture em uma matriz

⎕ao alfabeto em maiúsculas, 'AB...Z'

⎕a[ ]substitua 0 1por'A' 'B'

ngn
fonte
Por curiosidade. Quantos bytes seria simplesmente gerar a matriz de 0s e 1s sem espaços? Estou assumindo que ⎕a[...}convertê-los para Ae Bsem espaços é mais curto do que mantê-los como 0e 1sem espaços, considerando que você o usou, mas é curioso saber se há muita diferença de bytes se você os mantiver como 0e 1.
Kevin Cruijssen
1
@KevinCruijssen Tanto quanto eu posso jogar golfe, teria o mesmo comprimento - ou ⎕d[... ]ou ⊃¨⍕¨... Na última expressão ⍕¨é "formato cada" - ele transforma cada número em um vetor de caracteres aninhado , então precisamos "primeiro cada "( ⊃¨) para obter apenas escalares de caracteres (e, portanto, nenhum espaço em branco ao imprimir).
ngn 25/07/18
5

Carvão , 21 bytes

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

Experimente online! Usos 0e 1. Link é uma versão detalhada do código e inclui §*#quais traduzem a saída para *e #na pergunta. Explicação:

    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
fonte
5

Gelatina ,  12  15 bytes

+3 correção n=1de bug de borda :(

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

Um programa completo que aceita um número inteiro que imprime a saída conforme definido no OP usando 0e 1para *e #respectivamente.

Experimente online!

Quão?

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
fonte
Parece que este é exatamente o meu algoritmo, mas uma implementação diferente que gera 0s em vez de 1s e vice-versa.
Erik the Outgolfer
Sim, efetivamente a mesma coisa ... e eu não havia atualizado minha postagem para mostrar a correção que fiz.
Jonathan Allan
4

Gelatina , 15 bytes

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

Experimente online!

Programa completo.

*= 1
#=0

Erik, o Outgolfer
fonte
4

Java 10, 145 bytes

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;}

Todo o ternário torna um pouco confuso, mas funciona bem. Tentei aplainar o loop aninhado e várias outras coisas, mas elas apenas aumentaram a contagem de bytes. Experimente online aqui .

Ungolfed:

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 bytes

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;}

Experimente on-line aqui (o TIO ainda não possui o Java 11, portanto, ele usa um método personalizado que resulta na mesma contagem de bytes que String#repeat()).

Agradecimentos a Kevin Cruijssen por jogar 52 bytes de forma impressionante!

Ungolfed:

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
fonte
3
Se você mudar para Java 11 você pode golfe para 127 bytes usando "*".repeat(...)e "#".repeat(...)(bem como devolver uma cadeia em vez de imprimir diretamente e golfe n-j-1a 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
Obrigado, é uma grande economia de bytes. Eu consegui criar uma versão de 145 bytes para o Java 10 usando loops aninhados - mal posso esperar pelo lançamento do Java 11, esse repeat()método é realmente bom para jogar golfe.
OOBalance
4

Lua ,  148  133 Bytes

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

Experimente online!

-15 bytes graças a @KevinCruijssen e @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
fonte
2
Não conheço Lua muito bem, mas parece que você pode salvar cinco bytes: (n+1)/2para -~n/2; or n-i+1para or-~n-i; i%2==0para i%2<1; e reverse() orpara reverse()or. Além disso, sua versão do TIO e contagem de bytes contêm um ponto-e-vírgula à direita, o que não parece ser necessário. Boa primeira resposta, no entanto. +1 de mim. E bem-vindo ao PPCG! :)
Kevin Cruijssen
2
Você realmente não precisa de nenhum ponto e vírgula. 133 bytes, incluindo as sugestões de Kevin.
Jo rei
@KevinCruijssen Thanks! Posso perguntar o que -~nestá fazendo nas suas sugestões? Definitivamente funciona, mas não entendo o porquê.
Azure Heights
1
@AzureHeights Sure. ~é um operador de negação bit a bit unário. O que é importante para o codegolfing, no entanto, é que ~ipossui o mesmo valor que -i-1. Portanto, podemos usar em -~ivez de i+1e em ~-ivez de i-1. Isso é útil em dois casos, que eu poderia utilizar em sua resposta: livrar-se dos parênteses, porque -e ~ter precedência do operador sobre outras operações matemáticas, portanto (n+1)/2pode ser -~n/2. E a outra parte útil é livrar-se de espaços em alguns casos, como fiz com or-~n-i.
Kevin Cruijssen
1
Aqui estão as duas dicas relevantes, se você quiser ler um pouco mais sobre isso: Use unário ~para x+1ex-1 e Use unário ~para a-b-1ea+b+1 . Todas as dicas gerais, bem como dicas específicas de idiomas ( dicas para jogar golfe em Lua , neste caso), podem ser interessantes para ler. :)
Kevin Cruijssen
3

Perl 5 + -pa -MPOSIX -M5.010, 58 bytes

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

Experimente online!

Dom Hastings
fonte
3

C (gcc) , 104 99 bytes

h,j,k;f(i){char s[h=i++];for(j=0;k=++j>i/2?i-j:j,j<i;memset(memset(s,42,h)+j%2*k,35,h-k),puts(s));}

Experimente online!

ErikF
fonte
3

C (gcc) , 118 108 bytes

Este não vai ganhar, mas é uma abordagem diferente (ou pelo menos acho que sim!) Em vez de fazer manipulações de cordas, uso o fato de que 10x-1 sobre [1 ..n]={9,99,999,...}, que pode ser multiplicado para obter o padrão apropriado; printf()então faz o preenchimento zero para justificação à direita.

Infelizmente, intsó tem alcance suficiente para fazer até 9 dígitos (em plataformas de 32 bits), então você precisa ir paralong padrões maiores; uma linguagem que faz aritmética MP nativamente pode ser capaz de usar isso para alguma coisa.

Agradecimentos a ceilingcat pela sugestão.

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))));}

Experimente online!


Prova de conceito de que isso funciona com aritmética MP:

C # (compilador C # mono) , 187 165 bytes

(143 bytes + 22 bytes para using System.Numerics;o cabeçalho)

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;}

Experimente online!

ErikF
fonte
1
Prova de conceito com números fora dos intervalos máximos de números nativos (usando C # e BigIntegers): Experimente on-line!
ErikF 26/07
3

Vim, 99 pressionamentos de tecla

É sempre interessante tentar fazer o vim com argumentos de entrada. É muito antinatural, então não será incrivelmente curto. Provavelmente existem outras boas abordagens para isso.

A entrada é assumida como sendo por si só em um buffer. Presume-se que os registros estejam vazios. Supõe-se que o editor seja alto o suficiente para conter o resultado sem rolar (isso pode ser tecnicamente evitado com o custo de algumas teclas).

"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

Explicação

 | 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:
 | *####                *#####
 | ###**                ####**
 | ***##                ***###
 | ###**                ###***
 | *####                **####
 |                      #####*

E na base64, com caracteres reais (insira inpute pressione as teclas keyse execute usando vim -u NONE -s keys input)

Im5EQG5pDRtNbWFHZGRNFidhSSobcXdndmpva29JKhtAd3FAdxs6c2V0IHZlPWFsbA1AbmxoFkBua3IjOiVzLyAvIy9nDW8bMkdxcWR0IyRwMmowQHFxQHE=
algmyr
fonte
2

R , 75 bytes

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

Experimente online!

  • Inspirado pela resposta @Lynn
  • função obtendo ncomo parâmetro e retornando uma matriz de 0/1onde 0corresponde '*'e 1corresponde a'#'
digEmAll
fonte
2

K (ngn / k) , 22 bytes

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

Experimente online!

{ } função com argumento x

!xa lista (0;1;...;x-1)

i: atribuir a i

i&|imínimos ( &) ie seu inverso ( |)

i>/:compare com maior que ( >) em irelação a cada elemento da lista à direita (/: ) - retorne uma matriz booleana (lista de listas)

i|:/'para cada ( ') j in i, invertida ( |:- precisamos que a :força |seja unária) o elemento correspondente j vezes ( n f/ xaplica-se f nvezes x). Efetivamente, inverta todas as outras linhas.

"*#" use elementos da matriz como índices na string "*#"

ngn
fonte