Question

This is inspired by/taken from this thread: http://www.allegro.cc/forums/thread/603383

The Problem

Assume the user gives you a numeric input ranging from 1 to 7. Input should be taken from the console, arguments are less desirable.

When the input is 1, print the following:

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

Values greater than one should generate multiples of the pattern, ending with the one above, but stacked symmetrically. For example, 3 should print the following:

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

Bonus points if you print the reverse as well.

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

Can we try and keep it to one answer per language, that we all improve on?

Was it helpful?

Solution

Assembler, 165 bytes assembled

Build Instructions

  1. Download A86 from here
  2. Add a reference to the A86 executable into your DOS search path
  3. Paste the code below into a text file (example: triforce.asm)
  4. Invoke the assembler: a86 triforce.asm
  5. This will create a .COM file called triforce.com
  6. Type triforce to run

This was developed using the standard WinXP DOS box (Start->Programs->Accessories->Command Prompt). It should work with other DOS emulators.

Assemble using A86 and requires WinXP DOS box to run the .COM file it produces. Press 'q' to exit, keys 1-7 to draw the output.

  l20:mov ah,7
      int 21h
      cmp al,'q'
      je ret
      sub al,'0'
      cmp al,1
      jb l20
      cmp al,7
      ja l20
      mov [l0-1],al
      mov byte ptr [l7+2],6
      jmp $+2
      mov ah,2
      mov ch,0
      mov bh,3
   l0:mov bl,1
   l1:mov dh,0
   l3:cmp dh,ch
      je l2
      mov dl,32
      int 21h
      inc dh
      jmp l3
      ret
   l2:mov dh,bh
   l6:mov cl,12
   l5:mov dl,42
      cmp cl,bl
      ja l4
      mov dl,32
      cmp dh,1
      je l21
   l4:int 21h
      dec cl
      jnz l5
  l21:dec dh
      jnz l6
      mov dl,10
      int 21h
      mov dl,13
      int 21h
  l10:inc ch
   l9:add bl,2
   l7:cmp ch,6
      jne l1
  l13:add byte ptr [l7+2],6
  l11:dec bh
  l12:cmp bh,0
      jne l0
      xor byte ptr [l0+1],10
      xor byte ptr [l9+1],40
      xor byte ptr [l10+1],8
      xor byte ptr [l13+1],40
      sub byte ptr [l7+2],12
      mov dh,[l0-1]
      inc dh
      xor [l12+2],dh
      xor byte ptr [l11+1],8
      xor byte ptr [l1+1],1
      inc bh
      cmp byte ptr [l0+1],11
      je l0
      jmp l20

It uses lots of self-modifying code to do the triforce and its mirror, it even modifies the self-modifying code.

OTHER TIPS

GolfScript - 43 chars

~:!6*,{:^' '
 *'*'12*' '
  ^6%.+)*+
   -12>!^
    6/-*
     n}
     /

~:!6*,{:^' '*'*'12*' '^6%.+)*+-12>!^6/-*n}/

48 Chars for the bonus

~:!6*,.-1%+{
 :^' '*'*'12
  *' '^6%.+
   )*+-12>
    !^6/-
     *n}
      /

~:!6*,.-1%+{:^' '*'*'12*' '^6%.+)*+-12>!^6/-*n}/

Python - 77 Chars

n=input()
for k in range(6*n):print' '*k+('*'*12+' '*(k%6*2+1))[-12:]*(n-k/6)

n=input()
for k in range(6*n):j=1+k%6*2;print' '*k+('*'*(12-j)+' '*j)*(n-k/6)

89 Chars for the bonus

n=input();R=range(6*n)
for k in R+R[::-1]:print' '*k+('*'*11+' '*11)[k%6*2:][:12]*(n-k/6)

114 Chars Version just using string replacements

u,v=' *';s=(v*11+u)*input()
while s.strip():print s;s=u+s.replace(*((v*2+u,u*3),(v*1+u*10,v*11))[' * 'in s])[:-2]

Unk Chars all in one statement, should work w/ 2.x and 3.x. The enumerate() is to allow the single input() to work for both places you need to use it.

print ('\n'.join('\n'.join(((' '*(6*n))+' '.join(('%s%s%s'%(' '*(5-x),'*'*(2*x+1),' '*(5-x)) for m in range(i + 1)))) for x in range(5,-1,-1)) for n, i in enumerate(range(int(input())-1,-1,-1))))

Yet Another Method

def f(n): print '\n'.join(' '*6*(n-r)+(' '*(5-l)+'*'*(l*2+1)+' '*(5-l)+' ')*r for r in xrange(1, n+1) for l in xrange(6))
f(input())

Ruby - 74 Chars

(6*n=gets.to_i).times{|k|puts' '*k+('*'*(11-(j=k%6*2))+' '*(j+1))*(n-k/6)}

COBOL - 385 Chars

$ cobc -free -x triforce.cob && echo 7| ./triforce

PROGRAM-ID.P.DATA DIVISION.WORKING-STORAGE SECTION.
1 N PIC 9.
1 M PIC 99.
1 value '0100***********'.
2 I PIC 99.
2 K PIC 99.
2 V PIC X(22). 
2 W PIC X(99).
PROCEDURE DIVISION.ACCEPT N
COMPUTE M=N*6
PERFORM M TIMES
DISPLAY W(1:K)NO ADVANCING
PERFORM N TIMES
DISPLAY V(I:12)NO ADVANCING
END-PERFORM
DISPLAY ''
ADD 2 TO I
IF I = 13 MOVE 1 TO I ADD -1 TO N END-IF
ADD 1 TO K
END-PERFORM.

K could be returned to outside the group level. An initial value of zero for a numeric with no VALUE clause is compiler-implementation dependent, as is an initial value of space for an alpha-numeric field (W has been cured of this, at no extra character cost). Moving K back would save two characters. -free is compiler-dependant as well, so I'm probably being over-picky.

sed, 117 chars

s/$/76543210/
s/(.).*\1//
s/./*********** /gp
:
s/\*(\**)\*/ \1 /gp
t
:c
s/\* {11}\*/ ************/
tc
s/\*  /   /p
t

Usage: $ echo 7 | sed -rf this.sed

First attempt; improvements could probably be made...

Ruby 1.9 - 84 characters :

v=gets.to_i
v.times{|x|6.times{|i|puts' '*6*x+(' '*i+'*'*(11-2*i)+' '*i+' ')*(v-x)}}

Perl - 72 chars

die map$"x$_.("*"x(12-($l=1+$_%6*2)).$"x$l)x($n-int$_/6).$/,0..6*($n=<>)

78 chars

map{$l=$_%6*2;print$"x$_,("*"x(11-$l).$"x$l.$")x($n-int$_/6),$/}0..6*($n=<>)-1

87 chars

$n=<>;map{$i=int$_/6;$l=$_%6*2;print$"x$_,("*"x(11-$l).$"x$l.$")x($n-$i),$/}(0..6*$n-1)

97 chars

$n=<>;map{$i=int$_/6;$l=$_%6;print$"x(6*$i),($"x$l."*"x(11-2*$l).$"x$l.$")x($n-$i),$/}(0..6*$n-1)

108 chars

$n=<>;map{$i=int$_/6;$l=$_%6;print ""." "x(6*$i),(" "x$l."*"x(11-2*$l)." "x$l." ")x($n-$i),"\n";}(0..6*$n-1)

Powershell, 78 characters

0..(6*($n=read-host)-1)|%{" "*$_+("*"*(12-($k=1+$_%6*2))+" "*$k)*(.4+$n-$_/6)}

Bonus, 92 characters

$a=0..(6*($n=read-host)-1)|%{" "*$_+("*"*(12-($k=1+$_%6*2))+" "*$k)*(.4+$n-$_/6)}
$a
$a|sort

The output is stored in an array of strings, $a, and the reverse is created by sorting the array. We could, of course, just reverse the array, but it would be more characters to type :)

Haskell - 131 138 142 143 Chars

(⊗)=replicate
z o=[concat$(6*n+m)⊗' ':(o-n)⊗((11-m-m)⊗'*'++(1+m+m)⊗' ')|n<-[0..o-1],m<-[0..5]]
main=getLine>>=mapM_ putStrLn.z.read

This one is longer (146 148 chars) at present, but an interesting, alternate line of attack:

(⊗)=replicate
a↑b|a>b=' ';_↑_='*'
z o=[map(k↑)$concat$(6*n)⊗' ':(o-n)⊗"abcdefedcba "|n<-[0..o-1],k<-"abcdef"]
main=getLine>>=mapM_ putStrLn.z.read

FORTRAN - 97 Chars

Got rid of the #define and saved 8 bytes thanks to implict loops!

$ f95 triforce.f95  -o triforce && echo 7 | ./triforce

READ*,N
DO K=0,N*6
M=2*MOD(K,6)
PRINT*,(' ',I=1,K),(('*',I=M,10),(' ',I=0,M),J=K/6+1,N)
ENDDO
END

125 bytes for the bonus

READ*,N
DO L=1,N*12
K=L+5
If(L>N*6)K=N*12-L+6
M=2*MOD(K,6)
PRINT"(99A)",(32,I=7,K),((42,I=M,10),(32,I=0,M),J=K/6,N)
ENDDO
END

FORTRAN - 108 Chars

#define R REPEAT
READ*,N
DO I=0,6*N
J=MOD(I,6)*2
PRINT*,R(' ',I)//R(R('*',11-J)//R(' ',J+1),N-I/6)
ENDDO
END

JavaScript 1.8 - SpiderMonkey - 118 chars

N=readline()
function f(n,c)n>0?(c||' ')+f(n-1,c):''
for(i=0;i<N*6;i++)print(f(i)+f(N-i/6,f(11-(z=i%6*2),'*')+f(z+1)))

w/ bonus - 151 chars

N=readline()
function f(n,c)n>0?(c||' ')+f(n-1,c):''
function l(i)print(f(i)+f(N-i/6,f(11-(z=i%6*2),'*')+f(z+1)))
for(i=0;i<N*6;i++)l(i)
for(;i--;)l(i)

Usage: js thisfile.js

JavaScript - In Browser - 154 characters

N=prompt()
function f(n,c){return n>0?(c||' ')+f(n-1,c):''}
s='<pre>'
for(i=0;i<N*6;i++)s+=f(i)+f(N-i/6,f(11-(z=i%6*2),'*')+f(z+1))+'\n'
document.write(s)

The non-obfuscated version (before optimizations by gnarf):

var N = prompt();
var S = ' ';

function fill(c, n) {
    for (ret=''; n--;)
        ret += c;
    return ret;
}

var str = '<pre>';

for (i=0; i<N*6; i++) {
    str += fill(S, i);
    for (j=0; j<N-i/6; j++)
        str += fill('*', 11-i%6*2) + fill(S, i%6*2+1);
    str += '\n';
}

document.write(str);

Here's a different algorithm that uses replace() to go from one line to the next of each line of a triangle row:

161 characters

N=readline()
function f(n,c){return n>0?(c||' ')+f(n-1,c):''}l=0
for(i=N;i>0;){r=f(i--,f(11,'*')+' ');for(j=6;j--;){print(f(l++)+r)
r=r.replace(/\*\* /g,'   ')}}

F#, 184 181 167 151 147 143 142 133 chars

let N,r=int(stdin.ReadLine()),String.replicate
for l in[0..N*6-1]do printfn"%s%s"(r l" ")(r(N-l/6)((r(11-l%6*2)"*")+(r(l%6*2+1)" ")))

Bonus, 215 212 198 166 162 158 157 148 chars

let N,r=int(stdin.ReadLine()),String.replicate
for l in[0..N*6-1]@[N*6-1..-1..0]do printfn"%s%s"(r l" ")(r(N-l/6)((r(11-l%6*2)"*")+(r(l%6*2+1)" ")))

C - 120 Chars

main(w,i,x,y){w=getchar()%8*12;for(i=0;i<w*w/2;)y=i/w,x=i++%w,putchar(x>w-2?10:x<y|w-x-1<y|(x-y)%12>=11-2*(y%6)?32:42);}

Note that this solution prints some trailing spaces (which is okay, right?). It also relies on relational operators having higher precedence than bitwise OR, saving two characters.

124 Chars

main(n,i,k){n=getchar()&7;for(k=0;k<6*n;k++,putchar(10))for(i=-k-1;++i<12*n-2*k-1;putchar(32+10*(i>=0&&(11-i%12>2*k%12))));}

C - 177 183 Chars

#define P(I,C)for(m=0;m<I;m++)putchar(C)
main(t,c,r,o,m){scanf("%d",&t);for(c=t;c>0;c--)for(r=6;r>0;r--){P((t-c)*6+6-r,32);for(o=0;o<c;o++){P(r*2-1,42);P(13-r*2,32);}puts("");}}

C - 222 243 Chars (With Bonus Points)

#define P(I,C)for(m=0;m<I;m++)putchar(C)
main(t,c,r,o,m){scanf("%d",&t);for(c=t-1;-c<2+t;c-=1+!c)for(r=c<0?1:6;c<0?r<7:r>0;r+=c<0?1:-1){P((t-abs(c+1))*6+6-r,32);for(o=0;o<abs(c+1);o++){P(r*2-1,42);P(13-r*2,32);}puts("");}}

This is my first Code Golf submission as well!

Written in C

Bonus points (492 chars):

p(char *t, int c, int s){int i=0;for(;i<s;i++)printf("      ");for(i=0;i<c;i++)printf("%s",t);printf("\n");}main(int a, char **v){int i=0;int k;int c=atoi(v[1]);for(;i<c;i++){p("*********** ",c-i,i);p(" *********  ",c-i,i);p("  *******   ",c-i,i);p("   *****    ",c-i,i);p("    ***     ",c-i,i);p("     *      ",c-i,i);}for(i=0;i<c;i++){k=c-i-1;p("     *      ",1+i,k);p("    ***     ",1+i,k);p("   *****    ",1+i,k);p("  *******   ",1+i,k);p(" *********  ",1+i,k);p("*********** ",i+1,k);}}

Without bonus points (322 chars):

p(char *t, int c, int s){int i=0;for(;i<s;i++)printf("      ");for(i=0;i<c;i++)printf("%s",t);printf("\n");}main(int a, char **v){int i=0;int k;int c=atoi(v[1]);for(;i<c;i++){p("*********** ",c-i,i);p(" *********  ",c-i,i);p("  *******   ",c-i,i);p("   *****    ",c-i,i);p("    ***     ",c-i,i);p("     *      ",c-i,i);}}

First time posting, too!

Lua, 121 chars

R,N,S=string.rep,io.read'*n',' 'for i=0,N-1 do for j=0,5 do X=R(S,j)print(R(S,6*i)..R(X..R('*',11-2*j)..X..S,N-i))end end

123

R,N,S=string.rep,io.read'*n',' 'for i=0,N-1 do for j=0,5 do print(R(S,6*i)..R(R(S,j)..R('*',11-2*j)..R(S,j)..S,N-i))end end

PHP, 153

<?php $i=fgets(STDIN);function r($n,$c=' '){return$n>0?$c.r($n-1,$c):'';}for($l=0;$l<$i*6;){$z=$l%6*2;echo r($l).r($i-$l++/6,r(11-$z,'*').r($z+1))."\n";}

with Bonus, 210

<?php $i=fgets(STDIN);function r($n,$c=' '){return$n>0?$c.r($n-1,$c):'';}$o=array();for($l=0;$l<$i*6;){$z=$l%6*2;$o[]=r($l).r($i-$l++/6,r(11-$z,'*').r($z+1));}print join("\n",array_merge($o,array_reverse($o)));

dc 105 chars

123 129 132 139 141

[rdPr1-d0<P]sP?sn
0sk[1lk6%2*+sj32lkd0<Plnlk6/-si
[[*]12lj-d0<P32ljd0<Pli1-dsi0<I]dsIx
10Plk1+dskln6*>K]dsKx

Mathematica, 46 characters

The answer prints sideways.

TableForm@{Table["*",{l,#},{l},{j,6},{2j-1}]}&

HyperTalk - 272 chars

function triforce n
    put"******" into a
    put n*6 into h
    repeat with y=0 to h-1
        put"   " after s
        put char 1 to y of s after t
        repeat n-y div 6
            get y mod 6*2
            put char 1 to 11-it of (a&a)&&char 1 to it of s after t
        end repeat
        put return after t
    end repeat
    return t
end triforce

Indentation is neither needed nor counted (HyperCard automatically adds it).

Miscellanea:

Since there is no notion of console or way to access console arguments in HyperCard 2.2 (that I know of), a function is given instead. It can be invoked with:

on mouseUp
    ask "Triforce: "
    put triforce(it) into card field 1
end mouseUp

To use this, a card field would be created and set to a fixed-width font. Using HyperCard's answer command would display a dialog with the text, but it doesn't work because:

  • The answer dialog font (Chicago) is not fixed-width.
  • The answer command refuses to display long text (even triforce(2) is too long).

Common Lisp, 150 characters:

(defun f(n o)(unless(= n 0)(dotimes(x 6)(format t"~v@{~a~:*~}~-1:*~v@{~?~2:*~}~%"
 o" "n"~11@: "(list(- 11(* 2 x))#\*)))(f(1- n)(+ 6 o))))

77 char alternative python solution based on gnibbler's:

n=input()
k=0
exec"print' '*k+('*'*12+' '*(k%6*2+1))[-12:]*(n-k/6);k+=1;"*6*n

Amazingly the bonus came out exactly the same also (101 chars, oh well)

n=input()
l=1
k=0
s="print' '*k+('*'*12+' '*(k%6*2+1))[-12:]*(n-k/6);k+=l;"*6*n
exec s+'l=-1;k-=1;'+s
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top