Bir kum saati çiz


32

Yine Programlama 101 için bir görevden esinlenilmiş bir başka sorun var.

Giriş:

  • Olumlu bir tamsayı n >= 3. (garip olmalı)

Çıktı:

  • nilk satırda nyıldız bulunan ve her yeni satırda önceki satırdan daha az iki yıldız bulunan yıldız işaretleri. 1 yıldıza kadar. Oradan, her yeni hattın hattına geri dönene kadar iki yıldız işareti var.n . Boşluklar veya boşluklar gibi bir şey yıldızları hizalamak için kullanılmalıdır, böylece gerçekten bir kum saati gibi görünecektir.

Genel kurallar:

  • İzleyen yeni satırlara izin verilir, ancak kullanılması gerekmez.
  • girinti bir zorunluluktur.
  • Bu kod golf, bayt cinsinden en kısa cevap kazanır.
  • Kurs C ++ 'da öğretildiğinden, C ++' da çözümleri görmeye istekliyim.

Test durumu (n = 5):

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

buna göre düzenlendi, teşekkürler :-)
Sickboy 25:16


3
@Oliver OP'nin "Yıldız üçgeni çiz" yazdığını göz önünde bulundurursak , bu mücadeleyi yinelemeli olarak adlandırmanın adil olduğuna tam olarak emin değilim. Yine de kesinlikle ilgili.
Sherlock9

19
Buradaki herkes tam bağlamı bilmediğinden, OP aslen "Yıldız işareti üçgen çiz" yazdı ve bu mücadeleyi ek bir meydan okuma olarak düzenledi. Onlara bu parçayı çıkarmalarını ve farklı bir meydan okuma yapmalarını (ki yaptıklarını) söyledik. Bu zorluk bir kopya değildir . OP birçok yüksek temsilci kullanıcısının ve hatta birkaç modun tavsiye ettiği şeyi yapıyor .
DJMcMayhem

2
@JDL: Hayır, neden olmasın? Ah, şimdi anladığım kadarıyla kare ... :-D
Sickboy

Yanıtlar:


20

Kömür , 6 bayt

G↘←↗N*

Ölü basit. Yanları aşağıya ve sağa, yatay olarak sola ve yukarı-sağa giden bir giriş N ölçüsünden alınmış kenar uzunluğu ile üzerine bir poli G çizin :*

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

Sonra anahattı otomatik tamamla ve doldur.

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

Çevrimiçi deneyin!


Hah, bu çok tatlı!
CT14.IT

6
Bu dil çok ilginç! Bunu bundan sonra çok yakından izliyor olacağım: s.
Adnan

Bu dili daha önce görmedim ... İlginç görünüyor!
Jelly'le bir

12

Python 2, 57 bayt

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

Tam bir program. Satır satır gider, ortalanmış doğru yıldız sayısını yazdırır.

Özyinelemeli bir işlev daha uzundu (67 bayt):

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

veya

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

Ben değiştirmeye çalışırken önermek istedik maxbir ile abs, ama bende hepsi abs(n-1)+1ekleme parantez gerektirdiğinden daha kötü olan
njzk2

@ njzk2 Parens'i keserek kesebilirsiniz '*'*-~abs(n-1), ancak daha sonra aynı uzunluktadır '*'*max(n,2-n).
xnor

Orada def f(n,s=''):r=s+'*'*n+'\n';return 1/n*r or r+f(n-2,s+' ')+r61 byte için, ama yine de daha uzun. Önde gelen bir yeni hatta bile def f(n,s='\n'):r=s+'*'*n;return 1/n*r or r+f(n-2,s+' ')+r, hala 58 bayt ...
Dennis,

Bana öğrettiğin için +1 center. Bunun şimdiye kadar var olduğunu asla bilmiyordum.
DLosc

11

V , 12 bayt

Àé*hòl3Äjxx>

Çevrimiçi deneyin!

Bu gibi zorluklardan hoşlanıyorum çünkü V'nin 2D doğasının avantajlarını ortaya koyabiliyorum. Açıklama. İlk önce, bir n yıldız işareti yaratmamız gerekiyor . Yani bunu yapıyoruz:

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

Bir yan not olarak, bu doğrudan @ai*<esc>vim'e eşittir ve kayıt olun@a önceden "arg1" e ilklendirilir. Bu, sayısal girişi çok daha uygun hale getirir.

Sonra karakterle sağa doğru ilerleriz h. İşte eğlenceli kısım:

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

Şimdi teknik olarak, bu son bölüm

òl3Äjxx>>ò

Çünkü indent komutu aslında >>. V, uygun olmayan komutların geçerli satıra uygulandığını ve aynı zamanda òdöngü için ikinci karakteri de doldurduğunu varsayar .


10

C ++ Metatemplates, 186 bayt

C cevabımdaki açık formülle Metatemplates rekabet ediyor!

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

kullanımı:

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

rekabetsiz

Sadece eğlence uğruna:

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

Kullanımı:

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

2
C ++ 'ın en uzun soluklu kısmı olan PHP'yi yenmek için +1
matsjoyce

7

PowerShell v2 +, 54 bayt

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

Girdi alır $n(tek bir tamsayı olduğu garantilidir), iki aralık oluşturur $n..1ve 2..$nbunları bir araya getirir, ardından Where-Objectyalnızca tek olanları seçmek için kullanır |?{$_%2}. Bunlar bir döngüye beslenir. Her yinelemede, uygun sayıda yıldızla dizilen birleştirilmiş uygun sayıda boşluk oluştururuz. Bu dizeler boru hattında bırakılır ve örtük olarak çıkarWrite-Output , program tamamlandığında aralarına yeni satırlar ekler.

Örnekler

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

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

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

7

Python, 78 bayt

Yani sadece girinti ile:

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

Kullanımı:

print f(5)

6

C, 114 109 bayt

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

Önceki özyinelemeli çözüm:

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 bayt

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

Buradaki fikir, her kum saatini bir öncekinden oluşturmaktır: her satırın başına bir boşluk ekleyiniz ve hem nyıldızları hazırlayıp ekleyiniz .


4

05AB1E , 21 20 19 17 bayt

Carusocomputing sayesinde 2 bayt kurtardı

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

Çevrimiçi deneyin!

açıklama

;ƒ                   # 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û- Ne kadar uzakta olduğumun farkına vardığımda şaşırdım, cevap verdiğinizi gördüm, şimdi bu örneği kullanarak bu dilde yinelemeyi öğrenmeye çalışın. Teşekkürler!
Magic Octopus Urn

4
Aslında bir kere yardım edebilirim: ;ƒ'*¹N·-×Nð×ì})û»new palindromize komutunu kullanın. -2 bayt.
Magic Octopus Urn,

@carusocomputing: Teşekkürler! Palendromize komutunu bilmiyordum (Dokümanları yenilememiştim). Çok kullanışlı. Daha önce birkaç kez ihtiyacım var :)
Emigna

Eskiden bile 9 bayt . Her ne kadar ben emin yapıyorum ÅÉve .cmuhtemelen bunu gönderdiğiniz sırada henüz mevcut değildi. :)
Kevin Cruijssen

4

MATL , 12 bayt

Q2/Zv&<~42*c

Çevrimiçi deneyin!

açıklama

Bu, yakın zamanda eklenen simetrik aralık fonksiyonunu kullanır.

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

Güzel! Bu harika bir özellik. Bu, V cevabımın yakınına gelen tek cevap, bu yüzden şimdi bir ya da iki baytı çıkarmak için takıntı yapacağım. : D
DJMcMayhem

@DJMcMayhem Heh, bu konuda bayt sayısını azaltabileceğimi sanmıyorum
Luis Mendo

Evet, yapabileceğimi de sanmıyorum. Muhtemelen yine birkaç dakika içinde 4-byte Jelly cevabı olacak, hahaha ...
DJMcMayhem

4

PHP, 95 bayt

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

Satırları bir dizide saklamak ve ardından her şeyi çıkarmak yerine, for döngüsü 1'e kadar iner ve sonra orijinal sayıya geri döner.


3

C ++ 11, 93 bayt

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

Biraz ungolfed:

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

Kullanımı:

std::cout << f(5);

Güzel! bir bayt ASCII varsayarak ve :) '\n'ile değiştirilerek kurtarılabilir10
Quentin


3

R, 77 bayt

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

Bu daha sonra bu yazdırır karakter matrisi oluşturur catile,fill=nÇizgilerin doğru hizalandığından emin olarak . Öğelerin ilk önce bir matris sütununda saklandığını unutmayın (yani, ilk iki öğe vardır M[1,1]ve M[2,1]değildir) M[1,2].


3

Java 7, 170 165 164 bayt

5 byte tasarruf için @Hypino teşekkürler.
1 byte tasarruf için Kevin teşekkürler.

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

Sen çıkararak 2 bayt kaydedebilirsiniz s=dan s=s+"\n"değiştirerek ve 2 tane daha bayt return(n=--n-1)için return(n=n-2)4 bayt olmak üzere toplam.
Hypino

Merhaba. Şunları yapabilirsiniz golf iki parça: String s="",c="",t="";için String s,c,t=s=c="";( -2 bayt ) ve return(n=n-2)>=0?s+"\n"+c+c(n,++x)+karşı return n-1>0?s+"\n"+c+c(n-2,++x)+( -2 bayt tekrar)
Kevin Cruijssen

Fakat @KevinCruijssen modeli değiştirildikten sonra beklendiği gibi değil n=n-2-> n-1>0çünkü n bir fonksiyonun argümanında kullanılmalıdır.
Sayı

Biliyorum @Numberknot, ama aynı zamanda değişti netmekn-2 bu kısmında. return(n=n-2)>=0 ... nolarak değiştirilmek return n-1>0 ... n-2hala daha kısa. Not: Baytları kaydettiğim için teşekkür ettin, ancak düzenlemede kodunu değiştirmedin. ;)
Kevin Cruijssen

@ Numara # Umm .. Hala ikinci ipucumu unuttun. Her neyse, işte daha kısa bir varyasyon: ( ideone testi - 133 bytes ) 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:"*";}olmadant
Kevin Cruijssen

3

PHP - 95 bayt

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

Bir gerçek yerine yeni bir satır kullanarak bir bayt kaydedildi. "\r"


2

Pyth, 22 bayt

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

STDIN'de bir tamsayı girişi alan ve sonucu basan bir program.

Çevrimiçi deneyin

Nasıl çalışır

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 Bayt

Biraz daha küçük golf gerekir

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

Burada ideone üzerinde test edebiliriz


2

C, 79 bayt

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

Geri sayım değişkenini ksatır ve sütun indekslerine böler . Sütun dizini 0 ise (satırdaki son karakter), yeni satır karakteri (10) çıkarır. Ardından, orta yıldız işaretinin etrafında olacak şekilde satır ve sütun dizinlerini ayarlar. O zaman, abs(x) < abs(y)bir boşluk oluşturmak için kısa bir durumdur.


2

Ruby, 55 54 bayt

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

?**nEserleri; oradaki boşluğa ihtiyacın yok.
Value Ink,

2

Java 7, 156 bayt

Oldukça basit. İle çizgilerin kaydını tutar n, yıldızların j, ile boşluk sile ve yön d. Ben gerçekten sadece gemide özyinelemeyen bir Java cevabı istedim, ama biraz daha kısa olduğu için canımı yakmıyor :)

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

Satır sonları ile:

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 bayt

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

Ölçek:

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

Açıklama:

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

Sadece 1+sahip olan bir APL'yi kaldırın ve kullanın ⎕IO←0.
Adám

2

Haskell, 84 bayt

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

Güzel çözüm! Ama oldukça emin gerekmez değilim putStrve siz kurtulabilirsiniz fromEnumgibi bu .
ბიმო



2

PHP ,104 88 bayt

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

Çevrimiçi deneyin!

Bu, bu zorlukta PHP için en düşük puanları geçemez, ancak atmak için çok fazla delilik.

Tamam, şimdi bu mücadelede PHP için (uzun süre değil) en düşük puan olmak için golf oynamıştım, ancak hala çılgınca olduğu gerçeğini değiştirmiyor.

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

83? ayrıca, huh, php de korkaklara sahip, burada yararlı olmasa da
ASCII-sadece

@ ASCII-sadece sıçanlar! Yapacak daha çok işim var gibi görünüyor! lol
640KB



@ ASCII-sadece evet, güzel bitti! Elbette doğru yaklaşım!
640KB

1

Groovy, 66 Bayt

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

Deneyin: https://groovyconsole.appspot.com/script/5145735624392704

Açıklaması:

((n..1)+(2..n)) - Ters palindromize n [n,..,1,..,n]

.each{if(it%2>0){...} - Garip unsurlar boyunca yineleyin.

println(("*"*it).center(n)) - n yıldızları ortalayın ve her birini yeni satırda yazdırın.


.each'nin kod bloğu olabilir {it%2&&println(("*"*it).center(n))}.
Manatwork

1

PHP, 191 bayt

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

Gibi koş php -f golf_hourglass.php 15

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

Bunun ardındaki fikir, üst yarıyı (tek *olandan önceki kısım) oluşturmak, ardından sadece üst kısmı iki kere yankılanmak, ikincisi ise ters sırada yapmaktır.


Bence bu, bu görev için daha iyi bir başlangıçfor(;$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;bu daha iyi
Jörg Hülsermann 25:16

6 bayttan tasarruf etmek için implode () öğesini join () ile değiştirin.
Alex Howansky

Değiştir \nbir byte kaydetmek için gerçek bir yeni çizgi ile.
Alex Howansky

1

Pyke, 22 19 bayt

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

Burada dene!

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 bayt

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);
  }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.