Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/main/java/algorithms/sprint0/SlidingAverage.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ static List<Double> movingAverage(int n, List<Integer> arr, int windowSize) {
}
result.add(sum / (double) windowSize);
for (int i = windowSize; i < minSize; i++) {
sum += arr.get(i) - arr.get(i - windowSize);
sum += (long) arr.get(i) - arr.get(i - windowSize);
result.add(sum / (double) windowSize);
}
return result;
Expand Down
23 changes: 15 additions & 8 deletions src/main/java/algorithms/sprint1/Distances.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;

// https://contest.yandex.ru/contest/22450/run-report/157289807/
public class Distances {
private static final int MAX_INPUT_SIZE = 100_000;

// -------------------- SOLUTION --------------------
static int[] solve(int[] a) {
int n = a.length;
int[] dist = new int[n];
if (n == 0) return dist;

int lastZero = -n;
for (int i = 0; i < n; i++) {
Expand Down Expand Up @@ -113,18 +113,20 @@ void writeInt(int x) throws IOException {
void flush() throws IOException {
out.write(buf, 0, p);
p = 0;
out.flush();
}
}

// -------------------- INPUT / OUTPUT --------------------
static void run() {

try (InputStream input = new BufferedInputStream(new FileInputStream("input.txt"));
OutputStream output = new BufferedOutputStream(new FileOutputStream("output.txt"))) {
FastIn in = new FastIn(input);
FastOut out = new FastOut(output);
static void run(InputStream input, OutputStream output) {
try {
FastIn in = new FastIn(new BufferedInputStream(input));
FastOut out = new FastOut(new BufferedOutputStream(output));

int n = in.nextInt();
if (n < 1 || n > MAX_INPUT_SIZE) {
throw new IllegalArgumentException("Input size must be between 1 and " + MAX_INPUT_SIZE);
}
int[] a = new int[n];
for (int i = 0; i < n; i++) a[i] = in.nextInt();

Expand All @@ -141,6 +143,10 @@ static void run() {
}
}

static void run() {
run(System.in, System.out);
}

// -------------------- TESTS --------------------
static void assertEq(int[] exp, int[] act, String name) {
if (!Arrays.equals(exp, act)) {
Expand All @@ -149,6 +155,7 @@ static void assertEq(int[] exp, int[] act, String name) {
}

static void test() {
assertEq(new int[]{}, solve(new int[]{}), "empty");
assertEq(new int[]{0, 1, 2, 1, 0}, solve(new int[]{0, 1, 4, 9, 0}), "sample1");
assertEq(new int[]{0, 1, 2, 3, 4, 5}, solve(new int[]{0, 7, 9, 4, 8, 20}), "sample2");
assertEq(new int[]{0}, solve(new int[]{0}), "n=1");
Expand Down
50 changes: 42 additions & 8 deletions src/main/java/algorithms/sprint1/Solution2.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.StringTokenizer;

public class Solution2 {
private static final int MAX_LINE_COUNT = 1_000_000;

public static void solution(Node<String> head) {
StringBuilder output = new StringBuilder();
Node<String> current = head;
Expand All @@ -35,16 +38,47 @@ static void test() {
}

public static void main(String[] args) throws IOException {
StringBuilder outputBuffer = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8));
int lineCount = parseInt(reader.readLine());
int lineCount = readLineCount(reader);
PrintWriter writer = new PrintWriter(System.out, false, StandardCharsets.UTF_8);
for (int i = 0; i < lineCount; ++i) {
StringTokenizer tokenizer = new StringTokenizer(reader.readLine());
int firstValue = parseInt(tokenizer.nextToken());
int secondValue = parseInt(tokenizer.nextToken());
int result = firstValue + secondValue;
outputBuffer.append(result).append("\n");
StringTokenizer tokenizer = new StringTokenizer(readInputLine(reader, i + 1));
int firstValue = parseInt(nextToken(tokenizer, i + 1));
int secondValue = parseInt(nextToken(tokenizer, i + 1));
if (tokenizer.hasMoreTokens()) {
throw new IllegalArgumentException("Line " + (i + 1) + " must contain exactly two integers");
}
int result = Math.addExact(firstValue, secondValue);
writer.println(result);
}
writer.println();
writer.flush();
}

private static int readLineCount(BufferedReader reader) throws IOException {
String countLine = reader.readLine();
if (countLine == null) {
throw new IllegalArgumentException("Missing line count");
}
int lineCount = parseInt(countLine);
if (lineCount < 0 || lineCount > MAX_LINE_COUNT) {
throw new IllegalArgumentException("Line count must be between 0 and " + MAX_LINE_COUNT);
}
return lineCount;
}

private static String readInputLine(BufferedReader reader, int lineNumber) throws IOException {
String inputLine = reader.readLine();
if (inputLine == null) {
throw new IllegalArgumentException("Missing input line " + lineNumber);
}
return inputLine;
}

private static String nextToken(StringTokenizer tokenizer, int lineNumber) {
if (!tokenizer.hasMoreTokens()) {
throw new IllegalArgumentException("Line " + lineNumber + " must contain exactly two integers");
}
System.out.println(outputBuffer);
return tokenizer.nextToken();
}
}
24 changes: 22 additions & 2 deletions src/main/java/algorithms/sprint2/Calculator.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,16 @@ private static int eval(FastIn in) throws IOException {
if (t.length() == 1) {
char op = t.charAt(0);
if (op == '+' || op == '-' || op == '*' || op == '/') {
if (st.size() < 2) {
throw new IllegalArgumentException("Operator requires two operands: " + op);
}
int b = st.pop();
int a = st.pop();

if (op == '/' && b == 0) {
throw new IllegalArgumentException("Division by zero");
}

int r;
if (op == '+') {
r = a + b;
Expand All @@ -64,17 +71,30 @@ private static int eval(FastIn in) throws IOException {
}
}

st.push(parseInt(t));
try {
st.push(parseInt(t));
} catch (NumberFormatException exception) {
throw new IllegalArgumentException("Invalid token: " + t, exception);
}
}

if (st.size() != 1) {
throw new IllegalArgumentException("Expression must produce exactly one result");
}
return st.peek();
}

private static void run() throws Exception {
FastIn in = new FastIn(System.in);
FastOut out = new FastOut(System.out);

int ans = eval(in);
final int ans;
try {
ans = eval(in);
} catch (IllegalArgumentException exception) {
System.err.println("Invalid expression: " + exception.getMessage());
return;
}

out.writeInt(ans);
out.writeByte('\n');
Expand Down
6 changes: 4 additions & 2 deletions src/main/java/algorithms/sprint2/Deque.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,13 @@ static final class RingDeque {
}

private int next(int i) {
return (i+1) % cap;
i++;
return i == cap ? 0 : i;
}

private int prev(int i) {
return (i-1+cap) % cap;
i--;
return i == -1 ? cap - 1 : i;
}

boolean isEmpty() {
Expand Down
60 changes: 38 additions & 22 deletions src/main/java/algorithms/sprint3/FastSort.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

public class FastSort {

private static final int MAX_PARTICIPANTS = 100_000;
private static final int MAX_LOGIN_LENGTH = 256;

/*
Принцип работы алгоритма:
1) Считываем n участников в массив.
Expand Down Expand Up @@ -140,51 +143,64 @@ private int read() throws IOException {
return buffer[ptr++];
}

int nextInt() throws IOException {
int c;
do {
c = read();
if (c == -1) {
throw new EOFException();
}
} while (c <= ' ');

int nextInt(String fieldName, int minValue, int maxValue) throws IOException {
int c = nextNonWhitespace();
int value = 0;

while (c > ' ') {
value = value * 10 + c - '0';
if (c < '0' || c > '9') {
throw new IOException("Invalid integer token for " + fieldName);
}
int digit = c - '0';
if (value > (maxValue - digit) / 10) {
throw new IOException("Integer token for " + fieldName + " exceeds " + maxValue);
}
value = value * 10 + digit;
c = read();
}

if (value < minValue) {
throw new IOException("Integer token for " + fieldName + " is below " + minValue);
}
return value;
}

String next() throws IOException {
String next(int maxLength) throws IOException {
int c = nextNonWhitespace();
StringBuilder sb = new StringBuilder(Math.min(maxLength, 16));

while (c > ' ') {
if (sb.length() == maxLength) {
throw new IOException("Token length exceeds " + maxLength);
}
sb.append((char) c);
c = read();
}
return sb.toString();
}

private int nextNonWhitespace() throws IOException {
int c;
do {
c = read();
if (c == -1) {
throw new EOFException();
}
} while (c <= ' ');

StringBuilder sb = new StringBuilder();
while (c > ' ') {
sb.append((char) c);
c = read();
}
return sb.toString();
return c;
}
}

private static void run() throws Exception {
FastIn in = new FastIn(System.in);

int n = in.nextInt(); // n — количество участников
int n = in.nextInt("participant count", 0, MAX_PARTICIPANTS); // n — количество участников
Participant[] participants = new Participant[n];

for (int i = 0; i < n; i++) {
String login = in.next();
int solved = in.nextInt();
int penalty = in.nextInt();
String login = in.next(MAX_LOGIN_LENGTH);
int solved = in.nextInt("solved", 0, Integer.MAX_VALUE);
int penalty = in.nextInt("penalty", 0, Integer.MAX_VALUE);
participants[i] = new Participant(login, solved, penalty);
}

Expand Down
56 changes: 31 additions & 25 deletions src/main/java/algorithms/sprint5/Solution.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public class Solution {
*
* Почему алгоритм корректен:
* 1) По свойству BST искомый ключ может находиться только
* в одном из двух поддеревьев, поэтому рекурсивный спуск
* в одном из двух поддеревьев, поэтому спуск
* идёт ровно по нужному пути.
*
* 2) Если у удаляемой вершины не более одного ребёнка,
Expand All @@ -46,43 +46,49 @@ public class Solution {
* Временная сложность: O(h), где h — высота дерева,
* что в худшем случае даёт O(n), где n — число узлов в дереве.
*
* Дополнительная пространственная сложность: O(h) из-за стека рекурсии,
* что в худшем случае даёт O(n).
* Дополнительная пространственная сложность: O(1), поскольку обход
* выполняется итеративно.
*/

public static Node remove(Node root, int key) {
if (root == null) {
return null;
Node parent = null;
Node current = root;

while (current != null && current.getValue() != key) {
parent = current;
current = key < current.getValue() ? current.getLeft() : current.getRight();
}

if (key < root.getValue()) {
root.setLeft(remove(root.getLeft(), key));
if (current == null) {
return root;
}

if (key > root.getValue()) {
root.setRight(remove(root.getRight(), key));
if (current.getLeft() != null && current.getRight() != null) {
Node predecessorParent = current;
Node predecessor = current.getLeft();
while (predecessor.getRight() != null) {
predecessorParent = predecessor;
predecessor = predecessor.getRight();
}

current.setValue(predecessor.getValue());
if (predecessorParent == current) {
predecessorParent.setLeft(predecessor.getLeft());
} else {
predecessorParent.setRight(predecessor.getLeft());
}
return root;
}

if (root.getLeft() == null) {
return root.getRight();
Node replacement = current.getLeft() != null ? current.getLeft() : current.getRight();
if (parent == null) {
return replacement;
}

if (root.getRight() == null) {
return root.getLeft();
if (parent.getLeft() == current) {
parent.setLeft(replacement);
} else {
parent.setRight(replacement);
}

Node predecessor = findMax(root.getLeft());
root.setValue(predecessor.getValue());
root.setLeft(remove(root.getLeft(), predecessor.getValue()));
return root;
}

private static Node findMax(Node node) {
while (node.getRight() != null) {
node = node.getRight();
}
return node;
}
}
Loading