37

The challenge

The shortest code, by character count to output an ASCII representation of Sierpinski's Triangle of N iterations made from the following ASCII triangle:

 /\
/__\

Input is a single positive number.

Test cases

Input:
    2
Output:
       /\
      /__\
     /\  /\
    /__\/__\

Input:
    3
Output:
           /\
          /__\
         /\  /\
        /__\/__\
       /\      /\
      /__\    /__\
     /\  /\  /\  /\
    /__\/__\/__\/__\

Input:
    5
Output:
                                   /\
                                  /__\
                                 /\  /\
                                /__\/__\
                               /\      /\
                              /__\    /__\
                             /\  /\  /\  /\
                            /__\/__\/__\/__\
                           /\              /\
                          /__\            /__\
                         /\  /\          /\  /\
                        /__\/__\        /__\/__\
                       /\      /\      /\      /\
                      /__\    /__\    /__\    /__\
                     /\  /\  /\  /\  /\  /\  /\  /\
                    /__\/__\/__\/__\/__\/__\/__\/__\
                   /\                              /\
                  /__\                            /__\
                 /\  /\                          /\  /\
                /__\/__\                        /__\/__\
               /\      /\                      /\      /\
              /__\    /__\                    /__\    /__\
             /\  /\  /\  /\                  /\  /\  /\  /\
            /__\/__\/__\/__\                /__\/__\/__\/__\
           /\              /\              /\              /\
          /__\            /__\            /__\            /__\
         /\  /\          /\  /\          /\  /\          /\  /\
        /__\/__\        /__\/__\        /__\/__\        /__\/__\
       /\      /\      /\      /\      /\      /\      /\      /\
      /__\    /__\    /__\    /__\    /__\    /__\    /__\    /__\
     /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\
    /__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\

Code count includes input/output (i.e full program).

LiraNuna
  • 64,916
  • 15
  • 117
  • 140
  • I am sorry this is a 'generic' golf, I'm starting to run out of ideas... – LiraNuna Nov 13 '09 at 02:15
  • I started implementing this last night in javascript using the canvas tag, so I will assume that won't work here. – James Black Nov 13 '09 at 02:25
  • I can draw this to the screen in about 2 lines in C++ :p That XOR operator is freaking crazy. – mpen Nov 13 '09 at 03:15
  • 9
    *"I'm starting to run out of ideas..."* You've been mining the "console output figures" vein pretty hard. Maybe it's time to give that a break. One of the things that made Lasers different was that the input was non-trivial. Or even take a break on the whole thing, but I've gotten used to Thursday tee time. I dink around with most of your problems even if I don't submit many solutions. – dmckee --- ex-moderator kitten Nov 13 '09 at 03:21
  • 11
    LiraNuna, you've done an awesome job. There is a reason that your challenges get by far the most votes. If you never posted another you would still be a Stack Overflow legend. Thanks for all the fun! – DigitalRoss Nov 13 '09 at 04:37
  • I'm just curious... can someone please do one up in Mindfuck? – Steven Nov 13 '09 at 05:35
  • @Steven - It's brain (traditionally lowercase), not Mind, and the word from @Atwood is that it's "The Language that Shall Not Be Named". See http://meta.stackoverflow.com/questions/19478/the-many-memes-of-meta/24119#24119 – Chris Lutz Nov 13 '09 at 05:50
  • 2
    @dmckee: Then I'll try to think more of the way of Lasers. Though designing Lasers was tough. I have a few ideas but they are not polished. I can always start "Reverse" series! (reverse beehive!) – LiraNuna Nov 13 '09 at 06:06
  • I really don't like these text formatting golfs. I end up doing half of them anyways, though, since coming up with good mathematical/computational puzzle golfs is even harder. – ephemient Nov 13 '09 at 06:31
  • ephemient: *"text formatting"* ? What about cubes or hourglass style? those created ASCII from variables in input. Were those bad? I personally loved cubes and beehive - They were simple enough for newbies to create long answers and participate, but had the potential to be short with proper code. – LiraNuna Nov 13 '09 at 07:47
  • @LiraLuna: Those were interesting, and I feel sad that I was too late to make any good contributions to them. And despite my "dislike" I answered anyways (probably because it only took minutes to write the J solution, as opposed to the hours it usually takes). – ephemient Nov 13 '09 at 14:19
  • FYI: I started some meta discussion about these code-golf questions @ http://meta.stackexchange.com/questions/29687/should-authors-of-a-code-golf-question-not-refer-to-the-sources-for-their-entries – ChristopheD Nov 13 '09 at 21:42
  • @LiraNuna: If you've seen mine, they don't get voted up as much but i think that vein of questions has plenty of unasked ones waiting or your touch! Or maybe those will be my trademark... :) – RCIX Nov 14 '09 at 00:25
  • So, we have a tie - J vs. Golfscript. Which one should be picked? Golfscript was the first to reach 46 char count, should it be the 'winner'? I always select the 'winner' on Monday. – LiraNuna Nov 16 '09 at 20:56

21 Answers21

27

J

46 characters, reading from stdin.

(,.~,~[,.~' '$~#,#)^:(<:".1!:1]3)' /\',:'/__\'

\n always delimits sentences, which made it impossible to fit inside S3 (only 54 characters to play with). S4 is a bit big at 162, so I padded it to fit. Serendipitously, /\ is a legal adverb. ☺

               /\
              i=:3
             /\  /\
            %r=:1!:1
           /\      /\
          t=:]    [r+i
         /\  /\  /\  /\
        b=:' /\',:'/__\'
       /\              /\
      i=:1            -".t
     /\  /\          /\  /\
    h=:(' '$        ~#,#),.]
   /\      /\      /\      /\
  s=:(    h^:1    ,d=:    ,.~)
 /\  /\  /\  /\  /\  /\  /\  /\
(,,&(10{a.)"1[s^:(-i)b)(1!:2)(4)
ephemient
  • 198,619
  • 38
  • 280
  • 391
24

Sorry I'm late. This is based on A. Rex's Perl solution:

                           &I                               
                          ;for                              
                         $x  (2                             
                        ..<>){$E                            
                       .=      $E                           
                      ;my$    y;3*                          
                     33  +3  **  3;                         
                    s".+"$y.=$n.$&x2                        
                   ,$              E.                       
                  $&.$            E"ge                      
                 ;;  $_          .=  $y                     
                }print;;        sub I{($                    
               E,      $n      ,$      F,                   
              $B,$    U)=(    $",$    /,qw                  
             (/   \   _  ))  ;$  _=  $E  .$                 
            F.$B.$E.$n.$F.$U.$U.$B};33333333                
mob
  • 117,087
  • 18
  • 149
  • 283
20

Golfscript - 46

' /\ /__\ '4/{).+: ;.{ \ ++}%\{.+}%+~ ]}@~(*n*

Golfscript - 47

' /\ /__\ '4/): ;{  +: ;.{ \ ++}%\{.+}%+}@~(*n*

Golfscript - 48

' ': '/\ /__\\'+4/{2 *: ;.{ \ ++}%\{.+}%+}@~(*n*

Golfscript - 51

~' ': '/\ /__\\'+4/\(,{;2 *: ;.{ \ ++}%\{.+}%+}%;n*

Same algorithm as my shorter python ( and ruby ) answer

Golfscript - 78

2\~(?,{-1*}$1: ;{"  ":$*. 2base.{[$$+' /\ ']=}%n+@@{[$$+"/__\\"]=}%n .2*^: ;}%

Same algorithm as my longer python solution

This one has significant newlines

2\~(?,{-1*}$1: ;{"  ":
*. 2base.{[
2*' /\ ']=}%n+@@{[
2*"/__\\"]=}%n .2*^: ;}%
John La Rooy
  • 295,403
  • 53
  • 369
  • 502
16

Go, 273 characters

package main
import(f"fmt";"os";s"strconv";)func main(){var
t=[2]string{" /\\ ","/__\\"};
n,_:=s.Atoi(os.Args[1]);a:=1;N:=a<<uint(n);for
N>0{N-=2;for
k:=0;k<2;k++{for
j:=0;j<N;j++{f.Print(" ")}b:=a;for
b>0{o:=t[k];if
b&1==0{o="    "}f.Print(o);b>>=1}f.Print("\n")}a^=a*2}}

Whitespace is all significant.

Unminized with gofmt sierpinski-3.go | perl -p -e's/\t/ /g':

package main

import (
    "fmt";
    "os";
    "strconv";
)

func main() {
    var t = [2]string{" /\\ ", "/__\\"};
    n, _ := strconv.Atoi(os.Args[1]);
    a := 1;
    N := a << uint(n);
    for N > 0 {
        N -= 2;
        for k := 0; k < 2; k++ {
            for j := 0; j < N; j++ {
                fmt.Print(" ")
            }
            b := a;
            for b > 0 {
                o := t[k];
                if b&1 == 0 {
                    o = "    "
                }
                fmt.Print(o);
                b >>= 1;
            }
            fmt.Print("\n");
        }
        a ^= a * 2;
    }
}

I got a good hint for Go golf here.

Community
  • 1
  • 1
  • 5
    I'm guessing that "Go" isn't short for "Golfing Language" – mob Nov 13 '09 at 06:23
  • @mobrule: I only started learning Go yesterday. I'm sure that more experienced Go programmers could do better. Unfortunately there are not many experienced Go programmers since the language was only announced two days ago. See http://stackoverflow.com/questions/1712172/ –  Nov 13 '09 at 08:16
  • @LiraNuna: probably just my one-day-old Go is ugly. `b&1==0` is true if `b` contains an even number. It pulls the bottom bit out of b and tests whether it is zero or not. This is straight from Gnibbler's algorithm. –  Nov 13 '09 at 08:23
  • 1
    The `:=` makes me feel like I'm back in my high school Turbo Pascal class. – gnovice Nov 13 '09 at 14:49
  • 5
    I don't know Turbo Pascal, but in Go `x:=1` is short for `var x int = 1` and `y:="moo"` is short for `var y string = "moo"`. It pulls the type off the variable. –  Nov 13 '09 at 16:18
  • It's not fair to call a language ugly based on a code golf example. Beautiful code is almost against the code golf requirements. – Frank Nov 14 '09 at 14:14
  • In the unminimized version, all semicolons should be removed. – mk12 Jul 09 '13 at 16:09
10

Python - 102

a=" /\ ","/__\\"
j=' '
for n in~-input()*j:j+=j;a=[j+x+j for x in a]+[x*2for x in a]
print"\n".join(a)

Python - 105

a=" /\ ","/__\\"
j=' '
for n in(input()-1)*j:j+=j;a=[j+x+j for x in a]+[x+x for x in a]
print"\n".join(a)

Python - 109

a=" /\ ","/__\\"
for n in range(1,input()):j=' '*2**n;a=[j+x+j for x in a]+[x+x for x in a]
print"\n".join(a)

Python2.6 - 120

N=1<<input()
a=1
while N:
 N-=2
 for s in" /\ ","/__\\":print' '*N+bin(a)[2:].replace('0',' '*4).replace('1',s)
 a=a^a*2
John La Rooy
  • 295,403
  • 53
  • 369
  • 502
  • This same challenge was posted on AnarchyGolf. Here was my solution: http://golf.shinh.org/reveal.rb?Sierpinski+Fractal/MarkByers/1223081482&py – Mark Byers Nov 15 '09 at 21:38
9

Perl, 82 strokes

This version no longer prints a trailing newline. Only the first newline is necessary:

$_=' /\ 
/__\\';
for$x(2..<>){
my$y;
$".=$";
s#.+#$y.=$/.$&x2,$".$&.$"#ge;
$_.=$y
}
print

If command-line switches are allowed, then by traditional Perl golf scoring, this is 77+3 strokes (the first newline is literal):

#!perl -p
$\=' /\ 
/__\\';
$y="",
$".=$",
$\=~s#.+#$y.=$/.$&x2,$".$&.$"#ge,
$\.=$y
for 2..$_

Please feel free to edit my answer if you find an improvement.

FMc
  • 41,963
  • 13
  • 79
  • 132
A. Rex
  • 31,633
  • 21
  • 89
  • 96
  • If you're going to make extensive use of switches, you traditionally write it as a shell invocation: `perl -pae'code here'` (counting all the characters of the shell invocation and the shell quotes as part of the answer, which would also disallow you from using single quotes in your answer). But that might actually get longer. – Chris Lutz Nov 13 '09 at 06:03
  • 1
    @Chris Lutz: Traditional Perl golf scoring is the length of your code plus how many characters you have to add over the usual `perl`. So in my case, I think it's 77 strokes plus 4 for the extra ` -pa`. – A. Rex Nov 13 '09 at 06:16
  • @ephemient: I wasn't counting the newlines you just deleted anyway; they were there only for readability reasons (if you can say "readability" in this context). After I'm sure you're done editing, I'll change the answer to make that clear. Thanks for the help, though. – A. Rex Nov 13 '09 at 06:18
  • @A. Rex - I've always counted the invocation. (And `#!perl` isn't a valid shebang line on my system.) – Chris Lutz Nov 13 '09 at 06:26
  • @Chris Lutz: That's fine. I put the solutions in this order because I presume the first is the minimal one accepted by this particular golfing community. The Perl golf community would accept the second. It's worth noting that Perl golf has a long and storied tradition and I believe is the source of the word "golf". – A. Rex Nov 13 '09 at 06:34
  • Re `#!perl`: I include that because it's the shortest string so that Perl itself will interpret the switches. If I can push them to the command-line, great! If not, I can count those as raw characters. I think the second solution should be 87 characters now, which of course is longer than the first. It is possible in theory, however, to have it be less -- see my improvements on @mobrule's solution for the "Musical Notes" competition: http://stackoverflow.com/questions/1575096/code-golf-musical-notes/1575427#1575427 – A. Rex Nov 13 '09 at 06:38
  • Here's a 104-stroke solution that might inspire someone: `$_='/'.$"x(1+1<<<>)."/ \n";$\=$_.$\while s'.__.' /\ 'g||s#/.+?\S.#$"."/__\\"x($&=~y///c/4).$"#ge;print""` -- yes, it prints the empty string at the end =) – A. Rex Nov 13 '09 at 07:14
  • This is a neat solution. Sure GolfScript and J are shorter, but... surprise, this is readable. – dlamblin Nov 13 '09 at 12:15
  • @dlamblin, I'm sure the golfscript and J would be readable for you if you had spent as much time learning them as you have perl. I have only been using golfscript a short time. Everything you need to learn is on one webpage http://www.golfscript.com/golfscript/builtin.html – John La Rooy Nov 13 '09 at 12:50
  • 1
    And (almost) everything you need to know in J is linked from one webpage http://www.jsoftware.com/help/dictionary/vocabul.htm – ephemient Nov 13 '09 at 16:46
8

Haskell, 153 149 137 125 118 112 characters:

Using tail recursion:

(%)=zipWith(++)
p="  ":p
g t _ 1=t
g t s(n+1)=g(s%t%s++t%t)(s%s)n
main=interact$unlines.g[" /\\ ","/__\\"]p.read

earlier version, @118 characters:

(%)=zipWith(++)
f 1=[" /\\ ","/__\\"]
f(n+1)=s%t%s++t%t where t=f n;s=replicate(2^n)' ':s
main=interact$unlines.f.read

Using the (justly deprecated!) n+k pattern saved 4 characters.

I like how it comes out halfway readable even in compressed form.

edit:old main

main=do{n<-getLine;putStr$unlines$f$read n}
Community
  • 1
  • 1
comingstorm
  • 25,557
  • 3
  • 43
  • 67
7

Perl

94 characters when newlines are removed.

$c=2**<>;$\=$/;for$a(0..--$c){print$"x($c-$a&~1),
map$_*2&~$a?$"x4:$a&1?'/__\\':' /\ ',0..$a/2}
ephemient
  • 198,619
  • 38
  • 280
  • 391
  • You can save 5 characters by reading from stdin with `<>` if you want. If you don't, `pop` still saves characters. Either way, you can use the ridiculous construct `$c=2**~-<>;` or `$c=2**~-pop;` to save on parentheses around the `/2`. – A. Rex Nov 13 '09 at 07:51
7

Ruby — 85

a=' /\ ','/__\\'
j=' '
2.upto(gets.to_i){j+=j;a=a.map{|x|j+x+j}+a.map{|x|x+x}}
puts a


101 chars — /\-modified solution from Rosetta Code
(a=2**gets.to_i).times{|y|puts" "*(a-y-1)+(0..y).map{|x|~y&x>0?'  ':y%2>0?x%2>0?'_\\':'/_':'/\\'}*''}
Nakilon
  • 34,866
  • 14
  • 107
  • 142
John La Rooy
  • 295,403
  • 53
  • 369
  • 502
4

Python, 135 chars

S=lambda n:[" /\\ ","/__\\"]if n==1 else[" "*(1<<n-1)+x+" "*(1<<n-1)for x in S(n-1)]+[x+x for x in S(n-1)]
for s in S(input()):print s
fserb
  • 4,004
  • 2
  • 26
  • 23
4

C

Same algorithm as the Perl answer, but weighing in heavier, at 131 necessary characters.

a,b;main(c,v)char**v;{c=1<<atoi(v[1]);for(a=0;a<c;a++,puts(""))
for(b=c;b--;write(1,b&~a?"    ":a&1?"/__\\":" /\\ ",4-2*(b>a)))--b;}

I thought write(1,…) was UNIX API, but this seems to compile and run fine on Windows too.

If you replace char by int, it saves one character and still works, but it's of questionable legality.

Community
  • 1
  • 1
ephemient
  • 198,619
  • 38
  • 280
  • 391
  • 2
    `write()` is a Unix API, and part of POSIX, but Windows provides a lot of POSIX functions. They're all "deprecated" so to be "correct" on Windows you should use `_write()` but a) this is code golf, and b) the idea that POSIX is deprecated makes me giggle. – Chris Lutz Nov 14 '09 at 00:50
4

MATLAB - 64 characters (script version)

This assumes that you have the variable N already defined in your workspace:

A=[' /\ ';'/__\'];for i=1:N-1,B=32*ones(2^i);A=[B A B;A A];end;A

MATLAB - 78 characters (m-file function version)

Pass N as an argument to the function s:

function A=s(N),A=[' /\ ';'/__\'];for i=1:N-1,B=32*ones(2^i);A=[B A B;A A];end
Community
  • 1
  • 1
gnovice
  • 125,304
  • 15
  • 256
  • 359
4

Logo (not exactly following the requirements): 47 characters

to F:n if:n[repeat 3[F(:n-1)fd 2^:n rt 120]]end

I tested this only with http://www.calormen.com/Logo/ so I don't know if it's portable. It doesn't follow the requirements, but surely logo must be the appropriate language here? :) I love that at the time of writing logo is one character short of equalling golfscript and J.

Jack V.
  • 1,381
  • 6
  • 20
2

Lua, 139 characters

t={" /\\ ","/__\\"}for i=2,(...)do for j=1,#t do
t[#t+1]=t[j]:rep(2)k=(" "):rep(#t[j]/2)t[j]=k..t[j]..k end end
print(table.concat(t,"\n"))
Community
  • 1
  • 1
gwell
  • 2,695
  • 20
  • 20
2

Nroff, 542

$ nroff -rn=5 file.n

.pl 1
.nf
.de b
. nr i 0
. while d\\$1\\ni \{\
.   \\$3 \\$1\\ni \\$2\\ni
.   nr i +1
. \}
..
.de push
. nr i 0
. while d\\$2\\ni \{\
.   nr i +1
. \}
. nr j 0
. while d\\$1\\nj \{\
.   ds \\$2\\ni \&\\*[\\$1\\nj]
.   nr i +1
.   nr j +1
. \}
..
.ds l0 \& /\[rs] \&
.ds l1 "/__\[rs]
.ds s \&\ 
.de o
. ds \\$2 \&\\*s\\*[\\$1]\\*s
..
.de p
. ds \\$2 \&\\*[\\$1]\\*[\\$1]
..
.de assign
. ds \\$2 \&\\*[\\$1]
..
.nr a 2
.while \na<=\nn \{\
. ds s \&\*s\*s
. b l m o
. b l n p
. b m l assign
. push n l
. nr a +1
.\}
.de t
\\*[\\$1]
..
.b l zz t
DigitalRoss
  • 143,651
  • 25
  • 248
  • 329
1

GolfScript (45 44 chars)

~(' /\ /__\ '4/)@{.+\.{[2$.]*}%\{.+}%+\}*;n*

Similar to gnibbler's solution. My initial attempt was already quite similar, and then I looked at his and borrowed some ideas.

Peter Taylor
  • 4,918
  • 1
  • 34
  • 59
1

F#, 225 chars

let rec p n=if n=1 then" "else p(n-1)+p(n-1)
and S n=if n=1 then[" /\\ ";"/__\\"]else let s=S(n-1)in List.append(List.map(fun s->p(n)+s+p(n))s)(List.map(fun x->x+x)s)
for s in S(int(System.Console.ReadLine()))do printfn"%s"s
Brian
  • 117,631
  • 17
  • 236
  • 300
1

Clojure: 174 characters

Algorithm stolen from others above.

(doseq[q((fn f[n](if(= n 1)[" /\\ ""/__\\"](let[z(f(dec n))](concat(map #(let[y(repeat(Math/pow 2(dec n))\ )](apply str(concat y % y)))z)(map str z z)))))(read))](println q))

38 of those characters are parentheses. : (

(doseq [q ((fn f [n]
           (if (= n 1)
             [" /\\ " "/__\\"]
             (let [z (f (dec n))]
               (concat
                (map #(let [y (repeat (Math/pow 2 (dec n))\ )]
                        (apply str (concat y % y))) z)
                (map str z z))))) (read))] 
  (println q))
Brian Carper
  • 71,150
  • 28
  • 166
  • 168
1

Python, 120 characters (recursive solution)

S=lambda n:n<2and[" /\ ","/__\\"]or[" "*n+x+" "*n for x in S(n/2)]+[x+x for x in S(n/2)]
print"\n".join(S(1<<input()-1))

I started putting on the green where @fserb left off...

Paul Ivanov
  • 1,984
  • 1
  • 16
  • 14
0

Python, 186 chars (UNIX line termination)

for j in range(1,n):
 for s in p:
  print s
 x=2**j;y=2*x;p.extend(['']*x)
 for i in range(y-1,-1,-1):
  if i<x:
   s=' '*x;p[i]=s+p[i]+s
  else:
   q=p[i-x];p[i]=q+q
myk_raniu
  • 150
  • 1
  • 1
  • 7
0

Prolog, 811 Chars

:- module(sierpinsky, [draw/1]).

% draw(+Level)
draw(N) :- K is 2^(N+1)-1,
  for(Line, 0, K),
  draw2(N, Line, true, nl),
  fail.
draw(_).

% draw2(+Level, +Line, +Before, +After)
draw2(0, 0, Before, After) :- !,
  Before, write(' /\\ '), After.
draw2(0, 1, Before, After) :- !,
  Before, write('/__\\'), After.
draw2(N, Line, Before, After) :- N>0, K is 2^N, Line < K, !, M is N-1,
  draw2(M, Line, (Before, tab(K)), (tab(K), After)).
draw2(N, Line, Before, After) :- N>0, K is 2^N, Line >= K, !, M is N-1,
  Line2 is Line - K,
  draw2(M, Line2, Before, draw2(M, Line2, true, After)).

% for(+Variable, +Integer, +Integer)
for(V, N, M) :- N =< M, V = N.
for(V, N, M) :- N < M, K is N+1, for(V, K, M).

% tab(+Integer)
tab(N) :- for(_, 1, N), write(' '), fail.
tab(_).