diff --git a/.gitea/workflows/gradle_build.yml b/.gitea/workflows/gradle_build.yml
new file mode 100644
index 0000000..f135547
--- /dev/null
+++ b/.gitea/workflows/gradle_build.yml
@@ -0,0 +1,24 @@
+name: sample gradle build and test
+run-name: Build started by $ {{gitea.actor }}
+on:
+ push:
+ branches: [main]
+ pull_request:
+ branches: [main]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check out repository code
+ uses: actions/checkout@v4
+ - name: JDK setup
+ uses: actions/setup-java@v4
+ with:
+ distribution: 'zulu'
+ java-version: '21'
+ - name: Validate Gradle Wrapper
+ uses: gradle/actions/wrapper-validation@v3
+ - name: Gradle build
+ run: ./gradlew build -i
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/clients/src/main/java/com/hithomelabs/clients/ArrayQueueClient.java b/clients/src/main/java/com/hithomelabs/clients/ArrayQueueClient.java
new file mode 100644
index 0000000..7022367
--- /dev/null
+++ b/clients/src/main/java/com/hithomelabs/clients/ArrayQueueClient.java
@@ -0,0 +1,20 @@
+package com.hithomelabs.clients;
+
+import com.hithomelabs.princeton1.module4.ArrayQueue;
+import com.hithomelabs.princeton1.module4.Queue;
+
+public class ArrayQueueClient {
+ public static void main(String[] args) {
+ Queue queue = new ArrayQueue();
+ for(int i = 0; i < 21; i++){
+ queue.enqueue(i);
+ }
+ for(int i = 0; i < 13; i++){
+ System.out.println(queue.dequeue());
+ }
+
+ // Using object s, as stack is generic but every java Object has implementation of toString()
+ for (Object s : queue)
+ System.out.println(s);
+ }
+ }
diff --git a/clients/src/main/java/com/hithomelabs/clients/ArrayStackClient.java b/clients/src/main/java/com/hithomelabs/clients/ArrayStackClient.java
new file mode 100644
index 0000000..53a40c1
--- /dev/null
+++ b/clients/src/main/java/com/hithomelabs/clients/ArrayStackClient.java
@@ -0,0 +1,19 @@
+package com.hithomelabs.clients;
+
+import com.hithomelabs.princeton1.module4.ArrayStack;
+import com.hithomelabs.princeton1.module4.Stack;
+
+public class ArrayStackClient {
+ public static void main(String[] args) {
+ Stack stack = new ArrayStack();
+ for(int i = 0; i < 21; i++){
+ stack.push(i);
+ }
+ // Using object s, as stack is generic but every java Object has implementation of toString()
+ for (Object s : stack)
+ System.out.println(s);
+ while(!stack.isEmpty()){
+ System.out.println(stack.pop());
+ }
+ }
+}
diff --git a/clients/src/main/java/com/hithomelabs/clients/LinkedQueueClient.java b/clients/src/main/java/com/hithomelabs/clients/LinkedQueueClient.java
new file mode 100644
index 0000000..008742c
--- /dev/null
+++ b/clients/src/main/java/com/hithomelabs/clients/LinkedQueueClient.java
@@ -0,0 +1,20 @@
+package com.hithomelabs.clients;
+
+import com.hithomelabs.princeton1.module4.LinkedQueue;
+import com.hithomelabs.princeton1.module4.Queue;
+
+public class LinkedQueueClient {
+ public static void main(String[] args) {
+ Queue queue = new LinkedQueue();
+ for(int i = 0; i < 21; i++){
+ queue.enqueue(i);
+ }
+ for(int i = 0; i < 13; i++){
+ System.out.println(queue.dequeue());
+ }
+
+ // Using object s, as stack is generic but every java Object has implementation of toString()
+ for (Object s : queue)
+ System.out.println(s);
+ }
+ }
diff --git a/clients/src/main/java/com/hithomelabs/clients/Main.java b/clients/src/main/java/com/hithomelabs/clients/LinkedStackClient.java
similarity index 95%
rename from clients/src/main/java/com/hithomelabs/clients/Main.java
rename to clients/src/main/java/com/hithomelabs/clients/LinkedStackClient.java
index d8c5d68..33cc4e9 100644
--- a/clients/src/main/java/com/hithomelabs/clients/Main.java
+++ b/clients/src/main/java/com/hithomelabs/clients/LinkedStackClient.java
@@ -4,7 +4,7 @@ package com.hithomelabs.clients;
import com.hithomelabs.princeton1.module4.LinkedStack;
import com.hithomelabs.princeton1.module4.Stack;
-public class Main {
+public class LinkedStackClient {
public static void main(String[] args) {
Stack stack = new LinkedStack();
stack.push("hello");
diff --git a/module4/src/main/java/com/hithomelabs/princeton1/module4/ArrayQueue.java b/module4/src/main/java/com/hithomelabs/princeton1/module4/ArrayQueue.java
new file mode 100644
index 0000000..4e8988e
--- /dev/null
+++ b/module4/src/main/java/com/hithomelabs/princeton1/module4/ArrayQueue.java
@@ -0,0 +1,103 @@
+package com.hithomelabs.princeton1.module4;
+
+import javax.annotation.Nonnull;
+import java.util.Iterator;
+
+public class ArrayQueue extends Queue{
+
+ // insertion from tail, removal from head
+ public static final int DEFAULT_CAPACITY = 10;
+ private int capacity;
+ private int tail;
+ private int head;
+ private int size;
+ private E[] arr;
+
+ public ArrayQueue(){
+ this(DEFAULT_CAPACITY);
+ }
+
+ public ArrayQueue(int capacity){
+ this.capacity = capacity;
+ arr = (E[]) new Object[this.capacity];
+ size = 0;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return size == 0;
+ }
+
+ @Override
+ public E dequeue() {
+ if(isEmpty())
+ return null;
+ else{
+ E element = arr[head];
+ // Garbage collection
+ arr[head] = null;
+ head = (head+1)%capacity;
+ size = size - 1;
+ if(capacity >= 40 && size < capacity/4){
+ capacity = capacity/2;
+ resize(capacity, capacity*2);
+ }
+ return element;
+ }
+ }
+
+ @Override
+ public void enqueue(E element) {
+ // We plan capacity expansion if needed
+ if (size == capacity){
+ capacity = capacity * 2;
+ resize(capacity, capacity/2);
+ }
+ arr[tail] = element;
+ tail = (tail + 1) % capacity;
+ ++size;
+ }
+
+ // When resize takes place always the original array is full, so copy the complete array as is
+ private void resize(int capacity, int oldCapacity) {
+ E[] resizedArr = (E[]) new Object[capacity];
+ for(int i = 0; i < size; i++) {
+ resizedArr[i] = arr[head];
+ // halving because capacity has now doubled
+ arr[head] = null;
+ head = (head + 1) % oldCapacity;
+ }
+ arr = resizedArr;
+ // When resizing takes place, we bring the head to 0 and the tail to size
+ // tail is where new inserts will be made and head will be where elements will be removed
+ tail = size;
+ head = 0;
+
+ }
+
+ @Override
+ public int size() {
+ return size;
+ }
+
+ @Override
+ @Nonnull
+ public Iterator iterator() {
+ return new Iterator() {
+ int counter = size;
+ int pointer = head;
+ @Override
+ public boolean hasNext() {
+ return counter != 0;
+ }
+
+ @Override
+ public E next() {
+ E element = arr[pointer];
+ pointer = (pointer + 1)% capacity;
+ --counter;
+ return element;
+ }
+ };
+ }
+}
diff --git a/module4/src/main/java/com/hithomelabs/princeton1/module4/ArrayStack.java b/module4/src/main/java/com/hithomelabs/princeton1/module4/ArrayStack.java
new file mode 100644
index 0000000..0ae2eb6
--- /dev/null
+++ b/module4/src/main/java/com/hithomelabs/princeton1/module4/ArrayStack.java
@@ -0,0 +1,98 @@
+package com.hithomelabs.princeton1.module4;
+import javax.annotation.Nonnull;
+import java.util.Iterator;
+
+// Concrete implementation of stack using arrays
+// Creating a generic stack of type E
+public class ArrayStack extends Stack {
+
+ // Capacity and size are two variables, capacity determines total capacity of array, capacity defaults at 10
+ // Everytime size == capacity, capacity = 2 * capacity
+ private static final int DEFAULT_CAPACITY = 10;
+ private int capacity;
+ private int size;
+ private E[] arr;
+
+ public ArrayStack(int capacity){
+ this.capacity = capacity;
+ arr = (E[]) new Object[this.capacity];
+ }
+
+ // Constructor chaining, default constructor will call parametrised constructor with default initial capacity 10
+ public ArrayStack(){
+ this(DEFAULT_CAPACITY);
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return size == 0;
+ }
+
+ private void changeCapacity(int newCapacity){
+ E[] resizedArr = (E[]) new Object[newCapacity];
+ for (int i = 0; i < size; i++)
+ resizedArr[i] = arr[i];
+ arr = resizedArr;
+ }
+
+ private void incrementSize(){
+ if (size == capacity){
+ capacity = 2 * capacity;
+ changeCapacity(capacity);
+ }
+ }
+
+ // Push always happens at the end of the stack
+ // Say the size of the stack is 1, new element gets inserted at 1
+ @Override
+ public void push(E element) {
+ // Lazy approach, we assume size to always be lesser than capacity
+ incrementSize();
+ arr[size++] = element;
+ }
+
+ @Override
+ public E pop() {
+ if (isEmpty())
+ return null;
+ else{
+ E e = arr[--size];
+ arr[size] = null;
+ checkResize();
+ return e;
+ }
+ }
+
+ private void checkResize() {
+ if (size < capacity / 4 && capacity >= 40){
+ capacity = capacity / 2;
+ changeCapacity(capacity);
+ }
+ }
+
+ @Override
+ public int size() {
+ return size;
+ }
+
+ @Override
+ @Nonnull
+ public Iterator iterator() {
+ return new Iterator() {
+
+ int current = 0;
+
+ @Override
+ public boolean hasNext() {
+ return current != size;
+ }
+
+ @Override
+ public E next() {
+ E element = arr[current];
+ current = current + 1;
+ return element;
+ }
+ };
+ }
+}
diff --git a/module4/src/main/java/com/hithomelabs/princeton1/module4/LinkedQueue.java b/module4/src/main/java/com/hithomelabs/princeton1/module4/LinkedQueue.java
new file mode 100644
index 0000000..ec37bbe
--- /dev/null
+++ b/module4/src/main/java/com/hithomelabs/princeton1/module4/LinkedQueue.java
@@ -0,0 +1,74 @@
+package com.hithomelabs.princeton1.module4;
+
+import javax.annotation.Nonnull;
+import java.util.Iterator;
+
+public class LinkedQueue extends Queue{
+
+ Node head;
+ Node tail;
+ int size;
+
+ private class Node{
+ E value;
+ Node next;
+
+ Node(E value){
+ this.value = value;
+ }
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return size==0;
+ }
+
+ @Override
+ public E dequeue() {
+ if(isEmpty())
+ return null;
+ E element = head.value;
+ // Only a single element is present
+ if (head == tail){
+ tail = null;
+ }
+ head = head.next;
+ --size;
+ return element;
+ }
+
+ @Override
+ public void enqueue(E element) {
+ Node newNode = new Node(element);
+ if(isEmpty())
+ head = newNode;
+ else
+ tail.next = newNode;
+ tail = newNode;
+ ++size;
+ }
+
+ @Override
+ public int size() {
+ return size;
+ }
+
+ @Override
+ @Nonnull
+ public Iterator iterator() {
+ return new Iterator() {
+ Node current = head;
+ @Override
+ public boolean hasNext() {
+ return current != tail;
+ }
+
+ @Override
+ public E next() {
+ E element = current.value;
+ current = current.next;
+ return element;
+ }
+ };
+ }
+}
diff --git a/module4/src/main/java/com/hithomelabs/princeton1/module4/Queue.java b/module4/src/main/java/com/hithomelabs/princeton1/module4/Queue.java
new file mode 100644
index 0000000..6c4999d
--- /dev/null
+++ b/module4/src/main/java/com/hithomelabs/princeton1/module4/Queue.java
@@ -0,0 +1,10 @@
+package com.hithomelabs.princeton1.module4;
+
+public abstract class Queue implements Iterable {
+
+ public abstract boolean isEmpty();
+ public abstract E dequeue();
+ public abstract void enqueue(E element);
+ public abstract int size();
+}
+