Drawing Diamonds
September 9, 2014
We begin with auxiliary functions that write an asterisk, a row of n blanks, a properly-spaced row of n asterisks, and an unfilled row of n asterisks:
(define (star) (display #\*))
(define (blanks n)
(do ((n n (- n 1))) ((zero? n)) (display #\space)))
(define (filled n)
(do ((n n (- n 1))) ((= n 1) (star)) (star) (blanks 1)))
(define (unfilled n)
(cond ((= n 1) (star))
(else (star) (blanks (+ n n -3)) (star))))
Note that the unfilled
function writes two stars except for the case n = 1, when it writes only one star.
Then the function that draws a diamond is easy. It takes two parameters, the width of the diamond n and a boolean that is #t
when the diamond is filled and #f
when it is outlined:
(define (diamond n filled?)
(do ((i 1 (+ i 1))) ((< n i))
(blanks (- n i))
(if filled? (filled i) (unfilled i))
(newline))
(do ((i (- n 1) (- i 1))) ((zero? i))
(blanks (- n i))
(if filled? (filled i) (unfilled i))
(newline)))
Here are some examples:
> (diamond 5 #t) * * * * * * * * * * * * * * * * * * * * * * * * * > (diamond 5 #f) * * * * * * * * * * * * * * * *
You can run the program at http://programmingpraxis.codepad.org/bvsiQ3LM.
In Python.
In Java, another approach
(define (<> n fill?)
(let ((b (- 1 n)))
(do ((r b (+ r 1))) ((>= r n))
(do ((k b (+ k 1))) ((= k n) (newline))
(write-char (if (fill? n r k) #\* #\space))))))
(define (solid n r k) (and (< (+ (abs r) (abs k)) n) (odd? (+ r k n))))
(define (hollow n r k) (= (+ (abs r) (abs k) 1) n))
; Usage: (<> n solid) or (<> n hollow) for n = 0, 1, 2, 3, ...
My solution in Scheme:
Let’s use some old-style VT100 cursor movement commands to draw the diamond, instead of generating a bunch of strings (obviously, needs to be run in a suitable terminal window). Looks nicer with a small delay when drawing characters:
And if we want to use strings, it’s easy to generate them recursively. We can extend a solution for n to a solution for n+1 by adding an extra ” ” at the start of each line and adding an extended duplicate of the last line. How we do the extension determines how the diamond is filled:
This is better for the main loop of my C++ solution – we don’t need to treat the two passes separately, just rotate by 90° at each corner:
Python 3 version. Depends on print function to insert spaces between each argument.
When run the output looks like this:
My Haskell solution.
In C++
#include
#include
int main()
{
int i,n;
cout<>n;
for( i=0;ii;j–)
cout<<" ";
for(int k=0;k<i;k++)
cout<<" *";
cout<0;i–)
{
for(int j=n;j>i;j–)
cout<<" ";
for(int k=0;k<i;k++)
cout<<" *";
cout<<"\n";
}
getch();
}
Without string, formatting, … support and only basic operators (but comprehension lists):
t n f=[[if c<=0 &&(f||c==0)&& mod x 2==mod y 2 then ‘*’ else ‘ ‘
|x<-w,let c=abs x+abs y-n+1]|y<-w]where w=[-n+1..n-1]
(the previous one is wrong, cannot be deleted/edited?)
Haskell:
Another Java solution:
j = 7
k = 7
p = 1
for i in range(8):
print ” ” * k,” *” * i
k -=1
while j > 1:
j -= 1
print ” ” * p,” *” * j
p +=1
Hy, why print if using php programming te output number 2