| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- import java.util.Arrays;
-
- final class BaseConverter {
-
- private static final int MINIMUM_VALID_BASE = 2;
-
- private static final String INVALID_BASE_ERROR_MESSAGE = "Bases must be at least 2.";
-
- private final int numeral;
-
- BaseConverter(final int originalBase, final int[] originalDigits) {
- validateInputs(originalBase, originalDigits);
- this.numeral = computeNumeral(originalBase, originalDigits);
- }
-
- int[] convertToBase(final int newBase) {
- if (newBase < MINIMUM_VALID_BASE) {
- throw new IllegalArgumentException(INVALID_BASE_ERROR_MESSAGE);
- }
-
- final int largestExponent = computeLargestExponentForBase(newBase);
- final int[] result = new int[largestExponent + 1];
- int remainder = numeral;
-
- for (int currentExponent = largestExponent; currentExponent >= 0; currentExponent--) {
- final int coefficient = (int) Math.floor(remainder / Math.pow(newBase, currentExponent));
-
- result[largestExponent - currentExponent] = coefficient;
-
- remainder -= coefficient * Math.pow(newBase, currentExponent);
- }
-
- return result;
- }
-
- private void validateInputs(final int originalBase, final int[] originalDigits) {
- if (originalBase < MINIMUM_VALID_BASE) {
- throw new IllegalArgumentException(INVALID_BASE_ERROR_MESSAGE);
- }
-
- if (originalDigits.length == 0) {
- throw new IllegalArgumentException("You must supply at least one digit.");
- }
-
- if (originalDigits.length > 1 && originalDigits[0] == 0) {
- throw new IllegalArgumentException("Digits may not contain leading zeros.");
- }
-
- if (Arrays.stream(originalDigits).min().getAsInt() < 0) {
- throw new IllegalArgumentException("Digits may not be negative.");
- }
-
- if (Arrays.stream(originalDigits).max().getAsInt() >= originalBase) {
- throw new IllegalArgumentException("All digits must be strictly less than the base.");
- }
- }
-
- private int computeNumeral(final int originalBase, final int[] originalDigits) {
- int result = 0;
-
- final int largestExponent = originalDigits.length - 1;
-
- for (int currentExponent = largestExponent; currentExponent >= 0; currentExponent--) {
- result += originalDigits[largestExponent - currentExponent] * Math.pow(originalBase, currentExponent);
- }
-
- return result;
- }
-
- private int computeLargestExponentForBase(final int newBase) {
- int result = 0;
-
- while (Math.pow(newBase, result + 1) < numeral) {
- result += 1;
- }
-
- return result;
- }
-
- }
|