Compare commits

...

19 Commits

Author SHA1 Message Date
d0a47f7b64 Added headers and fixed the loops/prints. Added Comments. 2024-03-23 17:47:02 -04:00
f04910cb73 Began the sentinel loop. 2024-03-22 23:24:44 -04:00
e0f1af33a1 Updated copilot gitignore. 2024-03-22 22:03:45 -04:00
a7c4cfa36c Removed unneeded conditional. 2024-03-22 21:58:25 -04:00
Jonathan Turner
1feed10d53 Merge remote-tracking branch 'origin/dev' into dev
# Conflicts:
#	src/Assignments/A3/InterpolationSearch.java
2024-03-21 12:56:01 -04:00
Jonathan Turner
d9735ec2bd Fixed InterpolationSearch getting caught on missing element. 2024-03-21 12:55:46 -04:00
Jonathan Turner
abb7b04383 Fixed InterpolationSearch getting caught on missing element. 2024-03-21 12:54:42 -04:00
Jonathan Turner
b97fb17561 Began implementation of TestInterpolationSearch#runIntSearch 2024-03-21 12:54:17 -04:00
Jonathan Turner
d31dbbb4d8 Implemented TestInterpolationSearch#RandomDistinct 2024-03-21 12:12:35 -04:00
Jonathan Turner
aec729b236 Implemented InterpolationSearch.java 2024-03-21 12:08:29 -04:00
f842d5c2ea Starting Assignment 3 2024-03-07 12:29:09 -05:00
726af6ba4b Finished Assignment 2. 2024-02-23 22:26:14 -05:00
Jonathan Turner
9d87b9924f Started Big O Analysis. 2024-02-22 22:12:21 -05:00
456c003159 Implemented Sentinel Loop. 2024-02-18 12:48:44 -05:00
da90939e5e Implemented Algorithm Only. 2024-02-17 17:42:01 -05:00
Jonathan Turner
7fa5f88499 Began algorithm implementation. 2024-02-17 13:40:58 -05:00
Jonathan Turner
6cfc94869b Added subset generation method and JavaDocs. 2024-02-17 13:39:54 -05:00
Jonathan Turner
75fd07d3e9 Finished the Pseudo Code Syntax. 2024-02-17 13:39:26 -05:00
Jonathan Turner
cec04a4544 Finished the Logical Steps for Partition.java 2024-02-17 13:26:46 -05:00
5 changed files with 660 additions and 3 deletions

3
.idea/.gitignore vendored
View File

@ -8,4 +8,5 @@
/dataSources.local.xml /dataSources.local.xml
.iml .iml
.xml .xml# GitHub Copilot persisted chat sessions
/copilot/chatSessions

View File

@ -0,0 +1,357 @@
// Name: Jonathan Turner
// Class: CS 4306/01
// Term: Spring 2024
// Instructor: Dr. Haddad
// Assignment: 2
// IDE Name: IntelliJ
/*
Algorithm Design Block
Algorithm title: Finding Equal Disjoint Sets
Logical steps:
Step 1: Get the number of items in the set as user input.
Step 2: Get the elements in the set as user input.
Step 3: Add all the elements to the list and save it to a variable.
Step 4: If the sum is odd, there is no disjoint sets and it is not possible.
Step 5: Set a variable that will hold the first set and second set representing the disjoint and initialize it to null.
Step 6: Create a List that holds a list of elements which represent each subset.
Step 7: Generate the subsets using a subset generation method. (Ex. Bit Shift Counting)
Step 8: Iterate through all the subsets that were generate.
Step 9: If the current iteration's sum is equal to half of the total sum, move to step 11. Otherwise, continue iterating.
Step 10: If the value is not found, then there is no disjoint equal subsets. End algorithm.
Step 11: Assign the first set's variable to the current iteration's values.
Step 12: Assign the second set's variable to the values of the original set that are not in the first set.
Step 13: Return the results of the two equal disjoint sets that were found.
Pseudocode Syntax:
count <- input
elements <- input
first_set, second_set <- empty
sum <- 0
for each number in elements:
sum <- sum + number
if sum % 2 is 0:
subsets <- generate_subsets(elements)
for each subset in subsets:
current_sum <- 0
for each value in subset:
current_sum <- current_sum + value
if sum / 2 is current_sum:
first_set <- subset
if first_set is not empty:
second_set <- elements - first_set
else
return "no equal disjoint subsets"
return first_set, second_set
Big-O Analysis: (Based on Implementation)
n = the number of elements in the set.
k = the number of elements in the current subset.
| init Comps | init values | i | totalSum | generateSubsets | subset | value | subsetTotal | if(half) | asignSet | secondSubset | printResults
-------------------------------------------------------------------------------------------min-------max-------------------------min--max---------------------------------
| 1 | 1 | 1 | 1 | 2^n | 1 | 2^(n)+1 | 1 2^(n)+1 | 2^(n) | 0 1 | 1 | 1
| | | 2 | 1 | | 2 | 2^(n)+2 | 1 2^(n)+2 | 2^(n) | 0 1 | 2 | 1
| | | 3 | 1 | | 3 | 2^(n)+3 | 1 2^(n)+3 | 2^(n) | 0 1 | 3 | 1
| | | 4 | 1 | | 4 | 2^(n)+4 | 1 2^(n)+4 | 2^(n) | 0 1 | 4 | 1
| | | ... | ... | | ... | ... | 1 ... | ... |... ... |... | 1
| | | n | 1 | | 2^n | 2^(n)+k | 1 2^(n)+k | 2^(n) | 0 1 | k | 1
--------------------------------------------------------------------------------------------------------------------------------------------------------------
| 1 | 1 | X | n | 2^n | X | X | 1 k*2^(n) + | n*2^(n) | 0 2^n | k | 1
(k^(2)+k)/2 |
Best-Case Scenario: 1 + 1 + n + 2^n + 1 + (n*2^(n)) + 0 + k + 1 = n + 2^n + (n*2^(n)) + k + 4
Worse-Case Scenario: 1 + 1 + n + 2^n + k*2^n+(k*2^(n))/2 + n*2^(n) + 2^n + k + 1 = 2^n + k*2^n + (k*2^(n))/2 + n*2^(n) + k + 4
Average-Case: (n*2^(n) + 2^n + k + 4 + 2^n + k*2^n + (k*2^(n))/2 + n*2^(n) + k + 4)/2
Big O => O(2^n)
*/
package Assignments.A2;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
/**
* Generates, if possible, two equal subsets of a given set of elements that are equal to each other.
*
* @author Jonathan Turner
* @version Spring 2024
*/
public class Partition {
private int[] set;
private List<List<Integer>> subsets;
public static void main(String[] args) {
Partition program = new Partition();
program.start();
}
/**
* Used as the main sentential loop and loops until the exit option is selected.
*
* @precondition none
* @postcondition none
*/
public void start() {
int option = this.getOption();
while (option != 4) {
this.executeOption(option);
option = this.getOption();
}
}
/**
* Performs the action related to the option that was chosen.
*
* @precondition none
* @postcondition the action was performed.
*
* @param option the option that was chosen.
*/
private void executeOption(int option) {
if (option == 1) {
System.out.println("Please specify the size of the set.");
System.out.print("Size: ");
int newSize = this.getIntegerInput();
while (newSize < 1) {
System.out.println("Please enter a valid set size.");
System.out.print("Size: ");
newSize = this.getIntegerInput();
}
this.set = new int[newSize];
} if (option == 2) {
if (this.set == null) {
System.out.println("Please enter a set size and values ");
System.out.println();
return;
}
this.set = this.getValues();
} else {
if (this.set == null || this.set[0] == 0) {
System.out.println("Please enter a set size and values before executing the algorithm.");
System.out.println();
return;
}
this.performAlgorithm();
}
System.out.println();
}
/**
* Prints out the menu of options, asks for an input, and if that input is invalid it prints an error and
* prompts the user again for the input.
*
* @precondition none
* @postcondition none
*
* @return the option selected
*/
private int getOption() {
this.displayMenu(); // Prints out the menu
// Asks for the option and begins the loop until a valid option is gathered.
System.out.print("Enter option number: ");
int input = getIntegerInput();
while (input < 1 || input > 4) { // Compares it to the valid options available.
System.out.println("\nPlease enter a valid input.");
System.out.print("Enter option number: ");
input = getIntegerInput();
}
System.out.println();
return input;
}
/**
* Displays the menu options.
*
* @precondition none
* @postcondition the menu is displayed.
*/
private void displayMenu() {
System.out.println("-----------------MAIN MENU--------------");
System.out.println("1. Read set size (number of integers)");
System.out.println("2. Read set elements (integer values)");
System.out.println("3. Run algorithm and display outputs");
System.out.println("4. Exit program");
System.out.println();
}
/**
* Gets user input to a number. A prompt must be provided prior to running this method.
* If the input was not an integer/(unable to be autoboxed), returns -1.
*
* @precondition none
* @postcondition none
*
* @return the integer input, if invalid -1.
*/
private int getIntegerInput() {
Scanner sc = new Scanner(System.in);
try {
String textInput = sc.nextLine();
return Integer.parseInt(textInput);
} catch (Exception e) {
return -1;
}
}
/**
* Gets the values for the set. If the input is invalid, it will prompt the user again.
*
* @precondition none
* @postcondition the values are gathered.
*
* @return the values of the set.
*/
private int[] getValues() {
Scanner sc = new Scanner(System.in);
String input = null;
int[] values = new int[this.set.length];
System.out.println("Please enter a list of " + this.set.length + " positive values. (Ex. 34 35 21 23)");
while (values[0] == 0) {
System.out.print("Values: ");
input = sc.nextLine();
String[] stringRep = input.split(" ");
/* If the input values are not the same number as the set size */
if (stringRep.length != values.length || input.isEmpty() ) {
System.out.println("Please enter a valid list of " + this.set.length + " positive values. (Ex. 34 35 21 23)");
continue;
}
/* Attempts to convert each value from String to Integer. */
try {
for (int i = 0; i < values.length; i++) {
values[i] = Integer.parseInt(stringRep[i]);
if (values[i] < 1) {
System.out.println("Please enter a valid list of " + this.set.length + " positive values. (Ex. 34 35 21 23)");
Arrays.fill(values, 0);
break;
}
}
} catch (Exception e) {
System.out.println("Please enter a valid list of " + this.set.length + " positive values. (Ex. 34 35 21 23)");
}
}
return values;
}
/**
* Iterates through all the possible subsets generated by this.generateSubsets
* and if a subset is found that is exactly half the size it sets the firstset
* to those values and the second subset to the missing values.
*
* @precondition set.length != 0
* @postcondition the resulting sets are printed.
*/
public void performAlgorithm() {
int totalSum = 0;
for (int i = 0; i < this.set.length; i++) {
totalSum += this.set[i];
}
List<Integer> firstSubset = null;
List<Integer> secondSubset = null;
/* If the total is odd, there cannot be equal disjoint subsets. */
if (totalSum % 2 == 1) {
printResults(firstSubset, secondSubset);
return;
}
/*
* Checks through every subset that was generated,
* if a subset is found it sets the firstSubset to the found subset.
*/
generateSubsets();
for (List<Integer> subset : subsets) {
int subsetTotal = 0;
for (int value : subset) {
subsetTotal += value;
}
if (totalSum / 2 == subsetTotal) {
firstSubset = subset;
break;
}
}
/* Checks if a list was found, if so creates second sublist. */
if (firstSubset != null) {
secondSubset = new ArrayList<>();
for (int secondValue : this.set) {
if (!firstSubset.contains(secondValue)) {
secondSubset.add(secondValue);
}
}
}
printResults(firstSubset, secondSubset);
}
/**
* Prints the results of the algorithm based on the two subsets. Prints the setsize and the original set.
* If the subsets were null (No match found) print output associated, otherwise print the both lists.
*
* @precondition none
* @postcondition the output is displayed.
*
* @param firstSubset the first subset.
* @param secondSubset the second subset.
*/
private void printResults(List<Integer> firstSubset, List<Integer> secondSubset) {
int setSize = this.set.length;
String original = "";
for (int values : this.set) {
original += values + " ";
}
String first = "{";
String second = "{";
if (firstSubset != null) {
for (int fValues : firstSubset) {
first += fValues + ",";
}
first = first.substring(0, first.length()-1) + "}";
for (int sValues : secondSubset) {
second += sValues + ",";
}
second = second.substring(0, second.length()-1) + "}";
} else {
first = "No disjoint subsets with the same sum";
second = "of their elements found";
}
System.out.println("Set size: " + setSize + " integers");
System.out.println("Integer values: " + original);
System.out.println("Disjoint subsets with same sum: " + first);
System.out.println(" " + second);
}
/**
* Generates the list of subsets using Bit Shift Counting by iterating over all combinations of 1 to n.
* After shifting the counter, the current subset is created initialized and if 1 shifted by j is logically
* ANDed with the i and is not equal to 0, it adds the value j represents to the subset.
*
* @precondition none
* @postcondition the subsets are generated and added to the field.
*/
public void generateSubsets() {
List<List<Integer>> subsets = new ArrayList<>();
int n = this.set.length;
for (int i = 0; i < (1 << n); i++) {
List<Integer> currentSubset = new ArrayList<>();
for (int j = 0; j < n; j++) {
if ((i & (1 << j)) != 0) {
currentSubset.add(this.set[j]);
}
}
subsets.add(currentSubset);
}
this.subsets = subsets;
}
}

View File

@ -0,0 +1,106 @@
// Name: Jonathan Turner
// Class: CS 4306/01
// Term: Spring 2024
// Instructor: Dr. Haddad
// Assignment: 3
// IDE Name: IntelliJ
package Assignments.A3;
public class InterpolationSearch {
/** Holds if the value was found or not. */
private final boolean found;
/** Holds the index of the key, -1 if not found. */
private final int index;
/** Holds the number of divisions used to perform the search. */
private int divisions;
/**
* Accepts the values, performs the search, and assigns the fields to the corresponding output data.
* <p>
* This constructor accepts in the array to be searched and the key to be searched for. Based off of this,
* the method will perform some precondition checks to ensure the values are valid and then perform the
* search using the formula provided in the slide deck.
* </p>
*
* @param array The list of values being search through.
* @param key The desired value being searched for.
*
* @throws IllegalArgumentException If the array is empty.
*/
public InterpolationSearch(int[] array, int key) {
/* Precondition for empty list. */
if (array.length == 0) {
throw new IllegalArgumentException("The searched array cannot be empty.");
}
/* Precondition check to see if the list is size 1 element. */
if (array.length == 1) {
this.found = (array[0] == key);
this.divisions = 0;
this.index = (array[0] == key ? 0 : -1);
return;
}
/* Sets the default values for the search */
int low = 0;
int high = array.length-1;
this.divisions = 0;
/* Iterates as long as high is not less than low */
while (high >= low) {
int probe;
/* Checks if high is the same thing as low to prevent division by zero. */
if (high != low) {
probe = low + (((key - array[low]) * (high - low)) / (array[high] - array[low]));
this.divisions++;
} else {
probe = high;
}
/* Checks if it passed the element due to it not being in list. */
if (array[high] < key || array[low] > key) {
break;
}
/* Checks if the key is less than the probe's value */
if (array[probe] > key) {
high = probe - 1;
} else if (array[probe] < key) { /* Checks if the key is greater than the probes value */
low = probe + 1;
} else { /* The key was found at the probes index. */
this.found = true;
this.index = probe;
return;
}
}
/* Sets the values if the key was not in the list. */
this.found = false;
this.index = -1;
}
/**
* Gets if the key was found.
* @return if it was found.
*/
public boolean isFound() {
return found;
}
/**
* Gets the number of divisions it took for the search to conclude.
* @return the number of divisions
*/
public int getDivisions() {
return divisions;
}
/**
* Gets the index at which the key was found. If the key was not found it returns -1.
* @return the found index.
*/
public int getIndex() {
return index;
}
}

View File

@ -0,0 +1,189 @@
// Name: Jonathan Turner
// Class: CS 4306/01
// Term: Spring 2024
// Instructor: Dr. Haddad
// Assignment: 3
// IDE Name: IntelliJ
package Assignments.A3;
import java.util.*;
public class TestInterpolationSearch {
/** Holds the list of 1024 unique values used to search through */
public int[] values;
/** Holds the size of the table to generate */
public int tableSize;
public static void main(String[] args) {
TestInterpolationSearch program = new TestInterpolationSearch();
program.start();
}
/**
* Used as the main sentential loop and loops until the exit option is selected.
*
* @precondition none
* @postcondition none
*/
public void start() {
int option = this.getOption();
while (option != 4) {
this.executeOption(option);
option = this.getOption();
}
}
/**
* Displays the menu options.
*
* @precondition none
* @postcondition the menu is displayed.
*/
private void displayMenu() {
System.out.println("----------------------MAIN MENU-------------------");
System.out.println("1. Create, populate, and display array Values[]");
System.out.println("2. Read output table size");
System.out.println("3. Run interpolation search and display outputs");
System.out.println("4. Exit program");
System.out.println();
}
/**
* Prints out the menu of options, asks for an input, and if that input is invalid it prints an error and
* prompts the user again for the input.
*
* @precondition none
* @postcondition none
*
* @return the option selected
*/
private int getOption() {
this.displayMenu(); // Prints out the menu
// Asks for the option and begins the loop until a valid option is gathered.
System.out.print("Enter option number: ");
int input = getIntegerInput();
while (input < 1 || input > 4) { // Compares it to the valid options available.
System.out.println("\nPlease enter a valid input.");
System.out.print("Enter option number: ");
input = getIntegerInput();
}
System.out.println();
return input;
}
/**
* Gets user input to a number. A prompt must be provided prior to running this method.
* If the input was not an integer/(unable to be autoboxed), returns -1.
*
* @precondition none
* @postcondition none
*
* @return the integer input, if invalid -1.
*/
protected int getIntegerInput() {
Scanner sc = new Scanner(System.in);
try {
String textInput = sc.nextLine();
return Integer.parseInt(textInput);
} catch (Exception e) {
return -1;
}
}
public void executeOption(int option) {
/* The option used for the values generation */
if (option == 1) {
this.randomDistinct();
System.out.println("The generated Values: ");
/* Displays the generated values */
for (int i = 0; i < this.values.length; i++) {
System.out.print(String.format("%-6s", this.values[i]));
/* Splits the rows at 30 columns */
if ((i+1) % 30 == 0) {
System.out.println();
}
}
System.out.println();
} else if (option == 2) { /* Handles the table size */
System.out.println("Enter the table size: ");
System.out.print("Size: ");
int size = -1;
size = getIntegerInput();
/* Used if the table input is invalid */
while (size < 1) {
System.out.println("Enter a valid table size: (size > 0)");
System.out.print("Size: ");
size = getIntegerInput();
}
this.tableSize = size;
} else if (option == 3) { /* Generates and displays the table */
if (this.values == null) { /* Used to check if the values have been generated */
System.out.println("Please generate the values first.");
System.out.println();
return;
}
if (this.tableSize < 1) { /* Used to check if the table size has been set */
System.out.println("Please enter a table size.");
System.out.println();
return;
}
/* Runs the search */
this.runIntSearch();
}
System.out.println();
}
/**
* Generates a list of 1024 random, non-repeating, integers and assigns them to the values field.
*/
public void randomDistinct() {
/* Used to track what ints have been used */
HashSet<Integer> isUsed = new HashSet<>();
int[] newList = new int[1024];
Random random = new Random();
/* Loops 1024 times and assigns a new unique value each time. */
for (int i = 0; i < 1024; i++) {
int newValue = -1;
/* Ensures that there is no duplicate values */
do {
newValue = random.nextInt(9999) + 1;
} while (isUsed.contains(newValue));
/* Adds the value to the known list and also to the generated list. */
newList[i] = (newValue);
isUsed.add(newValue);
}
/* Sorts and assigns the values generated to the field. */
Arrays.sort(newList);
this.values = newList;
}
public void runIntSearch() {
int totalDivisions = 0;
Random rand = new Random();
/* Prints out the table headers */
System.out.println(" " + String.format("%-10s%-10s%-10s%-10s", "Key", "Found", "Index", "Divisions"));
System.out.println("----------------------------------------------");
/* Prints out each row and performs the Interpolation Search for each value up to the table size. */
for (int i = 0; i < this.tableSize; i++) {
int key = rand.nextInt(9999) + 1;
InterpolationSearch results = new InterpolationSearch(this.values, key);
System.out.println(" " + String.format("%-10s%-10s%-10s%-10s", key, results.isFound(), results.getIndex(), results.getDivisions()));
totalDivisions += results.getDivisions();
}
/* Prints out the average and the difference from the expected average */
double averageDivs = (double) totalDivisions / (double) this.tableSize;
System.out.println("\nDivisions average: " + averageDivs);
System.out.println("Difference: " + Math.abs(3.322 - averageDivs));
System.out.println();
}
}

View File

@ -23,7 +23,11 @@ public class FakeCoin extends Application {
* @postcondition a new FakeCoin application is created. * @postcondition a new FakeCoin application is created.
*/ */
public FakeCoin() { public FakeCoin() {
super(new String[]{"The number of coins","Set FakeCoin Weight and Location","Find Fake Coin"}); super(new String[]{
"The number of coins",
"Set FakeCoin Weight and Location",
"Find Fake Coin"
});
this.setLocation = false; this.setLocation = false;
} }
@ -78,7 +82,7 @@ public class FakeCoin extends Application {
} }
private void performAlgorithm() { private void performAlgorithm() {
} }
/** /**