Created
September 1, 2015 22:00
-
-
Save marwinxxii/07818ec9239956f55a2d to your computer and use it in GitHub Desktop.
Fibonacci
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.agapitov; | |
import java.io.BufferedReader; | |
import java.io.IOException; | |
import java.io.InputStreamReader; | |
public class Main { | |
public static final int MAX_INDEX_VALUE = 100000000; | |
public static final int MAX_INDEX_STR_LENGTH = 10; | |
public static void main(String[] args) { | |
if (args.length == 0) { | |
processItemsFromInputStream(); | |
} else { | |
processItems(args); | |
} | |
} | |
private static void processItemsFromInputStream() { | |
println("Please enter index of item in sequence.\n" + | |
"Or run as `java com.agapitov.Main {indexes separated by space}`"); | |
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); | |
String s; | |
try { | |
while ((s = reader.readLine()) != null) { | |
if (!s.isEmpty()) { | |
processItem(s); | |
} | |
} | |
reader.close(); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
private static void processItems(String[] items) { | |
for (String item : items) { | |
if (!processItem(item)) { | |
break; | |
} | |
} | |
} | |
public static boolean processItem(String item) { | |
String indexStr = item.trim(); | |
int index; | |
try { | |
index = parseIndex(indexStr); | |
} catch (IllegalArgumentException e) { | |
println(e.getMessage()); | |
return false; | |
} | |
long value = calculateFibonacciNumber(index); | |
println(String.format("Index: %d, value: %d", index, value)); | |
return true; | |
} | |
public static int parseIndex(String item) { | |
if (item.length() > MAX_INDEX_STR_LENGTH) { | |
throw new IllegalArgumentException("Index is too big or incorrect: " + item); | |
} | |
int index; | |
try { | |
index = Integer.parseInt(item, 10); | |
} catch (NumberFormatException e) { | |
throw new NumberFormatException("Index is incorrect: " + item); | |
} | |
if (index < 0) { | |
throw new IllegalArgumentException("Index value must be positive: " + index); | |
} | |
if (index > MAX_INDEX_VALUE) { | |
throw new IllegalArgumentException("Max index value is: " + MAX_INDEX_VALUE); | |
} | |
return index; | |
} | |
public static long calculateFibonacciNumber(int index) { | |
if (index < 0) { | |
throw new IllegalArgumentException("Fibonacci sequence index must be greater or equal zero"); | |
} | |
if (index < 2) { | |
return index; | |
} | |
int start = 0, prev = 1; | |
for (int i = 2; i <= index; i++) { | |
int newValue = start + prev; | |
start = prev; | |
prev = newValue; | |
} | |
return prev; | |
} | |
private static void println(String line) { | |
System.out.println(line); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.agapitov; | |
import org.junit.Test; | |
import static com.agapitov.Main.MAX_INDEX_VALUE; | |
import static com.agapitov.Main.calculateFibonacciNumber; | |
import static com.agapitov.Main.parseIndex; | |
import static org.junit.Assert.assertEquals; | |
public class MainTest { | |
@Test | |
public void fibShouldReturnZero() { | |
assertEquals(0, calculateFibonacciNumber(0)); | |
} | |
@Test | |
public void fibShouldReturnOne() { | |
assertEquals(1, calculateFibonacciNumber(1)); | |
} | |
@Test | |
public void fibShouldReturnCorrectValue() { | |
long[] expected = new long[]{0, 1, 1, 2, 3, 5, 8, 13, 21}; | |
for (int i = 0; i < expected.length; i++) { | |
assertEquals("Index: " + i, expected[i], calculateFibonacciNumber(i)); | |
} | |
} | |
@Test(expected = IllegalArgumentException.class) | |
public void fibShouldThrowIfNegative() { | |
calculateFibonacciNumber(-1); | |
} | |
@Test(expected = NumberFormatException.class) | |
public void shouldRefuseNonNumberIndexes() { | |
parseIndex("Hello"); | |
} | |
@Test(expected = IllegalArgumentException.class) | |
public void shouldRefuseNegativeIndexes() { | |
parseIndex("-1"); | |
} | |
@Test(expected = IllegalArgumentException.class) | |
public void shouldThrowIfTooLong() { | |
parseIndex(String.valueOf(Long.MAX_VALUE)); | |
} | |
@Test(expected = IllegalArgumentException.class) | |
public void shouldThrowIfGreaterThanMax() { | |
parseIndex(String.valueOf(MAX_INDEX_VALUE + 100)); | |
} | |
@Test | |
public void shouldParseDecimalPositiveIndex() { | |
assertEquals(10, parseIndex("10")); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment