コードゴルフクリスマス版:高さNのクリスマスツリーを印刷する方法


89

数字を指定すると、コード文字の最小数を使用してN高さのクリスマスツリーを印刷するにはどうすればよいNですか? Nは、最小値3、および最大値に制限されていると想定されます30(境界およびエラーチェックは不要です)。Nプログラムまたはスクリプトへの唯一のコマンドライン引数として指定されます。

すべての言語は高く評価されています。すでに実装されている言語があり、短くすることができる場合は、可能であれば編集します。明確にするために改行と空白を含めますが、文字数には含めないでください。

クリスマスツリーはそのように生成され、その「トランク」は中央の「*」のみで構成されます。

N = 3:

   *
  ***
 *****
   *

N = 4:

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

N = 5:

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

Nは、1本の幹線を含まない枝の高さを定義します。

メリークリスマスPPCG!

回答:


46

J、24文字

(,{.)(}:@|."1,.])[\'*'$~

   (,{.)(}:@|."1,.])[\'*'$~5
    *    
   ***   
  *****  
 ******* 
*********
    *    

説明:

'*'$~5
*****

[\'*'$~5
*    
**   
***  
**** 
*****

次に}:@|."1、各行を反転し、最後の列を取り除き、,.ステープルで留め]ます。

次に,{.、最初の列を下部に貼り付けます。

以前のエントリ

29文字、スペースなし。

   ((\:i。@#)、}。) "1 $& '*'" 0>:0、〜i.3
  *
 ***
*****
  *
   ((\:i。@#)、}。) "1 $& '*'" 0>:0、〜i.11
          *
         ***
        *****
       *******
      *********
     ***********
    *************
   ***************
  *****************
 *******************
*********************
          *

   NB。1から n までカウントしてから、もう一度1
   >:0、〜i.3
1 2 3 1
   NB。'*'をそれぞれ x 複製します
   $& '*' "0>:0、〜i.3
*
**
***
*
   NB。各行を逆にする
   (\:i。@#) "1 $& '*'" 0>:0、〜i.3
  *
 **
***
  *
   NB。先行列を取り除く
   }。 "1 $& '*'" 0>:0、〜i.3

*
**

   NB。一緒に貼り付ける
   ((\:i。@#)、}。) "1 $& '*'" 0>:0、〜i.3
  *
 ***
*****
  *

ちょうど9以上の文字を使用すると、この機能に名前を付けることができます:c=:[:((\:i.@#),}.)"1[:$&'*'"0[:>:0,~i.
ephemient

11
何、コードを理解できるようにするために何らかのJドキュメントライブラリを使用していますか?:)

92

Brainfuck、240文字

              ,
             >++
            +++++
           +[-<---
          --->],[>+
         +++++++[-<-
        ----->]<<[->+
       +++++++++<]>>]<
      [->+>+>>>>>>>+<<<
     <<<<<<]>>>>++++++++
    [-<++++>]>++++++[-<++
   +++++>]+>>>++[-<+++++>]
  <<<<<<[-[>.<-]<[-<+>>+<]<
 [->+<]>>>>>[-<.>>+<]>[-<+>]
>.<<++<<<-<->]>>>>>>>-[-<<<<<
           <.>>>
           >>>]<
           <<<<.

まだやっていません。機能しますが、1桁の数字でのみ機能します。

編集:完了!EOFとして0を使用するインタープリターで機能します。NOTE-1のコメントソースのsを参照してください。

もう一度編集します。Brainfuckにはコマンドライン引数を読み取るための標準的な方法がないため、代わりにstdin(標準入力)を使用しました。もちろん、ASCII。

3回目の編集:ああ.、コードを圧縮するときに文字を削除(出力)したようです。一定...

メインループの基本的なメモリ管理を次に示します。文字数を30ほど減らすために大幅に最適化できると確信しています。

  1. 一時的
  2. カウンターのコピー
  3. カウンター(0までカウント)
  4. スペース文字(10進数32)
  5. アスタリスク文字(10進数42)
  6. 現在の行のアスタリスクの数(1 + 2 * counter)
  7. 一時的
  8. 改行文字
  9. 一時的?
  10. 行の合計数(つまり、入力値。トランクを印刷するときに、最後まで保存されます)

要約版:

,>++++++++[-<------>],[>++++++++[-<------>]<<[->++++++++++<]>>]<[->+>+>>>>>>>+<<<<<<<<<]>>>>++++++++[-<++++>]>++++++[-<+++++++>]+>>>++[-<+++++>]<<<<<<[-[>.<-]<[-<+>>+<]<[->+<]>>>>>[-<.>>+<]>[-<+>]>.<<++<<<-<->]>>>>>>>-[-<<<<<<.>>>>>>]<<<<<.

そして、きれいなバージョン:

ASCII to number
,>
++++++++[-<------>]  = 48 ('0')

Second digit (may be NULL)
,
NOTE:   Add plus sign here if your interpreter uses negative one for EOF
[ NOTE: Then add minus sign here
 >++++++++[-<------>]
 <<[->++++++++++<]>>  Add first digit by tens
]

Duplicate number
<[->+>+>>>>>>>+<<<<<<<<<]>>

Space char
>>++++++++[-<++++>]

Asterisk char
>++++++[-<+++++++>]

Star count
+

New line char
>>>++[-<+++++>]<<<

<<<

Main loop
[
Print leading spaces
-[>.<-]

Undo delete
<[-<+>>+<]
<[->+<]
>>

Print stars
>>>[-<.>>+<]

Add stars and print new line
>[-<+>]
>.<
<++

<<<

-<->
End main loop
]

Print the trunk
>>>>>>>
-[-<<<<<<.>>>>>>]
<<<<<.

Merry Christmas =)

1
私の脳は、F .....病気に感じている

3
何てことだ。
匿名の

63

Perl、50文字

(1関連スペース)

perl:1行バージョン:

print$"x($a-$_),'*'x($_*2+1),$/for 0..($a=pop)-1,0

そして今、より多くのホワイトスペースがあります:

print $"  x ( $a - $_ ),             #"# Syntax Highlight Hacking Comment
      '*' x ( $_ * 2  + 1),
      $/
for 0 .. ( $a = pop ) - 1, 0;

$ perl tree.pl 3
   *
  ***
 *****
   *
$ perl tree.pl 11
           *
          ***
         *****
        *******
       *********
      ***********
     *************
    ***************
   *****************
  *******************
 *********************
           *
$ 

Perl以外のユーザー向けの拡張説明。

# print $Default_List_Seperator ( a space )  
#     repeated ( $a - $currentloopiterationvalue ) times,
print $" x ( $a - $_ ), 
#"# print '*' repeated( $currentloopiteration * 2 + 1 ) times. 
  '*' x ( $_ * 2  + 1),
# print $Default_input_record_seperator ( a newline )
  $/
# repeat the above code, in a loop, 
#   iterating values 0 to ( n - 1) , and then doing 0 again
for 0 .. ( $a = pop ) - 1, 0;
# prior to loop iteration, set n to the first item popped off the default list, 
#   which in this context is the parameters passed on the command line. 

25
神聖なくだらない... perlは本当に読めない。

8
@zenazn、また、ほとんどのゴルフはあらゆる言語のBADコードであることに注意する必要があります。これが最もクリーンなコードの競合であれば、私たちもそれを勝ち取ることができます。
ケントフレドリック

5
@zenazn:証拠は、あなたは私たちが協力し、上お互いのコードを向上さ見ることができ、これは証明WEを読むことができ、お互いのコードは完全に罰金。
ケントフレドリック

1
PS:Perl以外のプログラマーの説明をありがとう。まだかなり読みにくいですが、少なくとも理にかなっています。しばらくすると慣れるでしょう。

2
@RobH:JはAPLの子です。ある意味では、APLの文字セットをすべての操作に特別なシンボルで使用しないため、読みにくくなります。代わりに、複数の意味を持つASCII文字をオーバーロードします。 stackoverflow.com/questions/392788/1088931#1088931
ephemient

26

言語:Python(シェル経由)、文字数:64(2つの有効なスペース)

python -c "
n=w=$1
s=1
while w:
    print' '*w+'*'*s
    s+=2
    w-=1
print' '*n+'*'"

$ sh ax6 11
           *
          ***
         *****
        *******
       *********
      ***********
     *************
    ***************
   *****************
  *******************
 *********************
           *

8
私はほとんどこのソリューションについて気に入っているのpythonはそれが最も読みやすいソリューションの一つだ、それは本当に難しい曖昧なコードを書くことができますということです

シェルを使用して引数を処理していますが、これはコードゴルフIMOの精神ではありません。「import sys」と「n = w = int(sys.argv [1])」およびループ本体に1文字のインデントを使用すると、このバージョンでは89文字になります。

4
これが以前のやり方です。この質問の趣旨は楽しみを持つことです。さらに、1つの言語のみを使用する仕様もありませんでした。たとえば、brainfuckの回答を参照してください。引数なし。

26

x86 asm 16ビット、50バイト

まだアセンブリバージョンはありませんか?:)

    bits 16
    org 100h

    mov si, 82h
    lodsb
    aaa
    mov cx, ax
    mov dx, 1
    push cx 
    mov al, 20h
    int 29h
    loop $-2
    push dx
    mov al, 2ah
    int 29h
    dec dx
    jnz $-3
    pop dx
    mov al, 0ah
    int 29h
    inc dx
    inc dx
    pop cx
    loop $-23
    shr dx, 1
    xchg cx, dx
    mov al, 20h
    int 29h
    loop $-2
    mov al, 2ah
    int 29h
    ret

(注:このバージョンでは、Nは1〜9に制限されています)

G:\>tree 9
         *
        ***
       *****
      *******
     *********
    ***********
   *************
  ***************
 *****************
         *

ここからダウンロード


24

言語:Windows Batch Script衝撃的!

@echo off
echo Enable delayed environment variable expansion with CMD.EXE /V

rem Branches
for /l %%k in (1,1,%1) do (
set /a A=%1 - %%k
set /a B=2 * %%k - 1
set AA=
for /l %%i in (1,1,!A!) do set "AA=!AA! "
set BB=
for /l %%i in (1,1,!B!) do set BB=*!BB!
echo !AA!!BB!
)

rem Trunk
set /a A=%1 - 1
set AA=
for /l %%i in (1,1,!A!) do set "AA=!AA! "
echo !AA!*

マゾ!私はそれが好きです

とてもいい... +1

2
遅延変数展開は、setlocal enabledelayedexpansionコマンドを使用して有効にできます。
ヘレン

男。マジ?

それを機能させることはできません。初めて試しましたが。
-Fabinout

21

ルビー、64バイト

n=ARGV[0].to_i
((1..n).to_a+[1]).each{|i|puts' '*(n-i)+'*'*(2*i-1)}

n=$*[0].to_i
((1..n).to_a<<1).each{|i|puts' '*(n-i)+'*'*(2*i-1)}

メリークリスマス!

編集:Joshua Swinkによって提案された改善が追加されました


ダンルビーでまだ誰も試していないことを願っていた。良くやった。

これは、Rubyの非常に優れたラインです。

私はあまりにも不潔に見えましたか?申し訳ありませんが、私の意図ではありません!メリークリスマス!:)

意地悪するつもりもなかったし、もちろん正しかった!メリークリスマス!

1
1.9では、さらにいくつかの文字を保存できます:n=$*[0].to_i;puts [*1..n,1].map{|i|" "*(n-i)+"*"*(2*i-1)}58に引き下げられます

14

言語:C#、文字数:120

static void Main(string[] a)
{
    int h = int.Parse(a[0]);

    for (int n = 1; n < h + 2; n++)
        Console.WriteLine(n <= h ?
            new String('*', n * 2 - 1).PadLeft(h + n) :
            "*".PadLeft(h + 1));
    }
}

フォーマットなしのコードのみ(120文字):

int h=int.Parse(a[0]);for(int n=1;n<h+2;n++)Console.WriteLine(n<=h?new String('*',n*2-1).PadLeft(h+n):"*".PadLeft(h+1));

109文字のバージョン(コードのみ):

for(int i=1,n=int.Parse(a[0]);i<n+2;i++)Console.WriteLine(new String('*',(i*2-1)%(n*2)).PadLeft((n+(i-1)%n)));

高さ= 10の結果:

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

13

言語:dc(シェル経由)文字数:83

少し短いDCバージョン:

dc -e '?d1rdsv[d32r[[rdPr1-d0<a]dsaxszsz]dsbx1-rd42rlbx2+r10Plv1-dsv0<c]dscxszsz32rlbx[*]p' <<<$1

編集:定数10を$ 1に変更


11
良い主よ、それは一体何ですか?

1
ただmanページを読んでください;-)

12

python、「-c」トリック... @ 61文字(および1行)

python -c"for i in range($1)+[0]:print' '*($1-i)+'*'*(2*i+1)"

実際、それは57文字で、質問の仕様に従って ''スペースのみが重要です。

10

以下は107文字の合理的なスペース効率の高いHaskellバージョンです。

main=interact$(\g->unlines$map(\a->replicate(g-a)' '++replicate(a*2-1)'*')$[1..g]++[1]).(read::[Char]->Int)

それを実行する:

$ echo 6 | runhaskell tree.hs
     *
    ***
   *****
  *******
 *********
***********
     *

メリークリスマス、すべて:)


10

言語:dc(シェル経由)、文字数:119(1つの有効なスペース)

それのあいまいさのために:)

dc -e "$1dsnsm"'
[[ ]n]ss
[[*]n]st
[[
]n]sl
[s2s1[l2xl11-ds10<T]dsTx]sR
[lndlslRxlcdltlRxllx2+sc1-dsn0<M]sM
1sclMxlmlslRxltxllx
'

$ sh ax3 10
          *
         ***
        *****
       *******
      *********
     ***********
    *************
   ***************
  *****************
 *******************
          *

まじで、wtf?P:私は、単一の行を理解していない

dcは逆ポーランド計算機です。「man dc」は明らかな方法です:)

6

より良いC ++、約210文字:

#include <iostream>
using namespace std;
ostream& ChristmasTree(ostream& os, int height) {
    for (int i = 1; i <= height; ++i) {
        os << string(height-i, ' ') << string(2*i-1, '*') << endl;
    }
    os << string(height-1, ' ') << '*' << endl;
    return os;
}

179に最小化:

#include <iostream>
using namespace std;ostream& xmas(ostream&o,int h){for(int i=1;i<=h;++i){o<<string(h-i,' ')<<string(2*i-1,'*')<<endl;}o<<string(h-1,' ')<<'*'<<endl;return o;}

stdを使用します。誰でも?

strager-私が始めたとき、std :: 'sと' using namespace std; 'しかありませんでした。テキストがたくさんありました。今では文字数が減ると思います。

あなたのバージョンは私のものよりも非効率的です。文字列を作成する必要があるため、私のバージョンは必要な文字を印刷するだけです。:)
ピョン08

6

言語:python、トリックなし、78文字

import sys
n=int(sys.argv[1])
for i in range(n)+[0]:print' '*(n-i)+'*'*(2*i+1)

6

グルービー 62B

n=args[0]as Long;[*n..1,n].any{println' '*it+'*'*(n-~n-it*2)}

_

n = args[0] as Long
[*n..1, n].any{ println ' '*it + '*'*(n - ~n - it*2) }

5

ΤΖΩΤΖΙΟΥの答えを改善します。コメントできないので、ここに新しい投稿があります。72文字。

import sys
n=int(sys.argv[1])
for i in range(n)+[0]:
   print ("*"*(2*i+1)).center(2*n)

「python -c」トリックを使用して、61文字。

python -c "
for i in range($1)+[0]:
   print ('*'*(2*i+1)).center(2*$1)
"

センター関数を学び、「python -c」は複数の行コードを受け入れることができることを学びました。ありがとう、ΤΖΩΤΖΙΟΥ。


5

Linqを使用したC#:

    using System;
    using System.Linq;
    class Program
        {
            static void Main(string[] args)
            {
                int n = int.Parse(args[0]);
                int i=0;
                Console.Write("{0}\n{1}", string.Join("\n", 
                   new int[n].Select(r => new string('*',i * 2 + 1)
                   .PadLeft(n+i++)).ToArray()),"*".PadLeft(n));
            }
       }

170文字。

int n=int.Parse(a[0]);int i=0;Console.Write("{0}\n{1}",string.Join("\n",Enumerable.Repeat(0,n).Select(r=>new string('*',i*2+1).PadLeft(n+i++)).ToArray()),"*".PadLeft(n));

5

AWK、1行に86文字。

awk '{s="#";for(i=0;i<$1;i++){printf"%"$1-i"s%s\n","",s;s=s"##"}printf"%"$1"s#\n",""}'

echo "8" | awk '{s="#";for(i=0;i<$1;i++){printf"%"$1-i"s%s\n","",s;s=s"##"}printf"%"$1"s#\n",""}'
        #
       ###
      #####
     #######
    #########
   ###########
  #############
 ###############
        #

cat tree.txt
3
5

awk '{s="#";for(i=0;i<$1;i++){printf"%"$1-i"s%s\n","",s;s=s"##"}printf"%"$1"s#\n",""}' tree.txt
   #
  ###
 #####
   #
     #
    ###
   #####
  #######
 #########
     #

5

言語:Java、文字数:219

class T{ /* 219 characters */
  public static void main(String[] v){
    int n=new Integer(v[0]);
    String o="";
    for(int r=1;r<=n;++r){
      for(int s=n-r;s-->0;)o+=' ';
      for(int s=1;s<2*r;++s)o+='*';
      o+="%n";}
    while(n-->1)o+=' ';
    System.out.printf(o+"*%n");}}

参考までに、以前の最小269から231文字までの再帰を使用して、以前のJavaソリューションを削ることができました。もう少し長くなりますが、T本当にオブジェクト指向であるため、このソリューションが好きです。ランダムなサイズのTインスタンスの小さなフォレストを作成できます。そのタックの最新の進化は次のとおりです。

class T{ /* 231 characters */
  public static void main(String[] v){new T(new Integer(v[0]));}}
  String o="";
  T(int n){
    for(int r=1;r<=n;++r){
      x(' ',n-r);x('*',2*r-1);o+="%n";}
    x(' ',n-1);
    System.out.printf(o+"*%n");
  }
  void x(char c,int x){if(x>0){o+=c;x(c,x-1);}
 }

新しい文字カウントは251(1つの関連スペース)である

「public static void main」を取り除き、静的ブロックを使用してjava 6でコンパイルします;)
Fabinout

私はそれがほぼ9年だったと知っています(笑..)いくつかのものをゴルフすることができます:class T{public static void main(String[]v){long n=new Long(v[0]),r=1,s;String o="";for(;r<=n;r++){for(s=n-r;s-->0;)o+=' ';for(;++s<2*r;)o+='*';o+="\n";}while(n-->1)o+=' ';System.out.println(o+"*");}}(199文字/バイト)
ケビンCruijssen

5

言語:PowerShell、文字数:41(1スペースを含む)

1..$args[0]+1|%{" "*(30-$_)+"*"*($_*2-1)}

5

dyalog APLを使用した21文字。

m,⍨⌽0 1↓m←↑'*'\¨⍨1,⍨⍳

⍳は、1で始まる整数のベクトルを返します。

1、⍨は、ベクトルの末尾に1を追加します。これが木の根元になります。

'*' \¨⍨は、前のベクトルで指定された長さの*文字列のベクトルを提供します。

↑は、ベクトルを行列に変換し、右側にスペースを追加します。

m←は行列をmに保存します。

0 1↓は、ゼロ行と最初の列をドロップします。

matrixはマトリックスを反転します。

m、⍨は右側のmと連結します。


m,⍨⌽0 1↓m←->(⌽,0 1↓⊢)
ngn

4

言語:C、文字数:133

Cバージョンの改善。

char s[61];

l(a,b){printf("% *.*s\n",a,b,s);}

main(int i,char**a){
  int n=atoi(a[1]);memset(s,42,61);
  for(i=0;i<n;i++)l(i+n,i*2+1);l(n,1);
}

動作し、引数としてツリーの高さを取ります。K&Rスタイルのコードを許容するコンパイラが必要です。

今はとても汚い気がします。これはコードがcodeいです。


これには、私の最初のJavaカットと同じ問題があります。コマンドライン引数を使用した完全なプログラムではありません!

ああ?これは必須ですか?問題ない。それを修正します。

不要な改行がすべて削除されると、138文字になります。
Can BerkGüder08年

133をカウントします(すべての空白を削除してファイルサイズをチェックしました)

4

R(62バイト)

Rソリューションはまだ見ていません。見逃した場合は修正してください。

for(i in c(1:N,1))cat(rep(" ",N-i),rep("*",2*i-1),"\n",sep="")

出力:

> N <- 3
> for(i in c(1:N,1))cat(rep(" ",N-i),rep("*",2*i-1),"\n",sep="")
  *
 ***
*****
  *
> 
> N <- 4
> for(i in c(1:N,1))cat(rep(" ",N-i),rep("*",2*i-1),"\n",sep="")
   *
  ***
 *****
*******
   *
> 
> N <- 5
> for(i in c(1:N,1))cat(rep(" ",N-i),rep("*",2*i-1),"\n",sep="")
    *
   ***
  *****
 *******
*********
    *

3

言語:C、文字数:176(2つの関連スペース)

#include <stdio.h>
#define P(x,y,z) for(x=0;x++<y-1;)printf(z);
main(int c,char **v){int i,j,n=atoi(v[1]);for(i=0;i<n;i++){P(j,n-i," ")P(j,2*i+2,"*")printf("\n");}P(i,n," ")printf("*\n");}


3

言語:Python、重要な文字数:90

いですが、動作します:

import sys
n=int(sys.argv[1])
print"\n".join(" "*(n-r-1)+"*"*(r*2+1)for r in range(n)+[0])

...

$ python tree.py 13
            *
           ***
          *****
         *******
        *********
       ***********
      *************
     ***************
    *****************
   *******************
  *********************
 ***********************
*************************
            *

あなたのキャラクター数は98(2つの重大なスペース、引用符で囲まれたもの)である

3

これはCWであるため、コードゴルフは常に「文字数」などの観点から整理されているのは好きではありません。コンパイラー/インタープリターの命令数(または同様の基準)で整理できませんか?ここに再びRubyソリューションがありますが、基本的には同じですが、現在は人間が消費するものでもあります。

SPACE = " "
ASTERISK = "*"
height_of_tree=ARGV[0].to_i
tree_lines = (1..height_of_tree).to_a
tree_lines.push 1 # trunk
tree_lines.each do | line |
   spaces_before = SPACE*(height_of_tree-line)
   asterisks = ASTERISK*(2*line-1) 
   puts spaces_before + asterisks
end

最初の声明に同意します。そのような言葉で言えば、perlのような言語には最初から利点があります。statemetnsの数などのようなものでなければなりません。

おかげで...昨日ゴルフについて質問しましたが、それを行う方法は「トークン」であるかもしれません...そのように名前の長さなどは罰せられません。



2

PHP、111文字

(最後の文字は改行でなければなりません。)

<?php $n=$argv[1];for($r='str_repeat';$i<$n;$i++)echo $r(' ',$n-$i).$r('*',$i*2+1)."\n";echo $r(' ',$n).'*' ?>

読み取り可能なバージョン:

<?php

$n = $argv[1];

for ($r = 'str_repeat'; $i < $n; $i++)
    echo $r(' ', $n - $i) . $r('*' , $i * 2 + 1) . "\n";

echo $r(' ', $n) . '*'

?>

文字列を作成してからエコーすることで、複数の文字を保存できます。おもう。試してみてください。

良いアイデアですが、試してみましたが、長くなります。「$ t。=(...)」は「echo(...)」よりも1文字だけ短いため、最後に「echo $ t」も必要です。

「$ i = 0;」を削除して、4文字短くしました。forステートメントの最初の部分。PHPは、整数コンテキストで使用される存在しない変数がすでに0であると想定しています!:P

forの中に$ r = ..を入れてcharを保存しました。また、改行文字は2バイトではなく1バイトにする必要があります。=]

ええ、テキストエディターで列番号を使用してカウントしているため、1カウントが間違っていることに気付きました。Linuxを使用しているため、改行文字は1バイトです。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.