砂時計を描く


32

プログラミング101のタスクに触発されたのは、もう1つの課題です。

入力:

  • 正の整数n >= 3。(奇妙でなければならない)

出力:

  • nアスタリスクの行。最初の行にはnアスタリスクがあり、すべての新しい行には前の行よりも2つ少ないアスタリスクがあります。アスタリスクを1つ押すまで。そこから、nアスタリスクに戻るまで、すべての新しい行には前の行よりも2つのアスタリスクが付いています。スペースまたはスペースのようなものを使用して、実際に砂時計のように見えるようにアスタリスクを揃える必要があります。

一般的なルール:

  • 末尾の改行は許可されますが、使用する必要はありません。
  • インデントは必須です。
  • これはコードゴルフなので、バイト単位の最短回答が勝ちです。
  • このコースはC ++で教えられているので、C ++で解決策を見たいと思っています。

テストケース(n = 5):

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

それに応じて編集、ありがとう:-)
シックボーイ


3
@Oliver OP 「アスタリスクの三角形を描く」と書いたのを考えると、このチャレンジを複製と呼ぶのが公正かどうかは完全にはわかりません。しかし、それは間違いなく関連しています。
Sherlock9

19
ここの全員が完全なコンテキストを知っているわけではないため、OPは最初に「アスタリスクの三角形を描く」を投稿し、このチャレンジを追加のチャレンジとして編集しました。私たちは彼らにその部分を削除し、それを別の挑戦にするように言いました(彼らはしました)。この課題は重複していません。OPは、多くの高解像度ユーザーと、いくつかのmodが推奨していることを行っています。
DJMcMayhem

2
@JDL:いいえ、なぜですか?ああ、今、私はあなたが正方形の意味を理解しています...
-D-シックボーイ

回答:


20

、6バイト

G↘←↗N*

とてもシンプル。のポリゴンGを描画*します。辺の長さを入力N umber から取得します。辺は、左右、左右、上下になります。

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

次に、アウトラインをオートコンプリートして入力します。

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

オンラインでお試しください!


ああ、それはかなりおかしなことです!
CT14.IT

6
この言語は非常に興味深いです!私はこれからこれを非常に注意深く見ます:p。
アドナン

この言語を見たことがない...面白そう!私は...あなたが何とかゼリーとそれを組み合わせた場合は、取得したいのだろうか
Esolangingフルーツ

12

Python 2、57バイト

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

完全なプログラム。行ごとに移動し、中央に正しい数のアスタリスクを印刷します。

再帰関数はより長くなりました(67バイト):

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

または

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

私は交換してくださいしようとして提案したいmaxabs、私が得たすべてがあるabs(n-1)+1ほかは、括弧を必要とするために悪化している、
njzk2

@ njzk2を行うことで括弧を切り取ることができます'*'*-~abs(n-1)が、それはと同じ長さ'*'*max(n,2-n)です。
xnor

def f(n,s=''):r=s+'*'*n+'\n';return 1/n*r or r+f(n-2,s+' ')+r61バイトありますが、それでも長くなります。主要な改行def f(n,s='\n'):r=s+'*'*n;return 1/n*r or r+f(n-2,s+' ')+rがあっても、まだ58バイトです
デニス

について教えてくれた+1 center。今まで存在することを知らなかった。
DLosc

11

V、12バイト

Àé*hòl3Äjxx>

オンラインでお試しください!

Vの2Dの性質の利点を誇示できるので、このような課題が好きです。説明。最初に、n個のアスタリスクの文字列を作成する必要があります。したがって、これを行います。

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

サイドノートとして、これは直接@ai*<esc>vimと同等であり、レジスタ@aは「arg1」に事前に初期化されます。これにより、数値入力がはるかに便利になります。

次に、で文字を右に移動しhます。楽しい部分は次のとおりです。

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

技術的には、この最後の部分は

òl3Äjxx>>ò

indentコマンドは実際には>>です。Vは、都合の悪いことに、不完全なコマンドが現在の行に適用されると想定し、òループのために2番目の文字を暗黙的に埋めます。


10

C ++メタテンプレート、186バイト

私のCの答えからの明示的な式で、Metatemplatesは競合しています!

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

ゴルフをしていない:

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

使用法:

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

非競合

楽しみのためだけに:

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

使用法:

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

2
C ++の最も長い部分でPHPを破った+1
matsjoyce

7

PowerShell v2 +、54バイト

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

入力$n(奇数の整数であることが保証されます)を受け取り$n..12..$nとで2つの範囲を構築し、それらを連結してからWhere-Object、で奇数の範囲のみを選択するために使用します|?{$_%2}。それらはループに送られます。反復ごとに、適切な数のアスタリスクで文字列連結された適切な数のスペースを作成します。これらの文字列はパイプラインに残され、Write-Outputプログラムの完了時に暗黙的な挿入による改行がそれらの間に改行を挿入します。

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

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

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

7

Python、78バイト

インデントのみで:

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

使用法:

print f(5)

6

C、114 109バイト

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

なし:

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

以前の再帰的ソリューション:

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バイト

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

ここでのアイデアは、前のものから各砂時計を生成することです。すべての行の先頭にスペースを追加し、nアスタリスクを追加および追加します。


4

05AB1E21 20 19 17バイト

carusocomputingのおかげで2バイト節約

;ƒ'*¹N·-×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

Ir"*"×.pRû-ここまで来て、自分がどれだけ離れているかを理解したときに顔を掌握し、あなたが答えたのを見たので、この例を使ってこの言語の反復を学びましょう。ありがとう!
魔法のタコUr

4
私は実際に一度助けることができます:;ƒ'*¹N·-×Nð×ì})û»新しいpalindromizeコマンドを使用してください。-2バイト。
魔法のタコUr

@carusocomputing:ありがとう!palendromizeコマンドについては知りませんでした(ドキュメントを更新していませんでした)。非常に便利。以前に何度か必要でした:)
エミグナ

レガシーでも9バイト。ビルトインはかなり確かだと思いますがÅÉ.cおそらくこれを投稿した時点ではまだ利用できませんでした。:)
ケビンクルーッセン

4

MATL、12バイト

Q2/Zv&<~42*c

オンラインでお試しください!

説明

これは、最近追加された 対称範囲関数を使用します。

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

いいね!それは素晴らしい機能です。これが私のV回答に近づいた唯一の回答であるため、1バイトまたは2バイトを取り出すことに取りつかれます。:D
DJMcMayhem

@DJMcMayhemへー、私はこれのバイト数を減らすことができるとは思わない
ルイスメンドー

ええ、私もできるとは思いません。おそらくハハハ...、とにかく数分で4バイトゼリーの答えがあることでしょう
DJMcMayhem

4

PHP、95バイト

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

行を配列に格納してからすべてを出力する代わりに、forループは1まで停止し、元の数値に戻ります。


3

C ++ 11、93バイト

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

わずかに未使用:

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

使用法:

std::cout << f(5);

いいね!ASCIIを想定し'\n'10:)に置き換えることで1バイトを節約できます
クエンティン


3

R、77バイト

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

文字行列catfill=n作成し、行を適切に整列させながら、を介して印刷します。要素は行列の最初に格納されることに注意してください(つまり、最初の2つの要素はM[1,1]and M[2,1]ではなくand M[1,2]です)。


3

Java 7、 170 165 164バイト

5バイトを節約してくれた@Hypinoに感謝します。
1バイトを節約してくれたKevinに感謝します。

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

s=から削除することで2バイトを節約しs=s+"\n"、に変更return(n=--n-1)することでさらに2バイトをreturn(n=n-2)合計4バイト節約できます。
ヒピノ

こんにちは。することができますゴルフ二つの部分:String s="",c="",t="";String s,c,t=s=c="";-2バイト)、およびreturn(n=n-2)>=0?s+"\n"+c+c(n,++x)+return n-1>0?s+"\n"+c+c(n-2,++x)+-2バイト再び)
ケビンCruijssen

ただし、nは関数の他の引数で使用する必要があるため、@ KevinCruijssenパターンはn=n-2->を変更した後、期待どおりではありませんn-1>0
ナンバーノット

@Numberknot知っていますが、その部分にも変更nn-2ました。return(n=n-2)>=0 ... nに変更されるのreturn n-1>0 ... n-2はまだ短いです。PS:バイトを節約してくれたことに感謝していますが、編集中のコードは変更していません。;)
ケビンクルーイッセン

@Numberknot Umm ..あなたはまだ私の2番目のヒントを忘れていました。とにかく、ここでの短い変異体である: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:"*";}なしtideoneテスト - 133バイト
ケビンCruijssen

3

PHP-95バイト

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

の代わりに実際の改行を使用してバイトを保存しました "\r"


2

Pyth、22バイト

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

STDINで整数の入力を受け取り、結果を出力するプログラム。

オンラインで試す

使い方

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バイト

ゴルフを少し小さくする必要があります

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

ここでideoneでテストできます


2

C、79バイト

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

countdown変数kを行インデックスと列インデックスに分割します。列インデックスが0(行の最後の文字)の場合、改行文字(10)が出力されます。次に、行と列のインデックスを調整して、中央のアスタリスクを中心にします。次に、abs(x) < abs(y)スペースを出力するための短い条件です。



2

Java 7、156バイト

かなり簡単です。の行n、の星j、のスペースs、の方向を追跡しdます。私は本当に非再帰的なJavaの回答をボード上で欲しかったのですが、それが少し短いことも害になりません:)

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

改行あり:

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バイト

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

テスト:

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

説明:

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

1+を持つAPLを削除して使用します⎕IO←0
アダム

2

Haskell、84バイト

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

いい解決策!しかし、私はあなたが必要としないと確信しておりputStr、あなたはこのfromEnumようなものを取り除くことができます。
ბიმო



2

PHP104 88バイト

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

オンラインでお試しください!

これは、このチャレンジでPHPの最低得点を上回っていませんが、捨てるにはあまりにもクレイジーです。

さて、このチャレンジでPHPのスコア(最低ではないが)が最低になったが、それでもクレイジーだという事実は変わらない。

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

83?それはここに有用ではないのですが、また、ハァッ、PHPは、あまりにも裸の単語を持っている
ASCIIのみ

@ASCIIのみのラット!もっとやるべきことがあるようです!lol
640KB



@ASCIIのみです!それは確かに正しいアプローチです!
640KB

1

Groovy、66バイト

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

試してください:https : //groovyconsole.appspot.com/script/5145735624392704

説明:

((n..1)+(2..n)) -逆パリンドロマイズn [n,..,1,..,n]

.each{if(it%2>0){...} -奇数要素を反復処理します。

println(("*"*it).center(n)) -n個の星を中央に配置し、それぞれを改行で印刷します。


.eachコードブロックは可能性があり{it%2&&println(("*"*it).center(n))}
マナトワーク

1

PHP、191バイト

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

のように走る php -f golf_hourglass.php 15

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

その背後にある考え方は、上半分(シングルの前の部分*)を作成し、上部分を2回エコーしますが、2回目は逆の順序でエコーすることです。


I think this is a better start for this task 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; this is better
Jörg Hülsermann

Replace implode() with join() to save 6 bytes.
Alex Howansky

Replace \n with an actual new line to save a byte.
Alex Howansky

1

Pyke, 22 19 bytes

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

Try it here!

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

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);
  }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.