From d9a7eeb79e9328327096a1d853707ab236e9d60f Mon Sep 17 00:00:00 2001 From: Joey Eamigh <55670930+JoeyEamigh@users.noreply.github.com> Date: Mon, 9 Oct 2023 15:03:49 -0400 Subject: [PATCH] assn03 --- .envrc | 12 ++ .jabbarc | 1 + .vscode/launch.json | 16 +- Justfile | 13 +- src/assn03/LinkedList.java | 353 +++++++++++++++++++++++++++++++++++++ src/assn03/Main.java | 135 ++++++++++++++ src/assn03/Node.java | 16 ++ src/assn03/NodeImpl.java | 32 ++++ 8 files changed, 574 insertions(+), 4 deletions(-) create mode 100644 .envrc create mode 100644 .jabbarc create mode 100644 src/assn03/LinkedList.java create mode 100644 src/assn03/Main.java create mode 100644 src/assn03/Node.java create mode 100644 src/assn03/NodeImpl.java diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3d422b6 --- /dev/null +++ b/.envrc @@ -0,0 +1,12 @@ +jabba() { + local fd3=$(mktemp /tmp/jabba-fd3.XXXXXX) + ( + JABBA_SHELL_INTEGRATION=ON $HOME/.jabba/bin/jabba "$@" 3>|${fd3} + ) + local exit_code=$? + eval $(cat ${fd3}) + rm -f ${fd3} + return ${exit_code} +} + +jabba use diff --git a/.jabbarc b/.jabbarc new file mode 100644 index 0000000..ea7dcaf --- /dev/null +++ b/.jabbarc @@ -0,0 +1 @@ +20.0.2 \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index d3fb27c..72522da 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,6 +4,20 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ + { + "type": "java", + "name": "Main", + "request": "launch", + "mainClass": "assn03.Main", + "projectName": "COMP210_238a5b6" + }, + { + "type": "java", + "name": "JavaWarmUp", + "request": "launch", + "mainClass": "assn02.JavaWarmUp", + "projectName": "COMP210_238a5b6" + }, { "type": "java", "name": "Current File", @@ -32,4 +46,4 @@ "projectName": "COMP210_238a5b6" } ] -} \ No newline at end of file +} diff --git a/Justfile b/Justfile index bc56e5a..f6367a6 100644 --- a/Justfile +++ b/Justfile @@ -1,12 +1,19 @@ default: run -run file=(`find src -type f -printf '%T@ %p\n' | sort -n | cut -d " " -f 2- | tail -1`): - java {{file}} +recentFile := `find src -type f -printf '%T@ %p\n' | sort -n | cut -d " " -f 2- | tail -1` +recentFolder := `find src -type d -printf '%T@ %p\n' | sort -n | cut -d' ' -f 2- | sed 's/src\///' | tail -2 | head -1` + +echo: + echo {{recentFile}} + echo {{recentFolder}} + +run file=recentFile: + if [ -f ./src/{{recentFolder}}/Main.java ]; then java --enable-preview -XX:+ShowCodeDetailsInExceptionMessages -cp ./out {{recentFolder}}.Main; else java {{file}}; fi all: for file in `find src -type f -printf '%T@ %p\n' | sort -n | cut -d " " -f 2-`; do just run $file; done -zip folder=(`find src -type d -printf '%T@ %p\n' | sort -n | cut -d' ' -f 2- | sed 's/src\///' | tail -1`): +zip folder=recentFolder: rm -rf ./zips/{{folder}}.zip zip -r ./zips/{{folder}}.zip ./src/{{folder}} diff --git a/src/assn03/LinkedList.java b/src/assn03/LinkedList.java new file mode 100644 index 0000000..ad975d8 --- /dev/null +++ b/src/assn03/LinkedList.java @@ -0,0 +1,353 @@ +package assn03; + +public class LinkedList { + private Node head = null; + private Node tail = null; + private int size = 0; + + /** + * Task1 + * Remove the node at index i of the list. + * Note that the first element is at index 0 + * If i is larger than the size of the list, throw an IndexOutOfBounds Exception + * + * ex: list: A -> B -> C -> D + * i: 1 + * list after removeAtIndex: A -> C -> D + * + * @param i - index of node to remove + */ + public void removeAtIndex(int i) { + this.validIndex(i); + + if (i == 0) { + head = head.getNext(); + size--; + return; + } + + Object node = this.get(i); + this.remove(node); + } + + /** + * Task2 + * Return true if this linked list is equal to the list argument, false + * otherwise. + * Two lists are equal if they have the same size, and the same + * elements in the same order. + * ex: list: 1 -> 4 -> 2 + * list2: 1 -> 4 -> 2 + * return: true + * + * list: 1 -> 5 + * list2: 2 -> 5 + * return false; + * + * @param list2 - the list to compare with the current list + * @return true if the lists have the same elements in the same order, false + * otherwise + */ + public boolean isEqual(LinkedList list2) { + if (this.size() == list2.size()) { + for (int i = 0; i < this.size(); i++) + if (this.get(i) != list2.get(i)) + return false; + + return true; + } + + return false; + } + + /** + * Task3 + * Given a sorted linked list, remove the duplicate values from the list + * ex: list: 5 -> 6 -> 7 -> 7 -> 7 -> 8 -> 8 -> 9 + * list after removeRepeats: 5 -> 6 -> 7 -> 8 -> 9 + * + */ + public void removeRepeats() { + if (this.size() <= 0) + return; + + Node previous = head; + for (int i = 1; i < this.size(); i++) { + Node current = previous.getNext(); + + if (previous.getValue() == current.getValue()) { + this.removeAtIndex(i); + i--; + } + + previous = current; + } + } + + /** + * Task4 + * Reverse the list + * + * ex list: 10 -> 9 -> 8 -> 7 + * list after reverse: 7 -> 8 -> 9 -> 10 + * + */ + public void reverse() { + if (this.size() <= 1) + return; + + Node previous = null; + Node current = head; + Node next = null; + + while (current != null) { + next = current.getNext(); + current.setNext(previous); + previous = current; + current = next; + } + + head = previous; + } + + /** + * Task5 + * Merge the given linked list2 into the current list. The 2 lists will always + * be + * either the same size, or the current list will be longer than list2. + * The examples below show how to handle each case. + * + * Note: Do NOT create and return a new list, merge the second list into the + * first one. + * + * ex: list: 1 -> 2 -> 3 + * list2: 4 -> 5 -> 6 + * return: 1 -> 4 -> 2 -> 5 -> 3 -> 6 + * + * list: 1 -> 2 -> 3 -> 4 + * list2: 5 -> 6 + * return 1 -> 5 -> 2 -> 6 -> 3 -> 4 + * + * @param list2 + */ + public void merge(LinkedList list2) { + if (this.size() <= 0) + return; + + Node current = head; + Node current2 = list2.getHead(); + Node next = null; + Node next2 = null; + + while (current != null && current2 != null) { + next = current.getNext(); + next2 = current2.getNext(); + + current.setNext(current2); + current2.setNext(next); + + current = next; + current2 = next2; + } + } + + /* Implementations below are being given to you. Do not modify below this. */ + + public int size() { + return size; + } + + public boolean isEmpty() { + return size == 0; + } + + public void clear() { + head = null; + tail = null; + size = 0; + } + + public boolean contains(Object element) { + Node current = head; + while (current != null) { + if (current.getValue().equals(element)) { + return true; + } + current = current.getNext(); + } + return false; + } + + public T[] toArray() { + T[] arr = (T[]) new Object[size()]; + Node current = head; + int i = 0; + if (isEmpty()) { + return arr; + } + while (current != null) { + arr[i] = current.getValue(); + current = current.getNext(); + i++; + } + return arr; + } + + public void add(Object element) { + Node newNode = new NodeImpl((T) element, null); + if (isEmpty()) { + head = newNode; + tail = newNode; + size++; + } else { + tail.setNext(newNode); + tail = newNode; + size++; + } + + } + + public boolean remove(Object element) { + Node current = head; + if (isEmpty()) { + return false; + } + if (current.getValue() == element) { + head = head.getNext(); + size--; + return true; + } + while (current.getNext().getValue() != element) { + current = current.getNext(); + if (current == null) { + return false; + } + } + if (current.getNext().getNext() == null) { + tail = current; + } + current.setNext(current.getNext().getNext()); + size--; + return true; + } + + public T get(int index) { + validIndex(index); + Node current = head; + int i = 0; + while (i < index) { + current = current.getNext(); + i++; + } + return current.getValue(); + } + + public T set(int index, Object element) { + validIndex(index); + Node current = head; + T prevValue = null; + int i = 0; + if (index == 0) { + prevValue = head.getValue(); + head.setValue((T) element); + } else { + while (current != null) { + if (i == index) { + prevValue = current.getValue(); + current.setValue((T) element); + return prevValue; + } + current = current.getNext(); + i++; + } + } + + return prevValue; + } + + public void add(int index, Object element) { + if (index > size) { + validIndex(index); + } + Node current = head; + int i = 0; + if (index == 0) { + if (isEmpty()) { + add(element); + return; + } else { + Node newNode = new NodeImpl((T) element, head.getNext()); + head = newNode; + size++; + return; + } + + } else if (index == size) { + add(element); + return; + } + while (current != null) { + if (i == (index - 1)) { + Node temp = current.getNext(); + Node newNode = new NodeImpl((T) element, temp); + current.setNext(newNode); + size++; + return; + } else { + current = current.getNext(); + i++; + } + } + } + + public int indexOf(Object element) { + Node current = head; + int index = 0; + while (current != null) { + if (current.getValue().equals((T) element)) { + return index; + } + index++; + current = current.getNext(); + } + return -1; + } + + public int lastIndexOf(Object element) { + Node current = head; + int index = -1; + int i = 0; + while (current != null) { + if (current.getValue().equals((T) element)) { + index = i; + } + i++; + current = current.getNext(); + } + return index; + } + + public void validIndex(int i) { + if (i < 0 || i >= size) { + throw new IndexOutOfBoundsException("Invalid index"); + } + } + + public Node getHead() { + return head; + } + + @Override + public String toString() { + String list = ""; + Node current = head; + while (current != null) { + if (current.getNext() == null) + list += current.getValue(); + else + list += current.getValue() + " -> "; + current = current.getNext(); + } + return list; + } +} \ No newline at end of file diff --git a/src/assn03/Main.java b/src/assn03/Main.java new file mode 100644 index 0000000..ee40273 --- /dev/null +++ b/src/assn03/Main.java @@ -0,0 +1,135 @@ +package assn03; + +public class Main { + + public static void main(String[] args) { + LinkedList defaultList = new LinkedList(); + defaultList.add(10); + defaultList.add(20); + defaultList.add(60); + defaultList.add(30); + System.out.println("list = " + defaultList.toString()); + System.out.println("size of list = " + defaultList.size()); + System.out.println("list contains 10?: " + defaultList.contains(10)); // implemented + System.out.println("list contains 50?: " + defaultList.contains(50)); + System.out.println("set element at index 2 to be 10"); + defaultList.set(2, 10); + System.out.println("get element at index 2 = " + defaultList.get(2)); + System.out.println("list = " + defaultList.toString()); + System.out.println("Last Index of element 10 in list = " + defaultList.lastIndexOf(10)); + + defaultList.remove(20); + System.out.println("list after removing 20 = " + defaultList.toString()); + + int indexOf30 = defaultList.indexOf(30); + System.out.println("index of '30' = " + indexOf30); + + // Test task 1 + LinkedList task1List1 = new LinkedList(); + task1List1.add(1); + task1List1.add(4); + task1List1.add(2); + System.out.println("task1List1 = " + task1List1.toString()); + task1List1.removeAtIndex(1); + System.out.println("Task 1: task1List1 after removing index 1 = " + task1List1.toString()); + + LinkedList task1List2 = new LinkedList(); + task1List2.add(1); + task1List2.add(4); + task1List2.add(2); + System.out.println("task1List2 = " + task1List2.toString()); + task1List2.removeAtIndex(0); + System.out.println("Task 1: task1List2 after removing index 0 = " + task1List2.toString()); + + LinkedList task1List3 = new LinkedList(); + task1List3.add(1); + task1List3.add(4); + task1List3.add(2); + System.out.println("task1List3 = " + task1List3.toString()); + try { + task1List3.removeAtIndex(3); + } catch (Exception e) { + System.out.println("task1List3 = successfully failed to remove index 3 - " + e.getMessage()); + } + + // Test task 2 + LinkedList task2List1 = new LinkedList(); + task2List1.add(1); + task2List1.add(4); + task2List1.add(2); + System.out.println("task2List1 = " + task2List1.toString()); + + LinkedList task2List2 = new LinkedList(); + task2List2.add(1); + task2List2.add(4); + task2List2.add(2); + System.out.println("task2List2 = " + task2List2.toString()); + + System.out.println("Task 2: task2List1 equals task2List2? " + task2List1.isEqual(task2List2)); + + LinkedList task2List3 = new LinkedList(); + task2List3.add(1); + task2List3.add(5); + System.out.println("task2List3 = " + task2List3.toString()); + + System.out.println("Task 2: task2List1 equals task2List3? " + task2List1.isEqual(task2List3)); + + // Test task 3 + LinkedList task3List1 = new LinkedList(); + task3List1.add(1); + task3List1.add(2); + task3List1.add(2); + task3List1.add(2); + task3List1.add(2); + task3List1.add(3); + task3List1.add(3); + task3List1.add(3); + task3List1.add(4); + System.out.println("task3List1 before removing repeats = " + task3List1.toString()); + task3List1.removeRepeats(); + System.out.println("task3List1 after removing repeats = " + task3List1.toString()); + + // Test task 4 + LinkedList task4List = new LinkedList(); + task4List.add(1); + task4List.add(2); + task4List.add(3); + task4List.add(4); + System.out.println("task4List before reversing = " + task4List.toString()); + task4List.reverse(); + System.out.println("task4List after reversing = " + task4List.toString()); + + // Test task 5 + LinkedList task5List1 = new LinkedList(); + task5List1.add(1); + task5List1.add(2); + task5List1.add(3); + + LinkedList task5List2 = new LinkedList(); + task5List2.add(4); + task5List2.add(5); + task5List2.add(6); + + System.out.println("task5List1 = " + task5List1.toString()); + System.out.println("task5List2 = " + task5List2.toString()); + + task5List1.merge(task5List2); + System.out.println("task5List1 after merging task5List2 = " + task5List1.toString()); + + LinkedList task5List3 = new LinkedList(); + task5List3.add(1); + task5List3.add(2); + task5List3.add(3); + task5List3.add(4); + + LinkedList task5List4 = new LinkedList(); + task5List4.add(5); + task5List4.add(6); + + System.out.println("task5List3 = " + task5List3.toString()); + System.out.println("task5List4 = " + task5List4.toString()); + + task5List3.merge(task5List4); + System.out.println("task5List3 after merging task5List4 = " + task5List3.toString()); + } +} diff --git a/src/assn03/Node.java b/src/assn03/Node.java new file mode 100644 index 0000000..4d687e9 --- /dev/null +++ b/src/assn03/Node.java @@ -0,0 +1,16 @@ +package assn03; + +public interface Node { + + T getValue(); + + void setValue(T value); + + Node getNext(); + + void setNext(Node next); + + default boolean hasNext() { + return (getNext() != null); + } +} \ No newline at end of file diff --git a/src/assn03/NodeImpl.java b/src/assn03/NodeImpl.java new file mode 100644 index 0000000..d3bb4e3 --- /dev/null +++ b/src/assn03/NodeImpl.java @@ -0,0 +1,32 @@ +package assn03; + +public class NodeImpl implements Node { + + private T _value; + private Node _next; + + public NodeImpl(T value, Node next) { + _value = value; + _next = next; + } + + @Override + public T getValue() { + return _value; + } + + @Override + public void setValue(T value) { + _value = value; + } + + @Override + public Node getNext() { + return _next; + } + + @Override + public void setNext(Node next) { + _next = next; + } +}