Skip to content

Commit

Permalink
Recursive Mathematics Assignment
Browse files Browse the repository at this point in the history
  • Loading branch information
hadiali6 committed Nov 28, 2023
1 parent cc79815 commit b05c37e
Show file tree
Hide file tree
Showing 2 changed files with 305 additions and 0 deletions.
148 changes: 148 additions & 0 deletions Assignment03/ExtraCredit.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
* The class is designed for extra credit
* The student implements the fibby method using iterative approach
* and then benchmark with their recursive approach to draw conclusion
* @author Varik Hoang <varikmp@uw.edu>
* @author Hadi Ali <hadi.ali@bellevuecollege.edu>
*/
public class ExtraCredit
{
/**
* The method accepts non-negative integer and returns a value as described below
* @param theDecimalNumber is a non-negative decimal number (n)
* @return the value in following way:
* - return 1 when n = 0
* - return sum of fibby(floor(n/4)) and fibby(floor(3n/4)) when n > 0
*/
public static int fibby(int theDecimalNumber) {
if (theDecimalNumber == 0) {
return 1;
}
int[] table = new int[theDecimalNumber + 1];
table[0] = 1;

for (int i = 1; i <= theDecimalNumber; ++i) {
int firstArg = i / 4;
int secondArg = (3 * i) / 4;
table[i] = table[firstArg] + table[secondArg];
}
return table[theDecimalNumber];
}

public static void main(String args[])
{
int[] dataset = new int[]
{
10, 25, 50, 75, 100, 125, 150, 175, 200, 225, 250, // small dataset
500, 1000, 1500, 2000, 2500, 5000, 7500, 10000, 12500, 15000, 17500, // medium dataset
25000, 50000, 75000, 100000, 200000, 500000, 1000000, 2000000 // large dataset
};

// sanity check the iterative fibby function
if (fibby(1000000) != MathematicsRec.fibby(1000000))
{
System.err.println("Please make sure your iterative fibby correct before doing the benchmark");
return;
}

long sum;
int count;
int attempts = 5;
setContent("iterative_fibby.txt", "");
setContent("recursive_fibby.txt", "");

// benchmarking
for (int value: dataset)
{
/**
* The iterative fibby
*/
fibby(value);

// start benchmarking for each value
sum = 0;
count = attempts;
while (count --> 0)
{
long startTime = System.nanoTime();
fibby(value);
long endTime = System.nanoTime();

// get the difference
sum += endTime - startTime;
}
// write out the execution time in nanoseconds (/1000000 in milliseconds)
appendContent("iterative_fibby.txt", (double) sum / attempts + "\n");

/**
* The recursive fibby
*/
MathematicsRec.fibby(value);

// start benchmarking for each value
sum = 0;
count = attempts;
while (count --> 0)
{
long startTime = System.nanoTime();
MathematicsRec.fibby(value);
long endTime = System.nanoTime();

// get the difference
sum += endTime - startTime;
}
// write out the execution time in nanoseconds (/1000000 in milliseconds)
appendContent("recursive_fibby.txt", (double) sum / attempts + "\n");
}
}

/**
* The method writes content to file (overwrite if file is existed)
* @param path the file along with the path
* @param content the content is written to file
*/
protected static void setContent(String path, String content) { setContent(new File(path), content); }
protected static void setContent(File file, String content)
{
BufferedWriter bw;

try
{
bw = new BufferedWriter(new FileWriter(file));
bw.write(content);
bw.flush();
bw.close();
}
catch (IOException ex) { System.err.println(ex.getMessage()); }
}

/**
* The method appends content to file (overwrite if file is existed)
* @param path the file along with the path
* @param content the content is appended to file
*/
protected static void appendContent(String path, String content) { appendContent(new File(path), content); }
protected static void appendContent(File file, String content)
{
FileOutputStream fos;

try
{
fos = new FileOutputStream(file, true);

FileChannel channel = fos.getChannel();
ByteBuffer buffer = ByteBuffer.wrap(content.getBytes("UTF-8"));
channel.write(buffer);
channel.close();
}
catch (IOException ex) { System.err.println(ex.getMessage()); }
}
}
157 changes: 157 additions & 0 deletions Assignment03/MathematicsRec.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/**
* The MathematicsRec class feature various methods that given number(s) perform different
* mathematical functions using only recursion.
* @author Hadi Ali <hadi.ali@bellevuecollege.edu>
*/
class MathematicsRec {
/**
* The method returns a value which:
* - Increases each of even decimal digits of n by one
* - Decreases each of odd decimal digits of n by one
* @param theDecimalNumber the input decimal number (n)
* @return the new decimal number after digit adjustments
*/
public static long eduodd(final long theDecimalNumber) {
if (theDecimalNumber == 0) {
return 1;
} else if (theDecimalNumber < 0) {
return -eduodd(-theDecimalNumber);
} else {
long lastDigit = theDecimalNumber % 10;
long remainingDigits = theDecimalNumber / 10;

if (lastDigit % 2 == 0) {
lastDigit += 1;
} else {
lastDigit -= 1;
}

if (remainingDigits == 0) {
return lastDigit;
}

return eduodd(remainingDigits) * 10 + lastDigit;
}
}

/**
* The method accepts non-negative integer and returns a value as described below
* @param theDecimalNumber is a non-negative decimal number (n)
* @return the value in following way:
* - return 1 when n = 0
* - return sum of fibby(floor(n/4)) and fibby(floor(3n/4)) when n > 0
*/
public static int fibby(final int theDecimalNumber) {
if (theDecimalNumber == 0) {
return 1;
}

int floorN4 = theDecimalNumber / 4;
int floor3N4 = (3 * theDecimalNumber) / 4;

return fibby(floorN4) + fibby(floor3N4);
}


/**
* The method calls a method that prints all consecutive values of n and its fibby value
* @param theLowerBound the lower bound (start)
* @param theUpperBound the upper bound (end)
*/

public static void stg(final int theLowerBound, final int theUpperBound) {
stg(theLowerBound, theUpperBound, -1);
}

/**
* The method that recursively prints all consecutive values of n and its fibby value
* @param theCurrentNumber the current number that is recursively iterated by +1 (lower bound)
* @param theUpperBound the upper bound (end)
* @param thePreviousFibby the previous number from the fibby() method
*/
private static void stg(final int theCurrentNumber, final int theUpperBound, final int thePreviousFibby) {
if (theCurrentNumber > theUpperBound) return;

int currentFib = fibby(theCurrentNumber);
if (currentFib != thePreviousFibby) {
System.out.println(theCurrentNumber + " " + currentFib);
}

stg(theCurrentNumber + 1, theUpperBound, currentFib);
}
/**
* The method returns the median that split the array into 3 parts
* @param theList the list of integers (a)
* @return the median of the list of integers
*/
public static double median3(final int[] theList) {
return median3Helper(theList, 0, theList.length - 1);
}

/**
* The method that recursively calculates the approximate median
* @param theList the list of integers (a)
* @param theLowerBound the lower bound (start)
* @param theUpperBound the upper bound (end)
* @return the median of the list of integers
*/
private static double median3Helper(final int[] theList, final int theLowerBound, final int theUpperBound) {
int length = theUpperBound - theLowerBound + 1;

if (length == 1) {
return theList[theLowerBound];
}
if (length == 2) {
return (theList[theLowerBound] + theList[theUpperBound]) / 2.0;
}

int size = length / 3;
int remainder = length % 3;
int midStart, midEnd;

if (remainder == 0) {
midStart = theLowerBound + size;
midEnd = theLowerBound + (2 * size) - 1;
} else if (remainder == 1) {
midStart = theLowerBound + size;
midEnd = theLowerBound + size + (length - 2 * size) - 1;
} else {
midStart = theLowerBound + size + 1;
midEnd = theLowerBound + 2 * size;
}

double median1 = median3Helper(theList, theLowerBound, midStart - 1);
double median2 = median3Helper(theList, midStart, midEnd);
double median3 = median3Helper(theList, midEnd + 1, theUpperBound);

return medianOfThree(median1, median2, median3);
}

/**
* The method that finds the median of three numbers
* @param theMedian1Value value of the first median section
* @param theMedian2Value value of the second median section
* @param theMedian3Value value of the third median section
* @return the median of the original list of integers
*/
private static double medianOfThree(final double theMedian1Value, final double theMedian2Value, final double theMedian3Value) {
double max = theMedian1Value;

if (theMedian2Value > max) {
max = theMedian2Value;
}
if (theMedian3Value > max) {
max = theMedian3Value;
}

double min = theMedian1Value;
if (theMedian2Value < min) {
min = theMedian2Value;
}
if (theMedian3Value < min) {
min = theMedian3Value;
}

return theMedian1Value + theMedian2Value + theMedian3Value - max - min;
}
}

0 comments on commit b05c37e

Please sign in to comment.