Dibujar un reloj de arena

32

Nuevamente inspirado por una tarea para la Programación 101, aquí hay otro desafío.

Entrada:

  • Un entero positivo n >= 3. (tiene que ser extraño)

Salida:

  • nlíneas de asteriscos, donde la primera línea tiene nasteriscos y cada nueva línea tiene dos asteriscos menos que la línea anterior. Hasta golpear 1 asterisco. A partir de ahí, cada nueva línea tiene dos asteriscos más que la línea anterior hasta volver a los nasteriscos. Los espacios o algo así como espacios deben usarse para alinear los asteriscos para que realmente se vea como un reloj de arena.

Reglas generales:

  • Las nuevas líneas finales están permitidas pero no tienen que usarse.
  • sangrado es imprescindible.
  • Este es el código de golf, por lo que la respuesta más corta en bytes gana.
  • Como el curso se imparte en C ++, estoy ansioso por ver soluciones en C ++.

Caso de prueba (n = 5):

*****
 ***
  *
 ***
*****
Chico enfermo
fuente
editado en consecuencia, gracias :-)
Sickboy
3
Posible duplicado de Dibujar un triángulo asterisco
Oliver Ni
3
@Oliver Teniendo en cuenta que OP escribió "Dibujar un triángulo asterisco", no estoy completamente seguro de que llamar a este desafío un duplicado sea justo. Sin embargo, definitivamente está relacionado.
Sherlock9
19
Como no todos aquí conocen el contexto completo, OP publicó originalmente el "Dibujar un triángulo asterisco" y editó este desafío como un desafío adicional. Les dijimos que eliminaran esa parte y la convirtieran en un desafío diferente (lo cual hicieron). Este desafío no es un duplicado. OP está haciendo lo que muchos usuarios de alta reputación, e incluso algunos mods han recomendado.
DJMcMayhem
2
@JDL: No, ¿por qué lo harías? Ah, ahora entiendo lo que quieres decir con cuadrado ... :-D
Sickboy

Respuestas:

20

Carbón de leña , 6 bytes

G↘←↗N*

Muy simple. Dibuje una poli G en de *, con longitud lateral tomada desde una entrada N umber, donde los lados bajan-y-derecha, horizontalmente a la izquierda y de arriba a la derecha:

*   *
 * *
  *
 * *
*****

Luego autocompletar el contorno y llenarlo.

*****
 ***
  *
 ***
*****

Pruébalo en línea!

DLosc
fuente
Ja, eso es bastante loco!
CT14.IT
66
¡Este lenguaje es muy interesante! Estaré observando esto muy de cerca a partir de ahora: p.
Adnan
No he visto este idioma antes ... ¡Parece interesante! Me pregunto qué obtendrías si lo combinaras con Jelly de alguna manera ...
Esolanging Fruit
12

Python 2, 57 bytes

N=n=input()
exec"print('*'*max(n,2-n)).center(N);n-=2;"*n

Un programa completo Va línea por línea, imprimiendo el número correcto de asteriscos centrados.

Una función recursiva era más larga (67 bytes):

f=lambda n,p='':p+n*'*'+'\n'+(1%n*' 'and f(n-2,p+' ')+p+n*'*'+'\n')

o

f=lambda n,p='':1/n*(p+'*\n')or f(n-2,p+' ').join([p+n*'*'+'\n']*2)
xnor
fuente
Quería sugerir intentar reemplazar el maxcon un abs, pero todo lo que obtuve es abs(n-1)+1, lo que es peor porque la adición requiere paréntesis
njzk2
@ njzk2 Puede cortar los parens haciendo '*'*-~abs(n-1), pero luego tiene la misma longitud que '*'*max(n,2-n).
xnor
Hay def f(n,s=''):r=s+'*'*n+'\n';return 1/n*r or r+f(n-2,s+' ')+r61 bytes, pero aún es más largo. Incluso con una nueva línea líder, def f(n,s='\n'):r=s+'*'*n;return 1/n*r or r+f(n-2,s+' ')+rsigue siendo 58 bytes ...
Dennis
1 por enseñarme acerca center. Nunca supe que existía hasta ahora.
DLosc
11

V , 12 bytes

Àé*hòl3Äjxx>

Pruébalo en línea!

Me gustan los desafíos como este porque puedo mostrar las ventajas de la naturaleza 2D de V. Explicación. Primero, necesitamos crear una cadena de n asteriscos. Entonces, hacemos esto:

À           " Arg1 times:
 é          " Insert the following single character:
  *         " '*'

Como nota al margen, esto es directamente equivalente a @ai*<esc>in vim, y el registro @ase preinicializa a "arg1". Esto hace que la entrada numérica sea mucho más conveniente.

Luego, avanzamos el personaje a la derecha con h. Aquí está la parte divertida:

ò           " Until an error is thrown:
 l          "   Move one character to the right. This will throw an error on anyline with only one asterisk in it
  3Ä        "   Make 3 copies of this line
    j       "   Move down one line
     xx     "   Delete two characters
       >    "   Indent this line once.

Ahora técnicamente, esta última parte es

òl3Äjxx>>ò

Porque el comando sangría es en realidad >>. V asume convenientemente que los comandos incompletos se aplican a la línea actual y también rellena implícitamente el segundo òcarácter para el bucle.

DJMcMayhem
fuente
10

Plantillas de C ++, 186 bytes

¡Con la fórmula explícita de mi respuesta C, las Metatemplates están compitiendo!

template<int N,int X=N*N+N-1>struct H{enum{I=X/(N+1)-N/2,J=X%(N+1)-N/2-1};S s{(J==-N/2-1?'\n':((I>=J&I>=-J)|(I<=J&I<=-J)?'*':' '))+H<N,X-1>().s};};template<int N>struct H<N,-1>{S s="";};

Sin golf:

using S=std::string;

template <int N, int X=N*N+N-1>
struct H{
 enum{I=X/(N+1)-N/2,J=X%(N+1)-N/2-1};
 S s{(J==-N/2-1 ? '\n' : ( (I>=J&I>=-J)|(I<=J&I<=-J) ?'*':' '))+H<N,X-1>().s};
};

template <int N> struct H<N,-1> {S s="";}; 

uso:

std::cout << H<5>().s;

no competidor

Solo por diversión:

//T: Tuple of chars
template <char C, char...Tail> struct T { S r=S(1,C)+T<Tail...>().r; };

//specialization for single char
template <char C> struct T<C> { S r=S(1,C); };

//M: Repeated char
template <int N, char C> struct M { S r=S(N,C); };

//U: concatenates T and M
template <class Head, class...Tail> struct U { S r=Head().r+U<Tail...>().r; };

//specialization for Tail=M
template <int N, char C> struct U<M<N,C>> { S r{M<N,C>().r}; };

//specialization for Tail=T
template <char...C> struct U<T<C...>> { S r=T<C...>().r; };

//finally the Hourglass
template <int N, int I=0> struct H {
 S s=U<
       M<I,' '>,
       M<N,'*'>,
       T<'\n'>
      >().r;
 S r{s + H<N-2,I+1>().r + s};
};

//specialization for recursion end
template <int I> struct H<1,I> {
 S r=U<
       M<I,' '>,
       T<'*','\n'>
      >().r;
};

Uso:

std::cout << H<5>().r;
Karl Napf
fuente
2
+1 por vencer a PHP con la parte más larga de C ++
matsjoyce
7

PowerShell v2 +, 54 bytes

param($n)$n..1+2..$n|?{$_%2}|%{" "*(($n-$_)/2)+"*"*$_}

Toma información $n(se garantiza que es un número entero impar), construye dos rangos con $n..1y 2..$ny los concatena juntos, luego los usa Where-Objectpara seleccionar solo los impares con |?{$_%2}. Esos son alimentados en un bucle. En cada iteración, construimos el número apropiado de espacios, concatenado con cadenas con el número apropiado de asteriscos. Esas cadenas se dejan en la tubería y la salida a través de Write-Outputinserciones implícitas de nuevas líneas entre ellas al finalizar el programa.

Ejemplos

PS C:\Tools\Scripts\golfing> 3,5,7|%{.\draw-an-hourglass.ps1 $_;""}
***
 *
***

*****
 ***
  *
 ***
*****

*******
 *****
  ***
   *
  ***
 *****
*******
AdmBorkBork
fuente
7

Python, 78 bytes

Entonces solo con sangría:

f=lambda n,i=0:n>1and' '*i+'*'*n+'\n'+f(n-2,i+1)+' '*i+'*'*n+'\n'or' '*i+'*\n'

Uso:

print f(5)
Karl Napf
fuente
6

C, 114 109 bytes

i,j;k(n){for(i=-n/2;i<=n/2;++i)for(j=-n/2;j<=n/2+1;++j)putchar(j==n/2+1?10:(i>=j&i>=-j)|(i<=j&i<=-j)?42:32);}

sin golf:

i,j;
k(n){
 for(i=-n/2;i<=n/2;++i)
  for(j=-n/2;j<=n/2+1;++j)
   putchar(j==n/2+1?10:(i>=j&i>=-j)|(i<=j&i<=-j)?42:32);
}

Solución recursiva previa:

p(a,c){while(a--)putchar(c);}
f(n,i){p(i,32);p(n,42);p(1,10);}
g(n,i){if(n>1)f(n,i),g(n-2,i+1);f(n,i);}
h(n){g(n,0);}
Karl Napf
fuente
5

JavaScript (ES6), 66 bytes

f=(n,s="*".repeat(n))=>n>1?s+`
`+f(n-2).replace(/^/gm," ")+`
`+s:s

La idea aquí es generar cada reloj de arena a partir del anterior: agregue un espacio al comienzo de cada línea, y añada y agregue nasteriscos.

ETHproducciones
fuente
4

05AB1E , 21 20 19 17 bytes

Ahorro de 2 bytes gracias a carusocomputing

;ƒ'*¹N·-×Nð×ì})û»

Pruébalo en línea!

Explicación

;ƒ                   # for N in [0 ... floor(input/2)+1]
  '*                 # push an asterisk
    ¹N·-×            # repeat the asterisk input-N*2 times
         Nð×ì        # prepend N spaces
             }       # end loop
              )      # wrap stack in a list
               û     # palendromize
                »    # join with newlines
Emigna
fuente
Ir"*"×.pRû- Llegué tan lejos, con la cara palmada cuando me di cuenta de lo lejos que estaba, vi que había respondido, e intentaré aprender la iteración en este idioma ahora usando este ejemplo. ¡Gracias!
Urna mágica de pulpo
44
De hecho, puedo ayudar por una vez: ;ƒ'*¹N·-×Nð×ì})û»use el nuevo comando palindromize. -2 bytes.
Urna mágica de pulpo
@carusocomputing: ¡Gracias! No sabía sobre el comando palendromize (no había actualizado los documentos). Muy útil. Lo he necesitado varias veces antes :)
Emigna
9 bytes , incluso en el legado. Aunque estoy bastante seguro de que las construcciones ÅÉy .cprobablemente aún no estaban disponibles en el momento en que publicaste esto. :)
Kevin Cruijssen
4

MATL , 12 bytes

Q2/Zv&<~42*c

Pruébalo en línea!

Explicación

Esto hace uso de la función de rango simétrico recientemente agregada .

Q     % Input n implicitly. Add 1
      % STACK: 6
2/    % Divide by 2
      % STACK: 3
Zv    % Symmetric range
      % STACK: [1 2 3 2 1]
&<~   % Matrix of all pairwise "greater than or or equal to" comparisons
      % STACK: [1 1 1 1 1
                0 1 1 1 0
                0 0 1 0 0
                0 1 1 1 0
                1 1 1 1 1]
42*   % Multiply by 42 (ASCII code of '*')
      % STACK: [42 42 42 42 42
                 0 42 42 42  0
                 0  0 42  0  0
                 0 42 42 42  0
                42 42 42 42 42]
c     % Convert to char. Implicitly display, with char 0 shown as space
      % STACK: ['*****'
                ' *** '
                '  *  '
                ' *** '
                '*****']
Luis Mendo
fuente
¡Agradable! Esa es una característica genial. Esta es la única respuesta que se acercó a mi respuesta V, así que ahora me voy a obsesionar con quitar uno o dos bytes. : D
DJMcMayhem
@DJMcMayhem Heh, no creo que pueda reducir el número de bytes en este caso
Luis Mendo
Sí, tampoco creo que pueda. Probablemente habrá una respuesta Jelly de 4 bytes en un par de minutos, jajaja ...
DJMcMayhem
4

PHP, 95 bytes

for($c=str_pad,$m=$n=$argv[1];$n<=$m;$n+=$d=$d>0||$n<2?2:-2)echo$c($c('',$n,'*'),$m,' ',2)."
";

En lugar de almacenar las filas en una matriz y luego generar todo, el ciclo for desciende hasta 1 y luego vuelve al número original.

chocochaos
fuente
3

C ++ 11, 93 bytes

#include<string>
using S=std::string;S f(int n,int i=0){S s=S(i,32)+S(n,42)+'\n';return n>1?s+f(n-2,i+1)+s:s;}

Ligeramente incólume:

std::string f(int n,int i=0){
 auto s=std::string(i,' ') + std::string(n,'*') + '\n';
 return n>1 ? s+f(n-2,i+1)+s : s;
}

Uso:

std::cout << f(5);
Karl Napf
fuente
¡Agradable! se puede guardar un byte asumiendo ASCII y reemplazándolo '\n'por 10:)
Quentin
3

MATL , 20 bytes

XyY>t1X!*t2X!+ZS42*c

Pruébalo en línea!

DJMcMayhem
fuente
Puede guardar algunos bytes con la función de rango simétrico recientemente introducida: Q2 / Zv & <~ 42 * c
Luis Mendo
@LuisMendo ¡Eso es genial! Como es un enfoque completamente diferente, te dejaré tenerlo.
DJMcMayhem
Ok, lo publicaré!
Luis Mendo
3

R, 77 bytes

M=matrix(" ",n<-scan(),n);for(i in 1:n)M[i:(n-i+1),i]="*";cat(M,sep="",fill=n)

Crea una matriz de caracteres, que luego imprime a través de cat, fill=nasegurándose de que las líneas se alineen correctamente. Tenga en cuenta que los elementos se almacenan en una columna de matriz primero (es decir, los dos primeros elementos son M[1,1]y M[2,1]no M[1,2]).

JDL
fuente
3

Java 7 170 165 164 bytes

Gracias a @Hypino por guardar 5 bytes.
Gracias a Kevin por guardar 1 byte.

String c(int n,int x){String s,c,t=c=s=" ";int i=0;for(;i++<n;s+="*");for(i=x;i-->=0;c+=" ");for(i=x;i-->0;t+=" ");return(n=n-2)>=0?s+"\n"+c+c(n,++x)+"\n"+t+s:"*";} 
Nudo numérico
fuente
Puede guardar 2 bytes mediante la eliminación s=de s=s+"\n"y 2 más bytes cambiando return(n=--n-1)a return(n=n-2)un total de 4 bytes.
Hypino
Hola. Puede jugar golf en dos partes: String s="",c="",t="";a String s,c,t=s=c="";( -2 bytes ) y return(n=n-2)>=0?s+"\n"+c+c(n,++x)+a return n-1>0?s+"\n"+c+c(n-2,++x)+( -2 bytes nuevamente)
Kevin Cruijssen
Pero el patrón @KevinCruijssen no es el esperado después de cambiar n=n-2-> n-1>0porque n debe usarse en otro argumento de una función.
Numberknot
@Numberknot Lo sé, pero también cambié na n-2esa parte. return(n=n-2)>=0 ... nser cambiado a return n-1>0 ... n-2es aún más corto. PD: Me has agradecido por guardar bytes, pero no has cambiado tu código en tu edición. ;)
Kevin Cruijssen
@Numberknot Umm ... aún olvidaste mi segundo consejo. De todos modos, aquí hay una variante más corta: String c(int n,int x){String s,c=s="";int i=0;for(;i++<n;s+="*");for(i=x;i-->0;c+=" ");return n>1?s+"\n "+c+c(n-2,x+1)+"\n"+c+s:"*";}sin la t( prueba de ideona - 133 bytes )
Kevin Cruijssen
3

PHP - 95 bytes

$c=2;for($i=$a=$argv[1];$i<=$a;$i-=$c*=$i<2?-1:1)echo str_pad(str_repeat("*",$i),$a," ",2)."
";

Guardado un byte usando una nueva línea real en lugar de un "\r"

CT14.IT
fuente
2

Pyth, 22 bytes

j+J.e+*dk*b\*_:1hQ2_PJ

Un programa que toma la entrada de un número entero en STDIN e imprime el resultado.

Pruébalo en línea

Cómo funciona

j+J.e+*dk*b\*_:1hQ2_PJ  Program. Input: Q
              :1hQ2     Range from 1 to Q+1 in steps of 2. Yields [1, 3, 5, ..., Q]
             _          Reverse
   .e                   Enumnerated map with b as elements and k as indices:
      *dk                 k spaces
         *b\*             b asterisks
     +                    Concatenate the spaces and asterisks
  J                     Store in J
                    PJ  All of J except the last element
                   _    Reverse
 +                      Concatenate J and its modified reverse
j                       Join on newlines
                        Implicitly print
TheBikingViking
fuente
2

C, 195 191 Bytes

Debería jugar golf un poco más pequeño

x,y,i;f(n){for(i=0;i<n;i+=2,puts("")){for(y=n-i;y<n;y+=2,putchar(32));for(x=i;x++<n;putchar(42));}for(i=n-2;~i;i-=2,puts("")){for(y=n-i+2;y<n;y+=2,putchar(32));for(x=i-1;x++<n;putchar(42));}}

Podemos probarlo aquí en ideone

cleblanc
fuente
2

C, 79 bytes

h(m,n,k){for(n=m++,k=n*m;--k;putchar(k%m?abs(k%m-m/2)>abs(k/m-n/2)?32:42:10));}

Divide la variable de cuenta regresiva ken índices de fila y columna. Si el índice de la columna es 0 (último carácter en una fila), genera un carácter de nueva línea (10). Luego ajusta los índices de fila y columna para que estén alrededor del asterisco central. Entonces, abs(x) < abs(y)es una condición corta para generar un espacio.

anatolyg
fuente
2

Ruby, 55 54 bytes

f=->n,s=0{puts a=' '*s+?**n;(f[n-2,s+1];puts a)if n>1}
Lee W
fuente
?**ntrabajos; No necesitas el espacio allí.
Value Ink el
2

Java 7, 156 bytes

Bastante simple. Realiza un seguimiento de las líneas con n, estrellas con j, espacios con sy dirección con d. Realmente solo quería una respuesta Java no recursiva en el tablero, pero no duele que también sea un poco más corta :)

String f(int n){String o="";int j=n,s=0,i,d=0;for(;n-->0;o+="\n"){for(i=0;i++<s;)o+=" ";for(i=0;i++<j;)o+="*";d+=j<2?1:0;j+=d<1?-2:2;s+=d<1?1:-1;}return o;}

Con saltos de línea:

String f(int n){
    String o="";
    int j=n,s=0,i,d=0;
    for(;n-->0;o+="\n"){
        for(i=0;i++<s;)
            o+=" ";
        for(i=0;i++<j;)
            o+="*";
        d+=j<2?1:0;
        j+=d<1?-2:2;
        s+=d<1?1:-1;
    }
    return o;
}
Geobits
fuente
2

APL, 19 bytes

' *'[1+∘.≤⍨(⊢⌊⌽)⍳⎕]

Prueba:

      ' *'[1+∘.≤⍨(⊢⌊⌽)⍳⎕]
⎕:
      5
*****
 *** 
  *  
 *** 
*****

Explicación:

                 ⎕   ⍝ read number  
                ⍳    ⍝ 1..N
           ( ⌊ )     ⍝ at each position, minimum of
            ⊢        ⍝ 1..N
              ⌽      ⍝ and N..1 (this gives 1..N/2..1)
       ∘.≤⍨          ⍝ outer product with ≤
     1+              ⍝ add 1 to each value
' *'[             ]  ⍝ 1→space, 2→asterisk
marinus
fuente
Simplemente elimine 1+y use un APL que tenga ⎕IO←0.
Adám
2

Haskell, 84 bytes

f n|l<-div n 2,k<-[-l..l]=putStr$unlines[[" *"!!(fromEnum$abs x<=abs y)|x<-k]|y<-k]
Angs
fuente
Buena solución! Pero estoy bastante seguro de que no es necesario el putStry usted puede deshacerse de la fromEnumcomo este .
ბიმო
2

C (gcc) , 80 74 bytes

Gracias ceilingcat por 6 bytes

-Du(x,k)=for(x=~n;x+=2,x<n;putchar(k))

i;j;f(n){u(i,10)u(j,i*i<j*j?32:42);}

Pruébalo en línea!

l4m2
fuente
2

PHP ,104 88 bytes

for(;$i++<$argn;$a.='**',$i++>1?$o=$s.$o:1)$o.=$s=str_pad("*$a",$argn,' ',2)."
";echo$o;

Pruébalo en línea!

Esto no supera los puntajes más bajos para PHP en este desafío, pero es demasiado loco para tirarlo.

Bien, ahora lo he jugado para que sea el puntaje más bajo (no por mucho tiempo) para PHP en este desafío, pero no cambia el hecho de que todavía es una locura.

$ echo 7|php -nF hour.php
*******
 *****
  ***
   *
  ***
 *****
*******
640 KB
fuente
83? también eh, php también tiene palabras vacías, aunque no es útil aquí
solo ASCII
@ ¡Ratas solo ASCII! ¡Parece que tengo más trabajo por hacer! jajaja
640KB
1
82? alternativa 82
solo ASCII
@ Sí, solo ASCII, ¡bien hecho! ¡Eso es seguro el enfoque correcto!
640 KB el
1

Groovy, 66 bytes

{n->((n..1)+(2..n)).each{if(it%2>0){println(("*"*it).center(n))}}}

Pruébelo: https://groovyconsole.appspot.com/script/5145735624392704

Explicado:

((n..1)+(2..n)) - Invertir palindromizar a n [n,..,1,..,n]

.each{if(it%2>0){...} - Iterar a través de elementos extraños.

println(("*"*it).center(n)) - Centre n estrellas e imprima cada una en la nueva línea.

Urna de pulpo mágico
fuente
.eachEl bloque de código podría ser {it%2&&println(("*"*it).center(n))}.
manatwork
1

PHP, 191 bytes

$b=[];for($i=$a=$argv[1]+1;$i>0;$i--){$i--;if($i<=1){$c=str_pad("*",$a," ",2)."\n";break;}$b[]=str_pad(str_repeat("*",$i),$a," ",2)."\n";}echo implode("",$b).$c.implode("",array_reverse($b));

Corre como php -f golf_hourglass.php 15

# php -f golf_hourglass.php 15
***************
 *************
  ***********
   *********
    *******
     *****
      ***
       *
      ***
     *****
    *******
   *********
  ***********
 *************
***************

La idea detrás de esto es crear la mitad superior (la parte anterior al single *), luego hacer eco de la parte superior dos veces, pero la segunda vez en orden inverso.

ʰᵈˑ
fuente
Creo que este es un mejor comienzo para esta tareafor(;$i<$a=$argv[1];$i+=2){$t=str_pad(str_pad("",$i+1,"*"),$a," ",2)."\n";$i?$s.=$t:$r=$t;}echo strrev($s)."\n".$r.$s;
Jörg Hülsermann
for(;$i<$a=$argv[1];$i++){$t=str_pad(str_pad("",$i+1+$i%2,"*"),$a," ",2)."\n";$i%2?$s.=$t:$s=$t.$s;}echo$s;esto es mejor
Jörg Hülsermann
Reemplace implode () con join () para guardar 6 bytes.
Alex Howansky
Reemplace \ncon una nueva línea real para guardar un byte.
Alex Howansky
1

Pyke, 22 19 bytes

F-ed*ih\**+)2%'X_OX

Pruébalo aquí!

F          )        -    for i in range(input)
 -                  -        Q-i
  e                 -       floor(^/2)
   d*               -      ^*" "
          +         -     ^+V
     ih             -       i+1
       \**          -      ^*"*"
            2%      -   ^[::2]
              'X_   - splat(^),
                       reversed(^)
                 OX - splat(^[:-1])
Azul
fuente
1

C, 117 bytes

void p(c,n){while(n--)putchar(c);}void h(n){for(int i=n;i>=-n;i-=i==1?4:2){p(32,(n-abs(i))/2);p(42,abs(i));p(10,1);}}

Sin golf

void printNum(c, n) {
  while (n--)
    putchar(c);
}

void hourGlass(n) {
  for (int i = n; i >= -n; i-=i==1?4:2) {
    printNum(32, (n - abs(i)) / 2);
    printNum(42, abs(i));
    printNum(10, 1);
  }
}
Kerndog73
fuente