Patrón alterno


16

En una pregunta de stackoverflow ahora eliminada, alguien publicó lo siguiente:

Escriba un programa o función para imprimir patrones alternos *y #basados ​​en un número entero dado n. Algunos ejemplos:

Entrada: n=1
Salida:

*

Entrada n=5
Salida:

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

Entrada: n=8
Salida:

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

Como parecía un desafío de golf de código bastante bueno, aquí está.

¿Cómo se construyen estos patrones?

La primera línea comienza con un solo *, seguido de la n-1cantidad de seguimiento #.
La segunda línea contiene dos *, con una n-2cantidad de plomo #.
La tercera línea comienza con tres *, seguida de la n-3cantidad de seguimiento #.
etc.

Una vez que hemos alcanzado el medio ( n/2), contamos nuevamente con la cantidad de *, que se puede ver en los ejemplos anteriores.

TENGA EN CUENTA que para números de entrada impares, el par de líneas invertidas (primero y último; segundo y próximo al último; etc.) son exactamente iguales. En el n=5ejemplo, la primera y la última línea son *####; la segunda y la penúltima línea son ###**.
Sin embargo, para números de entrada pares, el par de líneas invertidas se invierte. En el n=8ejemplo, la primera y la última línea son *#######y #######*; la segunda y próxima a las últimas líneas son ######**y **######; etc.

Reglas de desafío:

  • Puede usar dos caracteres imprimibles distintos en lugar de *y #. Puedes usar Ay B; 3y 7; <y >; etc. Indique en sus respuestas lo que ha utilizado.
  • Puede suponer nque será un entero positivo ( >= 1)
  • Se le permite generar una lista / matriz de cadenas para cada línea o una matriz 2D de caracteres, en lugar de imprimirlos en STDOUT.

Reglas generales:

  • Este es el , por lo que la respuesta más corta en bytes gana.
    No permita que los lenguajes de code-golf lo desanimen a publicar respuestas con lenguajes que no sean codegolf. Trate de encontrar una respuesta lo más breve posible para 'cualquier' lenguaje de programación.
  • Se aplican reglas estándar para su respuesta, por lo que puede usar STDIN / STDOUT, funciones / método con los parámetros adecuados y programas completos de tipo retorno. Tu llamada.
  • Las lagunas predeterminadas están prohibidas.
  • Si es posible, agregue un enlace con una prueba para su código.
  • Además, se recomienda agregar una explicación para su respuesta.

Casos de prueba (primero a n=1través n=10)

*

*#
#*

*##
#**
*##

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

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

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

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

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

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

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

" Puede usar dos caracteres distintos en lugar de * y # ". ¿Tienen que ser imprimibles? ¿Podemos usar NUL y SOH (códigos ASCII 0 y 1)?
ngn

@ngn Lo siento, solo caracteres imprimibles. Se aclarará en la descripción del desafío.
Kevin Cruijssen

Respuestas:


14

Jalea , 9 bytes

>þµoṚUÐeY

Pruébalo en línea!

Explicación

>þ           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.

17

Python 2 , 62 bytes

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

Pruébalo en línea!

Usos xy espacio.

Las filas se calculan así:

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

Usando el %*sespecificador para elegir entre ny -n.



6

MATL, 34 31 18 bytes

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

Pruébalo en MATL Online

Utiliza 0 para * y 1 para #. Basado en la respuesta de Lynn's Jelly .


Respuesta anterior, 31 bytes:

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

Pruébalo en MATL Online

Utiliza 1 para * y 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

6

APL (Dyalog Classic) , 18 bytes

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

Pruébalo en línea!

salidas en ABlugar de*#

entrada evaluada

⍳⎕ el vector 0 1 ... n-1

⊢⌊⌽min ( ) entre ellos ( ) y su reverso ( ) - ver trenes

⊂>⊢⌊⌽ dónde está el vector como un todo ( ) menor que cada uno de sus ⊢⌊⌽- devuelve un vector de vectores booleanos (0/1)

⊢∘⌽\ revertir cualquier otro vector

mezclar en una matriz

⎕a el alfabeto en mayúscula, 'AB ...Z'

⎕a[ ]reemplazar 0 1con'A' 'B'


Por curiosidad. ¿Cuántos bytes sería simplemente generar la matriz de 0s y 1s sin espacios? Supongo que ⎕a[...}convertirlos en Ay Bsin espacios es más corto que mantenerlos como 0y 1sin espacios, teniendo en cuenta que lo ha usado, pero tengo curiosidad por saber si hay mucha diferencia en bytes si los mantiene como 0y 1.
Kevin Cruijssen

1
@KevinCruijssen Hasta donde puedo jugar, sería la misma longitud, ya sea ⎕d[... ]o ⊃¨⍕¨... En la última expresión ⍕¨es "formatear cada uno", convierte cada número en un carácter anidado vector de caracteres , por lo que necesitamos "primero cada uno "( ⊃¨) para obtener solo escalares de caracteres (y, por lo tanto, sin espacios en blanco al imprimir).
ngn

5

Carbón , 21 bytes

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

Pruébalo en línea! Usos 0y 1. El enlace es una versión detallada del código e incluye el §*#que traduce el resultado al *y #en la pregunta. Explicación:

    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

5

Jalea ,  12  15 bytes

+3 arreglando el n=1error del caso de borde :(

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

Un programa completo que acepta un número entero que imprime la salida como se define en el OP usando 0y1 para *y #respectivamente.

Pruébalo en línea!

¿Cómo?

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

Parece que este es exactamente mi algoritmo, pero una implementación diferente que genera 0s en lugar de 1s y viceversa.
Erik the Outgolfer

Sí, efectivamente, lo mismo ... y no había actualizado mi publicación para mostrar la solución que hice.
Jonathan Allan


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 el ternario lo hace un poco desordenado, pero funciona bien. Intenté aplanar el bucle anidado y varias otras cosas, pero solo aumentaron el recuento de bytes. Pruébelo en línea aquí .

Sin golf:

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

Pruébalo en línea aquí (TIO todavía no tiene Java 11, por lo que utiliza un método personalizado que produce el mismo recuento de bytes que String#repeat()).

Gracias a Kevin Cruijssen por jugar al golf la friolera de 52 bytes!

Sin golf:

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
}

3
Si cambia a Java 11 se puede jugar golf a 127 bytes utilizando "*".repeat(...)y "#".repeat(...)(así como el retorno de una cadena en lugar de directamente y jugar al golf 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

Gracias, eso es un gran ahorro en bytes. Me las arreglé para crear una versión de 145 bytes para Java 10 usando bucles anidados; no puedo esperar al lanzamiento de Java 11, ese repeat()método es realmente bueno para jugar al golf.
OOBalance

4

Lua ,  148133  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

Pruébalo en línea!

-15 bytes gracias a @KevinCruijssen y @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

2
No conozco demasiado bien a Lua, pero parece que puedes guardar cinco bytes: (n+1)/2para-~n/2 ; or n-i+1a or-~n-i; i%2==0a i%2<1; y reverse() ora reverse()or. Además, su versión de TIO y el número de bytes contienen un punto y coma final que no parece ser necesario. Buena primera respuesta, sin embargo. +1 de mi parte Y bienvenido a PPCG! :)
Kevin Cruijssen

2
En realidad no necesitas ninguno de los punto y coma. 133 bytes incluyendo las sugerencias de Kevin.
Jo King

@KevinCruijssen ¡Gracias! ¿Puedo preguntar qué -~nestá haciendo en sus sugerencias? Definitivamente funciona, pero no entiendo por qué.
Azure Heights

1
@AzureHeights Claro. ~es un operador unario de negación bit a bit. Sin embargo, lo importante para codegolfing es que ~itiene el mismo valor que -i-1. Por tanto, podemos usar en -~ilugar de i+1y en ~-ilugar de i-1. Esto es útil en dos casos, que podría utilizar en su respuesta: deshacerse del paréntesis, porque -y ~tiene prioridad de operador sobre otras operaciones matemáticas, por lo que(n+1)/2 puede ser -~n/2. Y la otra parte útil es deshacerse de los espacios en algunos casos, como hice con or-~n-i.
Kevin Cruijssen

1
Estos son los dos consejos relevantes si desea leer un poco más al respecto: Use unary ~para x+1yx-1 y Use unary ~para a-b-1ya+b+1 . Todos los consejos generales, así como los consejos específicos del idioma ( consejos para jugar al golf en Lua en este caso), pueden ser interesantes de leer. :)
Kevin Cruijssen




3

C (gcc) , 118 bytes

Este no va a ganar, pero es un enfoque diferente (¡o al menos eso creo!) En lugar de hacer manipulaciones de cuerdas, aprovecho el hecho de que 10X-1 terminado [1 ..norte]={9 9,99,999,...}, que luego se puede multiplicar para obtener el patrón apropiado; printf()luego hace el relleno de cero para la justificación correcta.

Lamentablemente, intsolo tiene un rango suficiente para hacer hasta 9 dígitos (en plataformas de 32 bits), por lo que debe buscar longpatrones más grandes; un lenguaje que nativamente hace aritmética MP podría usar esto para algo.

Gracias a ceilingcat por la sugerencia.

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

Pruébalo en línea!


Prueba de concepto de que esto funciona con aritmética MP:

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

(143 bytes + 22 bytes para using System.Numerics;el encabezado)

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

Pruébalo en línea!


1
Prueba de concepto con números fuera de los rangos de enteros nativos máximos (usando C # y BigIntegers): ¡ Pruébelo en línea!
ErikF

3

Vim, 99 pulsaciones de teclas

Siempre es interesante intentar hacer vim con argumentos de entrada. Es muy poco natural, por lo que no va a ser sorprendentemente corto. Probablemente hay otros buenos enfoques para esto.

Se supone que la entrada está sola en un búfer. Se supone que los registros están vacíos. Se supone que el editor es lo suficientemente alto como para contener el resultado sin desplazamiento (técnicamente esto podría evitarse a costa de algunas pulsaciones de 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

Explicación

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

Y en base64, con caracteres reales (ingrese la entrada en input y las teclas keysy ejecute usando vim -u NONE -s keys input)

Im5EQG5pDRtNbWFHZGRNFidhSSobcXdndmpva29JKhtAd3FAdxs6c2V0IHZlPWFsbA1AbmxoFkBua3IjOiVzLyAvIy9nDW8bMkdxcWR0IyRwMmowQHFxQHE=

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

Pruébalo en línea!

  • Inspirado por la respuesta de @Lynn
  • función obteniendo ncomo parámetro y devolviendo una matriz de 0/1donde 0corresponde '*'y 1corresponde a'#'

2

K (ngn / k) , 22 bytes

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

Pruébalo en línea!

{ } funcionar con argumento x

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

i: asignar a i

i&|imínimos ( &) de iy su reverso (| )

i>/:compare con mayor que ( >) icontra cada elemento de la lista de la derecha ( /:) - devuelva una matriz booleana (lista de listas)

i|:/'para cada ( ') j eni , reversa ( |:- necesitamos que la :fuerza |sea ​​unaria) el elemento correspondiente j veces (se n f/ xaplica f nveces x). Efectivamente, invierta cada dos filas.

"*#" usar elementos matriciales como índices en la cadena "*#"

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.