lots of exercises in java... from https://github.com/exercism/java

BaseConverter.java 2.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import java.util.Arrays;
  2. final class BaseConverter {
  3. private static final int MINIMUM_VALID_BASE = 2;
  4. private static final String INVALID_BASE_ERROR_MESSAGE = "Bases must be at least 2.";
  5. private final int numeral;
  6. BaseConverter(final int originalBase, final int[] originalDigits) {
  7. validateInputs(originalBase, originalDigits);
  8. this.numeral = computeNumeral(originalBase, originalDigits);
  9. }
  10. int[] convertToBase(final int newBase) {
  11. if (newBase < MINIMUM_VALID_BASE) {
  12. throw new IllegalArgumentException(INVALID_BASE_ERROR_MESSAGE);
  13. }
  14. final int largestExponent = computeLargestExponentForBase(newBase);
  15. final int[] result = new int[largestExponent + 1];
  16. int remainder = numeral;
  17. for (int currentExponent = largestExponent; currentExponent >= 0; currentExponent--) {
  18. final int coefficient = (int) Math.floor(remainder / Math.pow(newBase, currentExponent));
  19. result[largestExponent - currentExponent] = coefficient;
  20. remainder -= coefficient * Math.pow(newBase, currentExponent);
  21. }
  22. return result;
  23. }
  24. private void validateInputs(final int originalBase, final int[] originalDigits) {
  25. if (originalBase < MINIMUM_VALID_BASE) {
  26. throw new IllegalArgumentException(INVALID_BASE_ERROR_MESSAGE);
  27. }
  28. if (originalDigits.length == 0) {
  29. throw new IllegalArgumentException("You must supply at least one digit.");
  30. }
  31. if (originalDigits.length > 1 && originalDigits[0] == 0) {
  32. throw new IllegalArgumentException("Digits may not contain leading zeros.");
  33. }
  34. if (Arrays.stream(originalDigits).min().getAsInt() < 0) {
  35. throw new IllegalArgumentException("Digits may not be negative.");
  36. }
  37. if (Arrays.stream(originalDigits).max().getAsInt() >= originalBase) {
  38. throw new IllegalArgumentException("All digits must be strictly less than the base.");
  39. }
  40. }
  41. private int computeNumeral(final int originalBase, final int[] originalDigits) {
  42. int result = 0;
  43. final int largestExponent = originalDigits.length - 1;
  44. for (int currentExponent = largestExponent; currentExponent >= 0; currentExponent--) {
  45. result += originalDigits[largestExponent - currentExponent] * Math.pow(originalBase, currentExponent);
  46. }
  47. return result;
  48. }
  49. private int computeLargestExponentForBase(final int newBase) {
  50. int result = 0;
  51. while (Math.pow(newBase, result + 1) < numeral) {
  52. result += 1;
  53. }
  54. return result;
  55. }
  56. }