0% found this document useful (0 votes)
29 views90 pages

Computational Challenges

The document provides instructions for writing Java methods to analyze different types of numbers like narcissistic, palindrome, perfect and prime numbers. It includes writing methods to check properties of numbers, count numbers, sum numbers, output numbers to the console, and return arrays of numbers up to a given limit. The goal is to write methods that implement the given specifications and produce the expected console outputs.

Uploaded by

Ramesh Mahadevan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
29 views90 pages

Computational Challenges

The document provides instructions for writing Java methods to analyze different types of numbers like narcissistic, palindrome, perfect and prime numbers. It includes writing methods to check properties of numbers, count numbers, sum numbers, output numbers to the console, and return arrays of numbers up to a given limit. The goal is to write methods that implement the given specifications and produce the expected console outputs.

Uploaded by

Ramesh Mahadevan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 90

Version control

Sep 21 ● Added version control


● Added colour scheme

Colour scheme
purple Java code

blue Answer or hint

red Important comment

green Terminal output

Numbers
● Add a new class named Numbers to your ComputationalChallenges project and
copy the code below and personalise the preamble.

Numbers.java

/**
* <Write a description here.>
* @author <firstname> <LASTNAME>
* @version <submission>.<modification>
* @date <yyyy>.<mm>.<dd>
*/

import java.util.*;
import java.lang.*;
import java.io.*;

public class Numbers


{
public static void main ()
{
}
}

Narcissistic numbers (Armstrong numbers)


● Write a Java method that calculates integer powers of integer (by convention 0^0=1).
The header of your method should be:
public static int power(int base, int exponent)
The following instructions:
System.out.println(power(2,3));
System.out.println(power(3,2));
System.out.println(power(0,0));
should output to the console:
8
9
1

● Write a Java method that returns the number of digits of a given number. The header
of your method should be:
public static int countDigits(int number)
The following instructions:
System.out.println(countDigits(1234));
System.out.println(countDigits(0));
should output to the console:
4
1

● Write a Java method that returns an array whose elements are the digits of a given
number (your array should start with the rightmost digit). The header of your method
should be:
public static int[] getDigits(int number)
The following instructions:
System.out.println(java.util.Arrays.toString(getDigits(1234)));
System.out.println(getDigits(1234).length);
should output to the console:
[4, 3, 2, 1]
4

A narcissistic number is a number that is equal to the sum of its digits raised to the power of
the number of digits. For example 153 is a narcissistic number since 153 = 1^3 + 5^3 + 3^3.

● Write a Java method that returns true if a given integer is a narcissistic number and
false otherwise. The header of your method should be:
public static boolean isNarcissistic(int number)
The following instructions:
System.out.println(isNarcissistic(153));
should output to the console:
true

● Write a Java method that outputs the narcissistic numbers up to a given number. The
header of your method should be:
public static void printNarcissisticNumbersTo(int limit)
The following instructions:
printNarcissisticNumbersTo(500);
should output to the console:
0 1 2 3 4 5 6 7 8 9 153 370 371 407

● Write a Java method that returns the sum of narcissistic numbers up to a given
number. The header of your method should be:
public static int getSumOfNarcissisticNumbersTo(int limit)
The following instructions:
System.out.println(getSumOfNarcissisticNumbersTo(500));
should output to the console:
1346

● Write a Java method that returns the number of narcissistic numbers up to a given
number. The header of your method should be:
public static int countNarcissisticNumbersTo(int limit)
The following instructions:
System.out.println(countNarcissisticNumbersTo(500));
should output to the console:
14

● Write a Java method that returns an array whose elements are the narcissistic
numbers up to a given number. The header of your method should be:
public static int[] getNarcissisticNumbersTo(int limit)
The following instructions:
System.out.println(java.util.Arrays.toString(
getNarcissisticNumbersTo(500)));
should output to the console:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407]

Palindrome numbers
● Write a Java method that returns an integer whose digits are in reverse order of a
given integer. The header of your method should be:
public static int reverse(int number)
The following instructions:
System.out.println(reverse(1234));
should output to the console:
4321

● Write a Java method that returns true if a given number if a palindrome number and
false otherwise. The header of your method should be:
public static boolean isPalindromic(int number)
The following instructions:
System.out.println(isPalindromic(123));
System.out.println(isPalindromic(121));
should output to the console:
false
true
● Write a Java method that outputs the palindrome numbers up to a given number. The
header of your method should be:
public static void printPalindromicNumbersTo(int limit)
The following instructions:
printPalindromicNumbersTo(500);
should output to the console:
0 1 2 3 4 5 6 7 8 9 11 22 33 44 55 66 77 88 99 101 111 121 131 141 151 161 171 181 191
202 212 222 232 242 252 262 272 282 292 303 313 323 333 343 353 363 373 383 393 404
414 424 434 444 454 464 474 484 494

● Write a Java method that returns the number of palindromic numbers up to a given
number. The header of your method should be:
public static int countPalindromicNumbersTo(int limit)
The following instructions:
System.out.println(countPalindromicNumbersTo(500));
should output to the console:
59

● Write a Java method that returns an array whose elements are the palindrome
numbers up to a given number. The header of your method should be:
public static int[] getPalindromicNumbersTo(int limit)
The following instructions:
System.out.println(java.utils.Arrays.toString(
getPalindromicNumbersTo(500)));
should output to the console:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99, 101, 111, 121, 131, 141, 151,
161, 171, 181, 191, 202, 212, 222, 232, 242, 252, 262, 272, 282, 292, 303, 313, 323, 333,
343, 353, 363, 373, 383, 393, 404, 414, 424, 434, 444, 454, 464, 474, 484, 494]

Perfect numbers
● Write a Java method that returns the number of divisors of a given number. The
header of your method should be:
public static int countDivisors(int number)
The following instructions:
System.out.println(countDivisors(6));
should output to the console:
4

● Write a Java method that returns an array whose elements are the divisors of a given
number. The header of your method should be:
public static int[] getDivisors(int number)
The following instructions:
System.out.println(java.util.Arrays.toString(getDivisors(6)));
should output to the console:
[1, 2, 3, 6]
A perfect number is a positive integer that is equal to the sum of its proper divisors. For
example, the proper divisor of 6 are 1, 2, 3 (the number itself is not a proper divisor); hence,
6 is a perfect number since 1 + 2 + 3 = 6.

● Write a Java method that returns true if a given number is a perfect number and
false otherwise. The header of your method should be:
public static boolean isPerfect(int number)
The following instructions:
System.out.println(isPerfect(6));
should output to the console:
true

● Write a Java method that outputs the perfect numbers up to a given number. The
header of your method should be:
public static void printPerfectNumbersTo(int limit)
The following instructions:
printPerfectNumbersTo(500);
should output to the console:
6 28 496

● Write a Java method that returns the number of perfect numbers up to a given
number. The header of your method should be:
public static int countPerfectNumbersTo(int limit)
The following instructions:
System.out.println(countPerfectNumbersTo(500));
should output to the console:
3

● Write a Java method that returns an array whose elements are the perfect numbers
up to a given number. The header of your method should be:
public static int[] getPerfectNumbersTo(int limit)
The following instructions:
System.out.println(java.util.Arrays.toString(
getPerfectNumbersTo(500)));
should output to the console:
[6, 28, 496]

Prime numbers
A prime number is a number that is greater than 1 and that is only divisible by 1 and by itself.
Note that, by definition, 1 is not a prime number. For example, 2, 3, 5, 7, 11, 13, 17, 19 are
prime numbers.

● Write a Java method that returns true if a given number is prime and false
otherwise. The header of your method should be:
public static boolean isPrime(int number)
The following instructions:
System.out.println(isPrime(1));
should output to the console:
false

● Write a Java method that outputs on the same line the prime numbers from 1 to a
given number. The header of your method should be:
public static void printPrimeNumbersTo(int limit)
The following instructions:
printPrimeNumbersTo(10);
should output to the console:
2357

● Write a Java method that returns the number of prime numbers numbers from 1 to a
given number. The header of your method should be:
public static int countPrimeNumbersTo(int limit)
The following instructions:
countPrimeNumbersTo(10);
should output to the console:
4

● Write a Java method that returns the sum of prime numbers from 1 to a given
number. The header of your method should be:
public static int getSumOfPrimeNumbersTo(int limit)
The following instructions:
System.out.println(getSumOfPrimeNumbersTo(10));
should output to the console:
17

● Write a Java method that returns an array of prime numbers up to a given number.
The header of your method should be:
public static int[] getPrimeNumbersTo(int limit)
The following instructions:
System.out.println(java.util.Arrays.toString(
getPrimeNumbersTo(10)));
should output to the console:
[2, 3, 5, 7]

● Write a Java method that returns an array of prime numbers up to a given number
based on the sieve of Eratosthenes . The header of your method should be:
public static int[] sievePrimeNumbersTo(int limit)
The following instructions:
System.out.println(java.util.Arrays.toString(
sievePrimeNumbersTo(10)));
should output to the console:
[2, 3, 5, 7]
● Compare and contrast your method based on the sieve of Eratosthenes with a
method that performs the same task but that is based on a for-loop using isPrime.
Both methods can be improved by bounding the possible factors to check (e.g. square root).
The sieve of Eratosthenes has fewer loops (time complexity) - even though this is not trivial
to show. However, the sieve of Eratosthenes requires the creation of a potentially large array
of integers which has an impact on available resources such as memory (space complexity).

Semiprime numbers
A semiprime number is an integer that is the product of two (possibly equal) primes. For
example, there are 4 semi-prime numbers less than or equal to 10: 4=2x2, 6=2x3, 9=3x3,
10=2x5.

● Write a Java method that returns true if a given number is semiprime and false
otherwise. The header of your method should be:
public static boolean isSemiPrime(int number)
The following instructions:
System.out.println(isSemiPrime(6));
System.out.println(isSemiPrime(8));
should output to the console:
true
false

● Write a Java method that outputs on the same line the semi-prime numbers between
1 and a given number. The header of your method should be:
public static void printSemiPrimeNumbersTo(int limit)
The following instructions:
printSemiPrimeNumbersTo(10);
should output to the console:
4 6 9 10

● Write a Java method that returns an array whose elements are the semi-prime
numbers between 1 and a given number. The header of your method should be:
public static int[] getSemiPrimeNumbersTo(int limit)
The following instructions:
System.out.println(java.util.Arrays.toString(
getSemiPrimeNumbersTo(10)));
should output to the console:
[4, 6, 9, 10]

● Write Java method that returns the sum of the semi-prime numbers between 1 and a
given number (note that the order in which the semi-prime numbers are added is not
relevant). The header of your method should be:
public static int getSumOfSemiPrimeNumbersTo(int limit)
The following instructions:
System.out.println(getSumOfSemiPrimeNumbersTo(10));
should output to the console:
29

Twin primes
A twin prime is a prime number that is either 2 less or 2 more than another prime number; for
example, the twin prime pair (41, 43).

● Write a Java method that returns an array whose elements are the twin primes up to
and including a given limit. The header of your method should be:
public static int[] getTwinPrimeNumbersTo(int limit)
The following instructions:
System.out.println(java.util.Arrays.toString(
getTwinPrimeNumbersTo(100)));
should output to the console:
[3, 5, 7, 11, 13, 17, 19, 29, 31, 41, 43, 59, 61, 71, 73]

Arithmetics

Prime factors

Write a Java method that returns an array whose elements are the prime factors of a
given number. The prime factors should be sorted in increasing order; the first
element of the array is the smallest prime factor. The header of your method should
be:
public static int[] getPrimeFactors(int number)
The following instructions:
System.out.println(java.util.Arrays.toString(getPrimeFactors(60)));
should output to the console:
[2, 3, 5]

[ WORK IN PROGRESS ] Highest Common Factor

[ WORK IN PROGRESS ] Lowest Common Multiple

[ WORK IN PROGRESS ] Bezout relation

Euler’s conjecture
Euler conjectured on 1769 that the equation a 5 + b 5 + c 5 + d 5 = e 5 has no solution in
positive integers. Nearly two century later, a computer search found a counterexample.

● Write a Java method that returns an array containing the values of a < b < c < d < e
such that a 5 + b 5 + c 5 + d 5 = e 5 . The value of e should be the last element of your
array. You can use the fact that: 20 < a < 40 ; 70 < b < 90 ; 100 < c < 120 ; 120 < d <
140 ; 130 < e < 150 . The header of your method should be:
public static int[] findCounterexampleToEuler5()
The following instructions:
int[] counterexample = findCounterexampleToEuler5();
int a = counterexample[0];
int b = counterexample[1];
int c = counterexample[2];
int d = counterexample[3];
int e = counterexample[4];
double A = Math.pow(a,5);
double B = Math.pow(b,5);
double C = Math.pow(c,5);
double D = Math.pow(d,5);
double E = Math.pow(e,5);
System.out.println(A+B+C+D==E);
should output to the console:
true

Taxicab numbers
The number 1729 is famous for appearing in two unrelated mathematical anecdotes.

I remember once going to see him [Ramanujan] when he was lying ill at Putney. I
had ridden in taxicab No. 1729, and remarked that the number seemed to be rather a
dull one, and that I hoped it was not an unfavourable omen. "No", he replied, "it is a
very interesting number; it is the smallest number expressible as the sum of two
[positive] cubes in two different ways.
A Mathematician’s Apology by G. H. Hardy

How did the customer [Richard Feynman] beat the abacus? The number was
1729.03. I happened to know that a cubic foot contains 1728 cubic inches, so the
answer is a tiny bit more than 12. The excess, 1.03, is only one part in nearly 2000,
and I had learned in calculus that for small fractions, the cube root’s excess is one-
third of the number's excess. So all I had to do is find the fraction 1/1728, and
multiply by 4 (divide by 3 and multiply by 12). So I was able to pull out a whole lot of
digits that way.
Surely, you’re joking Mr Feynman! by R. Feynman

● Write a Java method that returns an array containing the values of a, b, c, d, such
that a3 + b3 = c3 + d3 = 1729. The header of your method should be:
public static int[] getTaxicabNumber2()
The following instructions:
int[] numbers = getTaxicabNumber2();
int a = numbers[0];
int b = numbers[1];
int c = numbers[2];
int d = numbers[3];
double A = Math.pow(a,3);
double B = Math.pow(b,3);
double C = Math.pow(c,3);
double D = Math.pow(d,3);
System.out.println(A+B==1729);
System.out.println(C+D==1729);
should output to the console:
true
true

Kaprekar constant
● Write a Java method that given a number returns a value that is calculated as follow:
a. arrange the digits of the number in increasing order;
b. arrange the digits of the number in decreasing order;
c. take away the smallest number from the largest number.
The header of your method should be:
public static int kaprekar(int number)
The following instruction:
System.out.println(kaprekar(198));
System.out.println(kaprekar(5432));
should return to the console:
792
3087

The Indian mathematician D. R. Kaprekar discovered that, starting from a 4-digit number
whose digits are not all the same and adding leading zeros to keep the number of digits at 4,
the above transformation applied iteratively will eventually reach 6174 at which point the
process will repeat since 7641 - 1467 = 6174.

For example, starting with 3524 yields 6174 after 3 iterations: (i) 5432 - 2345 = 3087; (ii)
8730 - 0378 = 8352; (iii) 8532 - 2358 = 6174. An example for which leading zeros are
necessary starts with 1121 and yields 6174 after 5 iterations: (i) 2111 - 1112 = 0999 (leading
zero added); (ii) 9990 - 0999 = 8991 (rather than 999 - 999 = 0); (iii) 9981 - 1899 = 8082;
(iv) 8820 - 0288 = 8532; (v) 8532 - 2358 = 6174.

● Write a Java method that, given a starting 4-digit number, returns an array whose
elements are the successive results of the Kaprekar process described above; the
first element of your array should be the starting number and the last element of your
array should be the first occurrence of 6174. If the number given has fewer than 4
digits, your method should add leading zeros. If the number given has more than 4
digits, your method should return an empty array. The header of your method should
be:
public static int[] iterateKaprekar4(int number)
The following instruction:
System.out.println(Arrays.toString(iterateKaprekar4(3524)));
System.out.println(Arrays.toString(iterateKaprekar4(1121)));
should return to the console:
[3524, 3087, 8352, 6174]
[1121, 999, 8991, 8082, 8532, 6174]

The equivalent number for 3-digit number is 495 (note that: 954 - 459 = 495). For example,
starting with 100 yields 495 after 5 iterations: 100 - 001 = 099 (add leading zero); (i) 990 -
099 = 891 (rather than 99 - 99 = 0); (ii) 981 - 189 = 792; (iii) 972 - 279 = 693; (iv) 963 - 369
= 594; (v) 954 - 459 = 495.

● Write a Java method that, given a starting 3-digit number, returns an array whose
elements are the successive results of the Kaprekar process described above; the
first element of your array should be the starting number and the last element of your
array should be the first occurrence of 495. If the number given has fewer than 3
digits, your method should add leading zeros. If the number given has more than 3
digits, your method should return an empty array. The header of your method should
be:
public static int[] iterateKaprekar3(int number)
The following instruction:
System.out.println(Arrays.toString(iterateKaprekar3(100)));
should return to the console:
[100, 891, 792, 693, 594, 495]

Euler Project

Problem 9: special pythagorean triples


A Pythagorean triple is a set of three positive numbers a ≤ b ≤ c for which a2 + b2 = c2. For
example, 32 + 42 = 52.

● Write a Java method that returns a Pythagorean triple a ≤ b ≤ c such that a + b + c =


s where s is a given number. If there is no such Pythagorean triple, your method
should return an empty array. The header of your method should be:
public static int[] getPythagoreanTripleWithSum(int value)
The following instructions:
System.out.println(java.util.Arrays.toString(
getPythagoreanTripleWithSum(2)));
System.out.println(java.util.Arrays.toString(
getPythagoreanTripleWithSum(1000)));
should output to the console:
[]
[200, 375, 425]

Problem 27: quadratic primes


Euler discovered the remarkable quadratic n2 + n + 41 that produces prime numbers for all
the integer values of n between 0 and 39. The quadratic n2 - 79n + 1601 produces prime
numbers for all the integer values of n between 0 and 79. There are other quadratics of the
form n2 + b n + c with integer coefficients b and c that produce prime numbers for
consecutive integer values of n starting at n = 0.

● Write a Java method that returns an array whose first element is the value of b and
whose second element is the value of c such that the quadratic n2 + b n + c produces
the maximum number of primes for consecutive values of n starting at n = 0 among
all quadratics of the form n2 + B n + C where Bmin ≤ B ≤ Bmax and Cmin ≤ C ≤ Cmax for
given values of Bmin, Bmax, Cmin, Cmax. The header of your method should be:
public static int[] getQuadraticPrimes(
int minB, int maxB, int minC, int maxC)
The following instructions:
int[] coefficients = getQuadraticPrimes(-1000,1000,-1000,1000);
int b = coefficients[0];
int c = coefficients[1];
System.out.println(b+c);
should output to the console:
910

Problem 35: circular primes


The number 197 is called a circular prime because all rotations of its digits in base 10 (719,
971, 197) are themselves prime. There are thirteen such primes below 100: 2, 3, 5, 7, 11,
13, 17, 31, 37, 71, 73, 79, and 97.

● Write a Java method that returns an array whose elements are the circular primes
below a given limit. The header of your method should be:
public static int[] getCircularPrimes(int limit)
The following instructions:
int[] circularPrimes = getCircularPrimes(100);
System.out.println(circularPrimes.length);
System.out.println(java.util.Arrays.toString(circularPrimes));
should output to the console:
13
[2, 3, 5, 7, 11, 13, 17, 31, 37, 71, 73, 79, 97]

Problem 37: truncatable primes


The number 3797 has an interesting property; it is a truncatable prime: being prime itself, it
is possible to continuously remove its leading digit (in base 10) from left to right, and all
resulting numbers (3797, 797, 97, and 7) remain prime. Similarly we can work from right to
left (3797, 379, 37, and 3). There are only 15 primes that are both truncatable from left to
right and from right to left.

● Write a Java method that returns an array whose elements are the 15 truncatable
primes. The header of your method should be:
public static int[] getTruncatablePrimes()
The following instructions:
int sum = 0;
for(int prime: getTruncatablePrimes())
{
sum += prime;
}
System.out.println(sum);
should output to the console:
748334

Problem 39: Integer right triangles


A Pythagorean triple is a set of three positive numbers a ≤ b ≤ c for which a 2 + b2 = c2. For
example, 32 + 42 = 52. There are exactly three Pythagorean triples whose sum is equal to
120: (20,48,52) (24,45,51) (30,40,50).

● Write a Java method that returns the sum below a given limit that maximises the
number of Pythagorean triples with with the same sum. The header of your method
should be:
public static int maximiseNumberOfPythagoreanTriplesWithSumBelow(
int limit)
The following instructions:
System.out.println(maximiseNumberOfPythagoreanTriplesWithSumBelow(
1000));
should output to the console:
840

Problem 46: Goldbach’s other conjecture


Goldbach’s conjecture is the oldest and best-known unsolved problem in number theory.
However, the German mathematician also proposed that every odd number can be written
as the sum of a prime and twice a square. For example, 9 = 7 + 2 x 12 ; 15 = 7 + 2 x 22 ; 21 =
3 + 2 x 32 ; 25 = 7 + 2 x 32 ; 27 = 19 + 2 x 22 ; 33 = 31 + 2 x 12. It turns out that this second
conjecture is false.

● Write a Java method that returns the smallest odd number that cannot be written as
the sum of a prime and twice a square. The header of your method should be:
public static int findCounterexampleToGoldbach()
The following instructions:
int counterexample = findCounterexampleToGoldbach();
int sumOfDigits = 0;
while(counterexample>0)
{
sumOfDigits += counterexample%10;
counterexample /= 10;
}
System.out.println(sumOfDigits);
should output to the console:
26
Problem 49: prime permutations
The arithmetic sequence, 1487, 4817, 8147, in which each of the terms increases by 3330,
is unusual in two ways: (i) each of the three terms are prime; and (ii) each of the 4-digit
numbers are permutations of one another. There are no arithmetic sequences made up of
three 1-digit, or three 2-digit, or three 3-digit primes, exhibiting this property, but there is
another 4-digit increasing sequence with the same property.

● Write a Java method that returns an array whose elements are the values of the
other 4-digit increasing sequence. The header of your method should be:
public static int[] findPrimePermutationsWithFourDigits()
The following instructions:
int[] permutations = findPrimePermutationsWithFourDigits();
System.out.println(permutations[0]+permutations[1]+permutations[2]);
should output to the console:
18897

Problem 50: consecutive prime sum


The prime 41, can be written as the sum of six consecutive primes: 41 = 2 + 3 + 5 + 7 + 11 +
13. This is the longest sequence of consecutive primes that adds to a prime below 100. The
longest sum of consecutive primes below 1000 that adds to a prime, contains 21 terms, and
is equal to 953.

● Write a Java method that returns an array of maximum length whose elements are
primes numbers below a given limit and which add to a prime number. The header of
your method should be:
public static int[] findLongestConsecutivePrimeSumBelow(int limit)
The following instructions:
int[] sum = 0;
for(prime: findLongestConsecutivePrimeSumBelow(1000))
{
sum += prime;
}
System.out.println(sum);
should output to the console:
953

[ WORK IN PROGRESS ] Problem 51: prime digit replacements


By replacing the first digit of the 2-digit number _ 3, it turns out that six of the nine possible
values (13, 23, 43, 53, 73, 83) are prime. By replacing the third and fourth digits of 5 6 _ _ 3
with the same digit, this 5-digit number is the first example having seven primes among the
ten generated numbers (56003, 56113, 56333, 56443, 56663, 56773, 56993).

● Write a Java method that returns an array of length 8 whose elements are prime
numbers which are generated by replacing some of their digits (not necessarily
adjacent digits but digits at the same place) with the same digit. The header of your
method should be:
public static int[] findPrimeDigitReplacementsOfLength8()
The following instructions:
int[] primes = findPrimeDigitReplacementsOfLength8();
int sum = 0;
for(int prime: primes) sum+=prime;
System.out.println(sum);
should output to the console:

International Mathematical Olympiads

IMO 1981 Problem 3


Problem 3 in the 1981 International Mathematical Olympiad (IMO) asked to determine the
maximum value of m 2 + n 2, where m and n are positive integers less than 1981 and ( m 2 -
mn - n 2 ) 2 = 1.

● Write a Java method that returns an array containing the values of m and n such that
m 2 + n 2 is maximum for m and n positive integers that are less than 1981 and ( m 2 -
mn - n 2 ) 2 = 1. The header of your method should be:
public static int[] solveIMO1981Problem3()
The following instructions:
int[] solution = solveIMO1981Problem3();
int m = solution[0];
int n = solution[1];
System.out.println(m*m+n*n);
should output to the console:
3524578

IMO 1994 Problem 4


Problem 4 in the 1994 International Mathematical Olympiad (IMO) asked to find all ordered
pairs (m, n) where m and n are positive integers such that ( n 3 + 1 ) / ( mn - 1 ) is an integer.

● Write a Java method that returns an array whose elements are the solutions to IMO
1994 Problem 4; each solution (m, n) is saved in an array of length 2 whose first
element is the value of m and whose second element is the value of n. You can use
the fact that m and n are positive integers less than 10. The header of your method
should be:
public static int[][] solveIMO1994Problem4()
The following instructions:
int[][] solutions = solveIMO1994Problem4();
int sum = 0;
for(int index=0; index<solutions.length; index++)
{
int m = solutions[index][0];
int n = solutions[index][1];
sum += m + n;
}
System.out.println(sum);
should output to the console:
48

Diophantine equation
A Diophantine equation is an equation, usually in two or more unknowns, such that only the
integer solutions are studied.

Diophantine riddle
A father's age is 1 less than twice that of his son. The digits making up the father's
age are reversed in the son's age.

● Write a Java method that returns an array that contains the possible values of the
father’s age. The header of your method should be:
public static int[] solveDiophantineRiddle()
The following instructions:
boolean check = true;
int[] solutions = solveDiophantineRiddle();
for(int index=0; index<solutions.length; index++)
{
int digit0 = solutions[index] % 10;
int digit1 = solutions[index] / 10;
check = check && (10*digit1+digit0==2*(10*digit0+digit1)-1);
}
System.out.println(check);
should output to the console:
true

Cosine rule
● Write a Java method that returns an array whose elements are the solutions to the
Diophantine equation: a2 + b2 - ab = 4032 where a, b, c are positive integers such
that: (i) a < b; (ii) a and b do not have any common factors; (iv) a and 403 do not
have any common factors; (v) b and 403 do not have any common factors. Save
each solution (a, b) in a array of length 2 whose first element is the value of a and
whose second element is the value of b. You can use the fact that b < 468. The
header of your method should be:
public static int[][] solveDiophantineCosineRule()
The following instructions:
int[][] solutions = solveDiophantineCosineRule();
int sum = 0;
for(int index=0; index<solutions.length; index++)
{
int a = solutions[index][0];
int b = solutions[index][1];
sum += a + b;
}
System.out.println(sum);
should output to the console:
2655

[ WORK IN PROGRESS ] Chakravala method


The chakravala method is an algorithm to solve indeterminate quadratic equations.
Words
[ WORK IN PROGRESS ] Basic string manipulations

[ WORK IN PROGRESS ] Letter distribution

[ WORK IN PROGRESS ] Palindromes

Sorting
[ WORK IN PROGRESS ] Selection sort

[ WORK IN PROGRESS ] Bubble sort

[ WORK IN PROGRESS ] Insertion sort

[ WORK IN PROGRESS ] Quicksort

[ WORK IN PROGRESS ] Heapsort

[ WORK IN PROGRESS ] Merge sort

[ WORK IN PROGRESS ] Patience sort

Two-dimensional arrays
● Create a new class TwoDimensionalArray and copy the code below.

TwoDimensionalArray.java

/**
* <write a description of class preamble here>
* @author <Firstname> <LASTNAME>
* @version <submission>.<modification>
* @date <yyyy>.<mm>.<dd>
*/

import java.util.*;
import java.lang.*;
import java.io.*;
public class TwoDimensionalArray
{
public static void main(String args[])
{
}
public static int[][] getRandomArray(int rows, int columns)
{
int[][] result = new int[rows][columns];
for (int row = 0; row < rows; row++)
{
for (int column = 0; column < columns; column++)
{
result[row][column] = (int)(Math.random() * 100);
}
}
return result;
}
}

Basic Algorithms

Printing a two-dimensional array


● Write a Java program that outputs the elements of a given two-dimensional array to
the terminal (elements in the same row should be on the same line). The header of
your method should be:
public static void print(int[][] array)
The following instructions:
print(new int[][] {{1,2,3},{4,5,6},{7,8,9}});
should output to the console:
1 2 3
4 5 6
7 8 9

Finding the maximum and the sum


● Write a Java program that returns the sum of all the elements of a given two-
dimensional array. The header of your method should be:
public static int getSum(int[][] array)
The following instructions:
System.out.println(getSum(new int[][] {
{1,2,3},
{4,5,6},
{7,8,9}}
));
should output to the console:
45
● Write a Java program that returns the value of the largest element of a given two-
dimensional array. The header of your method should be:
public static int getMaximum(int[][] array)
The following instructions:
System.out.println(getMaximum(new int[][] {
{1,2,3},
{4,5,6},
{7,8,9}}
));
should output to the console:
9

Operations by row and by column


● Write a Java program that returns the largest element in a given row (you can
assume that the row given exists). The header of your method should be:
public static int getMaximumOfRow(int[][] array,int row)
The following instructions:
System.out.println(getMaximumOfRow(new int[][] {
{1,2,3},
{4,5,6},
{7,8,9}}
,0));
should output to the console:
3

● Write a Java program that returns the largest element in a given column (you can
assume that the column given exists at least in one row). Make sure your method
works for ragged arrays. The header of your method should be:
public static int getMaximumOfColumn(int[][] array,int column)
The following instructions:
System.out.println(getMaximumOfColumn(new int[][] {
{1,2,3},
{4,5},
{7,8,9}}
,2));
should output to the console:
9

● Write a Java program that returns the sum of all elements in a given row. The header
of your method should be:
public static int getSumOfRow(int[][] array,int row)
The following instructions:
System.out.println(getSumOfRow(new int[][] {
{1,2,3},
{4,5,6},
{7,8,9}}
,0));
should output to the console:
6

●Write a Java program that returns the sum of all elements in a given column. Make
sure your method works for ragged arrays (if the given array is ragged, use zero for
the missing elements). The header of your method should be:
public static int getSumOfColumn(int[][] array, int column)
The following instructions:
System.out.println(getSumOfColumn(new int[][] {
{1,2,3},
{4,5},
{7,8,9}}
,2));
should output to the console:
12

Finding indices
●Write a Java program that returns the index of the first row with the largest element.
The header of your method should be:
public static int getRowOfMaximum(int[][] array)
The following instructions:
System.out.println(getRowOfMaximum(new int[][] {
{1,2,3},
{4,5,6},
{7,8,9}}
));
should output to the console:
2

●Write a Java program that returns the index of the first column with the largest
element. The header of your method should be:
public static int getColumnOfMaximum(int[][] array)
The following instructions:
System.out.println(getColumnOfMaximum(new int[][] {
{1,2,3},
{4,5,6},
{7,8,9}}
));
should output to the console:
2
● Write a Java program that returns the index of the row with the largest sum (in case
of equality returns the index of the first row). The header of your method should be:
public static int getRowWithMaxSum(int[][] array)
The following instructions:
System.out.println(getRowWithMaxSum(new int[][] {
{1,2,3},
{4,5,6},
{7,8,9}}
));
should output to the console:
2

● Write a Java program that returns the index of the column with the largest sum. (in
case of equality returns the index of the first row). Make sure your method works for
ragged arrays (if the given array is ragged, use zero for the missing elements). The
header of your method should be:
public static int getColumnWithMaxSum(int[][] array)
The following instructions:
System.out.println(getColumnWithMaxSum(new int[][] {
{1,2,3},
{4,6},
{7,8,9}}
));
should output to the console:
1

Case study

Grading
You need to write a program that grades multiple-choice tests. The answers are stored in a
two-dimensional array. Each row records a student’s answers to the questions. The key is
stored in a one-dimensional array.

● Write a Java method that returns an array with the number of correct answers for
each student. The header of your method should be:
public static int[] grade(char[][] answers, char[] keys)
The following instructions:
// Students' answers to the questions
char[][] answers = {
{'A', 'B', 'A', 'C', 'C', 'D', 'E', 'E', 'A', 'D'},
{'D', 'B', 'A', 'B', 'C', 'A', 'E', 'E', 'A', 'D'},
{'E', 'D', 'D', 'A', 'C', 'B', 'E', 'E', 'A', 'D'},
{'C', 'B', 'A', 'E', 'D', 'C', 'E', 'E', 'A', 'D'},
{'A', 'B', 'D', 'C', 'C', 'D', 'E', 'E', 'A', 'D'},
{'B', 'B', 'E', 'C', 'C', 'D', 'E', 'E', 'A', 'D'},
{'B', 'B', 'A', 'C', 'C', 'D', 'E', 'E', 'A', 'D'},
{'E', 'B', 'E', 'C', 'C', 'D', 'E', 'E', 'A', 'D'}
};
// Key to the questions
char[] keys = {'D', 'B', 'D', 'C', 'C', 'D', 'A', 'E', 'A', 'D'};
// Grade test
System.out.println(java.util.Arrays.toString(grade(answers, keys)));
should output to the console:
[7, 6, 5, 4, 8, 7, 7, 7]

Sudoku
A sudoku is a 9x9 grid divided into smaller 3x3 boxes. Some cells, called fixed cells, are
populated with numbers from 1 to 9. The objective is to fill the empty cells, also called free
cells, with the numbers 1 to 9 so that every row, every column, and every 3x3 box contains
the numbers 1 to 9.

● Write a Java method that checks if a 9x9 grid given as a two-dimensional array
satisfies the conditions to be a Sudoku. The header of your method should be:
public static boolean isSudoku(int[][] grid)
The following instructions:
int[][] grid1 = new int[][] {
{5, 3, 4, 6, 7, 8, 9, 1, 2},
{6, 7, 2, 1, 9, 5, 3, 4, 8},
{1, 9, 8, 3, 4, 2, 5, 6, 7},
{8, 5, 9, 7, 6, 1, 4, 2, 3},
{4, 2, 6, 8, 5, 3, 7, 9, 1},
{7, 1, 3, 9, 2, 4, 8, 5, 6},
{9, 6, 1, 5, 3, 7, 2, 8, 4},
{2, 8, 7, 4, 1, 9, 6, 3, 5},
{3, 4, 5, 2, 8, 6, 1, 7, 9}};
int[][] grid2 = new int[][] {
{3, 5, 4, 6, 7, 8, 9, 1, 2},
{6, 7, 2, 1, 9, 5, 3, 4, 8},
{1, 9, 8, 3, 4, 2, 5, 6, 7},
{8, 5, 9, 7, 6, 1, 4, 2, 3},
{4, 2, 6, 8, 5, 3, 7, 9, 1},
{7, 1, 3, 9, 2, 4, 8, 5, 6},
{9, 6, 1, 5, 3, 7, 2, 8, 4},
{2, 8, 7, 4, 1, 9, 6, 3, 5},
{3, 4, 5, 2, 8, 6, 1, 7, 9}};
int[][] grid3 = new int[][] {
{6, 3, 4, 6, 7, 8, 9, 1, 2},
{5, 7, 2, 1, 9, 5, 3, 4, 8},
{1, 9, 8, 3, 4, 2, 5, 6, 7},
{8, 5, 9, 7, 6, 1, 4, 2, 3},
{4, 2, 6, 8, 5, 3, 7, 9, 1},
{7, 1, 3, 9, 2, 4, 8, 5, 6},
{9, 6, 1, 5, 3, 7, 2, 8, 4},
{2, 8, 7, 4, 1, 9, 6, 3, 5},
{3, 4, 5, 2, 8, 6, 1, 7, 9}};
int[][] grid4 = new int[][] {
{5, 3, 4, 6, 7, 8, 9, 1, 2},
{6, 7, 2, 1, 9, 5, 3, 4, 8},
{8, 5, 9, 7, 6, 1, 4, 2, 3},
{1, 9, 8, 3, 4, 2, 5, 6, 7},
{4, 2, 6, 8, 5, 3, 7, 9, 1},
{7, 1, 3, 9, 2, 4, 8, 5, 6},
{9, 6, 1, 5, 3, 7, 2, 8, 4},
{2, 8, 7, 4, 1, 9, 6, 3, 5},
{3, 4, 5, 2, 8, 6, 1, 7, 9}};
System.out.println(isSudoku(grid1));
System.out.println(isSudoku(grid2));
System.out.println(isSudoku(grid3));
System.out.println(isSudoku(grid4));
should output to the console:
True
False
False
False

Birthday
● Add the guessBirthday() method below to your TwoDimensionalArray class.

guessBirthday

public static int guessBirthday() {


int day = 0;
int[][][] dates = {
{
{ 1, 3, 5, 7},
{ 9, 11, 13, 15},
{17, 19, 21, 23},
{25, 27, 29, 31}
},
{
{ 2, 3, 6, 7},
{10, 11, 14, 15},
{18, 19, 22, 23},
{26, 27, 30, 31}
},
{
{ 4, 5, 6, 7},
{12, 13, 14, 15},
{20, 21, 22, 23},
{28, 29, 30, 31}
},
{
{ 8, 9, 10, 11},
{12, 13, 14, 15},
{24, 25, 26, 27},
{28, 29, 30, 31}
},
{
{16, 17, 18, 19},
{20, 21, 22, 23},
{24, 25, 26, 27},
{28, 29, 30, 31}
}};
Scanner input = new Scanner(System.in);
for (int i = 0; i < dates.length; i++)
{
System.out.println("Is your birthday in set "+(i+1)+"?");
for (int j = 0; j < dates[i].length; j++)
{
for (int k = 0; k < dates[i][j].length; k++)
{
System.out.printf("%4d", dates[i][j][k]);
}
System.out.println();
}
System.out.print("Enter 0 for no and 1 for yes: ");
int answer = input.nextInt();
if (answer == 1)
{
day += dates[i][0][0];
}
System.out.println();
}
System.out.println("Your birthday is " + day);
return day;
}

● Run the guessBirthday() method.

● This mathematical trick is explained in this video.


Recursion
● Add a new class named Recursion to your ComputationalChallenges project
and copy the code below. Make sure to personalise your preamble.

Recursion

/**
* <Write a description here.>
* @author <firstname> <LASTNAME>
* @version <submission>.<modification>
* @date <yyyy>.<mm>.<dd>
*/

import java.util.*;
import java.lang.*;
import java.io.*;

public class Recursion


{
public static void main (String[] args)
{
int limit = 10;
}
}

Fibonacci sequence
The Fibonacci sequence satisfies the recurrence relationship: F(n) = F(n-1) + F(n-2) where
F(1)=1 and F(2)=1. The first 8 terms of the Fibonacci sequence are: 1, 1, 2, 3, 5, 8 ,13, 21.

● Write a recursive Java method that returns the term of the Fibonacci sequence given
its rank e.g. F(5) = 5, F(6) = 8. The header of your method should be:
public static int getFibonacciRecursive(int rank)
The following instructions:
System.out.println(getFibonacciRecursive(6));
should output to the console:
8

● Write an non-recursive Java method that returns the term of the Fibonacci sequence
given its rank. The header of your method should be:
public static int getFibonacciIterative(int rank)
The following instructions:
System.out.println(getFibonacciIterative(6));
should output to the console:
8
● Write a non-recursive Java method that returns an array of Fibonacci numbers up to
a given rank (for sake of simplicity, the first element of your array should be 0). The
header of your method should be:
public static int[] getFibonacciNumbersTo(int limit)
The following instructions:
System.out.println(getFibonacciNumbersTo(6)[6]);
should output to the console:
8

● With reference to the three Java methods you wrote to calculate Fibonacci numbers,
justify your answers to the following questions:
○ Which version did you find easier to code?
○ Which version do you think is more efficient.
The getFibonacciRecursive seems easier because the Fibonacci sequence is defined
recursively. However, getFibonacciIterative has a better time and space complexity
(it is faster and requires less resources). Finally, getibonacciNumbersTo uses the
recursive formula (so it is easier to code) but the array requires a lot of resources.

● Add the following method to your Recursion class and explain its utility.
This is a wrapper method that selects a default method.

Wrapper method

public static int getFibonacci(int rank)


{
return getFibonacciRecursive(rank);
//return getFibonacciIterative(rank);
//return getFibonacciNumbersTo(rank)[rank];
}

● Write 3 versions of a Java method that outputs the terms of the Fibonacci sequence
up to a given rank; each version should use the corresponding method to calculate
the Fibonacci number. The header of your methods should be:
public static void printFibonacciRecursive(int limit)
public static void printFibonacciIterative(int limit)
public static void printFibonacciNumbersTo(int limit)
The following instructions:
printFibonacciRecursive(6);
printFibonacciIterative(6);
printFibonacciNumbersTo(6);
should output to the console:
112358
112358
112358

● Add the following method to your Recursion class and explain its utility.
This is a wrapper method that selects a default method.

Wrapper method

public static void printFibonacci(int limit)


{
printFibonacciRecursive(limit);
//printFibonacciIterative(limit);
//printFibonacciNumbersTo(limit);
}

● Add the code below to your main method. Compile and run your Recursion class.

Test case

System.out.println("*** testing fibonacci");


System.out.print(" recursive: ");
printFibonacciRecursive(limit);
System.out.print(" iterative: ");
printFibonacciIterative(limit);
System.out.print(" numbersTo: ");
printFibonacciNumbersTo(limit);

Lucas sequences
The Fibonacci sequence is a particular case of Lucas sequences. A Lucas sequence
satisfies the same recurrence relation as the Fibonacci sequence: L(n) = L(n-1) + L(n-2) but
the 2 first terms of the sequence L(1) and L(2) can take any value.

For example, if L(1)=3 and L(2)=4 then


L(3)=L(3-1)+L(2-1)
L(3)=L(2)+L(1)
L(3)=4+3
L(3)=7
The first few terms of this sequence are given in the table below.
n 1 2 3 4 5 6

L(n) 3 4 7 11 18 29

Note that if L(1)=1 and L(2)=1 then L(n) is the Fibonacci sequence.

●Write a recursive Java method that returns the term of a Lucas sequence given its
rank and its first two terms. The header of your method should be:
public static int getLucasRecursive(
int term1,
int term2,
int rank)
The following instructions:
System.out.println(getLucasRecursive(1,1,6));
should output to the console:
8

● Write a non-recursive Java method that returns the term of a Lucas sequence given
its rank and its first two terms. The header of your method should be:
public static int getLucasIterative(
int term1,
int term2,
int rank)
The following instructions:
System.out.println(getLucasIterative(1,1,6));
should output to the console:
8

● Write a non-recursive Java method that returns an array of Lucas numbers up to a


given rank (make sure that the value you use for the first term of the array also
satisfies the recurrence relation). The header of your method should be:
public static int[] getLucasNumbersTo(
int term1,
int term2,
int rank)
The following instructions:
System.out.println(getLucasNumbersTo(1,1,6)[6]);
should output to the console:
8

● Add the following method to your Recursion class and explain its utility.
This is a wrapper method that selects a default method.

Wrapper method

public static int getLucas(int term1, int term2, int rank)


{
return getLucasRecursive(term1, term2, rank);
//return getLucasIterative(term1, term2, rank);
//return getLucasNumbersTo(term1, term2, rank)[rank];
}

● Write a Java method that checks that your getFibonacci wrapper method and
your getLucas wrapper method with term1=term2=1 return the same value for all
terms below a given rank. The header of your method should be:
public static boolean isFibonacciEqualToLucas(int limit)
The following instructions:
System.out.println(isFibonacciEqualToLucas(10));
should output to the console:
true

● Explain the utility of the isFibonacciEqualToLucas method.


It is good practice to check complex programmes on simple cases.

● Write 3 versions of a Java method that output the terms of a Lucas sequence up to a
given rank; each version should use the corresponding method to calculate the
Fibonacci number. The header of your methods should be:
public static void printLucasRecursive(
int term1,
int term2,
int limit)
public static void printLucasIterative(
int term1,
int term2,
int limit)
public static void printLucasNumbersTo(
int term1,
int term2,
int limit)
The following instructions:
printLucasRecursive(1,1,6);
printLucasIterative(1,1,6);
printLucasNumbersTo(1,1,6);
should output to the console:
112358
112358
112358

● Add the code below to your main method. Compile and run your Recursion class.

Test case

System.out.println("*** testing lucas");


System.out.print(" recursive: ");
printLucasRecursive(1,1,limit);
System.out.print(" iterative: ");
printLucasIterative(1,1,limit);
System.out.print(" numbersTo: ");
printLucasNumbersTo(1,1,limit);

● Compare and contrast the isLucasEqualFibonacci method and the 3


printLucas methods as a way to check if a programme is correct.
Both methods are good coding practices as they can help you check if your programme
performs as expected. However, the size of the terminal limits the printLucas methods
while isLucasEqualFibonacci does not show where the calculations might differ.

● Add the following method to your Recursion class and explain its utility.
This is a wrapper method that selects a default method.

Wrapper method

public static void printLucas(int term1, int term2, int limit)


{
printLucasRecursive(term1, term2, limit);
//printLucasIterative(term1, term2, limit);
//printLucasNumbersTo(term1, term2, limit);
}

Linear recurrence
Lucas sequences are a special case of linear recurrence of order 2 which satisfies the
following relationship: R(n) = c1*R(n-1) + c2*R(n-1) where c1 and c2 are constants and the
first two terms R(1) and R(2) can take any value.

For example, if c1=1 and c2=2 as well as R(1)=1 and R(2)=2 then
R(3)=c1*R(3-1)+c2*R(3-2)
R(3)=1*R(2)+2*R(1)
R(3)=1*2+2*1
R(3)=2+2
R(3)=4
The table below shows the first few terms of this sequence:

Note that if c1=c2=1 and R(1)=R(2)=1, you get the Fibonacci sequence.

● Write a recursive Java method that returns the term of a linear recurrence of order 2
given its rank and the parameters of the linear recurrence (the 2 constant coefficients
and the 2 initial terms). The header of your method should be:
public static int getLinearRecursive(
int coef1,
int coef2,
int term1,
int term2,
int rank)
The following instructions:
System.out.println(getLinearRecursive(1,1,1,1,6));
should output to the console:
8
● Write a non-recursive Java method that returns the term of a linear recurrence of
order 2 given its rank and the parameters of the linear recurrence (the 2 constant
coefficients and the 2 initial terms). The header of your method should be:
public static int getLinearIterative(
int coef1,
int coef2,
int term1,
int term2,
int rank)
The following instructions:
System.out.println(getLinearIterative(1,1,1,1,6));
should output to the console:
8

● Write a non-recursive Java method that returns an array of terms up to a given rank
for a linear recurrence of order 2 (for sake of simplicity, the first element of your array
should be set to zero so that the first term and second term are stored in the element
of index 1 and 2 respectively). The header of your method should be:
public static int[] getLinearNumbersTo(
int coef1,
int coef2,
int term1,
int term2,
int rank)
The following instructions:
System.out.println(getLinearNumbersTo(1,1,1,1,6)[6]);
should output to the console:
8

● Add the following method to your Recursion class and explain its utility.
This is a wrapper method that selects a default method.

Wrapper method

public static int getLinear(


int coef1,
int coef2,
int term1,
int term2,
int rank)
{
return getLinearRecursive(
coef1,
coef2,
term1,
term2,
rank);
//return getLinearIterative(
//coef1,
//coef2,
//term1,
//term2,
//rank);
//return getLinearNumbersTo(
//coef1,
//coef2,
//term1,
//term2,
//rank)[rank];
}

● Write a Java method that checks that your getFibonacci wrapper method and
your getLinear wrapper method with coef1=coef2=term1=term2=1 return the
same value for all terms below a given number. The header of your method should
be:
public static boolean isFibonacciEqualToLinear(int limit)
The following instructions:
System.out.println(isFibonacciEqualToLinear(10));
should output to the console:
true

● Explain the utility of the isFibonacciEqualToLinear method.


It is good practice to check complex programmes on simple cases.

● Write 3 versions of a Java method that output the terms of a Lucas sequence up to a
given rank (each version should use the corresponding method to calculate the
Fibonacci number). The header of your methods should be:
public static void printLinearRecursive(
int coef1,
int coef2,
int term1,
int term2,
int limit)
public static void printLinearIterative(
int coef1,
int coef2,
int term1,
int term2,
int limit)
public static void printLinearNumbersTo(
int coef1,
int coef2,
int term1,
int term2,
int limit)
The following instructions:
printLinearRecursive(1,1,1,1,6);
printLinearIterative(1,1,1,1,6);
printLinearNumbersTo(1,1,1,1,6);
should output to the console:
112358
112358
112358

● Add the code below to your main method. Compile and run your Recursion class.

Test case

System.out.println("*** testing linear");


System.out.print(" recursive: ");
printLinearRecursive(1,1,1,1,limit);
System.out.print(" iterative: ");
printLinearIterative(1,1,1,1,limit);
System.out.print(" numbersTo: ");
printLinearNumbersTo(1,1,1,1,limit);

● Compare and contrast the isFibonacciEqualToLinear method and the 3


printLinear methods as a way to check if a programme is correct.
Both methods are good practices coding practices (to check if a programme performs as
expected). However, the size of the terminal limits the printLinear methods while
isFibonacciEqualToLinear does not show where the calculations might differ.

● Add the following method to your Recursion class and explain its utility.
This is a wrapper method that selects a default method.

Wrapper method

public static void printLinear(


int coef1,
int coef2,
int term1,
int term2,
int rank)
{
printLinearRecursive(
coef1,
coef2,
term1,
term2,
rank);
//printLinearIterative(
//coef1,
//coef2,
//term1,
//term2,
//rank);
//printLinearIterative(
//coef1,
//coef2,
//term1,
//term2,
//rank);
}

Factorial
● Write a recursive Java method that returns the product of all integers from 1 to a
given number. The header of your method should be:
public static int factorialRecursive(int number)
The following instructions:
System.out.println(factorialRecursive(10));
should output to the console:
3628800

● Write a non-recursive Java method that returns the product of all integers from 1 to a
given number. The header of your method should be:
public static int factorialIterative(int number)
The following instructions:
System.out.println(factorialIterative(10));
should output to the console:
3628800

● Add the following method to your Recursion class and explain its utility.
This is a wrapper method that selects a default method.

Wrapper method for factorial

public static int factorial(int number)


{
return factorialRecursive(number);
//return factorialIterative(number);
}
Binomial coefficients
● Using the factorial formula to write a Java method that returns binomial coefficients.
The header of your method should be:
public static int binomialFactorial(int choose, int from)
The following instructions:
System.out.println(binomialFactorial(5,10));
should output to the console:
252

● Use Pascal’s formula to write a recursive Java method that returns the value of the
binomial coefficients. The header of your method should be:
public static int binomialRecursive(int choose, int from)
The following instructions:
System.out.println(binomialRecursive(5,10));
should output to the console:
252

● Add the following method to your Recursion class and explain its utility.
This is a wrapper method that selects a default method.

Wrapper method for binomial

public static int binomial(int choose, int from)


{
return binomialRecursive(choose, from);
//return binomialFactorial(choose, from);
}

● Write a Java method that outputs a given number of lines of Pascal’s triangle. The
header of your method should be:
public static void printPascalTriangle(int limit)
The following instructions:
printPascalTriangle(5);
should output to the console:
1
11
121
1331
14641
1 5 10 10 5 1

Ackermann functions
● The following program in pseudo-code defines a method that returns the value of a
simplified version of the Ackermann function.
● Write a recursive Java method that returns the value of the simplified Ackermann
function. The header of your method should be:
public static int ackermann(int m, int n)
The following instructions:
System.out.println(ackermann(3,3));
should output to the console:
61

● Write a Java methods that outputs the values of the simplified Ackermann function
for parameters below given numbers. More precisely, your method should return the
value of ackermann(m,n) at row m and column n where m is between 0 and
maxRow and n is between 0 and maxColumn. The header of your method should be:
public static void printAckermann(int maxRow, int maxColumn)
The following instructions:
printAckermann(3,6);
should output to the console:
1234567
2345678
3 5 7 9 11 13 15
5 13 29 61 125 253 509

● Describe what happens when you execute the following instruction:


ackermann(4,1);
The following error is triggered java.lang.StackOverflowError (your computer cannot
complete the calculation because it ran out of resources).

● The following program in pseudo-code defines a function that returns the value of the
complete Ackermann function.
● Write a recursive Java method that returns the value of the complete Ackermann
function. The header of your method should be:
public static int ackermann(int m, int n, int p)
The following instructions:
System.out.println(ackermann(3,3,2));
should output to the console:
27

● Write a Java methods that outputs the values of the complete Ackermann function for
parameters below given numbers. More precisely, your method should return the
value of ackermann(m,n,p) at row m and column n where m is between 0 and
maxRow and n is between 0 and maxColumn and p is given. The header of your
method should be:
public static void printAckermann(int maxRow, int maxColumn, int p)
The following instructions:
printAckermann(3,6,2);
should output to the console:
1000000
1111111
1 2 4 8 16 32 64
1 3 9 27 81 243 729

● Describe what happens when you execute the following instruction:


ackermann(3,3,3);
The following error is triggered java.lang.StackOverflowError (your computer cannot
complete the calculation because it ran out of resources).

Reversing digits
● Write a non-recursive java method that outputs the digits of a given integer in reverse
order. The header of your method should be:
public static void printReverseIterative(int number)
The following instructions:
printReverseIterative(1234);
printReverseIterative(0);
should output to the console:
4321
0

● Write a non-recursive java method that given an integer returns an integer whose
digits are in reverse order. The header of your method should be:
public static int getReverseIterative(int number)
The following instructions:
System.out.println(getReverseIterative(1234));
System.out.println(getReverseIterative(0));
should output to the console:
4321
0

● Write a recursive java method that outputs the digits of a given integer in reverse
order. The header of your method should be:
public static void printReverseRecursive(int number)
The following instructions:
printReverseRecursive(1234);
printReverseRecursive(0);
should output to the console:
4321
0

● Write a recursive java method that given an integer returns an integer whose digits
are in reverse order. The header of your method should be:
public static int getReverseRecursive(int number)
The following instructions:
System.out.println(getReverseRecursive(1234));
System.out.println(getReverseRecursive(0));
should output to the console:
4321
0

● Add the following method to your Recursion class and explain its utility.
This is a wrapper method that selects a default method.

Wrapper method for reverse

public static int reverse(int number)


{
return getReverseRecursive(number);
//return getReverseIterative(number);
}

Peano arithmetics

For this section (Peano), you are not allowed to use any of the basic arithmetic operations in
Java + * - / % nor the class Math (or equivalent). Instead you can make use of the
methods successor and predecessor defined in the class template below.

● Add a new class named Peano and copy the code below. Make sure your
personalise the preamble.

Peano arithmetics
/**
* <Write a description here.>
* @author <firstname> <LASTNAME>
* @version <submission>.<modification>
* @date <yyyy>.<mm>.<dd>
*/

import java.util.*;
import java.lang.*;
import java.io.*;

public class Peano


{
public static void main (String[] args)
{
}
public static int successor(int number)
{
if (number<0)
{
return 0;
}
else
{
return number+1;
}
}
public static int predecessor(int number)
{
if (number<=0)
{
return 0;
}
else
{
return number-1;
}
}

●Write a recursive Java methods that returns the sum of two given integers. The
header of your method should be:
public static int addition(int m, int m)
The following instructions:
System.out.println(add(3,2));
should output to the terminal;
5
● Write a recursive Java methods that returns the product of two given integers. The
header of your method should be:
public static int multiplication(int m, int m)
The following instructions:
System.out.println(multiplication(3,2));
should output to the terminal;
6

● Write a recursive Java methods that returns the exponential of a given number in a
given base. The header of your method should be:
public static int exponentiation(int m, int n)
The following instructions:
System.out.println(exponentiation(3,2));
should output to the terminal;
9

● Compare and contrast the recursive method call of multiplication and


exponentiation. Hence, suggest a definition for an operation that continues this
pattern (tetration).
The recursive call for multiplication is:
addition(m,multiplication(m,predecessor(n)));
The recursive call for exponentiation is:
multiplication(m,exponentiation(m,predecessor(n)));
To continue this pattern, the recursive call for tetration should be:
tetration(m,exponentiation(m,predecessor(n)));

● Write a recursive Java methods that returns the tetration of two given numbers. The
header of your method should be:
public static int tetration(int m, int m)
The following instructions:
System.out.println(tetration(3,2));
should output to the terminal;
27

Note that the methods Successor, Addition, Multiplication, Exponentiation,


Tetration form a sequence of operations that use the previous operation in its recursive
definition (hyperoperation). The complete Ackermann function somewhat resembles the
sequence of hyperoperations.

● Write a recursive Java methods that returns the hyperoperation of two given
numbers. The header of your method should be:
public static int hyperoperation(int m, int n, int p)
The following instructions:
System.out.println(hyperoperation(3,2,1));//addition(3,2)
System.out.println(hyperoperation(3,2,2));//multiplication(3,2)
System.out.println(hyperoperation(3,2,3));//exponentiation(3,2)
System.out.println(hyperoperation(3,2,4));//tetration(3,2)
System.out.println(hyperoperation(2,2,5));
should output to the terminal;
5
6
9
27
4

Tower of Hanoi
● Add a new class named TowerOfHanoi and copy the code below. Make sure your
personalise the preamble.

Tower of Hanoi

/**
* <Write a description here.>
* @author <firstname> <LASTNAME>
* @version <submission>.<modification>
* @date <yyyy>.<mm>.<dd>
*/

import java.util.*;
import java.lang.*;
import java.io.*;

public class TowerOfHanoi


{
public static void main ()
{
System.out.print("Solve the Tower of Hanoi for ");
Scanner input = new Scanner(System.in);
int numberOfDiscs= input.nextInt();
}
}

● Write a (recursive) Java method that returns the number of moves to solve the Tower
of Hanoi for a given number of discs. The header of your method should be:
public static int count(int numberOfDiscs)
The following instructions:
System.out.println(count(4));
should output to the console:
15

● Use your count method to investigate the number of moves to solve the Tower of
Hanoi. Suggest a formula to calculate the number of moves.
Write a for-loop to output the number of moves for a number of discs from 0 to 10 (for
example). The formula involves a power of 2.

● Write a recursive Java method that outputs the instructions for solving the Tower of
Hanoi for a given number of discs. The header of your method should be:
public static void move(int numberOfDiscs)
The following instructions:
move(4);
should output to the console:
Move top disc from peg 0 to peg 1
Move top disc from peg 0 to peg 2
Move top disc from peg 1 to peg 2
Move top disc from peg 0 to peg 1
Move top disc from peg 2 to peg 0
Move top disc from peg 2 to peg 1
Move top disc from peg 0 to peg 1
Move top disc from peg 0 to peg 2
Move top disc from peg 1 to peg 2
Move top disc from peg 1 to peg 0
Move top disc from peg 2 to peg 0
Move top disc from peg 1 to peg 2
Move top disc from peg 0 to peg 1
Move top disc from peg 0 to peg 2
Move top disc from peg 1 to peg 2

● Modify your move method so that each step of the solution is numbered. The header
of your method should be (it is the same as before):
public static void move(int numberOfDiscs)
The following instructions:
move(4);
should output to the console:
01. Move top disc from peg 0 to peg 1
02. Move top disc from peg 0 to peg 2
03. Move top disc from peg 1 to peg 2
04. Move top disc from peg 0 to peg 1
05. Move top disc from peg 2 to peg 0
06. Move top disc from peg 2 to peg 1
07. Move top disc from peg 0 to peg 1
08. Move top disc from peg 0 to peg 2
09. Move top disc from peg 1 to peg 2
10. Move top disc from peg 1 to peg 0
11. Move top disc from peg 2 to peg 0
12. Move top disc from peg 1 to peg 2
13. Move top disc from peg 0 to peg 1
14. Move top disc from peg 0 to peg 2
15. Move top disc from peg 1 to peg 2
● Modify your move method so that each step of the solution shows which method call
generated it. The header of your method should be (it is the same as before):
public static void move(int numberOfDiscs)
The following instructions:
move(4);
should output to the console:
01. Move top disc from peg 0 to peg 1 (call #3)
02. Move top disc from peg 0 to peg 2 (call #2)
03. Move top disc from peg 1 to peg 2 (call #4)
04. Move top disc from peg 0 to peg 1 (call #1)
05. Move top disc from peg 2 to peg 0 (call #6)
06. Move top disc from peg 2 to peg 1 (call #5)
07. Move top disc from peg 0 to peg 1 (call #7)
08. Move top disc from peg 0 to peg 2 (call #0)
09. Move top disc from peg 1 to peg 2 (call #10)
10. Move top disc from peg 1 to peg 0 (call #9)
11. Move top disc from peg 2 to peg 0 (call #11)
12. Move top disc from peg 1 to peg 2 (call #8)
13. Move top disc from peg 0 to peg 1 (call #13)
14. Move top disc from peg 0 to peg 2 (call #12)
15. Move top disc from peg 1 to peg 2 (call #14)

Abstract Data Structures


● Add a new class named AbstractDataStructure to your
ComputationalChallenges project and copy the code below.

● Make sure you personalise your preamble.

AbstractDataStructure

/**
* <Write a description here.>
* @author <firstname> <LASTNAME>
* @version <submission>.<modification>
* @date <yyyy>.<mm>.<dd>
*/

import java.util.*;
import java.lang.*;
import java.io.*;

public class AbstractDataStructure


{
public static void main (String[] args)
{
Stack<Integer> stackOfIntegers = new Stack<>();
Stack<Double> stackOfDoubles = new Stack<>();
Stack<Character> stackOfCharacters = new Stack<>();
Stack<String> stackOfStrings = new Stack<>();
Stack<int[]> stackOfArrays = new Stack<>();
Stack<Object> stackOfObjects = new Stack<>();
Stack stackOfUnspecifiedTypes = new Stack();
}
}

● Once you completed the Introduction to stacks section, add comments to your
program to explain why some of the methods need to specify a type for the elements
of the given stack.

Introduction to stacks
● Add the usingStacks() method below to your AbstractDataStructure class.

usingStacks()

public static void usingStacks()


{
Stack<String> stackOfStrings = new Stack<>();
stackOfStrings.push("Bonjour!");
stackOfStrings.push("Comment");
stackOfStrings.push("allez-vous?");
//printing the elements of a stack
while(!stackOfStrings.isEmpty())
{
System.out.println(stackOfStrings.pop());
}
}

● Run the usingStacks() method.

● Add a comment to your program to explain the output.

Your methods should only use of the following methods of the java.util.Stack class:
● pop()
● push()
● isEmpty()

Printing the elements of a stack


●Write a Java method that outputs the elements of a given stack to the terminal. The
header of your method should be:
public static void printStack(Stack stackOfUnspecifiedTypes)
The following instructions:
for(int element=1; element<10; element++)
{
stackOfDoubles.push(Math.sqrt(element));
}
printStack(stackOfDoubles);
printStack(stackOfDoubles);
should output to the console:
3.0
2.8284271247461903
2.6457513110645907
2.449489742783178
2.23606797749979
2.0
1.7320508075688772
1.4142135623730951
1.0

● Add a comment to your program to explain why the above instructions do not print
the elements of the stack twice.

Counting the number of elements in a stack


Your countStack() method should not use of the size() method of the
java.util.Stack class.

● Write a Java method that counts the elements of a given stack. The header of your
method should be:
public static int countStack(Stack stackOfUnspecifiedTypes)
The following instructions:
for(int element=1; element<10; element++)
{
stackOfArrays.push(new int[] {element});
}
System.out.println(countStack(stackOfArrays));
should output to the console:
9

Calculating the sum of the elements in a stack


● Write a Java method that returns the sum of the elements of a given stack. Your
method should return 0 if the given stack is empty. The header of your method
should be:
public static int sumStack(Stack<Integer> stackOfIntegers)
The following instructions:
for(int element=1; element<10; element++)
{
stackOfIntegers.push(element);
}
System.out.println(sumStack(stackOfIntegers));
should output to the console:
45

Finding the maximum of a stack



Write a Java method that finds the maximum element of a given stack. The header of
your method should be:
public static int maximumStack(Stack<Integer> stackOfIntegers)
The following instructions:
for(int element=1; element<10; element++)
{
stackOfIntegers.push(element);
}
System.out.println(maximumStack(stackOfIntegers));
should output to the console:
9

Getting an element from a stack


Your getStack() method should not use of the elementAt() method of the
java.util.Stack class.


Write a Java method that returns the element of a stack that is at a given index. By
convention, the index of the top element of a stack is 0 (same convention as arrays).
If the index exceeds the number of elements of the given stack, your method should
return an empty object. The header of your method should be:
public static Object getStack(
int index,
Stack<Object> stackOfObjects)
The following instructions:
for(int element=1; element<10; element++)
{
stackOfObjects.push(element);
}
System.out.println(getStack(1,stackOfObjects));
should output to the console:
8

Searching an element in a stack


Your searchStack() method should not use of the contains() method of the
java.util.Stack class.


Write a Java method that searches for a given element in a given stack. By
convention, the index of the top element of a stack is 0 (same convention as for
arrays). If the element is not found, your method should return -1. The header of
your method should be:
public static int searchStack(
Object element,
Stack<Object> stackOfObjects)
The following instructions:
stackOfObjects.push("A");
stackOfObjects.push("B");
stackOfObjects.push("C");
System.out.println(searchStack("A",stackOfObjects));
System.out.println(searchStack("A",stackOfObjects));
should output to the console:
2
-1

● Add a comment to your searchStack() method to explain why the same


instruction on the same variables does not return the same value.

Peeking at the top of a stack


Your peekStack() method should not use of the peek() method of the
java.util.Stack class.

● Write a Java method that returns the top of a stack without changing the given stack.
Your method should return an empty object if the given stack is empty. The header of
your method should be:
public static Object peekStack(Stack<Object> stackOfObjects)
The following instructions:
stackOfObjects.push("A");
stackOfObjects.push("B");
stackOfObjects.push("C");
System.out.println(peekStack(stackOfObjects));
printStack(stackOfObjects);
should output to the console:
C
C
B
A

Reversing the elements of a stack


● Write a Java method that returns a new stack whose elements are in reverse order of
the elements of a given stack. The header of your method should be:
public static Stack<Object> reverseStack(
Stack<Object> stackOfObjects)
The following instructions:
stackOfObjects.push("Bonjour!");
stackOfObjects.push("Comment");
stackOfObjects.push("allez-vous?");
printStack(reverseStack(stackOfObjects));
should output to the console:
Bonjour!
Comment
allez-vous?

Comparing two stacks


Your compareStack() method should not use of the equal() method of the
java.util.Stack class.

● Write a Java method that returns true if two stacks are equal and false otherwise
(two stacks are equal if they have the same number of elements and their respective
elements are equal). The header of your method should be:
public static boolean compareStack(
Stack<Object> stack1,
Stack<Object> stack2)
The following instructions:
Stack<Object> stack1 = new Stack<>();
Stack<Object> stack2 = new Stack<>();
stack1.push("A");
stack1.push("B");
stack1.push("C");
stack2.push("A");
stack2.push("B");
stack2.push("C");
System.out.println(compareStack(stack1,stack2));
stack1.push("A");
stack1.push("B");
stack1.push("C");
stack1.push("D");
stack2.push("A");
stack2.push("B");
stack2.push("C");
System.out.println(compareStack(stack1,stack2));
should output to the console:
true
false

Swapping the top two elements of a stack


● Write a Java method that returns a stack for which the position of the top two
elements are swapped. If the given stack contains fewer than two elements, your
method should return the given stack unchanged. The header of your method should
be:
public static Stack<Object> swapStack(Stack<Object> stackOfObjects)
The following instructions:
stackOfObjects.push("A");
stackOfObjects.push("B");
printStack(stackOfObjects);
System.out.println("=>");
stackOfObjects.push("A");
stackOfObjects.push("B");
printStack(swapStack(stackOfObjects));
should output to the console:
B
A
=>
A
B

Rotating the top three elements of a stack


● Write a Java method that return a stack for which the position of the top three
elements are rotated. If the given stack contains fewer than three elements, your
method should return the given stack unchanged. The header of your method should
be:
public static Stack<Object> rotateStack(
Stack<Object> stackOfObjects)
The following instructions:
stackOfObjects.push("A");
stackOfObjects.push("B");
stackOfObjects.push("C");
stackOfObjects.push("D");
printStack(stackOfObjects);
System.out.println("=>");
stackOfObjects.push("A");
stackOfObjects.push("B");
stackOfObjects.push("C");
stackOfObjects.push("D");
printStack(rotateStack(stackOfObjects));
should output to the console:
D
C
B
A
=>
B
D
C
A

Inserting an element in a stack


Your insertStack() method should not use of the insertElementAt() method of the
java.util.Stack class.
● Write a Java method that returns a new stack with a given element inserted at a
given index. By convention, the index of the top element of a stack is 0 (same
convention as for arrays). If the given index exceeds the number of elements in the
given stack, your method should return the given stack unchanged. The header of
your method should be:
public static Stack<Object> insertStack(
Object element,
int index,
Stack<Object> stackOfObjects)
The following instructions:
stackOfObjects.push("A");
stackOfObjects.push("B");
stackOfObjects.push("C");
printStack(insertStack("D",1,stackOfObjects));
should output to the console:
C
D
B
A

Applications of stacks

Evaluating expressions in infix notation


Infix notation is the notation commonly used in mathematical expressions.

How does your calculator evaluate infix expressions such as: 5 + ((1 + 2) * 4) - 3 ?

For simplicity, assume that the operands are positive integers and the operators are from the
following list: + - * / ( )

The problem can be solved using two stacks, the operands stack and operators stack,
for storing operands (i.e. numerals) and operators, respectively. Operands and operators are
pushed into the stacks before they are processed. When an operator is processed, it is
popped from the operators stack and applied to the first two operands that are popped
from operands stack. The resultant value is pushed back to operands stack. This
algorithm proceeds in two phases:

● Phase 1: scanning the expression


a. If the extracted token is an operand, push it to operands stack
b. If the extracted token is a + or - operator, repeatedly process the + - * /
operators at the top of operators stack (if any) then push the extracted
operator to operators stack
c. If the extracted token is a * or / operator, repeatedly process the * /
operators at the top of operators stack (if any) then push the extracted
operator to operators stack
d. If the extracted token is a ( symbol - left parenthesis-push it to operators
stack
e. If the extracted token is a ) symbol - right parenthesis - repeatedly process all
the + - * / operators at the top of operators stack until popping a
( symbol - left parenthesis - from the top of the operators stack

● Phase 2: clearing the stacks


a. repeatedly process the + - * / operators at the top of operators stack
until operators stack is empty

Note that Phase 2 could be replaced by a Phase 0 where a ( symbol - left parenthesis - is
added at the start of the expression and a ) symbol - right parenthesis - is added at the end
of the expression.

This algorithm is illustrated below on the infix expression 5 + ( ( 1 + 2 ) * 4 - 3.

expression token phase operands operators

5+((1+2)*4)-3 <empty> <empty> <empty>

+((1+2)*4)-3 5 1a 5 <empty>

((1+2)*4)-3 + 1b 5 +

(1+2)*4)-3 ( 1d 5 (
+

1+2)*4)-3 ( 1d 5 (
(
+

+2)*4)-3 1 1a 1 (
5 (
+

2)*4)-3 + 1b 1 +
5 (
(
+

)*4)-3 2 1a 2 +
1 (
5 (
+

*4)-3 ) 1e 3 (
5 +

4)-3 * 1c 3 *
5 (
+
)-3 4 1a 4 *
3 (
5 +

-3 ) 1e 12 +
5

3 - 1b 12 -
5 +

<empty> 3 1a 3 -
12 +
5

<empty> <empty> 2 9 +
5

<empty> <empty> 2 14 <empty>

<empty> <empty> <end> 14 <empty>

This algorithm is illustrated below on the infix expression: ( 3 - 1 ) * ( 4 + 5 )

expression token phase operands operators

(3-1)*(4+5) <empty> <start> <empty> <empty>

3-1)*(4+5) ( 1d <empty> (

-1)*(4+5) 3 1a 3 (

1)*(4+5) - 1b 3 -
(

)*(4+5) 1 1a 1 -
3 (

*(4+5) ) 1e 2 <empty>

(4+5) * 1c 2 *

4+5) ( 1d 2 (
*

+5) 4 1a 4 (
2 *

5) + 1b 4 +
2 (
*

) 5 1a 5 +
4 (
2 *
<empty> ) 1e 9 *
2

<empty> <empty> 2 18 <empty>

<empty> <empty> <end> 18 <empty>

● Write a Java method that returns the resultant value of an infix expression given as a
string. You can assume that the given expression is syntactically correct. The header
of your method should be:
public static int evaluateInfix(String expression)
The following instructions:
System.out.println(evaluateInfix("5+((1+2)*4)−3"));
System.out.println(evaluateInfix("(3-1)*(4+5)");
should output to the console:
14
18

Shunting-yard algorithm: converting infix to postfix


The shunting-yard algorithm is a method for parsing expressions from infix notation to postfix
notation. Infix notation is the notation commonly used in mathematical expressions. Postfix
notation or Reverse Polish Notation (RPN) was invented in the 1950s to reduce computer
memory access.

The infix expression 5 + ( ( 1 + 2 ) * 4 ) − 3 is equivalent to the postfix expression 5 1 2 + 4 * +


3 − . Note that the postfix equivalent does not need to be parenthesised, which leads to
faster calculations.

For simplicity, assume that the operands are positive integers and the operators are from the
following list: + - * / ( )

The shunting-yard algorithm proceeds in two phases:

● Phase 1: scanning the expression


a. If the extracted token is an operand, push it to the output string
b. If the extracted token is a + or - operator, repeatedly pop the operators + -
* / from the top of the stack and push them onto the output string then push
the extracted token to the top of the stack
c. If the extracted token is a * or / operator, repeatedly pop the operators * /
from the top of stack and push them to the output string then push the
extracted token to the top of the stack
d. If the extracted token is a ( symbol - left parenthesis - push it onto the stack
e. If the extracted token is a ) symbol - right parenthesis - repeatedly pop the
operators + - * / from the top of the stack and push it to the output string
until popping the ( symbol - left parenthesis - from the top of the operators
stack; do not append the ( symbol - left parenthesis - into the output string
● Phase 2: clearing the stack
a. Pop the operators + - * / from the top of the stack onto the output string
until the stack is empty.

Note that Phase 2 could be replaced by a Phase 0 where a ( symbol - left parenthesis - is
added at the start of the expression and a ) symbol - right parenthesis - is added at the end
of the expression.

This algorithm is illustrated below on the infix expression: 5 + ( ( 1 + 2 ) * 4 ) - 3

infix token phase stack postfix

5+((1+2)*4)-3 <empty> <start> <empty> <empty>

(5+((1+2)*4)-3) <empty> 0 <empty> <empty>

5+((1+2)*4)-3) ( 1d ( <empty>

+((1+2)*4)-3) 5 1a ( 5

((1+2)*4)-3) + 1b + 5
(

(1+2)*4)-3) ( 1d ( 5
+
(

1+2)*4)-3) ( 1d ( 5
(
+
(

+2)*4)-3) 1 1a ( 1
( 5
+
(

2)*4)-3) + 1b + 1
( 5
(
+
(

)*4)-3) 2 1a + 2
( 1
( 5
+
(

*4)-3) ) 1e ( +
+ 2
( 1
5

4)-3) * 1c * +
( 2
+ 1
( 5

)-3) 4 1a * 4
( +
+ 2
( 1
5

-3) ) 1e + *
( 4
+
2
1
5

3) - 1b - *
( 4
+
2
1
5

) 3 1a - 3
( *
4
+
2
1
5

<empty> ) 1e <empty> -
3
*
4
+
2
1
5

<empty> <empty> <end> <empty> -


3
*
4
+
2
1
5

This algorithm is illustrated below on the infix expression: ( 3 - 1 ) * ( 4 + 5 )


Infix Token Phase Stack Postfix

(3-1)*(4+5) <empty> <start> <empty> <empty>

((3-1)*(4+5)) <empty> 0 <empty> <empty>

3-1)*(4+5)) ( 1d ( <empty>

-1)*(4+5)) ( 1d ( <empty>
(

1)*(4+5)) 3 1a ( 3
(

)*(4+5)) - 1b - 3
(
(

*(4+5)) 1 1a - 1
( 3
(

(4+5)) ) 1e ( -
1
3

4+5)) * 1c * -
( 1
3

+5)) ( 1d ( -
* 1
( 3

5)) 4 1a ( 4
* -
( 1
3

)) + 1b + 4
( -
* 1
( 3

) 5 1a + 5
( 4
* -
( 1
3

<empty> ) 1e * +
( 5
4
-
1
3

<empty> ) 1e <empty> *
+
5
4
-
1
3

<empty> <empty> 2 <empty> 31-4+*

<empty> <empty> <end> <empty> 31-4+*

● Write a Java method that returns the postfix equivalent of a given infix expression.
You can assume that the given expression is syntactically correct. The header of
your method should be:
public static String convertInfixToPostfix(String expression)
The following instructions:
System.out.println(convertInfixToPostfix("5+((1+2)*4)-3"));
System.out.println(convertInfixToPostfix("(3-1)*(4+5)");
should output to the console:
5 1 2 + 4 * + 3 -
3 1 - 4 + *

Evaluating expressions in postfix notation


An expression in postfix notation does not contain any parentheses. Hence, evaluating an
expression in postfix notation is fairly straightforward; the algorithm only uses one stack (to
store the operands) and proceeds in a single phase (the resultant value is at the top of the
stack once the expression has been scanned).

For simplicity, assume that the operands are positive integers and the operators are from the
following list: + - * /

● Phase 1: scanning the expression


a. If the extracted token is an operand, push it to the stack
b. If the extracted token is an operator, pop the first two values from the top of
the stack and apply the operator to them; push the result back onto the stack

This algorithm is illustrated below on the postfix expression: 5 1 2 + 4 * + 3 −

expression token phase operands

512+4*+3- <empty> <start> <empty>

12+4*+3- 5 1a 5
2+4*+3- 1 1a 1
5

+4*+3- 2 1a 2
1
5

4*+3- + 1b 3
5

*+3- 4 1a 4
3
5

+3- * 1b 12
5

3- + 1b 17

- 3 1a 3
17

<empty> - 1b 14

<empty> <empty> <end> <empty>

This algorithm is illustrated below on the postfix expression: 3 1 - 4 5 + *

expression token phase operands

31-45+* <empty> <start> <empty>

1-45+* 3 1a 3

-45+* 1 1a 1
3

45+* - 1b 2

5+* 4 1a 4
2

+* 5 1a 5
4
2

* + 1b 9
2

<empty> * 1c 18

<empty> <empty> <end> 18


● Write a Java method that returns the resultant value of a postfix expression given as
a string. You can assume that the given expression is syntactically correct. The
header of your method should be:
public static int evaluatePostfix(String expression)
The following instructions:
System.out.println(evaluatePostfix("5 1 2 + 4 * + 3 -"));
System.out.println(evaluatePostfix("3 1 - 4 5 + *"));
should output to the console:
14
18

Running recursive processes: factorial


Recall that the factorial can be recursively defined as follow: factorial(n) = n *
factorial(n-1) for n > 0 and factorial(0) = 1

● Write a recursive Java method that returns a stack whose elements are the
successive steps of the recursive calculation of the factorial of a given number. The
header of your method should be:
public static Stack<String> traceFactorial(int number)
The following instructions:
printStack(traceFactorial(5));
should output to the console:
factorial(5) = 5 * factorial(5-1)
factorial(4) = 4 * factorial(4-1)
factorial(3) = 3 * factorial(3-1)
factorial(2) = 2 * factorial(2-1)
factorial(1) = 1 * factorial(1-1)
factorial(0) = 1

● Add a comment to your traceFactorial method to explain why the result does not
need to be reversed before to be printed.

The algorithm to evaluate expressions in infix notation can be modified to handle the factorial
function (cf. modifications in red below).

For simplicity, assume that the operands are positive integers and the operators are from the
following list: + - * / ( ) factorial

● Phase 0: preparing the expression


a. Initialise the expression to "factorial(" + number + ")" where the
parameter number is given

● Phase 1: scanning the expression


a. If the extracted token is an operand, push it to the operands stack
b. If the extracted token is a + or - operator, repeatedly process the + - * /
operators at the top of the operators stack (if any) then push the extracted
operator to the operators stack
c. If the extracted token is a * or / operator, repeatedly process the * /
operators at the top of the operators stack (if any) then push the extracted
operator to the operators stack
d. If the extracted token is a ( symbol - left parenthesis - push it to the
operators stack
e. If the extracted token is a ) symbol - right parenthesis - repeatedly process all
the + - * / operators at the top of the operators stack until popping a
( symbol - left parenthesis - from the top the operators stack
f. If the ( symbol - left parenthesis - at the top of the stack in step (e) is followed
by the token factorial, pop the element from the top the operands stack
and add the definition of its factorial at the beginning of the expression
g. If the extracted token is factorial, push it to the operators stack

● Phase 2: clearing the stacks


a. repeatedly process the + - * / operators at the top of operators stack
until operators stack is empty

This algorithm is illustrated below on the following calculation: factorial(3)

expression token phase operands operators

<empty> <empty> <start> <empty> <empty>

factorial(3) <empty> 0 <empty> <empty>

(3) factorial 1g <empty> factorial

3) ( 1d <empty> (
factorial

) 3 1a 3 (
factorial

<empty> ) 1e 3 factorial

3*factorial(3-1) <empty> 1f <empty> <empty>

*factorial(3-1) 3 1a 3 <empty>

factorial(3-1) * 1c 3 *

(3-1) factorial 1g 3 factorial


*

3-1) ( 1d 3 (
factorial
*
-1) 3 1a 3 (
3 factorial
*

1) - 1b 3 -
3 (
factorial
*

) 1 1a 1 -
3 (
3 factorial
*

<empty> ) 1e 2 factorial
3 *

factorial(2) <empty> 1f 3 *

(2) factorial 1g 3 factorial


*

2) ( 1d 3 (
factorial
*

) 2 1a 2 (
3 factorial
*

<empty> ) 1e 2 factorial
3 *

2*factorial(2-1) <empty> 1f 3 *

*factorial(2-1) 2 1a 2 *
3

factorial(2-1) * 1c 2 *
3 *

(2-1) factorial 1g 2 factorial


3 *
*

2-1) ( 1d 2 (
3 factorial
*
*

-1) 2 1d 2 (
2 factorial
3 *
*

1) - 1b 2 -
2 (
3 factorial
*
*

) 1 1a 1 -
2 (
2 factorial
3 *
*

<empty> ) 1e 1 factorial
2 *
3 *

1*factorial(1-1) <empty> 1f 2 *
3 *

(1-1) factorial 1g 2 factorial


3 *
*

1-1) ( 1d 2 (
3 factorial
*
*

-1) 1 1a 1 (
2 factorial
3 *
*

1) - 1b 1 -
2 (
3 factorial
*
*

) 1 1a 1 -
1 (
2 factorial
3 *
*

<empty> ) 1e 0 factorial
2 *
3 *

1 <empty> 1g 2 *
3 *

<empty> 1 1a 1 *
2 *
3
<empty> <empty> 2 2 *
3

<empty> <empty> 2 6 <empty>

<empty> <empty> <end> 6 <empty>

● Write a Java method that implements the algorithm described above to calculate the
factorial of a given number using stacks. The header of your method should be:
public static in stackFactorial(int number)
The following instructions:
System.out.println(stackFactorial(5));
should output to the console:
120

Running recursive processes: Fibonacci


Recall that the Fibonacci numbers can be recursively defined as follow: fibonacci(n) =
fibonacci(n-1) + fibonacci(n-2) for n > 2 and fibonacci(1) =
fibonacci(2) = 1.

● Write a recursive Java method that returns a stack whose elements are the
successive steps of the calculation the Fibonacci number of a given rank. The header
of your method should be:
public static Stack<Object> traceFibonacci(int rank)
The following instructions:
printStack(traceFibonacci(5));
should output to the console:
fibonacci(5) = fibonacci(5-1) + fibonacci(5-2)
fibonacci(4) = fibonacci(4-1) + fibonacci(4-2)
fibonacci(3) = fibonacci(3-1) + fibonacci(3-2)
fibonacci(2) = 1
fibonacci(1) = 1
fibonacci(2) = 1
fibonacci(3) = fibonacci(3-1) + fibonacci(3-2)
fibonacci(2) = 1
fibonacci(1) = 1

● Add a comment to your traceFibonacci method to explain why the return type
Stack<Object> is instead of Stack<String>.

The algorithm to evaluate expressions in infix notation can be modified to handle the
Fibonacci numbers (cf. modifications in red below).

For simplicity, assume that the operands are positive integers and the operators are from the
following list: + - * / ( ) fibonacci

● Phase 0: preparing the expression


a. Initialise the expression to "fibonacci(" + rank + ")" where the
parameter rank is given

● Phase 1: scanning the expression


a. If the extracted token is an operand, push it to the operands stack
b. If the extracted token is a + or - operator, repeatedly process the + - * /
operators at the top of the operators stack (if any) then push the extracted
operator to the operators stack
c. If the extracted token is a * or / operator, repeatedly process the * /
operators at the top of the operators stack (if any) then push the extracted
operator to the operators stack
d. If the extracted token is a ( symbol - left parenthesis - push it to the
operators stack
e. If the extracted token is a ) symbol - right parenthesis - repeatedly process all
the + - * / operators at the top of the operators stack until popping a
( symbol - left parenthesis - from the operators stack
f. If the ( symbol - left parenthesis - at the top of the stack in step (e) is followed
by the token fibonacci, add the definition of the Fibonacci number whose
rank is popped from the top of the operators stack
g. If the extracted token is fibonacci, push it to the operators stack

● Phase 2: clearing the stacks


a. repeatedly process the + - * / operators at the top of operators stack
until operators stack is empty

This algorithm is illustrated below on the following calculation: fibonacci(4)

expression token phase operands operators

<empty> <empty> <start> <empty> <empty>

fibonacci(4) <empty> 0 <empty> <empty>

(4) fibonacci 1g <empty> fibonacci

4) ( 1d <empty> (
fibonacci

) 4 1a 4 (
fibonacci

<empty> ) 1e 4 fibonacci

fibonacci(4-1) <empty> 1f <empty> <empty>


+fibonacci(4-2)

(4-1) fibonacci 1g <empty> fibonacci


+fibonacci(4-2)
4-1) ( 1d <empty> (
+fibonacci(4-2) fibonacci

-1) 4 1a 4 (
+fibonacci(4-2) fibonacci

1) - 1b 4 -
+fibonacci(4-2) (
fibonacci

) 1 1a 1 -
+fibonacci(4-2) 4 (
fibonacci

+fibonacci(4-2) ) 1e 3 fibonacci

fibonacci(3-1) <empty> 1f <empty> <empty>


+fibonacci(3-2)
+fibonacci(4-2)

(3-1) fibonacci 1g <empty> fibonacci


+fibonacci(3-2)
+fibonacci(4-2)

3-1) ( 1d <empty> (
+fibonacci(3-2) fibonacci
+fibonacci(4-2)

-1) 3 1a 3 (
+fibonacci(3-2) fibonacci
+fibonacci(4-2)

1) - 1c 3 -
+fibonacci(3-2) (
+fibonacci(4-2) fibonacci

) 1 1a 1 -
+fibonacci(3-2) 3 (
+fibonacci(4-2) fibonacci

+fibonacci(3-2) ) 1e 2 fibonacci
+fibonacci(4-2)

1 <empty> 1f <empty> <empty>


+fibonacci(3-2)
+fibonacci(4-2)

+fibonacci(3-2) 1 1a 1 <empty>
+fibonacci(4-2)

fibonacci(3-2) + 1c 1 +
+fibonacci(4-2)

(3-2) fibonacci 1g 1 fibonacci


+fibonacci(4-2) +
3-2) ( 1d 1 (
+fibonacci(4-2) fibonacci
+

-2) 3 1a 3 (
+fibonacci(4-2) 1 fibonacci
+

2) - 1c 3 -
+fibonacci(4-2) 1 (
fibonacci
+

) 2 1a 2 -
+fibonacci(4-2) 3 (
1 fibonacci
+

+fibonacci(4-2) ) 1e 1 fibonacci
1 +

1 <empty> 1f 1 +
+fibonacci(4-2) 1

+fibonacci(4-2) 1 1a 1 +
1

fibonacci(4-2) + 1b 1 +
1 +

(4-2) fibonacci 1g 1 fibonacci


1 +
+

4-2) ( 1d 1 (
1 fibonacci
+
+

-2) 4 1a 4 (
1 fibonacci
1 +
+

2) - 1c 4 -
1 (
1 fibonacci
+
+

) 2 1a 2 -
4 (
1 fibonacci
1 +
+
<empty> ) 1e 2 fibonacci
1 +
1 +

1 <empty> 1f 1 +
1 +

<empty> 1 1a 1 +
1 +
1

<empty> <empty> 2 2 +
1

<empty> <empty> 2 3 <empty>

<empty> <empty> <end> 3 <empty>

● Write a Java method that implements the algorithm described above to calculate the
Fibonacci number of a given rank using stacks. The header of your method should
be:
public static in stackFibonacci(int number)
The following instructions:
System.out.println(stackFibonacci(5));
should output to the console:
5

Running recursive processes: reversing the digit of a number


Recall that you can use tail recursion to reverse the digits of a number as follow:
reverse(from) = reverse(from,0) where the parameter from is given and
reverse(from,into) = reverse(from/10,into*10+from%10) for from > 0 and
reverse(0,into) = into

● Write a recursive Java method that returns a stack whose elements are the
successive steps of the calculation to reverse the digits of a given number. The
header of your method should be:
public static Stack<String> traceReverse(int number)
The following instructions:
printStack(traceReverse(1234));
should output to the console:
reverse(12345,0 ) = reverse(12345/10,0 *10+12345%10)
reverse(1234 ,5 ) = reverse(1234 /10,5 *10+1234 %10)
reverse(123 ,54 ) = reverse(123 /10,54 *10+123 %10)
reverse(12 ,543 ) = reverse(12 /10,543 *10+12 %10)
reverse(1 ,5432 ) = reverse(1 /10,5432 *10+1 %10)
reverse(0 ,54321) = 54321

The algorithm to evaluate expressions in infix notation can be modified to handle reversing
digits (cf. modifications in red below).
For simplicity, assume that the operands are positive integers and the operators are from the
following list: + - * / % , ( ) reverse

● Phase 0: preparing the expression


a. Initialise the expression to "reverse(" + number + ",0)" where the
parameter number is given

● Phase 1: scanning the expression


a. If the extracted token is an operand, push it to the operands stack
b. If the extracted token is a + or - operator, repeatedly process the + - * /
operators at the top of the operators stack (if any) then push the extracted
operator to the operators stack
c. If the extracted token is a * or / or % operator, repeatedly process the * / %
operators at the top of the operators stack (if any) then push the extracted
operator to the operators stack
d. If the extracted token is a ( symbol - left parenthesis - push it to the
operators stack
e. If the extracted token is a ) symbol - right parenthesis - repeatedly process all
the + - * / % operators at the top of the operators stack until popping a (
symbol - left parenthesis - from the top the operators stack
f. If the ( symbol - left parenthesis - at the top of the stack in step (e) is followed
by the token reverse, add the definition of the recursive call to the reverse
function applied to the first two elements popped from the top of the
operands stack
g. If the extracted token is reverse, push it to the operators stack
h. If the extracted token is the , symbol - comma - repeatedly process all the +
- * / % operators at the top of the operators stack until seeing a (
symbol - left parenthesis - at the top the stack; do not pop the ( symbol - left
parenthesis - from the top the operators stack

● Phase 2: clearing the stacks


a. repeatedly process the + - * / % operators at the top of operators stack
until operators stack is empty

This algorithm is illustrated below on the following calculation: reverse(12)

expression token phase operands operators

<empty> <empty> <start> <empty> <empty>

reverse(12,0) <empty> 0 <empty> <empty>

(12,0) reverse 1g <empty> reverse

12,0) ( 1d <empty> (
reverse

,0) 12 1a 12 (
reverse

0) , 1h 12 (
reverse

) 0 1a 0 (
12 reverse

<empty> ) 1e 0 reverse
12

reverse(12/10,0 <empty> 1f <empty> <empty>


*10+12%10)

(12/10,0*10+12 reverse 1g <empty> reverse


%10)

12/10,0*10+12 ( 1d <empty> (
%10) reverse

/ 12 1a 12 (
10,0*10+12%10 reverse
)

10,0*10+12%10 / 1c 12 /
) (
reverse

,0*10+12%10) 10 1a 10 /
12 (
reverse

0*10+12%10) , 1h 1 (
reverse

*10+12%10) 0 1a 0 (
1 reverse

10+12%10) * 1c 0 *
1 (
reverse

+12%10) 10 1a 10 *
0 (
1 reverse

12%10) + 1b 10 *
0 (
1 reverse

12%10) + 1b 0 (
1 reverse
12%10) + 1b 0 +
1 (
reverse

%10) 12 1a 12 +
0 (
1 reverse

10) % 1c 12 %
0 +
1 (
reverse

) 10 1a 10 %
12 +
0 (
1 reverse

<empty> ) 1e 10 %
12 +
0 (
1 reverse

<empty> ) 1e 2 +
0 (
1 reverse

<empty> ) 1e 2 (
1 reverse

<empty> ) 1e 2 reverse
1

reverse(1/10,2* <empty> 1f <empty> <empty>


10+1%10)

(1/10,2*10+1%1 reverse 1g <empty> reverse


0)

1/10,2*10+1%1 ( 1d <empty> (
0) reverse

/10,2*10+1%10) 1 1a 1 (
reverse

10,2*10+1%10) / 1c 1 /
(
reverse

,2*10+1%10) 10 1a 10 /
1 (
reverse

2*10+1%10) , 1h 0 (
reverse
*10+1%10) 2 1a 2 (
0 reverse

10+1%10) * 1c 2 *
0 (
reverse

+1%10) 10 1a 10 *
2 (
0 reverse

1%10) + 1b 20 +
0 (
reverse

%10) 1 1a 1 +
20 (
0 reverse

10) % 1c 1 %
20 +
0 (
reverse

) 10 1a 10 %
1 +
20 (
0 reverse

<empty> ) 1e 1 +
20 (
0 reverse

<empty> ) 1e 21 (
0 reverse

<empty> ) 1e 21 reverse
0

21 <empty> 1f <empty> reverse

<empty> 21 1a 21 <empty>

<empty> <empty> <end> 21 <empty>

● Write a Java method that implements the algorithm described above to calculate the
reverse of a given number using stacks. The header of your method should be:
public static in stackReverse(int number)
The following instructions:
System.out.println(stackReverse(12345));
should output to the console:
54321
Introduction to queues
● Add the following instructions to the main() method of your
AbstractDataStructure class.

main()

Queue<Integer> queueOfIntegers = new LinkedList<>();


Queue<Double> queueOfDoubles = new LinkedList<>();
Queue<Character> queueOfCharacters = new LinkedList<>();
Queue<String> queueOfStrings = new LinkedList<>();
Queue<int[]> queueOfArrays = new LinkedList<>();
Queue<Object> queueOfObjects = new LinkedList<>();
Queue queueOfUnspecifiedTypes = new LinkedList();

● Add the usingQueues() method to your AbstractDataStructure class.

usingQueues()

public static void usingQueues()


{
Queue<String> queueOfStrings = new LinkedList<>();
queueOfStrings.offer("Bonjour!");
queueOfStrings.offer("Comment");
queueOfStrings.offer("allez-vous?");
//printing the elements of a stack
while(queueOfStrings.size()>0)
{
System.out.println(queueOfStrings.remove());
}
}

● Run the usingQueues() method.

● Add a comment to your program to explain the output.

In this Introduction to queues section, your methods should only use the following methods
of the java.util.LinkedList class:
● remove()
● offer()
● size()

Checking if a queue is empty


● Write a Java method that returns true if the queue given is empty and false
otherwise. The header of your method should be:
public static boolean isEmptyQueue(
Queue queueOfUnspecifiedTypes)
The following instructions:
queueOfUnspecifiedTypes.offer("something");
System.out.println(isEmptyQueue(queueOfUnspecifiedTypes));
queueOfUnspecifiedTypes.remove();
System.out.println(isEmptyQueue(queueOfUnspecifiedTypes));
should output to the console:
false
true

Printing the elements of a queue


● Write a Java method that outputs the elements of a given queue to the terminal. The
header of your method should be:
public static void printQueue(Queue queueOfUnspecifiedTypes)
The following instructions:
for(int element=1; element<10; element++)
{
queueOfDoubles.offer(Math.sqrt(element));
}
printQueue(queueOfDoubles);
printQueue(queueOfDoubles);
should output to the console:
1.0
1.4142135623730951
1.7320508075688772
2.0
2.23606797749979
2.449489742783178
2.6457513110645907
2.8284271247461903
3.0

● Add a comment to your program to explain why the above instructions do not print
the elements of the queue twice.

Counting the number of elements in a queue


Your countQueue() method should not use of the size() method of the
java.util.Queue interface.

● Write a Java method that returns the number of elements of a given queue. The
header of your method should be:
public static int countQueue(Queue queueOfUnspecifiedTypes)
The following instructions:
for(int element=1; element<10; element++)
{
queueOfIntegers.offer(element);
}
System.out.println(countQueue(queueOfIntegers));
should output to the console:
9

Calculating the sum of the elements in a queue


● Write a Java method that returns the sum of the elements of a given queue. Your
method should return 0 if the given queue is empty. The header of your method
should be:
public static int sumQueue(Queue<Integer> queueOfIntegers)
The following instructions:
for(int element=1; element<10; element++)
{
queueOfIntegers.offer(element);
}
System.out.println(sumQueue(queueOfIntegers));
should output to the console:
45

Finding the maximum of a queue


● Write a Java method that finds the maximum element of a given stack. The header of
your method should be:
public static int maximumQueue(
Queue<Integer> queueOfIntegers)
The following instructions:
for(int element=1; element<10; element++)
{
queueOfIntegers.offer(element);
}
System.out.println(maximumQueue(queueOfIntegers));
should output to the console:
9

Getting an element from a queue


Your getQueue() method should not use of the elementAt() method of the
java.util.Queue interface.

● Write a Java method that returns the element of a queue that is at a given index. By
convention, the index of the first element of a queue is 0 (same convention as for
arrays). If the index exceeds the number of elements of the given queue, your
method should return an empty object. The header of your method should be:
public static Object getQueue(
int index,
Queue<Object> queueOfObjects)
The following instructions:
for(int element=1; element<10; element++)
{
queueOfObjects.offer(element);
}
System.out.println(getQueue(1,queueOfObjects));
queueOfObjects.clear();//empty queueOfObjects
should output to the console:
2

Searching an element in a queue


Your searchQueue() method should not use of the contains() method of the
java.util.Queue interface.

● Write a Java method that searches for a given element in a given queue. By
convention, the index of the first element of a queue is 0 (same convention as for
arrays). If the element is not found, your method should return -1. The header of
your method should be:
public static int searchQueue(
Object element,
Queue<Object> queueOfObjects)
The following instructions:
queueOfObjects.offer("A");
queueOfObjects.offer("B");
queueOfObjects.offer("C");
System.out.println(searchQueue("A",queueOfObjects));
System.out.println(searchQueue("A",queueOfObjects));
should output to the console:
0
-1

● Add a comment to your searchQueue() method to explain why the same


instruction on the same variables does not return the same value.

Peeking at the first element of a queue


Your peekQueue() method should not use of the peek() method of the
java.util.Queue interface.

● Write a Java method that returns the first element of a queue without changing the
given queue. Your method should return an empty object if the given queue is empty.
The header of your method should be:
public static Object peekQueue(PriorityQueue<Object> queueOfObjects)
The following instructions:
queueOfObjects.offer("A");
queueOfObjects.offer("B");
queueOfObjects.offer("C");
System.out.println(peekQueue(queueOfObjects));
printQueue(queueOfObjects);
should output to the console:
A
A
B
C

Reversing the elements of a queue


●Write a Java method that returns a new queue whose elements are in reverse order
of the elements of a given queue. The header of your method should be:
public static PriorityQueue<Object> reverseQueue(
Queue<Object> queueOfObjects)
The following instructions:
queueOfObjects.offer("allez-vous?");
queueOfObjects.offer("Comment");
queueOfObjects.offer("Bonjour!");
printQueue(reverseQueue(queueOfObjects));
should output to the console:
Bonjour!
Comment
allez-vous?

Comparing two queues


Your compareQueue() method should not use of the equal() method of the
java.util.Queue interface.

●Write a Java method that returns true if the two given queues are equal and false
otherwise (two queues are equal if they have the same number of elements and their
respective elements are equal). The header of your method should be:
public static boolean compareQueue(
Queue<Object> queue1,
Queue<Object> queue2)
The following instructions:
Queue<Object> queue1 = new LinkedList<>();
Queue<Object> queue2 = new LinkedList<>();
queue1.offer("A");
queue1.offer("B");
queue1.offer("C");
queue2.offer("A");
queue2.offer("B");
queue2.offer("C");
System.out.println(compareQueue(queue1,queue2));
queue1.offer("A");
queue1.offer("B");
queue1.offer("C");
queue1.offer("D");
queue2.offer("A");
queue2.offer("B");
queue2.offer("C");
System.out.println(compareQueue(queue1,queue2));
should output to the console:
true
false

Swapping the first two elements of a queue


● Write a Java method that returns a queue for which the position of the first two
elements are swapped. If the given queue contains fewer than two elements, your
method should return the given queue unchanged. The header of your method
should be:
public static Queue<Object> swapQueue(
Queue<Object> queueOfObjects)
The following instructions:
queueOfObjects.offer("A");
queueOfObjects.offer("B");
printQueue(queueOfObjects);
System.out.println("=>");
queueOfObjects.offer("A");
queueOfObjects.offer("B");
printQueue(swapQueue(queueOfObjects));
should output to the console:
A
B
=>
B
A

Rotating the first three elements of a queue


● Write a Java method that return a queue for which the position of the first three
elements are rotated. If the given stack contains fewer than three elements, your
method should return the given queue unchanged. The header of your method
should be:
public static Queue<Object> rotateQueue(
Queue<Object> queueOfObjects)
The following instructions:
queueOfObjects.offer("A");
queueOfObjects.offer("B");
queueOfObjects.offer("C");
queueOfObjects.offer("D");
printQueue(queueOfObjects);
System.out.println("=>");
queueOfObjects.offer("A");
queueOfObjects.offer("B");
queueOfObjects.offer("C");
queueOfObjects.offer("D");
printQueue(rotateQueue(queueOfObjects));
should output to the console:
A
B
C
D
=>
C
A
B
D

Inserting an element in a queue


Your insertQueue() method should not use of the insertElementAt() method of the
java.util.Queue interface.

● Write a Java method that returns a queue with a given element inserted at a given
index. By convention, the index of the first element of a queue is 0 (same convention
as for arrays). If the given index exceeds the number of elements in the given queue,
your method should return the given queue unchanged. The header of your method
should be:
public static Queue<Object> insertQueue(
Object element,
int index,
Queue<Object> queueOfObjects)
The following instructions:
queueOfObjects.offer("A");
queueOfObjects.offer("B");
queueOfObjects.offer("C");
printQueue(insertQueue("D",1,queueOfObjects));
should output to the console:
A
D
B
C

Applications of queues

Load balancing
A service provider has 4 counters labelled A, B, C, D to assist its customers. New customers
are directed to the counter with the least number of requests. New requests are issued with
a reference number (ticket) that specifies which counter to go to (A, B, C, D) as well as the
order of arrival at the counter.
● Write a Java methods that returns a queue of reference numbers (tickets) given a
number of customer requests. The header of your method should be:
public static Queue<String> loadBalanceCustomer(
int numberOfRequests)
The following instructions:
Queue<String> tickets = loadBalanceCustomer(9);
int customer = 0;
while( tickets.size() > 0 )
{
customer++;
System.out.println("Customer "
+ customer
+ " has ticket "
+ tickets.remove());
}
should output to the console:
Customer 1 has ticket A-1
Customer 2 has ticket B-1
Customer 3 has ticket C-1
Customer 4 has ticket D-1
Customer 5 has ticket A-2
Customer 6 has ticket B-2
Customer 7 has ticket C-2
Customer 8 has ticket D-2
Customer 9 has ticket A-3

Streaming
To improve efficiency, the service provider decides to direct its customers to different
counters depending on the nature of their requests. Requests are categorised by the letters
A, B, C, D and are dealt with by the counter that is labelled with the same letter. New
requests are issued with a reference number (ticket) that includes the type of request (A, B,
C, D) and the order of arrival at the counter. For example, A-1, A-2, etc… B-1, B-2, etc... C-
1, C-2, etc… D-1, D-2, etc… Incoming requests are stored in a queue.

● Write a Java methods that returns a queue of reference numbers (tickets) given a
queue of customer requests. The order of the reference numbers should match the
order of the customer requests. The header of your method should be:
public static Queue<String> streamCustomer(
Queue<Character> requests)
The following instructions:
PriorityQueue<Character> requests = new PriorityQueue<>();
requests.offer('A'); //1st customer
requests.offer('B'); //2nd customer
requests.offer('C'); //3rd customer
requests.offer('B'); //4th customer
requests.offer('D'); //5th customer
requests.offer('C'); //6th customer
requests.offer('A'); //7th customer
requests.offer('C'); //8th customer
requests.offer('D'); //9th customer
int customer = 0;
PriorityQueue<String> tickets = streamCustomer(requests);
while( tickets.size() > 0 )
{
customer++;
System.out.println("Customer "
+ customer
+ " has ticket "
+ tickets.remove());
}
should output to the console:
Customer 1 has ticket A-1
Customer 2 has ticket B-1
Customer 3 has ticket C-1
Customer 4 has ticket B-2
Customer 5 has ticket D-1
Customer 6 has ticket C-2
Customer 7 has ticket A-2
Customer 8 has ticket C-3
Customer 9 has ticket D-2

Ticketing
To respond to increasing number of customer requests, the service company decides to
open additional counters. There are now 5 counters for each type of requests (20 counters in
total) that are labelled A1, A2, … , A5; B1, B2, … , B5; C1, C2, … , C5; D1, D2, … , D5. New
requests are directed to the relevant counter with the least number of issued tickets.

● Write a Java methods that returns a queue of reference numbers (tickets) given a
queue of customer requests. The order of the reference numbers should match the
order of the customer requests. The header of your method should be:
public static Queue<String> issueTickets(
Queue<Character> requests)
The following instructions:
Queue<Character> requests = new LinkedList<>();
requests.offer('A'); //1st customer
requests.offer('A'); //2nd customer
requests.offer('A'); //3rd customer
requests.offer('A'); //4th customer
requests.offer('A'); //5th customer
requests.offer('A'); //6th customer
requests.offer('A'); //7th customer
requests.offer('A'); //8th customer
requests.offer('A'); //9th customer
int customer = 0;
Queue<String> tickets = issueTickets(requests);
while(tickets.size()>0)
{
customer++;
System.out.println("Customer "
+ customer
+ " has ticket "
+ tickets.remove());
}
should output to the console:
Customer 1 has ticket A1-1
Customer 2 has ticket A2-1
Customer 3 has ticket A3-1
Customer 4 has ticket A4-1
Customer 5 has ticket A5-1
Customer 6 has ticket A1-2
Customer 7 has ticket A2-2
Customer 8 has ticket A3-2
Customer 9 has ticket A4-2

Implementing stacks and queues using dynamic list structures

Stacks
● Write a Java class that implements a queue structure using LinkedList according
to the specifications of the UML diagram below.

MyQueue<E>

-list: java.util.LinkedList<E>

+push(e: E): void


+pop(): E
+isEmpty(): boolean

Queues
● Write a Java class that implements a queue structure using LinkedList according
to the specifications of the UML diagram below.

MyQueue<E>
-list: java.util.LinkedList<E>

+enqueue(e: E): void


+dequeue(): E
+isEmpty(): boolean

Implementing a linked list structure


● Use the design guide outlined below to implement a dynamic list structure in Java.

Interface
MyList defines a common interface for MyAbstractList, MyArrayList, and
MyLinkedList by defining the skeletal implementation of the following methods:
● Appends a new element at the end of this list.
● Inserts a new element at the specified index in this list.
● Removes all the elements from this list.
● Returns true if this list contains the specified element.
● Returns the element from this list at the specified index.
● Returns the index of the first matching element in this list.
● Returns true if this list does not contain any elements.
● Returns the index of the last matching element in this list.
● Removes the element from this list.
● Returns the number of elements in this list.
● Removes the element at the specified index and returns the removed element.
● Sets the element at the specified index and returns the element being replaced.

Abstract class
MyAbstractList declares variable size to indicate the number of elements in the list. In
addition, it provides the following methods:
● Creates a default list.
● Creates a list from an array of objects.
● Implements the add method.
● Implements the isEmpty method.
● Implements the size method.
● Implements the remove method.

Concrete class using array


MyArrayList uses an array to implement a dynamic list. It extends MyAbstractList. In
addition, it provides the following methods:
● Creates a default array list.
● Creates an array list from an array of objects.
● Trims the capacity of this array list to the list’s current size.
● Doubles the current array size if needed.
● Throws an exception if the index is out of bounds in the list.

The following instructions:


MyList<String> list = new MyArrayList<String>();
list.add("America");
System.out.println("(1) " + list);
list.add(0, "Canada");
System.out.println("(2) " + list);
list.add("Russia");
System.out.println("(3) " + list);
list.add("France");
System.out.println("(4) " + list);
list.add(2, "Germany");
System.out.println("(5) " + list);
list.add(5, "Norway");
System.out.println("(6) " + list);
list.remove("Canada");
System.out.println("(7) " + list);
list.remove(2);
System.out.println("(8) " + list);
list.remove(list.size() - 1);
System.out.print("(9) " + list + "\n(0) ");
for (String s: list) System.out.print(s.toUpperCase() + " ");
should output to the terminal:
(1) [America]
(2) [Canada, America]
(3) [Canada, America, Russia]
(4) [Canada, America, Russia, France]
(5) [Canada, America, Germany, Russia, France]
(6) [Canada, America, Germany, Russia, France, Norway]
(7) [America, Germany, Russia, France, Norway]
(8) [America, Germany, France, Norway]
(9) [America, Germany, France]
(0) AMERICA GERMANY FRANCE

Concrete class using linked structure


The MyLinkedList class uses a linked structure to implement a dynamic list. It extends
MyAbstractList. In addition, it provides the following methods:
● Creates a default linked list.
● Creates a linked list from an array of elements.
● Adds an element to the head of the list.
● Adds an element to the tail of the list.
● Returns the first element in the list.
● Returns the last element in the list.
● Removes the first element from the list.
● Removes the last element from the list.

The following instructions:


MyLinkedList<String> list = MyLinkedList<>();
list.add("America");
System.out.println("(01) " + list);
list.add(0, "Canada");
System.out.println("(02) " + list);
list.add("Russia");
System.out.println("(03) " + list);
list.addLast("France");
System.out.println("(04) " + list);
list.add(2, "Germany");
System.out.println("(05) " + list);
list.add(5, "Norway");
System.out.println("(06) " + list);
list.add(0, "Poland");
System.out.println("(07) " + list);
list.remove(0);
System.out.println("(08) " + list);
list.remove(2);
System.out.println("(09) " + list);
list.remove(list.size() - 1);
System.out.print("(10) " + list + "\n(11) ");
for (String s: list) System.out.print(s.toUpperCase() + " ");
should output to the terminal:
(01) [America]
(02) [Canada, America]
(03) [Canada, America, Russia]
(04) [Canada, America, Russia, France]
(05) [Canada, America, Germany, Russia, France]
(06) [Canada, America, Germany, Russia, France, Norway]
(07) [Poland, Canada, America, Germany, Russia, France, Norway]
(08) [Canada, America, Germany, Russia, France, Norway]
(09) [Canada, America, Russia, France, Norway]
(10) [Canada, America, Russia, France]
(11) CANADA AMERICA RUSSIA FRANCE
[ WORK IN PROGRESS ] Introduction to trees

Inorder tree traversal

Postorder tree traversal

Preorder tree traversal

[ WORK IN PROGRESS ] Applications of trees

Data compression

Miscellaneous
● Add a new class named Miscellaneous to your ComputationalChallenges
project and copy the code below. Make sure to personalise your preamble.

Miscellaneous

/**
* <Write a description here.>
* @author <firstname> <LASTNAME>
* @version <submission>.<modification>
* @date <yyyy>.<mm>.<dd>
*/

import java.util.*;
import java.lang.*;
import java.io.*;

public class Miscellaneous


{
public static void main (String[] args)
{
}
}

Basic algorithms on collections

Award of IB Diploma
The IB Diploma is awarded provided all the following requirements have been met:
1. CAS requirements have been met.
2. The total points are 24 or more.
3. There is no grade E awarded for theory of knowledge.
4. There is no grade E awarded for the extended essay.
5. There is no grade 1 awarded in a subject (HL or SL).
6. There are no more than two grade 2s awarded (HL or SL).
7. There are no more than three grade 3s or 2s awarded (HL or SL).
8. The candidate has gained 12 points or more on HL subjects (for candidates who
register for four HL subjects, the three highest grades count).
9. The candidate has gained 9 points or more on SL subjects (candidates who register
for two SL subjects must gain at least 5 points at SL).
10. The candidate has not received a penalty for academic misconduct from the Final
Award Committee.

The following matrix summarises the number of points earned from Theory of Knowledge
(ToK) and Extended Essay (EE).

ToK / EE A B C D E

A 3 3 2 2 Fail

B 3 2 2 1 Fail

C 2 2 1 0 Fail

D 2 1 0 0 Fail

E Fail Fail Fail Fail Fail

For your reference, the following grades boundaries were used in the May 2015 session.

Grade EE ToK ToK ToK


presentation essay final

A 29 - 36 19 - 20 28 - 40 46 - 60

B 23 - 28 16 - 18 22 - 27 37 - 45

C 16 - 22 13 - 15 16 - 21 28 - 36

D 8 - 15 9 - 12 9 - 15 17 - 27

E 0-7 0-8 0-8 0 - 16

● Write a Java method that:


○ returns true if a given set of results fulfils the requirements for the award of
the IB Diploma and false otherwise; as well as
○ outputs to the terminal the total number of points if the IB Diploma is awarded
and the list of conditions that have not been met otherwise.
The header of your method should be:
public static boolean isDiplomaAwarded(
boolean CAS, //true if CAS requirements are met
boolean FAW, //true if no penalty for academic dishonesty
char ToK, //grade for Theory of Knowledge
char EE, //grade for Extended Essay
int[] HL, //grades for HL subjects
int[] SL) //grades for SL subjects
The following instructions:
System.out.println("CANDIDATE 1");
int[] HL1 = new int[] {7,7,7};
int[] SL1 = new int[] {7,7,7};
System.out.println(isDiplomaAwarded(true,true,'A','A',HL1,SL1));
System.out.println("CANDIDATE 2");
int[] HL2 = new int[] {1,1,1};
int[] SL2 = new int[] {1,1,1};
System.out.println(isDiplomaAwarded(false,false,'E','E',HL2,SL2));
should output to the console:
CANDIDATE 1
- 45 points
true
CANDIDATE 2
1. CAS requirements not met
2. Total points less than 24
3. Grade E for theory of knowledge
4. Grade E for extended essay
5. Grade 1 awarded in a subject (HL or SL)
6. More than two grade 2s awarded (HL or SL)
7. More than three grade 3s or 2s awarded (HL or SL)
8. Fewer than 12 points gained on HL subjects
9. Fewer than 9 points gained on SL subjects
0. Penalty for academic misconduct
false

Student council elections


An election is held at school to elect a president for the student council. Candidates are
represented by a number starting from 1. Their names are stored in a corresponding array.

The students votes electronically and the numbers are entered into the collection. If any
candidates gets at least 50% of the votes, that person is elected, otherwise there is a second
vote between the two candidates with the highest number of votes.

● Write a Java method that outputs the vote count (as a numeral and a percentage) of
each candidate by decreasing number of votes followed bythe name of the winner or
the names of the two candidates in the next round. The header of your method
should be:
public static void getElectionResults(
String[] candidates,
ArrayList<Integer> votes)
The following instructions:
String[] candidates = new String[] {"A","B","C","D","E"};
int[] results = new int[candidates.length];
ArrayList<Integer> votes = new ArrayList<>();
//a second round is necessary
System.out.println("*** 1st test case");
results = new int[] {10,11,12,13,14};
for(int index=0; index<candidates.length; index++)
{
for(int result=0; result<results[index]; result++)
{
char candidate = candidates[index].charAt(0);
int alias = Character.getNumericValue(candidate)-9;
votes.add(alias);
}
}
getElectionResults(candidates,votes);
votes.clear();
//there is a majority winner
System.out.println("*** 2nd test case");
results = new int[] {9,1,1,1,1};
for(int index=0; index<candidates.length; index++)
{
for(int result=0; result<results[index]; result++)
{
char candidate = candidates[index].charAt(0);
int alias = Character.getNumericValue(candidate)-9;
votes.add(alias);
}
}
getElectionResults(candidates,votes);
should output to the console:
*** 1st test case
Candidate E has 14 votes (23%).
Candidate D has 13 votes (22%).
Candidate C has 12 votes (20%).
Candidate B has 11 votes (18%).
Candidate A has 10 votes (17%).
Candidate E and Candidate D move the next round.
*** 2nd test case
Candidate A has 9 votes (69%).
Candidate D has 1 votes ( 8%).
Candidate C has 1 votes ( 8%).
Candidate B has 1 votes ( 8%).
Candidate E has 1 votes ( 8%).
Candidate A has been elected.

● Add a comment to your method to explain the order in which the results of the 2nd
test case are printed.

[ WORK IN PROGRESS ] Euler’s house


● Find the number of possible ways to draw Euler’s house.

[ WORK IN PROGRESS ] Tic Tac Toe


● Write a Java programme to play Tic Tac Toe.

[ WORK IN PROGRESS ] Dynamical systems


● Find a numerical solution to the Predator-prey system.

You might also like