diff --git a/src/main/java/coderun/AverageElement.java b/src/main/java/coderun/AverageElement.java index 461cce6..99c8dc6 100644 --- a/src/main/java/coderun/AverageElement.java +++ b/src/main/java/coderun/AverageElement.java @@ -3,7 +3,6 @@ import static common.SafeParse.parseInt; -import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; @@ -11,12 +10,13 @@ import java.io.Reader; import java.io.Writer; import java.nio.charset.StandardCharsets; -import java.util.Arrays; public class AverageElement { + private static final int MAX_INPUT_CHARACTERS = 4096; + /** * Для чтения входных данных необходимо получить их * из стандартного потока ввода (System.in). @@ -58,26 +58,52 @@ public static void main(String[] args) throws IOException { } static void solve(Reader input, Writer output) throws IOException { - BufferedReader reader = new BufferedReader(input); BufferedWriter writer = new BufferedWriter(output); - String line = reader.readLine(); - if (line == null) { + String line = readBoundedLine(input); + if (line == null || line.isBlank()) { return; } String[] parts = line.trim().split("\\s+"); - writer.write(String.valueOf(average(parts))); + try { + writer.write(String.valueOf(average(parts))); + } catch (IllegalArgumentException ignored) { + return; + } writer.flush(); } static Integer average(String[] list) { - return Arrays - .stream(list) - .sequential() - .map(AverageElement::parseInteger) - .sorted() - .toList() - .get(1); + if (list.length < 2) { + throw new IllegalArgumentException("At least two integers are required"); + } + + int smallest = Integer.MAX_VALUE; + int secondSmallest = Integer.MAX_VALUE; + for (String value : list) { + int number = parseInteger(value); + if (number < smallest) { + secondSmallest = smallest; + smallest = number; + } else if (number < secondSmallest) { + secondSmallest = number; + } + } + return secondSmallest; + } + + private static String readBoundedLine(Reader input) throws IOException { + StringBuilder line = new StringBuilder(); + for (int character = input.read(); character != -1 && character != '\n'; character = input.read()) { + if (character == '\r') { + break; + } + if (line.length() == MAX_INPUT_CHARACTERS) { + return null; + } + line.append((char) character); + } + return line.isEmpty() ? null : line.toString(); } private static Integer parseInteger(String value) { diff --git a/src/test/java/coderun/AverageElementTest.java b/src/test/java/coderun/AverageElementTest.java index 0ae380b..4cf9df9 100644 --- a/src/test/java/coderun/AverageElementTest.java +++ b/src/test/java/coderun/AverageElementTest.java @@ -29,4 +29,31 @@ void shouldSolveFromReaderAndNormalizeWhitespace() throws IOException { assertEquals("5", output.toString()); } + + @Test + void shouldIgnoreInvalidOrInsufficientInput() throws IOException { + assertProducesNoOutput(""); + assertProducesNoOutput(" "); + assertProducesNoOutput("5"); + assertProducesNoOutput("1 invalid 3"); + } + + @Test + void shouldRejectAnOversizedInputLine() throws IOException { + assertProducesNoOutput("1 ".repeat(2049)); + } + + @Test + void shouldFindSecondValueWithoutSortingTheInput() { + assertEquals(2, AverageElement.average(new String[]{"4", "2", "3", "1"})); + assertEquals(1, AverageElement.average(new String[]{"1", "1"})); + } + + private static void assertProducesNoOutput(String input) throws IOException { + StringWriter output = new StringWriter(); + + AverageElement.solve(new StringReader(input), output); + + assertEquals("", output.toString()); + } }