How To Create Your Own Command-Line User Interface

I wrote a program last semester that calculates complex arithmetic using Fortran, and with that program I also started dabbling in CLI design. I set out today to write a program that does nothing more than present a testbed for a command-line interface. You should be able to copy this code and apply it to any project as a template, substituting your own commands and conditions.

~Jonathan

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
 *	Programmer:  Jonathan Landrum
 *	Date:        29 February 2012
 *
 *	Program:     userInterface.cpp
 *	Purpose:     To provide a testbed for
 *                   developing a useful CLI.
 *	Assumptions: None.
 */
 
#include <iostream>
#include <cstdlib>
 
using namespace std;
 
// --------------------------------------------------------
// main():
// --------------------------------------------------------
int main () {
 
	// Variables
	char   response;	// User response to the UI
	string input;		// User input to return
	string buffer;		// Disgarded carriage returns
	int    random;		// Random number for random phrase
 
	// Introduce the program
	cout << endl;
	cout << "-------------------------------" << endl;
	cout << "-    Hello World Generator    -" << endl;
	cout << "-------------------------------" << endl;
	cout << endl;
	cout << endl;
	cout << "ENTER A COMMAND:" << endl;
	cout << endl;
	cout << "     Echo a phrase........[E]" << endl;
	cout << "     Random Message.......[R]" << endl;
	cout << endl;
	cout << "     This help document...[?]" << endl;
	cout << "     EXIT.................[X]" << endl;
	cout << endl;
	cin  >> response;
	cout << endl;
 
 
	// Ensure we have a valid command
	while (response != 'e' && response != 'E' &&
	       response != 'r' && response != 'R' &&
	       response != 'x' && response != 'X' &&
	       response != '?') {
		cout << endl;
		cout << "Error:  << UNKNOWN COMMAND >>" << endl;
		cout << endl;
		cout << endl;
		cout << "ENTER A COMMAND: ";
		cin  >> response;
		cout << endl;
	} // End while
 
 
	// Keep the user in the loop unless they type "X"
	while (response != 'x' || response != 'X') {
		if (response == 'e' || response == 'E') {
			// Get rid of extraneous carriage returns
			getline(cin,buffer);
			cout << "Enter a string: ";
			getline(cin,input);
			cout << endl;
			cout << input << endl << endl;
		} else if (response == 'r' || response == 'R') {
			// Gives us a "random" seed from system time
			srand  (time(NULL));
			// Gives us a natural number from 1 to 5
			random = (rand() % 5) + 1;
			cout << "How to say hello in..." << endl;
			switch (random) {
				case 1:
					cout << "привет (Russian)" << endl;
					break;
				case 2:
					cout << "Hola (Spanish)" << endl;
					break;
				case 3:
					cout << "Hallo (German)" << endl;
					break;
				case 4:
					cout << "Bonjour (French)" << endl;
					break;
				case 5:
					cout << "Hello (English)" << endl;
					break;
				default:
					break;
			} // End random hello switch
			cout << endl;
		} else if (response == '?') {
			cout << "     Echo a phrase........[E]" << endl;
			cout << "     Random Message.......[R]" << endl;
			cout << endl;
			cout << "     This help document...[?]" << endl;
			cout << "     EXIT.................[X]" << endl;
			cout << endl;
		} else {
			break;
		} // End if
 
		cout << "ENTER A COMMAND: ";
		cin  >> response;
		cout << endl;
		while (response != 'e' && response != 'E' &&
		       response != 'r' && response != 'R' &&
		       response != 'x' && response != 'X' &&
		       response != '?') {
			cout << endl;
			cout << "Error:  << UNKNOWN COMMAND >>" << endl;
			cout << endl;
			cout << endl;
			cout << "ENTER A COMMAND: ";
			cin  >> response;
			cout << endl;
		} // End while
	} // End while
 
	// Exit
	cout << "\\\\//_ Live long and prosper." << endl;
	return (0);
} // End main

Using Einstein’s Relativity Formula to Find Mass Consumed by a Nuclear Reactor

I was doing some reading about Fortran this afternoon and ran across this problem. The story goes that we have a 400-MW nuclear reactor that is 100% efficient in its conversion to energy of the Uranium isotope U-235. Obviously, no reactor is 100% efficient, but the purpose of this exercise is not to find mass consumed, but to practice developing algorithms under that premise.

The program uses Einstein’s mass-energy equivalence formula to find mass consumed by the reactor.

Einstein's mass-energy equivalence formula

After putting in the constants for energy produced (400,000,000 joules/second) and the speed of light squared (8.98755179 × 1016 meters/second), it is simply a matter of using the most basic Algebraic manipulation to isolate mass. I will admit, it was an astonishingly small amount of U-235 turned into energy. Perhaps there’s hope for this technology after all.

~Jonathan

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
PROGRAM relativity
! ------------------------------------------------------------------------------
! Programmer:     Jonathan Landrum
!
! Purpose:        This program calculates the amount of mass consumed by a
!                 nuclear power plant over a user-supplied length of time. The
!                 calculation uses Einstein's relativity formula, E = mc^2.
!
! Assumptions:    1.) The power station has a 400-MW (400,000,000 joules per
!                     second) nuclear reactor. This is our E constant.
!                 2.) The plant is 100% efficient (not realistic, but the losses
!                     are not part of the point of this exercise.)
! 
! Revisions:      Date		Programmer		Description of Change
!                 ===========	=====================	========================
!                 28 Feb 2012	Jonathan Landrum	Original code.
! ------------------------------------------------------------------------------
 
	IMPLICIT NONE
 
	! DATA DICTIONARY: Declared constants
	INTEGER, PARAMETER :: seconds = 31536000	! Seconds in a year
	INTEGER, PARAMETER :: E       = 400000000	! Output in joules/s
	REAL,    PARAMETER :: C       = 8.98755179E16	! Speed of light^2 in m/s
 
	! DATA DICTIONARY: Declared variables
	CHARACTER :: response		! User-supplied response to exit or not
	REAL      :: time		! User-supplied length of time in years
	REAL      :: mass		! Mass consumed by the generator in kg
 
	! Introduce the program
	WRITE (*,*) '* * * * * * * * * * * * * * * * * * * * * * * * * * * * *'
	WRITE (*,*) '*                                                       *'
	WRITE (*,*) '*       Fortran Nuclear Power Generator Simulator       *'
	WRITE (*,*) '*                                                       *'
	WRITE (*,*) '* * * * * * * * * * * * * * * * * * * * * * * * * * * * *'
	WRITE (*,*)
	WRITE (*,*) 'This program uses Einstein''s theory of relativity to'
	WRITE (*,*) 'simulate how much mass is consumed by a 400-MW nuclear'
	WRITE (*,*) 'reactor, given it is 100% efficient.'
	WRITE (*,*)
	WRITE (*,*) '---------------------------------------------------------'
	WRITE (*,*)
 
	! Prompt the user to continue or exit
	WRITE (*,*) 'Would you like to continue? [Y/N]'
	READ  (*,*) response
	WRITE (*,*)
 
	DO WHILE (response == 'y' .OR. response == 'Y')
 
		! Prompt the user for length of time to run the simulation
		WRITE (*,*) 'How many years do you want to simulate?'
		READ  (*,*) time
		WRITE (*,*)
 
		! Perform calculations
		mass = E / C * seconds * time
 
		! Return results
		WRITE (*,*) 'The amount of Uranium-235 turned into energy by'
		WRITE (*,*) 'this station in ', time, ' years is ', mass,' kg.'
		WRITE (*,*)
 
		! Prompt the user to continue or exit
		WRITE (*,*) 'Would you like to continue? [Y/N]'
		READ  (*,*) response
		WRITE (*,*)
 
	END DO ! End "continue" loop
	WRITE (*,*) '\\//_ Live long and prosper.'
 
! Exit
END PROGRAM relativity

Fortran Complex Arithmetic Calculator

An assignment I was given last semester in Fortran asked us to make a program to calculate complex arithmetic problems. The point of the assignment was not complex arithmetic, but using external modules to solve a problem. We first had to make the module to include, called functions.f95, that contained all the complex arithmetic functions we would need. We were to call this module with a driver program. The Fortran compiler will link the two files together at compile time if we use include one specific line:

USE functions

the USE command pulls in the module named functions.f95 and allows the current program to use those functions as if they were contained in this program. That part was simple. Now on to the math.

There were five complex equations given in the assignment: addition, subtraction, multiplication, division, and exponentiation. The formulas for finding these answers were also supplied.

Complex Addition formula

Complex Addition formula

Complex Subtraction formula

Complex Subtraction formula

Complex Multiplication formula

Complex Multiplication formula

Complex Division formula

Complex Division formula

Complex Exponentiation formula

Complex Exponentiation formula

Now that we know the formulas, we can start making our functions.f95 file. The easiest way I saw to do it was to split up the Real and Imaginary parts of the formulas and handle them separately. Imaginary arithmetic operates just like Real arithmetic, with an i appended to the answer. Breaking this problem into pieces like this made a daunting task easily accomplished.

And, since I worked my way down the list, starting with addition, compiling, making sure it works, and then going on to subtraction, by the time I got to exponentiation I could simply call the multiplication functions I had already written to solve my problem. Here’s the finished functions.f95 file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
! =========================================
! Programmer:  Jonathan Landrum
! Date:        11 December 2011
! Class:       CSC 204
! =========================================
! Program:     functions.f95
! Purpose:     Provides functions for
!              complex arithmetic.
! Assumptions: None.
! =========================================
MODULE functions
CONTAINS
 
	! -------------------------------------
	!              Addition
	! -------------------------------------
 
	! -------------------------------------
	! addReal:
	! Performs real part of complex
	! addition
	! -------------------------------------
	INTEGER FUNCTION addReal(a, b, x, y)
		IMPLICIT NONE
		INTEGER :: a, b, x, y
		addReal = a + x
	END FUNCTION addReal
	! -------------------------------------
	! addImaginary:
	! Performs imaginary part of complex
	! addition
	! -------------------------------------
	INTEGER FUNCTION addImaginary(a, b, x, y)
		IMPLICIT NONE
		INTEGER :: a, b, x, y
		addImaginary = b + y
	END FUNCTION addImaginary
 
	! -------------------------------------
	!              Subtraction
	! -------------------------------------
 
	! -------------------------------------
	! subtractReal:
	! Performs real part of complex
	! subtraction
	! -------------------------------------
	INTEGER FUNCTION subtractReal (a, b, x, y)
		IMPLICIT NONE
		INTEGER :: a, b, x, y
		subtractReal = a - x
	END FUNCTION subtractReal
	! -------------------------------------
	! subtractImaginary:
	! Performs imaginary part of complex
	! subtraction
	! -------------------------------------
	INTEGER FUNCTION subtractImaginary (a, b, x, y)
		IMPLICIT NONE
		INTEGER :: a, b, x, y
		subtractImaginary = b - y
	END FUNCTION subtractImaginary
 
	! -------------------------------------
	!             Multiplication
	! -------------------------------------
 
	! -------------------------------------
	! multiplyReal:
	! Performs real part of complex
	! multiplication
	! -------------------------------------
	INTEGER FUNCTION multiplyReal (a, b, x, y)
		IMPLICIT NONE
		INTEGER :: a, b, x, y
		multiplyReal = a * x - b * y
	END FUNCTION multiplyReal
	! -------------------------------------
	! multiplyImaginary:
	! Performs imaginary part of complex
	! multiplication
	! -------------------------------------
	INTEGER FUNCTION multiplyImaginary (a, b, x, y)
		IMPLICIT NONE
		INTEGER :: a, b, x, y
		multiplyImaginary = a * y + b * x
	END FUNCTION multiplyImaginary
 
	! -------------------------------------
	!               Division
	! -------------------------------------
 
	! -------------------------------------
	! divideReal:
	! Performs real part of complex
	! division
	! -------------------------------------
	INTEGER FUNCTION divideReal (a, b, x, y)
		IMPLICIT NONE
		INTEGER :: a, b, x, y
		divideReal = a * x + b * y
	END FUNCTION divideReal
	! -------------------------------------
	! divideImaginary:
	! Performs imaginary part of complex
	! division
	! -------------------------------------
	INTEGER FUNCTION divideImaginary (a, b, x, y)
		IMPLICIT NONE
		INTEGER :: a, b, x, y
		divideImaginary = b * x - a * y
	END FUNCTION divideImaginary
 
	! -------------------------------------
	!            Exponentiation
	! -------------------------------------
 
	! -------------------------------------
	! exponentReal:
	! Performs complex exponentiation
	! -------------------------------------
	INTEGER FUNCTION exponentReal (a, b, n)
		IMPLICIT NONE
		INTEGER :: a, b, n, c = 1
		INTEGER :: out(2)
		out = (/a, b/)
		IF (n > 1) THEN
			WHILE (c < n) DO
				out(1) = multiplyReal(out(1), out(2), a, b)
                		out(2) = multiplyImaginary(out(1), out(2), a, b)
				c = c + 1
			END DO
		END IF
		exponentReal = out(1)
	END FUNCTION exponentReal
	! -------------------------------------
	! exponentImaginary:
	! Performs complex exponentiation
	! -------------------------------------
	INTEGER FUNCTION exponentImaginary (a, b, n)
		IMPLICIT NONE
		INTEGER :: a, b, n, c = 1
		INTEGER :: out(2)
		out = (/a, b/)
		IF (n > 1) THEN
			WHILE (c < n) DO
				out(1) = multiplyReal(out(1), out(2), a, b)
                		out(2) = multiplyImaginary(out(1), out(2), a, b)
				c = c + 1
			END DO
		END IF
		exponentImaginary = out(2)
	END FUNCTION exponentImaginary
END MODULE functions

Now that we’ve got our functions, we need a driver program that can use them. That’s easily accomplished, and I’ve even thrown in a bit of CLI design into this one. The main WHILE loop keeps the user in the loop unless they choose “X” to exit. They can select which type of complex arithmetic they’d like to do, and are then asked what the values are for a, b, x, and y. In the case of exponentiation, the user is asked for values for a and b, and a value for n, the degree to which the complex expression will be raised.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
! ----------------------------------------------------------
! Programmer:   Jonathan Landrum
! Date:         11 December 2011
! Class:        CSC 204
! ----------------------------------------------------------
! Program:      driver.exe
! Purpose:      Performs complex arithmetic using modules.
! Assumptions:  Module "functions" is in the same directory.
! ----------------------------------------------------------
 
PROGRAM driver
	USE functions
	IMPLICIT NONE
 
	CHARACTER :: response = 'y', kind
	INTEGER   :: a, b, x, y, n
 
	WRITE (*,*) '*******************************************'
	WRITE (*,*) '*                                         *'
	WRITE (*,*) '*  FORTRAN COMPLEX ARITHMETIC CALCULATOR  *'
	WRITE (*,*) '*                                         *'
	WRITE (*,*) '*******************************************'
	WRITE (*,*)
	WRITE (*,*) 'PURPOSE:'
	WRITE (*,*) 'Performs complex arithmetic using modules.'
	WRITE (*,*)
	WRITE (*,*) 'Copyright (c) 2011 Jonathan Landrum'
	WRITE (*,*)
	WRITE (*,*) '-------------------------------------------'
	WRITE (*,*)
 
	! Any response beginning with the letter "y" will work.
	WHILE (response == 'y' .OR. response == 'Y') DO
 
		WRITE (*,*) 'What kind of arithmetic would you like to do?'
		WRITE (*,*)
		WRITE (*,*) 'Addition.............[A]'
		WRITE (*,*) 'Subtraction..........[S]'
		WRITE (*,*) 'Multiplication.......[M]'
		WRITE (*,*) 'Division.............[D]'
		WRITE (*,*) 'Exponentiation.......[E]'
		WRITE (*,*)
		WRITE (*,*) 'EXIT.................[X]'
		WRITE (*,*)
		READ  (*,*) kind
		WRITE (*,*)
 
		! Addition
		IF (kind == 'a' .OR. kind == 'A') THEN
			WRITE (*,*) 'Complex addition takes the form:'
			WRITE (*,*) '(a + bi) + (x + yi) = (a + x) + (b + y)i'
			WRITE (*,*) 'Enter a value for a:'
			READ  (*,*) a
			WRITE (*,*) 'Enter a value for b:'
			READ  (*,*) b
			WRITE (*,*) 'Enter a value for x:'
			READ  (*,*) x
			WRITE (*,*) 'Enter a value for y:'
			READ  (*,*) y
			WRITE (*,*) '(',addReal(a, b, x, y),' + ',addImaginary(a, b, x, y),'i)'
		END IF
 
		! Subtraction
		IF (kind == 's' .OR. kind == 'S') THEN
			WRITE (*,*) 'Complex subtraction takes the form:'
			WRITE (*,*) '(a + bi) - (x + yi) = (a - x) + (b - y)i'
			WRITE (*,*) 'Enter a value for a:'
			READ  (*,*) a
			WRITE (*,*) 'Enter a value for b:'
			READ  (*,*) b
			WRITE (*,*) 'Enter a value for x:'
			READ  (*,*) x
			WRITE (*,*) 'Enter a value for y:'
			READ  (*,*) y
			WRITE (*,*) '(',subtractReal(a, b, x, y),' - ',subtractImaginary(a, b, x, y),'i)'
		END IF
 
		! Multiplication
		IF (kind == 'm' .OR. kind == 'M') THEN
			WRITE (*,*) 'Complex multiplication takes the form:'
			WRITE (*,*) '(a + bi) * (x + yi) = (a * x - b * y) + (a * y + b * x)i'
			WRITE (*,*) 'Enter a value for a:'
			READ  (*,*) a
			WRITE (*,*) 'Enter a value for b:'
			READ  (*,*) b
			WRITE (*,*) 'Enter a value for x:'
			READ  (*,*) x
			WRITE (*,*) 'Enter a value for y:'
			READ  (*,*) y
			WRITE (*,*) '(',multiplyReal(a, b, x, y),' + ',multiplyImaginary(a, b, x, y),'i)'
		END IF
 
		! Division
		IF (kind == 'd' .OR. kind == 'D') THEN
			WRITE (*,*) 'Complex division takes the form:'
			WRITE (*,*) '(a + bi)   (a + bi) * (x - yi)'
			WRITE (*,*) '-------- = -------------------'
			WRITE (*,*) '(x + yi)        x^2 + y^2'
			WRITE (*,*) 'Enter a value for a:'
			READ  (*,*) a
			WRITE (*,*) 'Enter a value for b:'
			READ  (*,*) b
			WRITE (*,*) 'Enter a value for x:'
			READ  (*,*) x
			WRITE (*,*) 'Enter a value for y:'
			READ  (*,*) y
			WRITE (*,*) '(',divideReal(a, b, x, y),' * ',divideImaginary(a, b, x, y),'i)'
			WRITE (*,*) '------------------------------'
			WRITE (*,*) '     ',x * x + y * y
		END IF
 
		! Exponentiation
		IF (kind == 'e' .OR. kind == 'E') THEN
			WRITE (*,*) 'Complex exponentiation takes the form:'
			WRITE (*,*) '(a + bi)^n = (a + bi) * (a + bi) * (a + bi)...'
			WRITE (*,*) 'Enter a value for a:'
			READ  (*,*) a
			WRITE (*,*) 'Enter a value for b:'
			READ  (*,*) b
			WRITE (*,*) 'Enter a power to raise this complex number to:'
			READ  (*,*) n
			WRITE (*,*) '(',exponentReal(a, b, n),' + ',exponentImaginary(a, b, n),'i)'
		END IF
 
		! EXIT
		IF (kind == 'x' .OR. kind == 'X') THEN
			EXIT
		END IF
 
		WRITE (*,*)
		WRITE (*,*) 'Would you like to continue? [Y/N]'
		WRITE (*,*)
		READ  (*,*) response
		WRITE (*,*)
 
	END DO ! Continue loop
	WRITE (*,*) '\\//_ Live long and prosper.'
END PROGRAM driver

All in all, it took me a bit, but it was well worth it. I am very happy with how this one came out.

~Jonathan

Swapping the Values of Two Variables Without Using a Third Variable

I’ve heard about this challenge before, and didn’t really think much of it at the time. Seemed superfluous to me to try to swap two variables without using a third one. But something I read today pushed me over the ledge to try it.

I was reading about the C++ Preprocessor, a separate program that calculates expressions before the program is compiled. I use at least one preprocessor directive in all my C++ programs, the #include <iostream> line right after the opening comments.

The book I was reading issued a challenge to use preprocessor commands to make a macro that swaps two variables, and the author went on to say, “If you’re a real hacker, write one that does not use a temporary variable declared outside the macro.” (Emphasis mine.) I couldn’t let that slip, so I wrote this program in response.

I want to point out that this endeavor would be better served as either a series of commands, or perhaps an inline function. But since the author asked for #define’s, that’s what I put.

~Jonathan

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/*
 *	Programmer:  Jonathan Landrum
 *	Date:        26 February 2012
 *
 *	Program:     variableSwap.cpp
 *	Purpose:     This program swaps the values of
 *                   two variables, without using a
 *                   temporary variable.
 *	Assumptions: None.
 */
 
#include <iostream>
#define SWAP(one,two) { one ^= two; two ^= one; one ^= two; }
 
using namespace std;
 
// --------------------------------------------------
// main():
// --------------------------------------------------
int main () {
 
	// Variables
	int one, two;
 
	// Introduce the program
	cout << endl;
	cout << "-----------------------------------" << endl;
	cout << "-    Two-Variable Value Swapper   -" << endl;
	cout << "-----------------------------------" << endl;
	cout << endl;
	cout << "This program exchanges values of two" << endl;
	cout << "variables WITHOUT using a temporary" << endl;
	cout << "variable." << endl;
	cout << endl;
	cout << "Enter a value for variable 1: ";
	cin  >> one;
	cout << "Enter a value for variable 2: ";
	cin  >> two;
	cout << endl;
 
	cout << "Variable 1 is " << one << endl;
	cout << "variable 2 is " << two << endl;
	cout << endl;
	cout << "Swapping the values..." << endl << endl;
 
	// Main processing loop
	SWAP(one,two);
 
	// Return the results
	cout << "Variable 1 is now " << one << endl;
	cout << "Variable 2 is now " << two << endl;
 
	cout << endl;
	cout << "\\\\//_ Live long and prosper." << endl;
 
	return (0);
} // End main

C++ Checkerboard Printer

I ran across a coding challenge in a programming book that said create a program that prints out an 8 × 8 checkerboard using loops. Each box was to be five characters wide and three lines tall, and they gave a 2 × 2 example:

+-----+-----+
|     |     |
|     |     |
|     |     |
+-----+-----+
|     |     |
|     |     |
|     |     |
+-----+-----+

Sounds easy enough, right? It’s actually quite similar to — and much easier than — the character diamond challenge I found. The only difference is the sides are vertical, so there’s no mucking around with spaces. Here’s a sample output:

A checkerboard printout from a C++ program

The idea is to create a primary loop that controls rows, and then populate it with secondary loops to take care of columns: one for the top row and three for the side walls. Save the last row for after the loop, and bada bing, you’ve got a checkerboard. I anticipated spending hours on it, and was a bit let down to be done in five minutes. But nonetheless, here it is.

~Jonathan

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/*
 *	Programmer:  Jonathan Landrum
 *	Date:        25 February 2012
 *
 *	Program:     checkerboard.cpp
 *	Purpose:     Prints a checkerboard of
 *	             user-defined size.
 *	Assumptions: None.
 */
 
#include <iostream>
 
using namespace std;
 
// --------------------------------------------------
// main():
// --------------------------------------------------
int main () {
 
	// Variables
	int counter, iterator, input;
 
	// Introduce the program
	cout << endl;
	cout << "----------------------------------" << endl;
	cout << "-    C++ Checkerboard Printer    -" << endl;
	cout << "----------------------------------" << endl;
	cout << endl;
	cout << "             +-----+" << endl;
	cout << "             |     |" << endl;
	cout << "             |     |" << endl;
	cout << "             |     |" << endl;
	cout << "             +-----+" << endl;
	cout << endl;
	cout << "This program takes user input of an" << endl;
	cout << "integer and prints a checkerboard" << endl;
	cout << "of that size." << endl;
 
	cout << "What size checkerboard do you want: ";
	cin  >> input;
 
	// Main processing loop
	for (counter = 0; counter < input; ++counter) {
 
		// Print the top line
		for (iterator = 0; iterator < input; ++iterator) {
			cout << "+-----";
		} // End for
		cout << "+" << endl;
 
		// Print the sides
		for (iterator = 0; iterator < input; ++iterator) {
			cout << "|     ";
		} // End for
		cout << "|" << endl;
 
		for (iterator = 0; iterator < input; ++iterator) {
			cout << "|     ";
		} // End for
		cout << "|" << endl;
 
		for (iterator = 0; iterator < input; ++iterator) {
			cout << "|     ";
		} // End for
		cout << "|" << endl;
	} // End for
 
	// Print the last line after the loop
	for (iterator = 0; iterator < input; ++iterator) {
		cout << "+-----";
	} // End for
	cout << "+" << endl;
 
	return (0);
} // End main

Fortran Temperature Converter

This is a fairly complex temperature converter I wrote last semester in Fortran after studying Chemistry over the summer. It’s not complex because it’s difficult, but because it protects the user in a lot of cases. The only thing I’ve found that will cause this program to fail is text input for the temperature to be converted.

However, there are plenty of loops to check for other user input. You’ll notice there are a couple “Unexpected Response” loops and a “Same Scale Selected” loop. The user is quite shielded from messing up. There are also logic loops for every conceivable case. You can convert to and from Celsius, Fahrenheit, and Kelvin scales, and the answer is presented in the correct format in every scenario. It won’t do your taxes for you, though.

~Jonathan

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
! ---------------------------------------------------------
! Programmer:  Jonathan Landrum
! Date:        11 September 2011
! ---------------------------------------------------------
! Program:     tempConverter.f95
! Purpose:     Converts temperatures from one temperature
!              scale to another.
! Assumptions: 1.) The temperature input is in the form of
!                  a real number, not text. Text will cause
!                  the program to return an error.
!              2.) The temperature to be converted is in
!                  Celsius, Fahrenheit, or Kelvin scales.
! ---------------------------------------------------------
 
PROGRAM tempConverter
 
	IMPLICIT NONE
 
	! Variables:
	REAL              :: input = 0, output = 0
	CHARACTER         :: scaleIn, scaleOut, response
	CHARACTER(LEN=10) :: scaleInPretty, scaleOutPretty
 
	! Introduce the program and ask for initial response
	WRITE (*,*) '*****************************************'
	WRITE (*,*) '*                                       *'
	WRITE (*,*) '*     FORTRAN Temperature Converter     *'
	WRITE (*,*) '*                                       *'
	WRITE (*,*) '*****************************************'
	WRITE (*,*)
	WRITE (*,*) 'Copyright (c) 2011 Jonathan Landrum'
	WRITE (*,*)
	WRITE (*,*) 'This program takes a degree measurement'
	WRITE (*,*) 'from one scale, and converts it to the'
	WRITE (*,*) 'same value in another scale.'
	WRITE (*,*)
	WRITE (*,*) 'Scales are: Celsius, Fahrenheit, Kelvin'
	WRITE (*,*)
	WRITE (*,*) 'Would you like to continue? [Y/N]'
	WRITE (*,*)
 
	! Anything besides Y terminates
	READ  (*,*) response
 
	! -----------------------------------------------------
	! Main Loop:
	! Keeps the user in the program until they choose to
	! close it.
	! -----------------------------------------------------
	DO WHILE ((response == 'Y') .OR. (response == 'y'))
 
		! -------------------------------------------------
		! scaleIn Loop:
		! Ensures a legitimate scale has been selected.
		! -------------------------------------------------
		WRITE (*,*)
		WRITE (*,*) 'What scale is your temperature in?'
		WRITE (*,*) 'Celsius: [C], Fahrenheit: [F], Kelvin: [K]'
 
		READ  (*,*) scaleIn
 
		DO WHILE ((scaleIn /= 'c') .AND. &
		          (scaleIn /= 'C') .AND. &
		          (scaleIn /= 'f') .AND. &
		          (scaleIn /= 'F') .AND. &
		          (scaleIn /= 'k') .AND. &
		          (scaleIn /= 'K'))
 
			WRITE (*,*)
			WRITE (*,*) 'UNEXPECTED RESPONSE'
			WRITE (*,*)
			WRITE (*,*) 'What scale is your temperature in?'
			WRITE (*,*) 'Celsius: [C], Fahrenheit: [F], Kelvin: [K]'
 
			READ  (*,*) scaleIn
		END DO ! End scaleIn
 
		WRITE (*,*)
		WRITE (*,*) 'What is the value of your temperature?'
		WRITE (*,*) 'Use numbers. Text input will fail.'
 
		READ  (*,*) input
 
		! -------------------------------------------------
		! scaleOut Loop:
		! Ensures a legitimate scale has been selected.
		! -------------------------------------------------
		WRITE (*,*)
		WRITE (*,*) 'What scale do you want to convert to?'
		WRITE (*,*) 'Celsius: [C], Fahrenheit: [F], Kelvin: [K]'
 
		READ  (*,*) scaleOut
 
		DO WHILE ((scaleOut /= 'c') .AND. &
		          (scaleOut /= 'C') .AND. &
		          (scaleOut /= 'f') .AND. &
		          (scaleOut /= 'F') .AND. &
		          (scaleOut /= 'k') .AND. &
		          (scaleOut /= 'K'))
 
			WRITE (*,*)
			WRITE (*,*) 'UNEXPECTED RESPONSE'
			WRITE (*,*)
			WRITE (*,*) 'What scale do you want to convert to?'
			WRITE (*,*) 'Celsius: [C], Fahrenheit: [F], Kelvin: [K]'
 
			READ  (*,*) scaleOut
		END DO ! End scaleOut
 
		! -------------------------------------------------
		! Same Scale Loop:
		! Ensures the conversion between the same scale
		! won't happen. (No use wasting resources.)
		! -------------------------------------------------
		DO WHILE ((((scaleIn == 'c') .OR. (scaleIn == 'C')) .AND. ((scaleOut == 'c') .OR. (scaleOut == 'C')))  &
		     .OR. (((scaleIn == 'f') .OR. (scaleIn == 'F')) .AND. ((scaleOut == 'f') .OR. (scaleOut == 'F')))  &
		     .OR. (((scaleIn == 'k') .OR. (scaleIn == 'K')) .AND. ((scaleOut == 'k') .OR. (scaleOut == 'K'))))
 
			WRITE (*,*)
			WRITE (*,*) 'SAME SCALE SELECTED'
			WRITE (*,*)
			WRITE (*,*) 'What scale do you want to convert to?'
			WRITE (*,*) 'Celsius: [C], Fahrenheit: [F], Kelvin: [K]'
 
			READ  (*,*) scaleOut
		END DO ! End Same Scale
 
		! -------------------------------------------------
		! Main Conversion Loop:
		! Does the converting for every possible case, and
		! stores the output in a variable. This will be
		! printed later.
		! -------------------------------------------------
 
		! Celsius to Fahrenheit
		IF      (((scaleIn == 'c') .OR. (scaleIn == 'C')) .AND. ((scaleOut == 'f') .OR. (scaleOut == 'F'))) THEN
			output = (1.8 * input + 32)
 
		! Celsius to Kelvin
		ELSE IF (((scaleIn == 'c') .OR. (scaleIn == 'C')) .AND. ((scaleOut == 'k') .OR. (scaleOut == 'K'))) THEN
			output = (input + 273.15)
 
		! Fahrenheit to Celsius
		ELSE IF (((scaleIn == 'f') .OR. (scaleIn == 'F')) .AND. ((scaleOut == 'c') .OR. (scaleOut == 'C'))) THEN
			output = ((input - 32) / 1.8)
 
		! Fahrenheit to Kelvin
		ELSE IF (((scaleIn == 'f') .OR. (scaleIn == 'F')) .AND. ((scaleOut == 'k') .OR. (scaleOut == 'K'))) THEN
			output = ((input + 459.67) / 1.8)
 
		! Kelvin to Celsius
		ELSE IF (((scaleIn == 'k') .OR. (scaleIn == 'K')) .AND. ((scaleOut == 'c') .OR. (scaleOut == 'C'))) THEN
			output = (input - 273.15)
 
		! Kelvin to Fahrenheit
		ELSE IF (((scaleIn == 'k') .OR. (scaleIn == 'K')) .AND. ((scaleOut == 'f') .OR. (scaleOut == 'F'))) THEN
			output = (1.8 * input - 459.67)
 
		END IF ! End Main Conversion
 
		! -------------------------------------------------
		! Output Prettifier:
		! Converts all the c's and f's to their respective
		! scales. No k's because they can be hard-coded.
		! -------------------------------------------------
		IF      ((scaleIn == 'c') .OR. (scaleIn == 'C')) THEN
			scaleInPretty = 'Celsius'
		ELSE IF	((scaleIn == 'f') .OR. (scaleIn == 'F')) THEN
			scaleInPretty = 'Fahrenheit'
		END IF
 
		IF      ((scaleOut == 'c') .OR. (scaleOut == 'C')) THEN
			scaleOutPretty = 'Celsius'
		ELSE IF	((scaleOut == 'f') .OR. (scaleOut == 'F')) THEN
			scaleOutPretty = 'Fahrenheit'
		END IF
 
		! -------------------------------------------------
		! Output:
		! Return results of the conversion, and offer to
		! do another, or terminate the program.
		! -------------------------------------------------
 
		! Degrees in, degrees out
		IF      (((scaleIn == 'c') .OR. (scaleIn == 'C') .OR. (scaleIn == 'f') .OR. (scaleIn == 'F')) &
		  .AND. ((scaleOut == 'c') .OR. (scaleOut == 'C') .OR. (scaleOut == 'f') .OR. (scaleOut == 'F'))) THEN
			WRITE (*,*) input, ' degrees ', scaleInPretty, ' is equal to ', output, ' degrees ', scaleOutPretty
 
		! Degrees in, Kelvin out
		ELSE IF (((scaleIn == 'c') .OR. (scaleIn == 'C') .OR. (scaleIn == 'f') .OR. (scaleIn == 'F')) &
		  .AND. ((scaleOut == 'k') .OR. (scaleOut == 'K'))) THEN
			WRITE (*,*) input, ' degrees ', scaleInPretty, ' is equal to ', output, 'Kelvin'
 
		! Kelvin in, degrees out
		ELSE IF (((scaleIn == 'k') .OR. (scaleIn == 'K')) &
		  .AND. ((scaleOut == 'c') .OR. (scaleOut == 'C') .OR. (scaleOut == 'f') .OR. (scaleOut == 'F'))) THEN
			WRITE (*,*) input, ' Kelvin is equal to ', output, ' degrees ', scaleOutPretty
 
		! No case for Kelvin in, Kelvin out; same scale, won't compute
		END IF ! End Output
 
		WRITE (*,*)
		WRITE (*,*) 'Do you have another temperature to convert? [Y/N]'
		WRITE (*,*)
		READ  (*,*) response ! Anything besides Y terminates
	END DO ! End Main Program Loop
 
	WRITE (*,*)
	WRITE (*,*) '\\//_ Live long and prosper.'
END PROGRAM tempConverter

The Twelve Days of Finals (A Parody)

My first semester at MC, I was thrust headlong into heavy math and computer science courses (heavy by my book, anyway). One of those courses was Problem Solving using Java. Of the many assignments given that semester, this one was my favorite.

We had to write a program that would recite the lyrics to the Christmas carol, “The Twelve Days of Christmas”. I asked for permission to change the words a bit. Finals were fast approaching, and I wanted to present an ode to examination.

It turned out exactly as I had hoped it would. My only complaint is the buffer doesn’t scroll back far enough to read all the lyrics. I originally planned to go back later and put in a call for writing the output to a text file, but that fell by the wayside. Perhaps someday.

~Jonathan

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// ==================================================================
// Programmer:  Jonathan Landrum
// Date:        23 February 2012
// ==================================================================
// Program:     TwelveDays.java
// Purpose:     A jovial take on the Christmas classic, "The Twelve
//              Days of Christmas".
// Assumptions: The user has a sense of humor. :o)
// ==================================================================
 
public class TwelveDays {
 
    // --------------------------------------------------------------
    // main()
    // You'll notice that the counting is backwards for the two
    // switches. This is because the song progresses in reverse order
    // (counts down.)
    // --------------------------------------------------------------
    public static void main (String[] args) {
 
        int day = 12;
        String ordinal = "", twelveDays = "";
 
        while (day > 0) {
 
            // This swith governs the ordinal applied to each day.
            switch (day) {
                case  1: ordinal = "12th"; break;
                case  2: ordinal = "11th"; break;
                case  3: ordinal = "10th"; break;
                case  4: ordinal =  "9th"; break;
                case  5: ordinal =  "8th"; break;
                case  6: ordinal =  "7th"; break;
                case  7: ordinal =  "6th"; break;
                case  8: ordinal =  "5th"; break;
                case  9: ordinal =  "4th"; break;
                case 10: ordinal =  "3rd"; break;
                case 11: ordinal =  "2nd"; break;
                case 12: ordinal =  "1st"; break;
            } // End ordinal switch
 
            // This switch governs which items are given each day.
            // You'll notice there are no break statements in this
            // switch. That is because we want it to "fall through"
            // each case every time.
            switch (day) {
                case  1: twelveDays += "Twelve packs of Rockstar,\n";
                case  2: twelveDays += "Eleven Alka-Seltzer,\n";
                case  3: twelveDays += "Ten jugs of Monster,\n";
                case  4: twelveDays += "Nine swigs of Maalox,\n";
                case  5: twelveDays += "Eight Macchiatos,\n";
                case  6: twelveDays += "Seven cans of Red Bull,\n";
                case  7: twelveDays += "Six shots of Pepto,\n";
                case  8: twelveDays += "Five-hour Energy,\n";
                case  9: twelveDays += "Four cans of Coke,\n";
                case 10: twelveDays += "Three Pepcid,\n";
                case 11: twelveDays += "Two Cappuccinos, and\n";
                case 12: twelveDays += "A roll of spearmint Tums.\n";
            } // End day switch
 
            // Print everything to the buffer.
            System.out.println ("On the " + ordinal + " day of " +
				"finals my teacher gave to me");
            System.out.println (twelveDays);
 
            // Reset the String twelveDays to null and start the
            // loop over again. This keeps each day from having its
            // text plus the previous day's text.
            twelveDays = "";
 
            // Decrementing day because it made more sense to me
            // to count down in this case.
            --day;
 
        } // End while loop
    } // End main method
} // End TwelveDays class

What Sigma Notation Means to a Computer Scientist

I went to the store with my wife today to find a snack, and ran across a bag of cheese puffs called Smart Puffs, and the bag design caught my attention.

Not-so-smart Puffs

That Sigma notation in the middle is incorrectly formed. But seeing it today reminded me of the first time I saw it in my second semester of Calculus. As a Computer Scientist, summation made perfect sense to me. It is, in essence, a for loop:

Summation as a for-loop

What you are saying with that Σ is to sum all i‘s from 1 to 100 (or whatever is on top), as I have shown before when finding sums in C++. An exact analog to a loop. Here’s a better graphic explaining summation:

Comparison between summation and adding

As you can see, summation is just a fancy way of writing a long string of addition. It doesn’t make a lot of sense to use a Σ for this small example, but when the top number goes out past 100 (or like the ones in Calculus that increase without bound) it’s much more practical to write it as a summation formula. I made a couple corrections to the image from before; I only hope someone from Pirate Brands notices this article and changes their bag accordingly.

Fixed that for you

~Jonathan

Converting Time in Seconds to Weeks, Days, Hours, Et Cetera

I found an interesting assignment in a C/C++ programming book I have. It was about converting seconds to minutes, and another about converting minutes/seconds to seconds. I decided to take that on, pushing it all the way to years. What this has actually become is an exercise in using modulo and division well.

The algorithm begins with calculating years, with each successive calculation containing all of the previous ones, and then changing the last operation from division to modulo. You have to do that in order to access the remainder left from the previous calculation. It’s more simple than it sounds. You only need to know ahead of time how many seconds are in a year, month, week, day, hour, and minute.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// ==================================================
// Programmer:  Jonathan Landrum
// Date:        20 February 2012
// ==================================================
// Program:     timeConverter.cpp
// Purpose:     Converts seconds input (integer) to
//              weeks, days, hours, minutes (etc.)
// Assumptions: 1.) Input is integer form. Floating
//                  point input will be rounded down
//                  to the nearest integer.
// ==================================================
 
#include <iostream>
using namespace std;
 
// --------------------------------------------------
// main():
// --------------------------------------------------
int main () {
 
	// Variables
	int years   = 0;
	int months  = 0; // 30 days
	int weeks   = 0;
	int days    = 0;
	int hours   = 0;
	int minutes = 0;
	int seconds = 0;
	unsigned long int input;
 
	// Introduce the program
	cout << endl;
	cout << "----------------------------" << endl;
	cout << "-      Time Converter      -" << endl;
	cout << "----------------------------" << endl;
	cout << endl;
	cout << "How many seconds to convert? ";
	cin  >> input;
 
	// Main processing loop
	years   = input / 31536000;
	months  = (input % 31536000) / 2592000;
	weeks   = ((input % 31536000) % 2592000) / 604800;
	days    = (((input % 31536000) % 2592000) % 604800) / 86400;
	hours   = ((((input % 31536000) % 2592000) % 604800) % 86400) / 3600;
	minutes = (((((input % 31536000) % 2592000) % 604800) % 86400) % 3600) / 60;
	seconds = ((((((input % 31536000) % 2592000) % 604800) % 86400) % 3600) % 60);
 
 
	// Return the results
	cout << "There are ";
	if (years != 0)
		cout << years << " years ";
 
	if (months != 0)
		cout << months << " months ";
 
	if (weeks != 0)
		cout << weeks << " weeks ";
 
	if (days != 0)
		cout << days << " days ";
 
	if (hours != 0)
		cout << hours << " hours ";
 
	if (minutes != 0)
		cout << minutes << " minutes ";
 
	if (seconds != 0) {
		if (input > 60)
			cout << "and " << seconds << " seconds ";
		else
			cout << seconds << " seconds ";
	} // End if. Will be rather uninpressive for input < 60.
 
	cout << "in " << input << " seconds." << endl;
 
	cout << endl;
	cout << "\\\\//_ Live long and prosper." << endl;
	cout << endl;
	return (0);
} // End main

Here’s a sample output from the program:

Time Converter

I’ve checked the output numerous times and it’s correct. The only thing it doesn’t do is Leap Year (as in calculating the date based on the Unix Epoch, for example), so it will return a higher number for days, weeks, etc. on those years.

Making correct Leap Year output could be done, but it would require inputting a starting year and calculating from there, and that’s not what this program does. It’s not a static time, for instance. It’s a general time, as in “how many days are in x seconds”. But the algorithm can be adapted for use in a time-since program. Perhaps I will write that one next.

~Jonathan

Calculating the Padovan Sequence with Fortran

The Padovan Sequence is a recursive series I discovered recently, and it is similar to the Fibonacci Sequence I’ve written about before. The difference is the patterns the two recursive sequences make.

This is a graphic representation of the Fibonacci Sequence:

Graphic representation of the Fibonacci Sequence

And this is a graphic representation of the Padovan Sequence:

Graphic representation of the Padovan Sequence

The base case of the Padovan Sequence is defined as
f(0) = f(1) = f(2) = 1

and the general case is defined as
f(n) = f(n − 2) + f(n − 3)

So you can see that we can easily create an algorithm to return the Padovan Sequence using any language which supports recursion, and I have chosen Fortran to do so. We can do this with an if/else block, defining first the general case, and then the base caes (or vice versa, if you’re so inclined.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
! ----------------------------------------------------------
! Programmer:   Jonathan Landrum
! Date:         17 February 2012
! ----------------------------------------------------------
! Program:      padovanSequence.f95
! Purpose:      Calculates the Padovan Sequence.
! Assumptions:  None.
! ----------------------------------------------------------
 
PROGRAM padovanSequence
 
	IMPLICIT NONE
 
	INTEGER :: counter = 0, input = 0, padovan
 
	WRITE (*,*) '* * * * * * * * * * * * * * * * * * * * * * *'
	WRITE (*,*) '*                                           *'
	WRITE (*,*) '*     FORTRAN PADOVAN SEQUENCE GENERATOR    *'
	WRITE (*,*) '*                                           *'
	WRITE (*,*) '* * * * * * * * * * * * * * * * * * * * * * *'
	WRITE (*,*)
	WRITE (*,*) 'This program calculates and returns members'
	WRITE (*,*) 'of the Padovan Sequence.'
	WRITE (*,*)
	WRITE (*,*) 'How many Padovan Numbers would like to return?'
	WRITE (*,*)
	READ  (*,*) input
 
	! If the user inputs a negative number, ask again
	DO WHILE (input < 0)
		WRITE (*,*)
		WRITE (*,*) 'ERROR: Negative input'
		WRITE (*,*)
		WRITE (*,*) 'How many Padovan Numbers would like to return?'
		WRITE (*,*)
		READ  (*,*) input
	END DO
	! END while negative
 
	WRITE (*,*)
	WRITE (*,*) '--------------------------------------------------'
 
	! We have a legitimate number, do the calculation
	DO WHILE (counter < input)
		WRITE (*,*) padovan(counter)
		counter = counter + 1
	END DO
	! END Processing loop
 
	WRITE (*,*) '--------------------------------------------------'
	WRITE (*,*)
	WRITE (*,*) '\\//_ Live long and prosper.'
	WRITE (*,*)
END PROGRAM padovanSequence
 
! ----------------------------------------------------------
! FUNCTION padovan:
! Calculates and returns the integer of the Padovan Sequence
! at the specified input position. The sequence is:
! 1, 1, 1, 2, 2, 3, 4, 5, 7, 9, 12, 16, 21, 28, 37, 49, etc.
! ----------------------------------------------------------
RECURSIVE FUNCTION padovan (input) RESULT (output)
	IMPLICIT NONE
 
	INTEGER :: input
	INTEGER :: output
 
	IF (input > 2) THEN
		output = padovan(input - 2) + padovan(input - 3)
	ELSE
		output = 1
	END IF
 
END FUNCTION padovan

Because this program uses recursion, caution should be observed when asking for more than 50 or 60 numbers. By putting the general case first in the padovan() function, I’ve saved a little time insofar that the if/else block only has one test now versus the three it would have if I had put the base case first.

A better way to get larger members of the set would be to either call for each member individually, or save previous output to an array or external file and have the function start from the previous number. Or you could even do as I did with my prime number calculator and have the user define a range. As it stands, the program re-calculates every number back to 1 each time, and it starts with 0 each time. So it is not useful for finding the higher members of the set. However, it was certainly a fun programming experience, as I hadn’t tried recursion with Fortran before.

~Jonathan