12
\$\begingroup\$

Ok, my first golf question. Please be gentle :) I know there's way too many ascii puzzles :P but here we go.

The task is simple, use your favorite programming language to print a triangle ripple. The input should be the size of the ripple.

Each triangle is evenly spaced out. Basically, you keep adding the triangles until there is not enough space for the smallest triangle.

You are allowed white spaces anywhere you want as long as the ripples are the same as the example with the correct size.

Example

q)g 1
__
\/
q)g 2
____
\  /
 \/
q)g 3
______
\    /
 \  /
  \/
q)g 4
________
\  __  /
 \ \/ /
  \  /
   \/
q)g 5
__________
\  ____  /
 \ \  / /
  \ \/ /
   \  /
    \/
q)g 6
____________
\  ______  /
 \ \    / /
  \ \  / /
   \ \/ /
    \  /
     \/
q)g 7
______________
\  ________  /
 \ \  __  / /
  \ \ \/ / /
   \ \  / /
    \ \/ /
     \  /
      \/
q)g 8
________________
\  __________  /
 \ \  ____  / /
  \ \ \  / / /
   \ \ \/ / /
    \ \  / /
     \ \/ /
      \  /
       \/

As usual, shortest code wins :)

\$\endgroup\$
  • 2
    \$\begingroup\$ While not an exact duplicate of Draw Concentric ASCII Hexagons, I'm not sure it adds much over the other. \$\endgroup\$ – Geobits Jun 12 '15 at 15:10
  • 4
    \$\begingroup\$ @Geobits IMO its different enough - the input spec is quite different, the method of figuring out how many shapes to draw is different, and triangles != hexagons ;-) \$\endgroup\$ – Digital Trauma Jun 12 '15 at 15:51
  • \$\begingroup\$ @WooiKent I'm now doubting if I understood the question correctly. What is a ripple? Is it one concentric set of triangles, or something else? \$\endgroup\$ – Digital Trauma Jun 12 '15 at 18:53
  • 2
    \$\begingroup\$ nice question, but it is underspecified. (1) Reading the text literally, when the input is 1,2 or 3, we should always output three triangles. (2) I would take it as a given that each set of triangles should be concentric, and (3) it appears they should also have their bottom corners on the same line. (4) Does the horizontal separation have to be exactly one space as shown, or are other separations allowed? (5) Is unnnecesary whitespace allowed to the (a,b,c,d) left, right, above, below? \$\endgroup\$ – Level River St Jun 12 '15 at 21:18
  • \$\begingroup\$ I think it's rather clear, although not explicit. You always draw one triangle of the given size, with nested triangles of size n-3, n-6, n-9, etc. \$\endgroup\$ – Sparr Jun 14 '15 at 0:30
5
\$\begingroup\$

Pyth, 31 bytes

VhQ+J<t+++*Nd*N"\ "d*Q\_Q_XJ"\/

Demonstration.

Explanation:

VhQ+J<t+++*Nd*N"\ "d*Q\_Q_XJ"\/
                                   Implicit: Q = eval(input()), d = ' '
VhQ                                for N in range(Q + 1):
                                   Concatenate:
          *Nd                      N spaces
         +   *N"\ "                N of the string "\ "
        +          d               another space
       +            *Q\_           Q of the string "_"
                                   If N = 2 and Q = 7, the string so far is:
                                   "  \ \  _______" and we want
                                   " \ \  _" as the left half.
      t                            Remove the first character.
     <                  Q          Take the first Q characters remaining.
                                   This is the left half of the triangle ripple.
    J                              Store it in J.
                          XJ"\/    Translate \ to / in J.
                         _         Reverse it.
   +                               Concatenate the left and right halves and print.
\$\endgroup\$
7
\$\begingroup\$

GNU sed -nr, 210

A start:

s/1/__/g
p
s#_(.*)_#\\\1/#
s#\\__#\\  #
s#__/#  /#
ta
:a
p
s#(.*) _{6}(_*) # \1\\  \2  /#;ta
s#(.*)  (  )# \1\2#;
s#(.*) _(_*)_ # \1\\\2/#
y/_/ /
Tc
:b
p
:c
s#(.*)((\\)  ( *)(/)|()()()\\/)# \1\3\4\5#;tb

Input is a positive unary integer via STDIN, as per this meta-question.

Output:

$ for i in 1 11 111 1111 11111 111111 1111111; do sed -rnf triripple.sed <<< $i; done
__
\/

____
\  /
 \/

______
\    /
 \  /
  \/

________
\  __  /
 \ \/ /
  \  /
   \/

__________
\  ____  /
 \ \  / /
  \ \/ /
   \  /
    \/

____________
\  ______  /
 \ \    / /
  \ \  / /
   \ \/ /
    \  /
     \/

______________
\  ________  /
 \ \  __  / /
  \ \ \/ / /
   \ \  / /
    \ \/ /
     \  /
      \/

$ 
\$\endgroup\$
5
\$\begingroup\$

C, 165 bytes

n,x,y,b,c;main(c,v)char**v;{for(n=atoi(v[1]);y<=n;++y){for(x=-n;x<n;++x){b=2*n-abs(2*x+1);c=b-2*y+2;b-=6*y;putchar(b>0?95:b<-4&c>0&c%4==1?"/\\"[x<0]:32);}puts("");}}

Before the golfing steps that destroy readability:

#include <stdio.h>
#include <stdlib.h>

int main(int c, char** v) {
    int n = atoi(v[1]);
    for (int y = 0; y <= n; ++y) {
        for (int x = -n; x < n; ++x) {
            int b = 2 * n - abs(2 * x + 1);
            int c = b - 2 * y + 2;
            b -= 6 * y;
            putchar(b > 0 ? 95 : 
                    b < -4 && c > 0 && c % 4 == 1 ? "/\\"[x<0] : 32);
        }
        puts("");
    }
}

This loops over all characters in the rectangle containing the figure, and evaluates the line equations that separate the inside of the triangle from the outside, as well as the ones that separate the different parts of the triangle.

\$\endgroup\$
  • \$\begingroup\$ Nice job with math. You should try this one: codegolf.stackexchange.com/q/51396/21348 \$\endgroup\$ – edc65 Jun 15 '15 at 8:39
  • \$\begingroup\$ 156: n,x,y,b,c;main(c,v)char**v;{for(n=atoi(v[1]);y<=n;++y)for(x=-n;x<=n;putchar(x++-n?b>6*y?95:b<6*y-4&c>0&c%4==1?"/\\"[x<1]:32:10))c=(b=2*n-abs(2*x+1))-2*y+2;} \$\endgroup\$ – edc65 Jun 15 '15 at 8:54
4
\$\begingroup\$

Retina, 182 bytes

1
_
^
#$_
((`#([^#]*?)( ?)_(_*)_( ?)([^#]*?)$
$0# $1\$3/$5
+)`\\( ?)_(_*)_( ?)/(?=[^#]*$)
\ $1$2$3 /
#( *(\\ )*\\ *)  ( *(/ )*/)$
$0# $1$3
)`#( *(\\ )*)\\/(( /)*)$
$0# $1$3
# 
#
^#
<empty line>

Takes input as unary.

Each line should go to its own file and # should be changed to newline in the files. This is impractical but you can run the code as is as one file with the -s flag, keeping the # markers. You can change the #'s to newlines in the output for readability if you wish. E.g.:

> echo -n 1111|retina -s triangle|tr # '\n'
________
\  __  /
 \ \/ /
  \  /
   \/

The code isn't too well golfed (yet).

\$\endgroup\$
2
\$\begingroup\$

C — 206 bytes

i,j,m,k,a,b;main(i,v)char**v;{m=atoi(v[1])*2;while(k<m*(m/2+1)){i=k/m;j=k%m;a=i*3,b=(i+j)%2;putchar("_\\/ "[j>=a&&j<m-a?0:j>i-2&&b&&j<i*3-1&&j<m/2?1:j<=m-i&&!b&&j>m-a&&j>=m/2?2:3]);if(j==m-1)puts("");k++;};}

 x,m,i,j,a,b;
int main(x,v)char**v;{
    m=atoi(v[1])*2;
    for(i=0;i<m/2+1;i++){
        for(j=0;j<m;j++){
            a=i*3,b=(i+j)%2;
            j>=a&&j<m-a?a=0:j>=i-1&&b&&j<i*3-1&&j<m/2?a=1:j<=m-i&&!b&&j>m-a&&j>=m/2?a=2:(a=3);putchar("_\\/ \n"[a]);
        }
        puts("");
    }
}

Example output

Pauls-iMac:ppcg pvons$ for i in $(seq 1 7); do ./a.out $i; done
__
\/
____
\  /
 \/ 
______
\    /
 \  / 
  \/  
________
\  __  /
 \ \/ / 
  \  /  
   \/   
__________
\  ____  /
 \ \  / / 
  \ \/ /  
   \  /   
    \/    
____________
\  ______  /
 \ \    / / 
  \ \  / /  
   \ \/ /   
    \  /    
     \/     
______________
\  ________  /
 \ \  __  / / 
  \ \ \/ / /  
   \ \  / /   
    \ \/ /    
     \  /     
      \/      
\$\endgroup\$
  • 1
    \$\begingroup\$ You can trim this down quite a bit. Taking advantage of old style C, you can declare variables without a type if they are int. Also, if you declare them at the global scope, they are automatically initialized to 0. Instead of having a bunch of putchar() calls in different branches, you can use a single call and replace the if statements with ternary operators. Of course it becomes hard to read that way, but it's completely in the spirit of this site to write ugly code if it's shorter. :) \$\endgroup\$ – Reto Koradi Jun 20 '15 at 6:53
  • \$\begingroup\$ Thanks @RetoKoradi, I reduced it from 279 to 214 by implementing your suggestions :) I think I'd need to improve my algorithm to get further improvements. \$\endgroup\$ – paulvs Jun 20 '15 at 23:12
  • \$\begingroup\$ Yes, once you get beyond the mechanics, the key is to find rules that simplify the logic as much as possible. If you look at my solution, which is fundamentally very similar, I found that the logic simplified quite a bit by placing the origin of the horizontal coordinate in the center of the triangle. That way, I could take advantage of the symmetry. And others probably found even better approaches. It's really interesting how much can be done on a problem that looks so deceptively simple. \$\endgroup\$ – Reto Koradi Jun 21 '15 at 1:21
1
\$\begingroup\$

JavaScript (ES6) 165 180 204

Run snippet in Firefox to test. If returning the string is not enough, using alert for output is 2 chars more.

// 165 - return the string
F=n=>
  (i=>{
    for(r='__'[R='repeat'](m=n);i<n;)
      r+=`\n`+' '[R](i)
       +('\\ '[R](t=-~(m>3?i:~-n/3))+' ').slice(0,n-i)
       +'__'[R](m>3?m-=3:0)
       +(' '+' /'[R](t)).slice(i++-n)
  })(0)||r


// 167 - output the string
A=n=>{
  for(i=0,r='__'[R='repeat'](m=n);i<n;)
    r+=`\n`+' '[R](i)
     +('\\ '[R](t=-~(m>3?i:~-n/3))+' ').slice(0,n-i)
     +'__'[R](m>3?m-=3:0)
     +(' '+' /'[R](t)).slice(i++-n);
  alert(r)
}

// TEST
out=x=>O.innerHTML += x+'\n' 

for(k=1;k<13;k++)out(k+'\n'+F(k))
<pre id=O></pre>

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.