Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Triforce Programming Challenge

Credits go to axilmar, Bruce Perry, Dustin Howett, kazzmir, machine, Martin Kalbfuß, Matthew Leverton, Peter Wang, and Xuzzers for helping out!
This thread is locked; no one can reply to it. rss feed Print
 1   2 
Triforce Programming Challenge
Kibiz0r
Member #6,203
September 2005
avatar

My internet friend had an interesting assignment for his programming midterm, so I thought I'd share it with you guys and see how creative we can get with our solutions.

Use whatever language you like; cookies for participants. :)

The Problem

Assume the user gives you a numeric input ranging from 1 to 7.

When the input is 1, print the following:

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

Values greater than one should generate multiples of the pattern, ending with the one above, but always stacked symmetrically.

For example, 3 should print the following:

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

For bonus points, also print the reverse:

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

My Solution

I used C#. I wrote the tests first, as I do with most programming tasks, especially those with detailed data manipulation. The first pass was completely imperative, with a ton of loops and counters all shoving stuff into a buffer, but once I had something working I boiled it down to its essence and LINQified it.

Source code below.

Program.cs#SelectExpand
1using System; 2using System.Collections.Generic; 3using System.Linq; 4using System.Text; 5 6namespace ConsoleApplication1 7{ 8 class Program 9 { 10 static void Main(string[] args) 11 { 12 Console.WriteLine("Welcome, Hero of Time"); 13 Console.WriteLine("How many triforces?"); 14 var iterations = Int32.Parse(Console.ReadLine()); 15 Console.WriteLine("Do you want to reverse them as well?"); 16 var reverse = Boolean.Parse(Console.ReadLine()); 17 Console.WriteLine(Triforce.MakeTriforce(iterations, reverse)); 18 Console.ReadKey(true); 19 } 20 } 21}

Triforce.cs#SelectExpand
1using System; 2using System.Collections.Generic; 3using System.Linq; 4using System.Text; 5 6namespace ConsoleApplication1 7{ 8 public static class Triforce 9 { 10 private static IEnumerable<string> makeTriforceIteration(int buffer, int iteration) 11 { 12 var triforce = @"*********** 13 ********* 14 ******* 15 ***** 16 *** 17 * "; 18 var bufferString = String.Join("", Enumerable.Repeat(" ", buffer)); 19 return from line in triforce.Split(new string[] { Environment.NewLine }, StringSplitOptions.None) 20 select bufferString + String.Join(" ", Enumerable.Repeat(line, iteration)); 21 } 22 23 public static string MakeTriforce(int iterations, bool reverse) 24 { 25 var result = (from buffer in Enumerable.Range(0, iterations) 26 let iteration = iterations - buffer 27 select makeTriforceIteration(buffer, iteration)).SelectMany(s => s); 28 if (reverse) 29 { 30 result = result.Concat(result.Reverse()); 31 } 32 return String.Join(Environment.NewLine, result); 33 } 34 } 35}

TriforceTest.cs#SelectExpand
1using System; 2using System.Collections.Generic; 3using System.Linq; 4using System.Text; 5using NUnit.Framework; 6 7namespace ConsoleApplication1 8{ 9 [TestFixture] 10 public class TriforceTest 11 { 12 [Test] 13 public void ProducesASingleTriforceWhenInputIs1() 14 { 15 var singleTriforce = @"*********** 16 ********* 17 ******* 18 ***** 19 *** 20 * "; 21 Assert.That(Triforce.MakeTriforce(1, false), Is.EqualTo(singleTriforce)); 22 } 23 24 [Test] 25 public void ProducesTwoTrifocesWhenInputIs2() 26 { 27 var doubleTriforce = @"*********** *********** 28 ********* ********* 29 ******* ******* 30 ***** ***** 31 *** *** 32 * * 33 *********** 34 ********* 35 ******* 36 ***** 37 *** 38 * "; 39 Assert.That(Triforce.MakeTriforce(2, false), Is.EqualTo(doubleTriforce)); 40 } 41 42 [Test] 43 public void ProducesThreeTrifocesWhenInputIs3() 44 { 45 var tripleTriforce = @"*********** *********** *********** 46 ********* ********* ********* 47 ******* ******* ******* 48 ***** ***** ***** 49 *** *** *** 50 * * * 51 *********** *********** 52 ********* ********* 53 ******* ******* 54 ***** ***** 55 *** *** 56 * * 57 *********** 58 ********* 59 ******* 60 ***** 61 *** 62 * "; 63 Assert.That(Triforce.MakeTriforce(3, false), Is.EqualTo(tripleTriforce)); 64 } 65 66 [Test] 67 public void ProducesReverse() 68 { 69 var reverseTriforce = @"*********** *********** *********** 70 ********* ********* ********* 71 ******* ******* ******* 72 ***** ***** ***** 73 *** *** *** 74 * * * 75 *********** *********** 76 ********* ********* 77 ******* ******* 78 ***** ***** 79 *** *** 80 * * 81 *********** 82 ********* 83 ******* 84 ***** 85 *** 86 * 87 * 88 *** 89 ***** 90 ******* 91 ********* 92 *********** 93 * * 94 *** *** 95 ***** ***** 96 ******* ******* 97 ********* ********* 98 *********** *********** 99 * * * 100 *** *** *** 101 ***** ***** ***** 102 ******* ******* ******* 103 ********* ********* ********* 104*********** *********** ***********"; 105 Assert.That(Triforce.MakeTriforce(3, true), Is.EqualTo(reverseTriforce)); 106 } 107 } 108}

Matthew Leverton
Supreme Loser
January 1999
avatar

#SelectExpand
1<?php 2 ($t = $argc > 1 ? intval($argv[1]) : 3) > 0 or die("enter count > 0\n"); 3 ($A = $argc > 2 ? intval($argv[2]) | 1 : 11) > 0 or die("enter size > 0\n"); 4 $B = ($A + 1) / 2; 5 6 ob_start(); 7 do 8 { 9 for ($z = 0; $z < $B; ++$z) 10 { 11 echo str_repeat(' ', $s); 12 for ($y = 0; $y < $t; ++$y) echo str_repeat(' ', $z).str_repeat('*', $A-($z*2)).str_repeat(' ', $z+1); 13 echo "\n"; 14 } 15 $s += $B; 16 } 17 while (--$t); 18 echo rtrim($b = ob_get_clean()); 19 20 foreach (array_reverse(explode("\n", $b)) as $l) echo "$l\n"; 21?>

Edit: added second parameter.

./triforce.php [count [size]]

Dustin Dettmer
Member #3,935
October 2003
avatar

trap15
Member #11,752
March 2010

Wrote this one in C, my usual choice for everything. Thought of using python, but meh.
Does the inverse one as well :)

#SelectExpand
1#include <stdio.h> 2 3void print_chunk(char string[], int count, int starts) 4{ 5 int i; 6 for(i = 0; i < starts; i++) 7 printf(" "); 8 for(i = 0; i < count; i++) 9 printf("%s", string); 10 printf("\n"); 11} 12 13void print_triforce_strip(int count, int start, int dir) 14{ 15 if(dir == 0) { 16 print_chunk("*********** ", count, start); 17 print_chunk(" ********* ", count, start); 18 print_chunk(" ******* ", count, start); 19 print_chunk(" ***** ", count, start); 20 print_chunk(" *** ", count, start); 21 print_chunk(" * ", count, start); 22 }else{ 23 print_chunk(" * ", count, start); 24 print_chunk(" *** ", count, start); 25 print_chunk(" ***** ", count, start); 26 print_chunk(" ******* ", count, start); 27 print_chunk(" ********* ", count, start); 28 print_chunk("*********** ", count, start); 29 } 30} 31 32int main(int argc, char *argv[]) 33{ 34 int i; 35 int c = atoi(argv[1]); 36 for(i = 0; i < c; i++) { 37 print_triforce_strip(c - i, i, 0); 38 } 39 for(i = 0; i < c; i++) { 40 print_triforce_strip(i + 1, c - i - 1, 1); 41 } 42 return 0; 43}

Matthew Leverton
Supreme Loser
January 1999
avatar

I like this version better:

#SelectExpand
1<?php 2 ($t = $argc > 1 ? intval($argv[1]) : 3) > 0 or die("enter count > 0\n"); 3 ($A = $argc > 2 ? intval($argv[2]) | 1 : 11) > 0 or die("enter size > 0\n"); 4 $B = ($A + 1) / 2; 5 6 for ($j = 0, $b = ''; $j < $t; ++$j) 7 { 8 $l = str_repeat(' ',$j * $B).str_repeat(' '.str_repeat('*', $A), $t-$j). ' '; 9 for ($i = 0; $i < $B; ++$i, $l = strtr($l, array(" *"=>" ", "* *" => " ", "* "=>" "))) 10 $b .= "$l\n"; 11 } 12 13 echo rtrim($b).implode("\n", array_reverse(explode("\n", $b)))."\n"; 14?>

trap15
Member #11,752
March 2010

Anyone gonna make a 1-liner Perl script to do it? :-X

kazzmir
Member #1,786
December 2001
avatar

Mine is in python and uses combinators. Not the shortest..

#SelectExpand
1#!/usr/bin/env python 2 3def reverse(l): 4 return l[::-1] 5 6class Triangle: 7 def __init__(self, height = 7): 8 self.height = height 9 10 def lines(self, pixel = '*'): 11 for length in range(self.height - 1, 0, -1): 12 yield ' ' * (self.height - length - 1) + pixel * (length * 2 - 1) + ' ' * (self.height - length) 13 14class Printer: 15 def __init__(self, triangle): 16 self.triangle = triangle 17 18 def show(self): 19 for line in self.triangle.lines(): 20 yield line 21 22class CombinePrinter(Printer): 23 def __init__(self, p1, p2): 24 self.p1 = p1 25 self.p2 = p2 26 27 def show(self): 28 s1 = self.p1.show() 29 s2 = self.p2.show() 30 while True: 31 try: 32 yield s1.next() + s2.next() 33 except StopIteration: 34 break 35 36class SequencePrinter(Printer): 37 def __init__(self, printer1, printer2): 38 self.printer1 = printer1 39 self.printer2 = printer2 40 41 def show(self): 42 s1 = self.printer1.show() 43 s2 = self.printer2.show() 44 while True: 45 try: 46 yield s1.next() 47 except StopIteration: 48 break 49 while True: 50 try: 51 yield s2.next() 52 except StopIteration: 53 break 54 55class SpacePrinter(Printer): 56 def __init__(self, printer, space): 57 self.printer = printer 58 self.space = space 59 60 def show(self): 61 s1 = self.printer.show() 62 while True: 63 try: 64 yield " " * self.space + s1.next() 65 # yield s1.next() 66 except StopIteration: 67 break 68 69class ReversePrinter(Printer): 70 def __init__(self, printer): 71 self.printer = printer 72 73 def show(self): 74 out = reverse([line for line in self.printer.show()]) 75 for line in out: 76 yield line 77 78def printN(num): 79 all = [Printer(Triangle()) for x in xrange(0, num)] 80 return reduce(lambda a, b: CombinePrinter(a, b), all) 81 82def triforce(height): 83 all = [SpacePrinter(printN(total), (height - total - 1) * 6) for total in xrange(1, height)] 84 return reduce(lambda a, b: SequencePrinter(b, a), all) 85 86def printit(printer): 87 for line in printer.show(): 88 print line 89 90# Printer().show(Triangle()) 91# printit(CombinePrinter(CombinePrinter(Printer(Triangle()), Printer(Triangle())), Printer(Triangle()))) 92# printit(printN(5)) 93# printit(SequencePrinter(printN(5), SpacePrinter(printN(4), 6))) 94def doit(n): 95 printit(SequencePrinter(triforce(n), ReversePrinter(triforce(n)))) 96 97import sys 98doit(int(sys.argv[1]))

Xuzzers
Member #11,753
March 2010

New user here.

My four-line solution in Python 2 (or 3?), doesn't do the reverse:

def triforce(num):
  for i in range(num - 1, -1, -1):
    for x in range(5, -1, -1):
      print (' ' * (6 * (num - 1 - i))) + ' '.join(('%s%s%s' % (' ' * (5 - x), '*' * ((2 * x) + 1), ' ' * (5 - x)) for m in range(0, i + 1)))
      
triforce(int(input()))

Not sure how to do the fancy code tags, but that works, I guess :).

Edit: fixed.

Kibiz0r
Member #6,203
September 2005
avatar

The bar has been raised!

This is my most compact solution, using a string extension for String.Repeat().
Edit: Removed prompts.

#SelectExpand
1using System; 2using System.Linq; 3 4namespace ConsoleApplication1 5{ 6 class Program 7 { 8 static void Main(string[] args) 9 { 10 var iterations = Int32.Parse(Console.ReadLine()); 11 var reverse = Boolean.Parse(Console.ReadLine()); 12 var triforce = from i in Enumerable.Range(0, iterations) 13 from j in Enumerable.Range(0, 6) 14 select " ".Repeat(6 * i) + (" ".Repeat(j) + "*".Repeat(11 - j * 2) + " ".Repeat(j + 1)).Repeat(iterations - i); 15 Console.WriteLine(reverse ? String.Join(Environment.NewLine, triforce.Concat(triforce.Reverse())) : String.Join(Environment.NewLine, triforce)); 16 } 17 } 18}

Xuzzers
Member #11,753
March 2010

Now, what does that say about Python and C# ;P.

Kibiz0r
Member #6,203
September 2005
avatar

They both let you take the long way or the short way?

Thomas Fjellstrom
Member #476
June 2000
avatar

n/m

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"Goto is the buldozer of coding. Sometimes, the buldozer is just the right tool for the job. Not often, but sometimes." -- LordBob

Dustin Howett
Member #11,754
March 2010

Perl one-liner, does not do reverse. Takes a single argument on the commandline.

#SelectExpand
1map { print "".(" " x (6*int($_/6))), ((" " x ($_%6)).("*" x (11-2*($_%6))).(" " x ($_%6))." ") x ($ARGV[0]-int($_/6)), "\n"; } ((0 .. (6*$ARGV[0])-1));

(EDIT: The following prints it reversed as well.

#SelectExpand
1map { print "".(" " x (6*int($_/6))), ((" " x ($_%6)).("*" x (11-2*($_%6))).(" " x ($_%6))." ") x ($ARGV[0]-int($_/6)), "\n"; } ((0 .. (6*$ARGV[0])-1), reverse(0 .. ((6*$ARGV[0])-1)));

)

Can be run as:

/usr/bin/perl -e 'map { print "".(" " x (6*int($_/6))), ((" " x ($_%6)).("*" x (11-2*($_%6))).(" " x ($_%6))." ") x ($ARGV[0]-int($_/6)), "\n"; } ((0 .. (6*$ARGV[0])-1));' 3

Peter Wang
Member #23
April 2000

... What?

#SelectExpand
1#include <stdio.h> 2#include <stdlib.h> 3 4char *tri[] = { 5"***********", 6" ********* ", 7" ******* ", 8" ***** ", 9" *** ", 10" * "}; 11 12int main(int argc, char *argv[]) 13{ 14 int h = atoi(argv[1]); 15 int x, y, w; 16 for (w = h; w > 0; w--) { 17 for (y = 0; y < 6; y++) { 18 for (x = 0; x < (h - w) * 6; x++) 19 putchar(' '); 20 for (x = 0; x < w - 1; x++) 21 printf("%s ", tri[y]); 22 printf("%s\n", tri[y]); 23 } 24 } 25 for (w = 1; w <= h; w++) { 26 for (y = 5; y >= 0; y--) { 27 for (x = 0; x < (h - w) * 6; x++) 28 putchar(' '); 29 for (x = 0; x < w - 1; x++) 30 printf("%s ", tri[y]); 31 printf("%s\n", tri[y]); 32 } 33 } 34 return 0; 35}

Kibiz0r
Member #6,203
September 2005
avatar

Xuzzers said:

Now, what does that say about Python and C# ;P.

Modded my solution to look slightly more like yours*, just because it looks eerily similar for two languages you probably wouldn't place next to each other at the dinner table.

*Looks almost exactly the same if you run it through a C# interpreter to avoid the boilerplate stuff!

I'll try a Ruby solution tomorrow if I feel like it.

Dustin Dettmer
Member #3,935
October 2003
avatar

Obligatory whitespace solution.

(Only 7 lines)

Peter Wang
Member #23
April 2000

Haskell:

#SelectExpand
1go n = do 2 mapM putStr $ map unlines $ reverse $ map reverse $ rows n 3 mapM putStr $ map unlines $ rows n 4 5rows n = [padrow (n-i) (row i) | i <- [1..n]] 6 7padrow w = map (sp ++) 8 where sp = replicate (6*w) ' ' 9 10row 1 = tri 11row n = zipWith join tri (row (n-1)) 12 13join x y = x ++ " " ++ y 14 15tri = map line [1..6] 16 17line n = sp ++ replicate (n*2-1) '*' ++ sp 18 where sp = replicate (6-n) ' '

axilmar
Member #1,204
April 2001

c++:

#SelectExpand
1#include <iostream> 2using namespace std; 3 4int main() { 5 cout << "input triforce number: "; 6 int n; 7 cin >> n; 8 for(int t = n; t > 0; --t) { 9 for(int i = 11; i >= 1; i -= 2) { 10 for(int j = 0; j < (n-t)*12/2; ++j) cout << " "; 11 for(int k = 0; k < t; ++k) { 12 for(int j = 0; j < 11/2 - i/2; ++j) cout << " "; 13 for(int j = 0; j < i ; ++j) cout << "*"; 14 for(int j = 0; j < 12/2 - i/2; ++j) cout << " "; 15 } 16 cout << endl; 17 } 18 } 19 return 0; 20}

Xuzzers
Member #11,753
March 2010

One line of Python:

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

Doesn't print the reverse, at least yet ::)

Edit: Online! The stuff with input() is to fake it when there is no input() allowed. http://codepad.org/ZwE4KsP3

Dustin Dettmer
Member #3,935
October 2003
avatar

#SelectExpand
1#include <iostream> 2using namespace std; 3 4int main() { 5 cout << "input triforce number: "; 6 int n; 7 cin >> n; 8 for(int t = n; t > 0; --t) { 9 for(int i = 11; i >= 1; i -= 2) { 10 cout << string((n-t)*12/2, ' '); 11 for(int k = 0; k < t; ++k) { 12 cout << string(11/2 - i/2, ' '); 13 cout << string(i, '*'); 14 cout << string(12/2 - i/2, ' '); 15 } 16 cout << endl; 17 } 18 } 19}

X-G
Member #856
December 2000
avatar

All I keep thinking is newfags can't triforce.

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

axilmar
Member #1,204
April 2001

#SelectExpand
1#include <iostream> 2#include <string> 3using namespace std; 4 5template <class T> T repeat(int times, const T &t) { return times > 0 ? t + repeat(times - 1, t) : T(); } 6 7int main() { 8 cout << "input triforce number: "; 9 int n; 10 cin >> n; 11 for(int t = n; t > 0; --t) { 12 for(int i = 11; i >= 1; i -= 2) { 13 cout << string((n-t)*6, ' ') << repeat(t, string(5 - i/2, ' ')+string(i,'*')+string(6 - i/2, ' ')) << "\n"; 14 } 15 } 16}

Arthur Kalliokoski
Second in Command
February 2005
avatar

Quote:

newfags can't triforce [knowyourmeme.com].

Well, truth be told, I seen the original post about 1 hour after it started, and began working on a plain old C implementation. About 15 minutes after that, I saw the "Now, what does that say about Python and C#" quote, and was somewhat flummoxed. Anyway, during the course of this I was informed that I no longer had a job, which torqued my gourd for quite a few hours, so I gave up entirely. But in the end, there have been a few posts well beyond what I'm capable of, so kudos to you ;D. Other subjects and areas of interest notwithstanding of course...

Nothing matters and what if it did

LennyLen
Member #5,313
December 2004
avatar

I seen the original post

You what?

Sirocco
Member #88
April 2000
avatar

Load "triforce",8,1
Run

-->
Graphic file formats used to fascinate me, but now I find them rather satanic.

 1   2 


Go to: