From a47911b1a3c75b28d97a3f2a25dacea75355e8e8 Mon Sep 17 00:00:00 2001 From: kdgorodkova Date: Sat, 28 Feb 2026 00:25:44 +0300 Subject: [PATCH 1/8] randomset: --- .../practice/randomSet/RandomSet.java | 139 +++++++++++++++++- 1 file changed, 134 insertions(+), 5 deletions(-) diff --git a/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java index 8af477b5..2539d775 100644 --- a/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java +++ b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java @@ -2,20 +2,149 @@ public class RandomSet { + private static final int INITIAL_CAPACITY = 16; + private static final double LOAD_FACTOR = 0.7; + + private Object[] data; + private int size; + + private Entry[] table; + private int capacity; + private int tableSize; + + private final Random random = new Random(); + + public RandomSet() { + data = new Object[INITIAL_CAPACITY]; + size = 0; + + capacity = INITIAL_CAPACITY; + table = (Entry[]) new Entry[capacity]; + tableSize = 0; + } + public boolean insert(T value) { - throw new UnsupportedOperationException("Not implemented"); + if (contains(value)) { + return false; + } + + ensureDataCapacity(); + ensureTableCapacity(); + + data[size] = value; + put(value, size); + + size++; + return true; } public boolean remove(T value) { - throw new UnsupportedOperationException("Not implemented"); + int index = findIndex(value); + if (index == -1) { + return false; + } + + int dataIndex = table[index].dataIndex; + + T lastElement = elementAt(size - 1); + data[dataIndex] = lastElement; + + int lastTableIndex = findIndex(lastElement); + table[lastTableIndex].dataIndex = dataIndex; + + data[size - 1] = null; + size--; + + table[index].deleted = true; + tableSize--; + + return true; } public boolean contains(T value) { - throw new UnsupportedOperationException("Not implemented"); + return findIndex(value) != -1; } public T getRandom() { - throw new UnsupportedOperationException("Not implemented"); + if (size == 0) { + throw new EmptySetException("Set is empty"); + } + + int index = random.nextInt(size); + return elementAt(index); + } + + private T elementAt(int index) { + return (T) data[index]; + } + + private void ensureDataCapacity() { + if (size >= data.length) { + Object[] newData = new Object[data.length * 2]; + System.arraycopy(data, 0, newData, 0, data.length); + data = newData; + } + } + + private void ensureTableCapacity() { + if ((double) tableSize / capacity >= LOAD_FACTOR) { + rehash(); + } + } + + private void rehash() { + Entry[] oldTable = table; + capacity *= 2; + table = (Entry[]) new Entry[capacity]; + tableSize = 0; + + for (Entry entry : oldTable) { + if (entry != null && !entry.deleted) { + put(entry.value, entry.dataIndex); + } + } + } + + private void put(T value, int dataIndex) { + int hash = hash(value); + while (table[hash] != null && !table[hash].deleted) { + hash = (hash + 1) % capacity; + } + table[hash] = new Entry<>(value, dataIndex); + tableSize++; + } + + private int findIndex(T value) { + int hash = hash(value); + int start = hash; + + while (table[hash] != null) { + if (!table[hash].deleted && table[hash].value.equals(value)) { + return hash; + } + hash = (hash + 1) % capacity; + if (hash == start) { + break; + } + } + + return -1; + } + + private int hash(T value) { + return (value == null ? 0 : Math.abs(value.hashCode())) % capacity; + } + + private static class Entry { + T value; + int dataIndex; + boolean deleted; + + Entry(T value, int dataIndex) { + this.value = value; + this.dataIndex = dataIndex; + this.deleted = false; + } } -} +} \ No newline at end of file From 15c6162671df3a41990e6c727185731dadb6fca6 Mon Sep 17 00:00:00 2001 From: kdgorodkova Date: Sat, 28 Feb 2026 01:08:38 +0300 Subject: [PATCH 2/8] randomset: --- .../java/lectures/lecture3/practice/randomSet/RandomSet.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java index 2539d775..e3f07dae 100644 --- a/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java +++ b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java @@ -1,5 +1,7 @@ package hse.java.lectures.lecture3.practice.randomSet; +import java.util.Random; + public class RandomSet { private static final int INITIAL_CAPACITY = 16; @@ -12,8 +14,6 @@ public class RandomSet { private int capacity; private int tableSize; - private final Random random = new Random(); - public RandomSet() { data = new Object[INITIAL_CAPACITY]; size = 0; From cf17ab58cfb951fb72311189003e6a37d8bcf7c3 Mon Sep 17 00:00:00 2001 From: kdgorodkova Date: Sat, 28 Feb 2026 01:13:49 +0300 Subject: [PATCH 3/8] randomset: --- .../java/lectures/lecture3/practice/randomSet/RandomSet.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java index e3f07dae..0d2c4750 100644 --- a/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java +++ b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java @@ -14,6 +14,8 @@ public class RandomSet { private int capacity; private int tableSize; + private final Random random = new Random(); + public RandomSet() { data = new Object[INITIAL_CAPACITY]; size = 0; From d3aafa97b8dbcee09ad106baec1a7b5d8d85da53 Mon Sep 17 00:00:00 2001 From: Ksenia Gorodkova Date: Sat, 14 Mar 2026 13:05:08 +0300 Subject: [PATCH 4/8] queue: --- .../tasks/queue/BoundedBlockingQueue.java | 48 ++++++++++++++++--- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/src/main/java/hse/java/lectures/lecture6/tasks/queue/BoundedBlockingQueue.java b/src/main/java/hse/java/lectures/lecture6/tasks/queue/BoundedBlockingQueue.java index 5c686cff..b35fe918 100644 --- a/src/main/java/hse/java/lectures/lecture6/tasks/queue/BoundedBlockingQueue.java +++ b/src/main/java/hse/java/lectures/lecture6/tasks/queue/BoundedBlockingQueue.java @@ -1,25 +1,59 @@ package hse.java.lectures.lecture6.tasks.queue; public class BoundedBlockingQueue { - + private final Object[] buffer; + private int head = 0; + private int tail = 0; + private int count = 0; + private final int capacity; public BoundedBlockingQueue(int capacity) { - + if (capacity <= 0) { + throw new IllegalArgumentException("Capacity error"); + } + this.capacity = capacity; + this.buffer = new Object[capacity]; } - public void put(T item) { + public void put(T item) throws InterruptedException { + if (item == null) { + throw new NullPointerException("Item error"); + } + + synchronized (this) { + while (count == capacity) { + wait(); + } + buffer[tail] = item; + tail = (tail + 1) % capacity; + count++; + + notifyAll(); + } } - public T take() { - return null; + public T take() throws InterruptedException { + synchronized (this) { + while (count == 0) { + wait(); + } + + T item = (T) buffer[head]; + buffer[head] = null; + head = (head + 1) % capacity; + count--; + + notifyAll(); + return item; + } } public int size() { - return 0; + return count; } public int capacity() { - return 0; + return capacity; } } From 388557f96070374f50634afab8528b4d8c80efbf Mon Sep 17 00:00:00 2001 From: Ksenia Gorodkova Date: Tue, 17 Mar 2026 00:06:23 +0300 Subject: [PATCH 5/8] synchronizer: --- .../tasks/synchronizer/StreamWriter.java | 12 ++++ .../tasks/synchronizer/StreamingMonitor.java | 65 ++++++++++++++++++- .../tasks/synchronizer/Synchronizer.java | 17 +++++ 3 files changed, 93 insertions(+), 1 deletion(-) diff --git a/src/main/java/hse/java/lectures/lecture6/tasks/synchronizer/StreamWriter.java b/src/main/java/hse/java/lectures/lecture6/tasks/synchronizer/StreamWriter.java index fedb5e66..77923f1d 100644 --- a/src/main/java/hse/java/lectures/lecture6/tasks/synchronizer/StreamWriter.java +++ b/src/main/java/hse/java/lectures/lecture6/tasks/synchronizer/StreamWriter.java @@ -28,8 +28,20 @@ public void attachMonitor(StreamingMonitor monitor) { public void run() { // Writer threads are intentionally infinite for the task contract. while (true) { + if (monitor.isCompleted()) { + break; + } + + if (!monitor.waitingForTurn(id)) { + break; + } + output.print(message); onTick.run(); + + if(!monitor.tickCompleated(id)) { + break; + } } } diff --git a/src/main/java/hse/java/lectures/lecture6/tasks/synchronizer/StreamingMonitor.java b/src/main/java/hse/java/lectures/lecture6/tasks/synchronizer/StreamingMonitor.java index 68e8f279..51e29849 100644 --- a/src/main/java/hse/java/lectures/lecture6/tasks/synchronizer/StreamingMonitor.java +++ b/src/main/java/hse/java/lectures/lecture6/tasks/synchronizer/StreamingMonitor.java @@ -1,5 +1,68 @@ package hse.java.lectures.lecture6.tasks.synchronizer; public class StreamingMonitor { - // impl your sync here + private int currentId = 1; + private final int writerCount; + private final int tickPerWriter; + private int[] totalTick; + private boolean completed = false; + + public StreamingMonitor(int writerCount, int tickPerWriter) { + this.writerCount = writerCount; + this.tickPerWriter = tickPerWriter; + this. totalTick = new int[writerCount+1]; + } + + public synchronized boolean waitingForTurn(int writerId) { + if (completed) { + return false; + } + + while (writerId != currentId && !completed) { + try { + wait(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return false; + } + } + + if (completed) { + return false; + } + + return true; + } + + public synchronized boolean tickCompleated(int writerId) { + if (completed) { + return false; + } + + totalTick[writerId]++; + + currentId = (currentId % writerCount) + 1; + + boolean allWriterCompleated = true; + + for (int i = 1; i < writerCount; i++) { + if(totalTick[i] < tickPerWriter) { + allWriterCompleated = false; + break; + } + } + + if (allWriterCompleated) { + completed = true; + notifyAll(); + return false; + } + + notifyAll(); + return true; + } + + public synchronized boolean isCompleted() { + return completed + } } diff --git a/src/main/java/hse/java/lectures/lecture6/tasks/synchronizer/Synchronizer.java b/src/main/java/hse/java/lectures/lecture6/tasks/synchronizer/Synchronizer.java index 3cb8aded..7a910718 100644 --- a/src/main/java/hse/java/lectures/lecture6/tasks/synchronizer/Synchronizer.java +++ b/src/main/java/hse/java/lectures/lecture6/tasks/synchronizer/Synchronizer.java @@ -23,11 +23,28 @@ public Synchronizer(List tasks, int ticksPerWriter) { */ public void execute() { // add monitor and sync + StreamingMonitor monitor = new StreamingMonitor(tasks.size(), ticksPerWriter); + + for (StreamWriter writer : tasks) { + writer.attachMonitor(monitor); + } + for (StreamWriter writer : tasks) { Thread worker = new Thread(writer, "stream-writer-" + writer.getId()); worker.setDaemon(true); worker.start(); } + + try { + synchronized (monitor) { + while (!monitor.isCompleted()) { + monitor.wait(); + } + } + + } catch(InterruptedException e) { + Thread.currentThread().interrupt(); + } } } From d042ccf8ebd717da5a8fd716fce5448cb3f5774b Mon Sep 17 00:00:00 2001 From: Ksenia Gorodkova Date: Tue, 17 Mar 2026 00:09:50 +0300 Subject: [PATCH 6/8] synchronizer: --- .../lectures/lecture6/tasks/synchronizer/StreamingMonitor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/hse/java/lectures/lecture6/tasks/synchronizer/StreamingMonitor.java b/src/main/java/hse/java/lectures/lecture6/tasks/synchronizer/StreamingMonitor.java index 51e29849..829caaae 100644 --- a/src/main/java/hse/java/lectures/lecture6/tasks/synchronizer/StreamingMonitor.java +++ b/src/main/java/hse/java/lectures/lecture6/tasks/synchronizer/StreamingMonitor.java @@ -63,6 +63,6 @@ public synchronized boolean tickCompleated(int writerId) { } public synchronized boolean isCompleted() { - return completed + return completed; } } From b8f508a6e8a5afd9bfce2bab0fe42bdd85a3faa3 Mon Sep 17 00:00:00 2001 From: Ksenia Gorodkova Date: Tue, 17 Mar 2026 00:18:23 +0300 Subject: [PATCH 7/8] synchronizer: --- .../tasks/synchronizer/StreamWriter.java | 3 ++- .../tasks/synchronizer/StreamingMonitor.java | 19 ++++++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/main/java/hse/java/lectures/lecture6/tasks/synchronizer/StreamWriter.java b/src/main/java/hse/java/lectures/lecture6/tasks/synchronizer/StreamWriter.java index 77923f1d..a4930622 100644 --- a/src/main/java/hse/java/lectures/lecture6/tasks/synchronizer/StreamWriter.java +++ b/src/main/java/hse/java/lectures/lecture6/tasks/synchronizer/StreamWriter.java @@ -28,7 +28,8 @@ public void attachMonitor(StreamingMonitor monitor) { public void run() { // Writer threads are intentionally infinite for the task contract. while (true) { - if (monitor.isCompleted()) { + + if (monitor == null) { break; } diff --git a/src/main/java/hse/java/lectures/lecture6/tasks/synchronizer/StreamingMonitor.java b/src/main/java/hse/java/lectures/lecture6/tasks/synchronizer/StreamingMonitor.java index 829caaae..edbfceb4 100644 --- a/src/main/java/hse/java/lectures/lecture6/tasks/synchronizer/StreamingMonitor.java +++ b/src/main/java/hse/java/lectures/lecture6/tasks/synchronizer/StreamingMonitor.java @@ -18,16 +18,29 @@ public synchronized boolean waitingForTurn(int writerId) { return false; } + if (totalTick[writerId] >= tickPerWriter) { + return false; + } + while (writerId != currentId && !completed) { try { wait(); + + if (completed) { + return false; + } + + if (totalTick[writerId] >= tickPerWriter) { + return false; + } + } catch (InterruptedException e) { Thread.currentThread().interrupt(); return false; } } - if (completed) { + if (completed || totalTick[writerId] >= tickPerWriter) { return false; } @@ -35,12 +48,12 @@ public synchronized boolean waitingForTurn(int writerId) { } public synchronized boolean tickCompleated(int writerId) { + totalTick[writerId]++; + if (completed) { return false; } - totalTick[writerId]++; - currentId = (currentId % writerCount) + 1; boolean allWriterCompleated = true; From c97644c01d04a22c6fb5ce3baf067bd1c0f0937c Mon Sep 17 00:00:00 2001 From: Ksenia Gorodkova Date: Tue, 17 Mar 2026 00:28:39 +0300 Subject: [PATCH 8/8] synchronizer: --- .../tasks/synchronizer/StreamingMonitor.java | 29 +++++++++---------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/main/java/hse/java/lectures/lecture6/tasks/synchronizer/StreamingMonitor.java b/src/main/java/hse/java/lectures/lecture6/tasks/synchronizer/StreamingMonitor.java index edbfceb4..8b0195c6 100644 --- a/src/main/java/hse/java/lectures/lecture6/tasks/synchronizer/StreamingMonitor.java +++ b/src/main/java/hse/java/lectures/lecture6/tasks/synchronizer/StreamingMonitor.java @@ -25,19 +25,18 @@ public synchronized boolean waitingForTurn(int writerId) { while (writerId != currentId && !completed) { try { wait(); - - if (completed) { - return false; - } - - if (totalTick[writerId] >= tickPerWriter) { - return false; - } - } catch (InterruptedException e) { Thread.currentThread().interrupt(); return false; } + + if (completed) { + return false; + } + + if (totalTick[writerId] >= tickPerWriter) { + return false; + } } if (completed || totalTick[writerId] >= tickPerWriter) { @@ -49,16 +48,10 @@ public synchronized boolean waitingForTurn(int writerId) { public synchronized boolean tickCompleated(int writerId) { totalTick[writerId]++; - - if (completed) { - return false; - } - - currentId = (currentId % writerCount) + 1; boolean allWriterCompleated = true; - for (int i = 1; i < writerCount; i++) { + for (int i = 1; i <= writerCount; i++) { if(totalTick[i] < tickPerWriter) { allWriterCompleated = false; break; @@ -71,6 +64,10 @@ public synchronized boolean tickCompleated(int writerId) { return false; } + do { + currentId = (currentId % writerCount) + 1; + } while (totalTick[currentId] >= tickPerWriter); + notifyAll(); return true; }