Dessine un sablier


32

Encore une fois inspiré par une tâche de programmation 101, voici un autre défi.

Contribution:

  • Un entier positif n >= 3. (doit être étrange)

Sortie:

  • nlignes d'astérisques, où la première ligne a des nastérisques et chaque nouvelle ligne a deux astérisques de moins que la ligne précédente. Jusqu'à frapper 1 astérisque. De là, chaque nouvelle ligne a deux astérisques de plus que la ligne précédente jusqu'à ce qu'elle revienne aux nastérisques. Des espaces ou quelque chose comme des espaces doivent être utilisés pour aligner les astérisques afin qu'ils ressemblent vraiment à un sablier.

Règles générales:

  • Les sauts de ligne sont autorisés mais ne doivent pas être utilisés.
  • l'indentation est un must.
  • C'est le code-golf, donc la réponse la plus courte en octets l'emporte.
  • Puisque le cours est enseigné en C ++, je suis impatient de voir des solutions en C ++.

Cas de test (n = 5):

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

modifié en conséquence, merci :-)
Sickboy

3
Reproduction possible de Dessiner un triangle astérisque
Oliver Ni

3
@Oliver Considérant que OP a écrit "Dessiner un triangle astérisque", je ne suis pas tout à fait sûr que d'appeler ce défi un doublon est juste. C'est certainement lié, cependant.
Sherlock9

19
Comme tout le monde ici ne connaît pas le contexte complet, OP a initialement publié le "Dessiner un triangle astérisque" et a édité ce défi comme un défi supplémentaire. Nous leur avons dit de retirer cette partie et d'en faire un défi différent (ce qu'ils ont fait). Ce défi n'est pas un doublon. OP fait ce que de nombreux utilisateurs de haute réputation, et même quelques mods ont recommandé.
DJMcMayhem

2
@JDL: Non, pourquoi le feriez-vous? Ah, maintenant je comprends ce que tu voulais dire par carré ... :-D
Sickboy

Réponses:


20

Charbon de bois , 6 octets

G↘←↗N*

Mort simple. Tracer une poly G sur de *, avec une longueur latérale prise à partir d' une entrée N ombre, où les côtés vont vers le bas et vers la droite, à l' horizontale à gauche, et vers le haut et à droite:

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

Remplissez ensuite automatiquement le plan et remplissez-le.

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

Essayez-le en ligne!


Hah, c'est assez fou!
CT14.IT

6
Cette langue est très intéressante! Je suivrai cela de très près à partir de maintenant: p.
Adnan

Je n'ai jamais vu cette langue avant ... Ça a l'air intéressant! Je me demande ce que vous obtiendriez si vous le
combiniez

12

Python 2, 57 octets

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

Un programme complet. Va ligne par ligne, imprimant le bon nombre d'astérisques centrés.

Une fonction récursive était plus longue (67 octets):

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

ou

f=lambda n,p='':1/n*(p+'*\n')or f(n-2,p+' ').join([p+n*'*'+'\n']*2)

Je voulais suggérer d'essayer de remplacer le maxpar un abs, mais tout ce que j'ai abs(n-1)+1, c'est pire, car l'addition nécessite des parenthèses
njzk2

@ njzk2 Vous pouvez couper les parens en faisant '*'*-~abs(n-1), mais alors c'est la même longueur que '*'*max(n,2-n).
xnor

Il y a def f(n,s=''):r=s+'*'*n+'\n';return 1/n*r or r+f(n-2,s+' ')+r61 octets, mais c'est encore plus long. Même avec une nouvelle ligne de premier plan, il def f(n,s='\n'):r=s+'*'*n;return 1/n*r or r+f(n-2,s+' ')+rreste 58 octets ...
Dennis

+1 pour m'avoir enseigné center. Je n'ai jamais su que cela existait jusqu'à présent.
DLosc

11

V , 12 octets

Àé*hòl3Äjxx>

Essayez-le en ligne!

J'aime les défis comme celui-ci parce que je peux montrer les avantages de la nature 2D de V. Explication. Tout d'abord, nous devons créer une chaîne de n astérisques. Donc, nous faisons ceci:

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

En remarque, ceci est directement équivalent à @ai*<esc>dans vim, et le registre @aest pré-initialisé à "arg1". Cela rend la saisie numérique beaucoup plus pratique.

Ensuite, on passe du caractère à droite avec h. Voici la partie amusante:

ò           " 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.

Maintenant techniquement, cette dernière partie est

òl3Äjxx>>ò

Parce que la commande de retrait est en fait >>. V suppose que les commandes incomplètes s'appliquent à la ligne actuelle et remplit également implicitement le deuxième òcaractère pour la boucle.


10

Méta-modèles C ++, 186 octets

Avec la formule explicite de ma réponse C, les métatemplates sont en concurrence!

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

Ungolfed:

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

usage:

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

non compétitif

Juste pour le plaisir:

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

Usage:

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

2
+1 pour avoir battu PHP avec la partie la plus longue de C ++
matsjoyce

7

PowerShell v2 +, 54 octets

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

Prend l'entrée $n(garanti d'être un entier impair), construit deux plages avec $n..1et 2..$net les concatène ensemble, puis utilise Where-Objectpour sélectionner uniquement les impaires avec |?{$_%2}. Ceux-ci sont introduits dans une boucle. À chaque itération, nous construisons le nombre approprié d'espaces, concaténé en chaîne avec le nombre approprié d'astérisques. Ces chaînes sont laissées sur le pipeline et sorties via des Write-Outputinsertions implicites de nouvelles lignes entre elles à la fin du programme.

Exemples

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

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

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

7

Python, 78 octets

Donc seulement avec indentation:

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

Usage:

print f(5)

6

C, 114 109 octets

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

ungolfed:

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

Solution récursive précédente:

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

5

JavaScript (ES6), 66 octets

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

L'idée ici est de générer chaque sablier à partir du précédent: ajoutez un espace au début de chaque ligne, et ajoutez à la fois des nastérisques et des préfixes .


4

05AB1E , 21 20 19 17 octets

Économisé 2 octets grâce à carusocomputing

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

Essayez-le en ligne!

Explication

;ƒ                   # 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

Ir"*"×.pRû- Je suis allé aussi loin, le visage palmé quand je me suis rendu compte à quel point j'étais loin, j'ai vu que tu avais répondu, j'allais essayer d'apprendre l'itération dans cette langue en utilisant maintenant cet exemple. Merci!
Urne de poulpe magique du

4
Je peux en fait vous aider pour une fois: ;ƒ'*¹N·-×Nð×ì})û»utilisez la nouvelle commande palindromize. -2 octets.
Urne de poulpe magique du

@carusocomputing: Merci! Je ne connaissais pas la commande palendromize (je n'avais pas actualisé les documents). Très utile.
J'en ai

9 octets , même dans l'héritage. Bien que je suis assez sûr que les builtins ÅÉet ne .csont probablement pas encore disponible au moment où vous a publié ce billet. :)
Kevin Cruijssen

4

MATL , 12 octets

Q2/Zv&<~42*c

Essayez-le en ligne!

Explication

Cela utilise la fonction de plage symétrique récemment ajoutée .

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: ['*****'
                ' *** '
                '  *  '
                ' *** '
                '*****']

Agréable! C'est une fonctionnalité intéressante. C'est la seule réponse qui se rapproche de ma réponse V, alors maintenant je vais obséder pour enlever un ou deux octets. : D
DJMcMayhem

@DJMcMayhem Heh, je ne pense pas que je serai en mesure de réduire le nombre d'octets sur celui-ci
Luis Mendo

Ouais, je ne pense pas que je peux non plus. Il y aura probablement une réponse Jelly de 4 octets dans quelques minutes de toute façon, hahaha ...
DJMcMayhem

4

PHP, 95 octets

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

Au lieu de stocker les lignes dans un tableau, puis de tout générer, la boucle for descend jusqu'à 1, puis revient au numéro d'origine.


3

C ++ 11, 93 octets

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

Légèrement non-golfé:

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

Usage:

std::cout << f(5);

Agréable! un octet peut être sauvegardé en supposant ASCII et en le remplaçant '\n'par 10:)
Quentin


3

R, 77 octets

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

Crée une matrice de caractères, qu'elle imprime ensuite via cat, fill=nen s'assurant que les lignes s'alignent correctement. Notez que les éléments sont stockés dans une matrice colonne en premier (c'est-à-dire que les deux premiers éléments sont M[1,1]et M[2,1]non M[1,2].)


3

Java 7, 170 165 164 octets

Merci à @Hypino d'avoir économisé 5 octets.
Merci à Kevin d'avoir économisé 1 octet.

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:"*";} 

Vous pouvez enregistrer 2 octets en supprimant à s=partir s=s+"\n"et 2 autres octets en changeant return(n=--n-1)pour return(n=n-2)un total de 4 octets.
Hypino

Salut. Vous pouvez String s="",c="",t="";String s,c,t=s=c="";return(n=n-2)>=0?s+"\n"+c+c(n,++x)+return n-1>0?s+"\n"+c+c(n-2,++x)+
jouer au

Mais le modèle @KevinCruijssen n'est pas comme prévu après avoir changé n=n-2-> n-1>0car n doit être utilisé dans un autre argument d'une fonction.
Numberknot

@Numberknot Je sais, mais j'ai aussi changé npour n-2cette partie. return(n=n-2)>=0 ... nêtre changé en return n-1>0 ... n-2est encore plus court. PS: Vous m'avez remercié d'avoir enregistré des octets, mais vous n'avez pas changé votre code dans votre édition. ;)
Kevin Cruijssen

@Numberknot Umm .. vous avez toujours oublié mon deuxième conseil. Quoi qu'il en soit, voici une variante plus courte: 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:"*";}sans le t( test idéone - 133 octets )
Kevin Cruijssen

3

PHP - 95 octets

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

Enregistré un octet en utilisant une nouvelle ligne réelle au lieu d'un "\r"


2

Pyth, 22 octets

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

Un programme qui prend l'entrée d'un entier sur STDIN et imprime le résultat.

Essayez-le en ligne

Comment ça marche

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

2

C, 195 191 octets

Devrait jouer au golf un peu plus petit

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

On peut le tester ici sur ideone


2

C, 79 octets

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

Il divise la variable de compte à rebours ken indices de ligne et de colonne. Si l'index de colonne est 0 (dernier caractère d'une ligne), il génère un caractère de nouvelle ligne (10). Ensuite, il ajuste les indices de ligne et de colonne autour de l'astérisque central. Ensuite, abs(x) < abs(y)c'est une condition courte pour sortir un espace.


2

Rubis, 55 54 octets

f=->n,s=0{puts a=' '*s+?**n;(f[n-2,s+1];puts a)if n>1}

?**ntravaux; vous n'avez pas besoin d'espace là-bas.
Value Ink

2

Java 7, 156 octets

Assez simple. Permet de suivre les lignes avec n, les étoiles avec j, les espaces avec set la direction avec d. Je voulais vraiment juste une réponse Java non récursive sur le tableau, mais ça ne fait pas de mal qu'elle soit aussi un peu plus courte :)

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

Avec des sauts de ligne:

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

2

APL, 19 octets

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

Tester:

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

Explication:

                 ⎕   ⍝ 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

Il suffit de supprimer 1+et d'utiliser un APL qui a ⎕IO←0.
2016 à 9h16

2

Haskell, 84 octets

f n|l<-div n 2,k<-[-l..l]=putStr$unlines[[" *"!!(fromEnum$abs x<=abs y)|x<-k]|y<-k]

Belle solution! Mais je suis sûr que vous n'avez pas besoin de putStrça et vous pouvez vous en débarrasser fromEnumcomme ça .
ბიმო



2

PHP ,104 88 octets

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

Essayez-le en ligne!

Cela ne bat pas les scores les plus bas pour PHP sur ce défi, mais c'est tout simplement trop fou pour moi de le jeter.

D'accord, j'ai donc joué maintenant pour que ce soit le score le plus bas (pas pour longtemps) pour PHP sur ce défi, mais cela ne change pas le fait qu'il est toujours fou.

$ echo 7|php -nF hour.php
*******
 *****
  ***
   *
  ***
 *****
*******

83? aussi hein, php a aussi des mots nus, bien que ce ne soit pas utile ici
ASCII uniquement le

@ Rats ASCII uniquement! On dirait que j'ai encore du travail à faire! lol
640KB



@ Oui ASCII seulement, bien joué! C'est à coup sûr la bonne approche!
640 Ko le

1

Groovy, 66 octets

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

Essayez-le: https://groovyconsole.appspot.com/script/5145735624392704

A expliqué:

((n..1)+(2..n)) - Palindromiser inverse à n [n,..,1,..,n]

.each{if(it%2>0){...} - Itérer à travers des éléments impairs.

println(("*"*it).center(n)) - Centrez n étoiles et imprimez chacune sur la nouvelle ligne.


.eachpourrait être le bloc de code {it%2&&println(("*"*it).center(n))}.
manatwork

1

PHP, 191 octets

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

Courir comme php -f golf_hourglass.php 15

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

L'idée derrière cela est de créer la moitié supérieure (la partie avant le single *), puis de répéter simplement la partie supérieure deux fois, mais la deuxième fois dans l'ordre inverse.


Je pense que c'est un meilleur début pour cette tâchefor(;$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;c'est mieux
Jörg Hülsermann

Remplacez implode () par join () pour économiser 6 octets.
Alex Howansky

Remplacez \npar une nouvelle ligne réelle pour enregistrer un octet.
Alex Howansky

1

Pyke, 22 19 octets

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

Essayez-le ici!

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

1

C, 117 octets

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

Ungolfed

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);
  }
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.