commit 4c1e3b6cc78a77c2f54ec38455a9bbaa37368187 Author: Aaron Helton Date: Fri May 10 23:57:25 2019 -0400 Initial Commit diff --git a/Homework 1/README.txt b/Homework 1/README.txt new file mode 100644 index 0000000..20e8b13 --- /dev/null +++ b/Homework 1/README.txt @@ -0,0 +1,11 @@ +All programs are written to run with any version of Python 3.2 or greater and were tested working with a Python 3.7 interpreter. + +The programs can be made executable in any (ba)sh process with chmod, or can be run by directly feeding them to the Python interpreter. + +All programs are self-contained and do not require any special arguments unless it explicitly takes command line arguments. None currently do. + +To pass the test data in the data folder to each program, simply call the program as normal and use the '<' syntax of the local shell along +with the path to the data file to input the data. + + Example: + aargonian@LocalDev:~$ python3 src/hamming.py < data/hamming_test.dat diff --git a/Homework 1/data/hamming_test.dat b/Homework 1/data/hamming_test.dat new file mode 100644 index 0000000..68abe83 --- /dev/null +++ b/Homework 1/data/hamming_test.dat @@ -0,0 +1,6 @@ +23495872345 2345 +-2342 2345234 +28486 27324 +0 4294967295 ++234 23425 +5 3 diff --git a/Homework 1/data/permutations_test.dat b/Homework 1/data/permutations_test.dat new file mode 100644 index 0000000..434b7b7 --- /dev/null +++ b/Homework 1/data/permutations_test.dat @@ -0,0 +1,7 @@ +1 +1 2 +1 2 3 +3 4 5 +4 9 +1 4 9 16 +1 4 9 16 25 diff --git a/Homework 1/data/read_input_test.dat b/Homework 1/data/read_input_test.dat new file mode 100644 index 0000000..410051e --- /dev/null +++ b/Homework 1/data/read_input_test.dat @@ -0,0 +1,6 @@ +This is line number 1. It should appear last. +This is line number 2. +This is line number 3. +This is line number ??? +This is line number 5. +This is the last line, and should be the first printed. diff --git a/Homework 1/data/sequence_product_test.dat b/Homework 1/data/sequence_product_test.dat new file mode 100644 index 0000000..8cc6b11 --- /dev/null +++ b/Homework 1/data/sequence_product_test.dat @@ -0,0 +1,5 @@ +1 1 23 234 1234 5 2 2 34 5 2 +2 4 6 8 10 20 30 40 50 60 +2 2 2 2 2 1 2 2 2 2 3 +1293840712340987123490872 3 12390487124 +77777777789 2342342 3 diff --git a/Homework 1/src/hamming.py b/Homework 1/src/hamming.py new file mode 100644 index 0000000..c5a68a8 --- /dev/null +++ b/Homework 1/src/hamming.py @@ -0,0 +1,54 @@ +#!/bin/python3 + +# Author : Aaron Helton +# Date : 01/26/2019 +# Class : CSC 310 +# Purpose : This program calculates the hamming distance of any two integer +# : numbers up to 32 bits long. The hamming distance is defined as +# : the number of bits that are different between the two numbers. + +def calculate_hamming_distance(num1, num2): + # We'll assume that both numbers are 32 bit. + # To make this easy, we just xor the two numbers together. This gives us + # a convenient number whose 1 bits are all where the two numbers differed + # bitwise. We can then just count the number of 1s in the new number. + different_bits = 0 + xored_bits = num1 ^ num2 + start = 0x80000000 # This is 1000 0000 0000 0000 0000 0000 0000 0000 + while start > 0: + if xored_bits & start > 0: + different_bits += 1 + start //= 2 + return different_bits + +def main(): + print('Hello, welcome to the hamming distance calculator.') + max_val = 2**32-1 + try: + while True: + nums = input('Please input two numbers separated by spaces: ') + + # Do a nice trick with comprehensions here where we iterate over the + # split string to create the sequence of numbers. The strip call is + # used to cull any extra space the user may have tacked on. + try: + # This time around I used a number of tests to make sure the + # data is sane, since unlike the other programs we are doing + # bitwise operations and need to be stricter on values. + numbers = [int(x) for x in nums.strip().split(' ')] + numbers = numbers[0:2] # We only care about the first two numbers. + if len(numbers) != 2: + print('Please enter two numbers.') + continue + if numbers[0] > max_val or numbers[1] > max_val or numbers[0] < 0 or numbers[1] < 0: + print('Please don\'t enter numbers larger than', max_val, 'or lower than 0!') + continue + print('The hamming distance of', numbers[0], 'and', numbers[1], + 'is', calculate_hamming_distance(numbers[0], numbers[1])) + except ValueError as err: + print('Please only input integer numbers.') + except EOFError as error: + print('\nLooks like you are done. Goodbye.') + +if __name__ == '__main__': + main() diff --git a/Homework 1/src/permutations.py b/Homework 1/src/permutations.py new file mode 100644 index 0000000..156a003 --- /dev/null +++ b/Homework 1/src/permutations.py @@ -0,0 +1,42 @@ +#!/bin/python3 + +# Author : Aaron Helton +# Date : 01/26/2019 +# Class : CSC 310 +# Purpose : This program takes as input a sequence of numbers and outputs all +# : possible permutations of those numbers. + +# The following code was found on stackoverflow, particularly as the solution. +# Link: https://stackoverflow.com/questions/104420/how-to-generate-all-permutations-of-a-list-in-python +# The code defines a generator function that recursively builds the permutation +# by chopping off the end of the list and appending each possible order to the +# element you are left with, recursively. +def permutations(sequence) -> None: + if len(sequence) <= 1: + yield sequence + else: + for permutation in permutations(sequence[1:]): + for i in range(len(sequence)): + yield permutation[:i] + sequence[0:1] + permutation[i:] + +def main(): + print('Hello, welcome to the permutation lister.') + try: + while True: + line = input('Please input numbers separated by spaces: ') + + # Do a nice trick with comprehensions here where we iterate over the + # split string to create the sequence of numbers. The strip call is + # used to cull any extra space the user may have tacked on. + try: + numbers = [int(x) for x in line.strip().split(' ')] + print("Permutations: ") + for perm in permutations(numbers): + print('\t', perm) + except ValueError as err: + print('Please only input integer numbers.') + except EOFError as error: + print('\nLooks like you are done. Goodbye.') + +if __name__ == '__main__': + main() diff --git a/Homework 1/src/read_input.py b/Homework 1/src/read_input.py new file mode 100644 index 0000000..f7c30fb --- /dev/null +++ b/Homework 1/src/read_input.py @@ -0,0 +1,42 @@ +#!/bin/python3 + +# Author : Aaron Helton +# Date : 01/26/2019 +# Class : CSC 310 +# Purpose : This program takes as input a series of strings by the user and, +# : upon receiving an EOF, prints them in reverse order. + +import sys + +def main(): + # Read lines from input into the list + input_list = [] + try: + while True: + string = input('Please enter something: '); + input_list.append(string) + except EOFError as error: + print('\nIn Reverse You Entered:') + + # We'll use the built-in reversed function to make reverse traversal + # easier :) + for string in reversed(input_list): + print(string) + + # Alternatively we could have done the following more verbosely: + + #for i in range(len(input_list)-1, -1, -1): + # print(input_list[i]) + + # We also could have just called input_list.reverse() before iterating + # over the list. + # Finally, we could do the following: + + #for item in input_list[::-1]: + # print(item) + + # The problem with both of those being that they actually make copies + # behind the scenes :( + +if __name__ == '__main__': + main() diff --git a/Homework 1/src/sequence_product.py b/Homework 1/src/sequence_product.py new file mode 100644 index 0000000..ab3c072 --- /dev/null +++ b/Homework 1/src/sequence_product.py @@ -0,0 +1,46 @@ +#!/bin/python3 + +# Author : Aaron Helton +# Date : 01/26/2019 +# Class : CSC 310 +# Purpose : This script takes as input from the user a sequence of numbers and +# : determines if any unique pair in the sequence has an odd product. + +# This function does the heavy lifting of figuring out if any two subpairs of +# the passed sequence are able to have a product which is odd. +# This algorithm makes clever use of the fact that the only way to multiply two +# numbers and end up with an odd result is to multiply two odd numbers. So +# instead of manually checking very multiplication, we check for the presence of +# at least two odd numbers! +# +# This algorithm has a worst case running time of O(n) and a best case of O(1). +def test_nums(number_sequence) -> bool: + odd_found = False + for i in number_sequence: + if i%2 == 1: + if odd_found: + return True + else: + odd_found = True + return False + +def main(): + print('Hello, welcome to the sequence tester.') + try: + while True: + line = input('Please input numbers separated by spaces: ') + + # Do a nice trick with comprehensions here where we iterate over the + # split string to create the sequence of numbers. The strip call is + # used to cull any extra space the user may have tacked on. + try: + numbers = [int(x) for x in line.strip().split(' ')] + print('Are there two numbers whose product is odd? :', + test_nums(numbers)) + except ValueError as err: + print('Please only input integer numbers.') + except EOFError as error: + print('\nLooks like you are done. Goodbye.') + +if __name__ == '__main__': + main() diff --git a/Homework 3/Main.java b/Homework 3/Main.java new file mode 100644 index 0000000..3b663f8 --- /dev/null +++ b/Homework 3/Main.java @@ -0,0 +1,374 @@ +import java.lang.reflect.Array; + +public class Main +{ + public static class Stack + { + protected static final int DEFAULT_CAPACITY = 16; + protected static final int MINIMUM_CAPACITY = 4; + + protected int head; + protected T[] stackArray; + + //Needed to parameterize array creations in push/pop and the constructor. + private Class c; + + public Stack(Class c) + { + this(c, DEFAULT_CAPACITY); + } + + public Stack(Class c, int capacity) + { + // Sanity Check + this.c = c; + if (capacity <= 0) + { + capacity = DEFAULT_CAPACITY; + } + else if (capacity < MINIMUM_CAPACITY) + { + capacity = MINIMUM_CAPACITY; + } + else + { + //Find the nearest power of two greater than or equal to capacity + int power = 0; + while (capacity > 1) + { + power++; + capacity = (int)Math.ceil(capacity / 2.0); + } + capacity = (int)Math.pow(2, power); + } + + + //Unchecked creation of a generic array. Classtype known through parameterization. + stackArray = (T[]) Array.newInstance(c, capacity); + head = -1; + } + + public void push(T value) + { + head++; + + //Expand the array if we have hit our capacity. + if (head == stackArray.length) + { + //Same as constructored: technically unchecked cast but we know the class type for sure with c. + T[] newStackArray = (T[])Array.newInstance(c, stackArray.length * 2); + System.arraycopy(stackArray, 0, newStackArray, 0, stackArray.length); + stackArray = newStackArray; + } + stackArray[head] = value; + } + + public T pop() + { + //Sanity check that we aren't popping on an empty stack + if (head < 0) + { + System.err.println("Unable to pop element: stack is empty"); + throw new RuntimeException("Pop Requested But Stack Empty"); + } + + //Grab the return value before we modify head + T ret = stackArray[head--]; + + //Check if we are at a fourth of the capacity on removal. If so, it should be safe to halve the size of the + //stack array to conserve memory. We wait until it's a fourth, and not at half, to preventing thrashing in + //case of many pops and pushes happening simultaneously. + if (head <= stackArray.length/4 && stackArray.length > DEFAULT_CAPACITY) + { + T[] newStackArray = (T[])Array.newInstance(c, stackArray.length/2); + System.arraycopy(stackArray, 0, newStackArray, 0, stackArray.length/2); + stackArray = newStackArray; + } + return ret; + } + + public T top() + { + if(head < 0) + { + System.err.println("Unable to retrieve top on empty stack!"); + throw new RuntimeException("Top value requested on empty stack"); + } + return stackArray[head]; + } + + public int size() + { + return head+1; + } + } + + public static class MinStack extends Stack + { + private final Stack minStack; + + public MinStack() + { + this(DEFAULT_CAPACITY); + } + + public MinStack(int capacity) + { + super(Integer.class, capacity); + minStack = new Stack<>(Integer.class, DEFAULT_CAPACITY); + } + + @Override + public void push(Integer value) + { + super.push(value); + + //Check if value is new min + if (minStack.head == -1 || value <= stackArray[minStack.top()]) + { + minStack.push(head); + } + } + + @Override + public Integer pop() + { + int ret = super.pop(); + if(minStack.top() == head+1) + { + minStack.pop(); // It is no longer the min value + } + return ret; + } + + public int getMin() + { + return stackArray[minStack.top()]; + } + } + + public static abstract class Evaluator + { + protected final String currentEval; + protected int currentIndex; + + public Evaluator(String eval) + { + this.currentEval = eval; + currentIndex = 0; + } + + protected boolean hasNext() + { + return currentIndex != currentEval.length(); + } + + protected String getNextToken() + { + //Sanity check + if(currentIndex == currentEval.length()) + return null; + if (Character.isDigit(currentEval.charAt(currentIndex))) + { + int numberStartIndex = currentIndex; + while(Character.isDigit(currentEval.charAt(currentIndex))) + { + currentIndex++; + } + return currentEval.substring(numberStartIndex, currentIndex); + } + else + { + while(Character.isWhitespace(currentEval.charAt(currentIndex++))){} + return currentEval.substring(currentIndex-1, currentIndex); + } + } + + protected boolean isNumber(String str) + { + for(int i = 0; i < str.length(); i++) + { + if (!Character.isDigit(str.charAt(i))) + return false; + } + return true; + } + + public abstract double evaluate(); + } + + public static class ArithmeticEvaluator extends Evaluator + { + private Stack ops; + private Stack vals; + + public ArithmeticEvaluator(String expression) + { + super(expression); + vals = new Stack<>(Double.class); + ops = new Stack<>(Character.class); + } + + private int precendence(Character op) + { + switch(op) + { + case '$': + return 0; + case '+': + return 1; + case '-': + return 1; + case '*': + return 2; + case '/': + return 2; + default: + return 3; + } + } + + private void runNextOp() + { + Double val1 = vals.pop(); + Double val2 = vals.pop(); + Double result = null; + Character op = ops.pop(); + switch(op) + { + case '+': + result = val2 + val1; + break; + case '-': + result = val2 - val1; + break; + case '*': + result = val2 * val1; + break; + case '/': + result = val2/val1; + break; + default: + System.err.println("What?"); + System.err.println("Operator Found: " + op); + } + vals.push(result); + } + + private void runOps(Character refOp) + { + while(vals.size() > 1 && precendence(refOp) <= precendence(ops.top())) + { + runNextOp(); + } + } + + @Override + public double evaluate() + { + while(hasNext()) + { + String token = getNextToken(); + if (isNumber(token)) + { + vals.push(Double.parseDouble(token)); + } + else + { + runOps(token.charAt(0)); + ops.push(token.charAt(0)); + } + } + runOps('$'); + currentIndex = 0; //In case the function is called again + return vals.pop(); + } + } + + public static class PostfixEvaluator extends Evaluator + { + private Stack vals; + + public PostfixEvaluator(String postfixEval) + { + super(postfixEval); + this.vals = new Stack<>(Double.class); + } + + @Override + public String getNextToken() + { + //Sanity check + if(currentIndex == currentEval.length()) + return null; + currentIndex++; + return currentEval.substring(currentIndex-1, currentIndex); + } + + @Override + public double evaluate() + { + while(hasNext()) + { + String token = getNextToken(); + if(isNumber(token)) + vals.push(Double.parseDouble(token)); + else + { + double val1 = vals.pop(); + double val2 = vals.pop(); + Double result = null; + switch(token.charAt(0)) + { + case '+': + result = val2+val1; + break; + case '-': + result = val2 - val1; + break; + case '*': + result = val2 * val1; + break; + case '/': + result = val2 / val1; + break; + default: + System.err.println("Something went wrong! Token: " + token.charAt(0)); + } + vals.push(result); + } + } + return vals.pop(); + } + } + + public static void main(String[] args) + { + System.out.println("Commencing MINSTACK TESTING: "); + MinStack stack = new MinStack(1); + System.out.println("PUSHING: -2"); + stack.push(-2); + System.out.println("PUSHING: 0"); + stack.push(0); + System.out.println("PUSHING: -3"); + stack.push(-3); + System.out.println("MIN: " + stack.getMin()); + System.out.println("POPPED: " + stack.pop()); + System.out.println("TOP: " + stack.top()); + System.out.println("MIN: " + stack.getMin()); + + System.out.println("Commencing ARITHMETIC_EVALUATOR TESTING: "); + String expression = "4 - 3 * 2 + 7"; + System.out.println("Expression: " + expression); + System.out.println("Expected Result: " + 5); + ArithmeticEvaluator eval = new ArithmeticEvaluator(expression); + System.out.println("Result: " + eval.evaluate()); + + System.out.println("Commencing POSTFIX_EVALUATOR TESTING: "); + expression = "52+83-*4/"; + System.out.println("Expression: " + expression); + System.out.println("Expected Result: " + 8.75); + PostfixEvaluator eval2 = new PostfixEvaluator(expression); + System.out.println("Result: " + eval2.evaluate()); + } +} diff --git a/Homework 3/README.txt b/Homework 3/README.txt new file mode 100644 index 0000000..af6d2b2 --- /dev/null +++ b/Homework 3/README.txt @@ -0,0 +1,8 @@ +My Homework3 consists of a single source file, Main.java, which can easily be compiled and run on the command line +with the following commands: + +~$ javac Main.java +~$ java Main + +Alternatively, it can be loaded into any compatible Java IDE. The source should work for any version of Java above +version 7, due to the use of generics and the reflection API. \ No newline at end of file diff --git a/Homework 3/Report.docx b/Homework 3/Report.docx new file mode 100644 index 0000000..00f9245 Binary files /dev/null and b/Homework 3/Report.docx differ diff --git a/Homework 4/ListSplice.java b/Homework 4/ListSplice.java new file mode 100644 index 0000000..cc576bc --- /dev/null +++ b/Homework 4/ListSplice.java @@ -0,0 +1,115 @@ +public class ListSplice +{ + public static class List + { + T item = null; + List next = null; + + public List() {} + public List(T item) + { + this.item = item; + this.next = null; + } + + public void append(T item) + { + if(this.item == null) + { + this.item = item; + } + else if(this.next == null) + { + this.next = new List(item); + } + else + { + List temp = next; + while(temp.next != null) + temp = temp.next; + temp.next = new List(item); + } + } + + @Override + public String toString() + { + if(this.item == null) + return "null"; + else + { + List temp = this; + StringBuilder builder = new StringBuilder(temp.item.toString()); + while(temp.next != null) + { + temp = temp.next; + builder.append("->"); + builder.append(temp.item.toString()); + } + return builder.toString(); + } + } + } + + public static List splice(List one, List two) + { + List temp = new List<>(); + while(one.next != null && two.next != null) + { + if(one.item < two.item) + { + temp.append(one.item); + one = one.next; + } + else + { + temp.append(two.item); + two = two.next; + } + } + while(one.next != null) + { + temp.append(one.item); + one = one.next; + } + while(two.next != null) + { + temp.append(two.item); + two = two.next; + } + return temp; + } + + public static void main(String[] args) + { + List listOne = new List<>(10); + listOne.append(20); + listOne.append(33); + listOne.append(48); + listOne.append(49); + listOne.append(50); + listOne.append(71); + listOne.append(75); + listOne.append(87); + listOne.append(100); + + List listTwo = new List<>(5); + listTwo.append(6); + listTwo.append(11); + listTwo.append(32); + listTwo.append(48); + listTwo.append(49); + listTwo.append(51); + listTwo.append(82); + listTwo.append(99); + listTwo.append(101); + listTwo.append(10001); + + System.out.println("List One:"); + System.out.println(listOne); + System.out.println("List Two:"); + System.out.println(listTwo); + System.out.println("List Splice: "); + System.out.println(splice(listOne, listTwo)); + } +} diff --git a/Homework 4/Main.java b/Homework 4/Main.java new file mode 100644 index 0000000..7bb4a5d --- /dev/null +++ b/Homework 4/Main.java @@ -0,0 +1,92 @@ +public class Main +{ + public static void main(String[] args) + { + int value = 20; + MyCircularDeque queue = new MyCircularDeque(10); + + queue.insertFront(value++); + System.out.println(queue); + queue.insertFront(value++); + System.out.println(queue); + queue.insertFront(value++); + System.out.println(queue); + queue.insertFront(value++); + System.out.println(queue); + queue.insertFront(value++); + System.out.println(queue); + queue.insertFront(value++); + System.out.println(queue); + queue.insertFront(value++); + System.out.println(queue); + queue.insertFront(value++); + System.out.println(queue); + queue.insertFront(value++); + System.out.println(queue); + queue.insertFront(value++); + System.out.println(queue); + queue.insertFront(value++); + System.out.println(queue); + queue.insertFront(value++); + System.out.println(queue); + queue.insertFront(value++); + System.out.println(queue); + queue.deleteLast(); + System.out.println(queue); + queue.deleteLast(); + System.out.println(queue); + queue.deleteLast(); + System.out.println(queue); + queue.insertLast(value++); + System.out.println(queue); + queue.insertLast(value++); + System.out.println(queue); + System.out.println("Removing value: " + queue.getFront()); + queue.deleteFront(); + System.out.println(queue); + System.out.println("Removing value: " + queue.getFront()); + queue.deleteFront(); + System.out.println(queue); + System.out.println("Appending value: " + ++value); + queue.insertFront(value); + System.out.println(queue); + System.out.println("Appending value: " + ++value); + queue.insertFront(value); + System.out.println(queue); + System.out.println("Appending value: " + ++value); + queue.insertFront(value); + System.out.println(queue); + System.out.println("Size: " + queue.getSize()); + + //Queue should be full at this point, so if we attempt to append to either the back or front, it should return false + System.out.println("Attempting to append value: " + ++value); + boolean success = queue.insertFront(value); + System.out.println("Success: " + success); + System.out.println(queue); + System.out.println("Attempting to append value to back: " + ++value); + success = queue.insertLast(value); + System.out.println("Success: " + success); + System.out.println(queue); + + System.out.println("Removing value: " + queue.getFront()); + queue.deleteFront(); + System.out.println(queue); + System.out.println("Removing value: " + queue.getFront()); + queue.deleteFront(); + System.out.println(queue); + System.out.println("Removing value: " + queue.getFront()); + queue.deleteFront(); + System.out.println(queue); + System.out.println("Removing value: " + queue.getFront()); + queue.deleteFront(); + System.out.println(queue); + System.out.println("Removing value: " + queue.getFront()); + queue.deleteFront(); + System.out.println(queue); + System.out.println("Size: " + queue.getSize()); + } + + public static boolean flipCoin() { + return Math.random()*10 < 5; + } +} diff --git a/Homework 4/MyCircularDeque.java b/Homework 4/MyCircularDeque.java new file mode 100644 index 0000000..eecea5e --- /dev/null +++ b/Homework 4/MyCircularDeque.java @@ -0,0 +1,138 @@ +/** + * Author: Aaron Helton + * Class: CSC 310 + * Date: 03/10/2019 + * Assignment: Homework 4 + * Purpose: This is an implementation of a circular deque (Double ended queue), with support for adding and deleting + * elements at both the back and the front of the queue. + */ +public class MyCircularDeque +{ + //We use Integer instead of int so we can utilize 'null', since Java has no 'none' equivalent to Python. + private Integer[] queue_array = null; + private int back = 0; + private int front = 0; + + public MyCircularDeque(int capacity) + { + queue_array = new Integer[capacity]; + } + + public int getSize() + { + //Special case: back and front point to the same element. If the queue is empty, this element should be null. + if(front == back) { + if(queue_array[front] == null) { + return 0; + } + return 1; + } + else if(front < back) { + return ((queue_array.length - front - back) % queue_array.length) + 1; + } else { + return front - back + 1; + } + } + + public boolean isEmpty() { + return front==back && queue_array[front] == null; + } + + public boolean isFull() { + if(front == back-1) + return true; + if(front == queue_array.length -1 && back == 0) + return true; + return false; + } + + public boolean insertFront(int value) + { + //Three scenarios: The queue is empty, a collision will occur, or we can insert normally + if (isFull()) { + return false; + } else if (isEmpty()) { + queue_array[front] = value; + return true; + } else { + front = (front + 1) % queue_array.length; + queue_array[front] = value; + return true; + } + } + + public boolean insertLast(int value) + { + if(isFull()) { + return false; + } else if (isEmpty()) { + queue_array[back] = value; + return true; + } else { + back = back == 0 ? queue_array.length-1 : back-1; + queue_array[back] = value; + return true; + } + } + + public boolean deleteFront() + { + if(isEmpty()) + return false; + if(front == back) { //Last element + queue_array[front] = null; + return true; + } else { + queue_array[front] = null; + front = front == 0 ? queue_array.length-1 : front-1; + return true; + } + } + + public int getFront() + { + if(isEmpty()) + return -1; + else + return queue_array[front]; + } + + public boolean deleteLast() + { + if(isEmpty()) + return false; + if(front == back) { + queue_array[back] = null; + return true; + } else { + queue_array[back] = null; + back = (back + 1) % queue_array.length; + return true; + } + } + + public int getLast() + { + if(isEmpty()) + return -1; + else + return queue_array[back]; + } + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder("["); + for(int i = 0; i < queue_array.length; i++) + { + if(queue_array[i] == null) + sb.append(" "); + else + sb.append(queue_array[i]); + if(i != queue_array.length -1) + sb.append(','); + } + sb.append(']'); + return sb.toString(); + } +} diff --git a/Homework 4/QueueTest.java b/Homework 4/QueueTest.java new file mode 100644 index 0000000..3a2d907 --- /dev/null +++ b/Homework 4/QueueTest.java @@ -0,0 +1,159 @@ +public class QueueTest +{ + public static class Queue + { + private class Node + { + T item; + Node next; + } + + private Node first; + //We COULD calculate this every time len is called, but it's more + //time efficient to just update it on (en/de)queue operations. + private int len; + + public Queue() + { + len = 0; + first = null; + } + + public void enqueue(T item) + { + if(first == null) + { + first = new Node(); + first.item = item; + } + else + { + Node temp = first; + while(temp.next != null) + temp = temp.next; + temp.next = new Node(); + temp.next.item = item; + } + len++; + } + + public T dequeue() + { + if(is_empty()) + throw new RuntimeException("Dequeue operation requested on empty Queue!"); + Node temp = first; + first = first.next; + len--; + return temp.item; + } + + public int len() + { + return len; + } + + public boolean is_empty() + { + return len == 0; + } + + public boolean search(T other) + { + Node temp = first; + while(temp != null) + { + if(temp.item.equals(other)) + return true; + temp = temp.next; + } + return false; + } + + public T first() + { + if(first == null) + return null; + else + return first.item; + } + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder("["); + Node temp = first; + while(temp != null) + { + sb.append(temp.item.toString()); + temp = temp.next; + } + sb.append("]"); + return sb.toString(); + } + } + + public static void main(String[] args) + { + Queue queue = new Queue<>(); + System.out.println("QUEUE:"); + System.out.println(queue); + System.out.println("LEN: " + queue.len()); + System.out.println("Appending 'a':"); + queue.enqueue("a"); + System.out.println("Appending 'b':"); + queue.enqueue("b"); + System.out.println("Appending 'c':"); + queue.enqueue("c"); + System.out.println("Appending 'd':"); + queue.enqueue("d"); + System.out.println("Appending 'e':"); + queue.enqueue("e"); + System.out.println("Appending 'f':"); + queue.enqueue("f"); + System.out.println("Appending 'g':"); + queue.enqueue("g"); + System.out.println("Appending 'h':"); + queue.enqueue("h"); + System.out.println("Appending 'i':"); + queue.enqueue("i"); + System.out.println("Appending 'j':"); + queue.enqueue("j"); + System.out.println("Appending 'k':"); + queue.enqueue("k"); + System.out.println("Appending 'l':"); + queue.enqueue("l"); + System.out.println("Appending 'm':"); + queue.enqueue("m"); + System.out.println("QUEUE:"); + System.out.println(queue); + System.out.println("LEN: " + queue.len()); + System.out.println("Searching for j: " + queue.search("j")); + System.out.println("Searching for a: " + queue.search("a")); + System.out.println("Dequeueing 5 items"); + queue.dequeue(); + queue.dequeue(); + queue.dequeue(); + queue.dequeue(); + queue.dequeue(); + System.out.println("QUEUE:"); + System.out.println(queue); + System.out.println("LEN: " + queue.len()); + System.out.println("FIRST: " + queue.first()); + System.out.println("LEN: " + queue.len()); + System.out.println("Searching for j: " + queue.search("j")); + System.out.println("Searching for a: " + queue.search("a")); + System.out.println("Is queue empty? " + queue.is_empty()); + System.out.println("Dequeuing 8 more items."); + queue.dequeue(); + queue.dequeue(); + queue.dequeue(); + queue.dequeue(); + queue.dequeue(); + queue.dequeue(); + queue.dequeue(); + queue.dequeue(); + System.out.println("QUEUE: "); + System.out.println(queue); + System.out.println("Is queue empty? " + queue.is_empty()); + } +} diff --git a/Homework 4/README b/Homework 4/README new file mode 100644 index 0000000..12330f8 --- /dev/null +++ b/Homework 4/README @@ -0,0 +1,7 @@ +All of the programs are Java files, and need to be run from a complete java environment. The easiest way is +to import them into an IDE, such as Netbeans, IntelliJ IDEA, or any other competing IDE. Alternatively, +the programs can be run from the command line after compiling them with the 'javac' command, followed by the +'java' command + +Note that for the CMD environment to function properly, both the java and javac commands should be in your PATH. + diff --git a/Homework 4/Report.docx b/Homework 4/Report.docx new file mode 100644 index 0000000..7179260 Binary files /dev/null and b/Homework 4/Report.docx differ diff --git a/Homework 5/README.txt b/Homework 5/README.txt new file mode 100644 index 0000000..3be25b3 --- /dev/null +++ b/Homework 5/README.txt @@ -0,0 +1,5 @@ +The programs contained in this folder are used to implement a simple list of instructions for solving a Tower of Hanoi puzzle with a given number of disks (hanoi.py), and +a program for printing the inorder and preorder traversals of a tree input to the program as an array of integers or null values (tree.py) + +Both programs can easily be run from within your Python IDE of choice without modification, or directly run on the command line using the appropriate Python 3 command with +no additionalarguments. \ No newline at end of file diff --git a/Homework 5/Report.docx b/Homework 5/Report.docx new file mode 100644 index 0000000..d48c538 Binary files /dev/null and b/Homework 5/Report.docx differ diff --git a/Homework 5/hanoi.py b/Homework 5/hanoi.py new file mode 100644 index 0000000..2282a37 --- /dev/null +++ b/Homework 5/hanoi.py @@ -0,0 +1,14 @@ +def solveTowers(disks, pegA, pegB, pegC): + if disks == 1: + print('Move disk', disks, 'from', pegA, 'to', pegC) + else: + solveTowers(disks-1, pegA, pegC, pegB); + print('Move disk', disks, 'from', pegA, 'to', pegC) + solveTowers(disks-1, pegB, pegA, pegC); + +def main(): + disks = int(input("How many disks: ")) + solveTowers(disks, 'A', 'B', 'C') + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/Homework 5/tree.py b/Homework 5/tree.py new file mode 100644 index 0000000..dacdd46 --- /dev/null +++ b/Homework 5/tree.py @@ -0,0 +1,59 @@ +class Tree: + def __init__(self): + self.tree_list = None + + def build_from_list(self, values): + self.tree_list = values + + def print_inorder(self): + if self.tree_list is not None: + self._print_inorder(0) + + def _print_inorder(self, current_pos): + if self._left_child(current_pos) < len(self.tree_list) and self.tree_list[self._left_child(current_pos)] is not None: + self._print_inorder(self._left_child(current_pos)) + print(' ' + str(self.tree_list[current_pos]) + ' ') + if self._right_child(current_pos) < len(self.tree_list) and self.tree_list[self._right_child(current_pos)] is not None: + self._print_inorder(self._right_child(current_pos)) + + def print_preorder(self): + if self.tree_list is not None: + self._print_preorder(0) + + def _print_preorder(self, current_pos): + print(' ' + str(self.tree_list[current_pos]) + ' ') + if self._left_child(current_pos) < len(self.tree_list) and self.tree_list[self._left_child(current_pos)] is not None: + self._print_preorder(self._left_child(current_pos)) + if self._right_child(current_pos) < len(self.tree_list) and self.tree_list[self._right_child(current_pos)] is not None: + self._print_preorder(self._right_child(current_pos)) + + @staticmethod + def _left_child(pos): + return pos*2+1 + + @staticmethod + def _right_child(pos): + return pos*2+2 + + +def det_value(x): + x = x.strip() + if x == 'null': + return None + return int(x) + + +def main(): + tree = Tree() + values = [1, None, 2, None, None, 3] + input_val = input("Please input a list of numbers that is space separated, or the literal 'null': ") + values = [det_value(x) for x in input_val.split(' ')] + tree.build_from_list(values) + print("In Order Traversal: ") + tree.print_inorder() + print("Preorder Traversal: ") + tree.print_preorder() + + +if __name__ == '__main__': + main() diff --git a/Homework 6/README.txt b/Homework 6/README.txt new file mode 100644 index 0000000..8b41277 --- /dev/null +++ b/Homework 6/README.txt @@ -0,0 +1,2 @@ +The program is implemented using a single Python source file, and can be run quite easily by just calling py3 heap.py +Alternatively, the source file can be loaded into your preferred IDE and run directly from there. \ No newline at end of file diff --git a/Homework 6/Report.docx b/Homework 6/Report.docx new file mode 100644 index 0000000..7138a84 Binary files /dev/null and b/Homework 6/Report.docx differ diff --git a/Homework 6/heap.py b/Homework 6/heap.py new file mode 100644 index 0000000..4392db0 --- /dev/null +++ b/Homework 6/heap.py @@ -0,0 +1,287 @@ +class MinBinHeap: + """ + This class is an implementation of a Minimum Binary Heap, where the top element of the tree is always the smallest. + This class maintains a heapsort by using an upheap/downheap method. + """ + def __init__(self): + self.heap = [] + + def _swap(self, pos1, pos2): + temp = self.heap[pos1] + self.heap[pos1] = self.heap[pos2] + self.heap[pos2] = temp + + @staticmethod + def parent(pos): + return (pos-1)//2 + + @staticmethod + def left_child(pos): + return 2*pos+1 + + @staticmethod + def right_child(pos): + return 2*pos+2 + + def has_left(self, pos): + return 2*pos+1 < len(self.heap) and self.heap[2*pos+1] is not None + + def has_right(self, pos): + return 2*pos+2 < len(self.heap) and self.heap[2*pos+2] is not None + + def find_min(self): + return self.heap[0] + + def remove_min(self): + return_val = self.heap[0] + self._swap(0, len(self.heap)-1) + self.heap.pop() + self.down_heap(0) + return return_val + + def insert(self, item): + self.heap.append(item) + self.up_heap(len(self.heap)-1) + + def is_empty(self): + return not (len(self.heap) > 0) + + def __len__(self): + return len(self.heap) + + def size(self): + return len(self) + + def down_heap(self, pos): + child_one = child_two = -1 + if self.has_left(pos): + child_one = self.left_child(pos) + if self.has_right(pos): + child_two = self.right_child(pos) + + if child_one is not -1 and child_two is not -1: + if self.heap[child_one] < self.heap[child_two]: + smallest = child_one + else: + smallest = child_two + elif child_one is -1 and child_two is not -1: + smallest = child_two + elif child_one is not -1 and child_two is -1: + smallest = child_one + else: + return + + if smallest is not -1: + if self.heap[smallest] < self.heap[pos]: + self._swap(pos, smallest) + self.down_heap(smallest) + + def up_heap(self, pos): + if pos is not 0: + if self.heap[pos] < self.heap[self.parent(pos)]: + self._swap(pos, self.parent(pos)) + self.up_heap(self.parent(pos)) + + def build_heap(self, build_list): + self.heap = [] + for i in range(len(build_list)): + self.insert(build_list[i]) + + +class MaxBinHeap: + def __init__(self): + self.heap = [] + + def _swap(self, pos1, pos2): + temp = self.heap[pos1] + self.heap[pos1] = self.heap[pos2] + self.heap[pos2] = temp + + @staticmethod + def parent(pos): + return (pos-1)//2 + + @staticmethod + def left_child(pos): + return 2*pos+1 + + @staticmethod + def right_child(pos): + return 2*pos+2 + + def has_left(self, pos): + return 2*pos+1 < len(self.heap) and self.heap[2*pos+1] is not None + + def has_right(self, pos): + return 2*pos+2 < len(self.heap) and self.heap[2*pos+2] is not None + + def find_max(self): + return self.heap[0] + + def remove_max(self): + return_val = self.heap[0] + self._swap(0, len(self.heap)-1) + self.heap.pop() + self.down_heap(0) + return return_val + + def insert(self, item): + self.heap.append(item) + self.up_heap(len(self.heap)-1) + + def is_empty(self): + return not (len(self.heap) > 0) + + def __len__(self): + return len(self.heap) + + def size(self): + return len(self) + + def down_heap(self, pos): + child_one = child_two = -1 + if self.has_left(pos): + child_one = self.left_child(pos) + if self.has_right(pos): + child_two = self.right_child(pos) + + if child_one is not -1 and child_two is not -1: + if self.heap[child_one] > self.heap[child_two]: + largest = child_one + else: + largest = child_two + elif child_one is -1 and child_two is not -1: + largest = child_two + elif child_one is not -1 and child_two is -1: + largest = child_one + else: + return + if largest is not -1: + if self.heap[largest] > self.heap[pos]: + self._swap(pos, largest) + self.down_heap(largest) + + def up_heap(self, pos): + if pos is not 0: + if self.heap[pos] > self.heap[self.parent(pos)]: + self._swap(pos, self.parent(pos)) + self.up_heap(self.parent(pos)) + + def build_heap(self, build_list): + self.heap = [] + for i in range(len(build_list)): + self.insert(build_list[i]) + + +def heapSort(items): + heap = MaxBinHeap() + heap.build_heap(items) + item_list = [] + while not heap.is_empty(): + item_list.insert(0, heap.remove_max()) + return item_list + + +class PriorityQueue: + class Node: + def __init__(self, item, priority): + self.value = item + self.priority = priority + self.next = None + self.prev = None + + def __lt__(self, other): + return self.priority < other.priority + + def __le__(self, other): + return self.priority <= other.priority + + def __ge__(self, other): + return self.priority >= other.priority + + def __gt__(self, other): + return self.priority > other.priority + + def __eq__(self, other): + return self.priority == other.priority + + def __repr__(self): + return str(self.value) + + def __str__(self): + return str(self.value) + + def __init__(self): + self.queueFront = None + + def is_empty(self) -> bool: + return self.queueFront is None + + def remove_min(self) -> int: + ret = self.queueFront.value + self.queueFront = self.queueFront.next + return ret + + def add(self, item, priority): + new_node = self.Node(item, priority) + if self.queueFront is None: + self.queueFront = new_node + elif self.queueFront > new_node: + self.queueFront.prev = new_node + new_node.next = self.queueFront + self.queueFront = new_node + else: + current_node = self.queueFront + while current_node.next is not None: + if current_node.next <= new_node: + current_node = current_node.next + else: + current_node.next.prev = new_node + new_node.next = current_node.next + current_node.next = new_node + new_node.prev = current_node + break + else: + current_node.next = new_node + new_node.prev = current_node + + + + +def main(): + print("Testing priority queue:") + pQueue = PriorityQueue() + values = [1, 6, 3, 7, 5, 9] + print("Unsorted:", values) + for value in values: + pQueue.add(value, value) + values = [] + while not pQueue.is_empty(): + values.append(pQueue.remove_min()) + print("Sorted: ", values) + + print("Testing Heap Sort") + item_list = [9, 7, 5, 2, 6, 4] + print("Unsorted:", item_list) + print("Sorted:", heapSort(item_list)) + + print("Testing Min Binary Heap") + heap = MinBinHeap() + print('Inserting', 5) + heap.insert(5) + print('Inserting', 7) + heap.insert(7) + print('Inserting', 3) + heap.insert(3) + print('Inserting', 11) + heap.insert(11) + + print("Removing all min elements:") + print(heap.remove_min()) + print(heap.remove_min()) + print(heap.remove_min()) + print(heap.remove_min()) + + +if __name__ == '__main__': + main() diff --git a/README.md b/README.md new file mode 100644 index 0000000..9669361 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# CSC 310 Homework + +This repository serves as a space for me to keep my homework for CSC 310, ultimately to be turned in as an assignment for Homework 7. + +Each assignment has its own README file. Most have been been written using python, but a few will require a working JAVA environment.