- Locate middle character
- Abbreviate word
- Convert CamelCase
- Reverse words
- Scramble String
- Colored Triangle
- Sort Weight
- Strip Comments
- BinarySearch
- Collatz Conjecture
- Number Expanded Form
- Compute Best Sum
- Fibonacci Product
- Valid Braces
- Prime Factors
- Next In Queue
- Find Routes
- Number Expanded Form
- Integer Depth
- Gap In Primes
- Readable Time
- Convert Roman
- Reverse Polish Notation
- Format Duration
- List Squared
- Factorization
- Multiplicative persistence
public String middleCharacter(String s) {
int N = s.length();
if (N < 2) return s;
return N % 2 == 0 ? s.substring(N / 2 - 1, N / 2 + 1) : String.valueOf(s.charAt(N / 2));
}
public String abbreviate(String s) {
Pattern p = Pattern.compile("[A-Za-z]{4,}");
Matcher m = p.matcher(s);
while (m.find()) {
String word = m.group();
int N = word.length();
String abbreviation = word.substring(0, 1) + String.valueOf(N - 2) + word.substring(N - 1, N);
s = s.replaceFirst(word, abbreviation);
}
return s;
}
public String toCamelCase(String s, String d) {
String[] words = s.split(d);
return Arrays.stream(words, 1, words.length)
.map(w -> w.substring(0, 1).toUpperCase() + w.substring(1))
.reduce(words[0], String::concat);
}
public String reverseWords(String s, String d) {
return Arrays.stream(s.split(d))
.reduce((a, b) -> b + d + a)
.get();
}
public boolean scramble(String s1, String s2) {
if (s1.length() < s2.length()) return false;
if (s1.equals(s2)) return true;
Map<String, Integer> letterIndex = new HashMap<>();
for (String s : s2.split("")) {
if (letterIndex.containsKey(s)) letterIndex.put(s, letterIndex.get(s) + 1);
else letterIndex.put(s, 1);
}
for (String s : s1.split("")) {
if (letterIndex.containsKey(s)) {
if (letterIndex.get(s) == 1) letterIndex.remove(s);
else letterIndex.put(s, letterIndex.get(s) - 1);
}
}
return letterIndex.size() == 0;
}
public char triangle(String row) {
if (row.length() == 1) return row.charAt(0);
StringBuilder next = new StringBuilder();
String sub;
for (int i = 1; i < row.length(); i++) {
sub = row.substring(i - 1, i + 1);
next.append(nextChar(sub));
}
return triangle(next.toString());
}
private char nextChar(String s) {
if (s.charAt(0) == s.charAt(1)) return s.charAt(0);
if (s.contains("R") && s.contains("G")) return 'B';
if (s.contains("R") && s.contains("B")) return 'G';
return 'R';
}
public String orderWeight(String row) {
String[] array = row.split(" ");
Arrays.sort(array, (a, b) -> {
int aWeight = a.chars().map(Character::getNumericValue).sum();
int bWeight = b.chars().map(Character::getNumericValue).sum();
return aWeight > bWeight ? 1 : aWeight != bWeight ? -1 : a.compareTo(b);
});
return String.join(" ", array);
}
public String stripComments(String text, String[] markers) {
StringBuilder sb = new StringBuilder();
for (String s : text.split("\\n")) {
for (String m : markers) {
if (s.contains(m)) {
s = s.substring(0, s.indexOf(m));
}
}
sb.append("\n").append(s.replaceAll("\\s+$", ""));
}
return sb.substring(1);
}
public int binaryToInt(int[] a) {
int N = a.length;
int result = 0;
for (int i = N - 1, k = 0; i >= 0; i--, k++) {
if (a[i] == 1) {
result += (int) Math.pow(2, k);
}
}
return result;
}
public int[] splitAndAdd(int[] numbers, int n) {
List<Integer> list = new ArrayList<>();
for (int entry : numbers) {
list.add(entry);
}
while (n > 0) {
int loop = list.size() / 2;
int offset = list.size() - loop - 1;
for (int i = 0; i < loop; i++) {
int elem = list.remove(0);
list.set(offset, list.get(offset) + elem);
}
--n;
}
return list.stream()
.mapToInt(i -> i)
.toArray();
}
public int[][] spiral(int n) {
int[][] arr = new int[n][n];
int v = 1, minRow = 0, minCol = 0, maxRow = n - 1, maxCol = n - 1;
while (v <= n * n) {
// complete top row
for (int k = minCol; k <= maxCol; k++) {
arr[minRow][k] = v++;
}
// complete top col
for (int k = minRow + 1; k <= maxRow; k++) {
arr[k][maxCol] = v++;
}
// complete bottom row
for (int k = maxCol - 1; k >= minCol; k--) {
arr[maxRow][k] = v++;
}
// complete spiral
for (int k = maxRow - 1; k >= minRow + 1; k--) {
arr[k][minCol] = v++;
}
minCol++;
minRow++;
maxCol--;
maxRow--;
}
return arr;
}
public int[] snail(int[][] array) {
if (array[0].length == 0) return new int[0];
int N = array.length;
int[] snail = new int[N * N];
int minCol = 0, minRow = 0, maxCol = N - 1, maxRow = N - 1;
int index = 0;
while (index < N * N) {
for (int i = minCol; i <= maxCol; i++) {
snail[index++] = array[minRow][i];
}
for (int i = minRow + 1; i <= maxRow; i++) {
snail[index++] = array[i][maxCol];
}
for (int i = maxCol - 1; i >= minCol; i--) {
snail[index++] = array[maxRow][i];
}
for (int i = maxRow - 1; i >= minRow + 1; i--) {
snail[index++] = array[i][minCol];
}
minCol++;
maxCol--;
minRow++;
maxRow--;
}
return snail;
}
public int binarySearch(int[] array, int value) {
return rank(array, value, 0, array.length - 1);
}
private int rank(int[] array, int value, int lo, int hi) {
if (lo > hi) return -1;
int mid = lo + (hi - lo) / 2;
if (value > array[mid]) {
return rank(array, value, mid + 1, hi);
} else if (value < array[mid]) {
return rank(array, value, lo, mid - 1);
} else {
return mid;
}
}
public long conjecture(long n) {
long count = 1;
while (n != 1) {
n = (n % 2 == 0) ? n / 2 : n * 3 + 1;
++count;
}
return count;
}
public int bestTotal(int limit, int k, List<Integer> list) {
int[] dist = list.stream().mapToInt(d -> d).toArray();
int[] subset = new int[k];
List<Integer> totals = new ArrayList<>();
computeTotals(dist, 0, subset, 0, k, totals, limit);
return totals.stream().max(Integer::compareTo).orElse(-1);
}
public void computeTotals(int[] dist, int i, int[] subset, int j, int k, List<Integer> totals, int limit) {
if (j == k) { // subset is full
int subTotal = 0;
for (int m = 0; m < k; m++) {
subTotal += subset[m];
}
if (subTotal <= limit) {
totals.add(subTotal);
}
return;
}
if (i >= dist.length) return;
subset[j] = dist[i];
computeTotals(dist, i + 1, subset, j + 1, k, totals, limit);
computeTotals(dist, i + 1, subset, j, k, totals, limit);
}
public long[] productFib(long n) {
long current = 0L;
long next = 1L;
long temp;
while (current * next < n) {
temp = current;
current = next;
next = temp + next;
}
return new long[]{current, next, current * next == n ? 1 : 0};
}
public boolean validBraces(String braces) {
final Map<String, String> braceIndex = new HashMap<>();
braceIndex.put("(", ")");
braceIndex.put("[", "]");
braceIndex.put("{", "}");
final Deque<String> braceStack = new LinkedList<>();
for (String brace : braces.split("")) {
if (braceIndex.containsKey(brace)) {
braceStack.push(braceIndex.get(brace));
} else if (braceStack.isEmpty() || !braceStack.pop().equals(brace)) {
return false;
}
}
return braceStack.isEmpty();
}
public String primeFactorTotal(int[] array) {
StringBuilder sb = new StringBuilder();
Set<Integer> primes = new TreeSet<>();
for (int n : array) {
primes.addAll(primeFactors(n));
}
for (int p : primes) {
int sum = 0;
for (int n : array) {
if (n % p == 0) sum += n;
}
sb.append(format("(%d %d)", p, sum));
}
return sb.toString();
}
private Set<Integer> primeFactors(int number) {
Set<Integer> primeFactors = new HashSet<>();
int n = number;
for (int i = 2; i <= n; i++) {
while (n % i == 0) {
primeFactors.add(i);
n /= i;
}
}
return primeFactors;
}
public String nextQueue(String[] arr, int n) {
if (arr.length == 0) return "";
int next = 5, prev = 1;
while (n - next > 0) {
n -= next;
next *= 2;
prev *= 2;
}
return arr[(n - 1) / prev];
}
public String findRoutes(String[][] routes) {
Map<String, String> fromTo = new HashMap<>();
for (String[] route : routes) fromTo.put(route[0], route[1]);
Set<String> from = new HashSet<>(fromTo.keySet());
from.removeAll(fromTo.values());
String origin = from.iterator().next();
String path = origin;
while (true) {
origin = fromTo.get(origin);
if (origin == null) break;
path += ", " + origin;
}
return path;
}
public String expanded(int n) {
int e = 1;
StringBuilder result = new StringBuilder();
while (n != 0) {
int k = n % 10;
if (k != 0) result.insert(0, " + " + k * e);
e *= 10;
n /= 10;
}
return result.substring(3);
}
public int depth(int n) {
Set<Integer> digits = new HashSet<>();
int depth = 0;
for (int i = 1; digits.size() < 10; i++, depth++) {
int k = n * i;
while (k != 0) {
digits.add(k % 10);
k /= 10;
}
}
return depth;
}
public long[] primeGaps(long gap, long start, int end) {
long prev = Long.MIN_VALUE;
for (long k = start; k < end; k++) {
if (isPrime(k)) {
if (k - prev == gap) {
return new long[]{prev, k};
}
prev = k;
}
}
return null;
}
public boolean isPrime(long n) {
for (int i = 2; i < n; i++) {
if (n % i == 0)
return false;
}
return true;
}
public String readableTime(int seconds) {
int hour = seconds / 3600;
int min = (seconds / 60) % 60;
int sec = seconds % 60;
return String.format("%02d:%02d:%02d", hour, min, sec);
}
public String romanFormat(int number) {
Map<Integer, String> romanIndex = new TreeMap<>(Collections.reverseOrder());
romanIndex.put(1000, "M");
romanIndex.put(900, "CM");
romanIndex.put(500, "D");
romanIndex.put(400, "CD");
romanIndex.put(100, "C");
romanIndex.put(90, "XC");
romanIndex.put(50, "L");
romanIndex.put(40, "XL");
romanIndex.put(10, "X");
romanIndex.put(9, "IX");
romanIndex.put(5, "V");
romanIndex.put(4, "IV");
romanIndex.put(1, "I");
StringBuilder sb = new StringBuilder();
for (int n : romanIndex.keySet()) {
while (number >= n) {
sb.append(romanIndex.get(n));
number -= n;
}
}
return sb.toString();
}
public double evaluatePolish(String expression) {
if (expression.isEmpty()) return 0;
Deque<Double> stack = new LinkedList<>();
Arrays.stream(expression.split(" ")).forEach(s -> {
Double b, a;
switch(s) {
case "+": stack.push(stack.pop() + stack.pop()); break;
case "*": stack.push(stack.pop() * stack.pop()); break;
case "-": b = stack.pop(); a = stack.pop(); stack.push(a - b); break;
case "/": b = stack.pop(); a = stack.pop(); stack.push(a / b); break;
default: stack.push(Double.parseDouble(s));
}
});
return stack.pop();
}
public String formatDuration(int time) {
if (time == 0) return "now";
StringBuilder result = new StringBuilder();
int year = time / 3600 / 24 / 365;
int day = time / 3600 / 24 % 365;
int hour = time / 3600 % 24;
int min = time / 60 % 60;
int sec = time % 60;
if (year > 0) {
result.append(format("%d %s", year, year == 1 ? "year" : "years"));
}
if (day > 0) {
if (result.length() > 0) result.append(hour > 0 ? ", " : " and ");
result.append(format("%d %s", day, day == 1 ? "day" : "days"));
}
if (hour > 0) {
if (result.length() > 0) result.append(min > 0 ? ", " : " and ");
result.append(format("%d %s", hour, hour == 1 ? "hour" : "hours"));
}
if (min > 0) {
if (result.length() > 0) result.append(sec > 0 ? ", " : " and ");
result.append(format("%d %s", min, min == 1 ? "minute" : "minutes"));
}
if (sec > 0) {
if (result.length() > 0) result.append(" and ");
result.append(format("%d %s", sec, sec == 1 ? "second" : "seconds"));
}
return result.toString();
}
public String listSquared(long start, long end) {
List<String> list = new ArrayList<>();
for (long number = start; number <= end; number++) {
long pair = pair(number);
if (pair != 0) list.add(String.format("[%d, %d]", number, pair));
}
return "[" + String.join(", ", list) + "]";
}
private long pair(long n) {
long sum = LongStream.range(1, n + 1)
.filter(k -> n % k == 0)
.map(k -> k * k)
.sum();
long sqrt = (long) Math.sqrt(sum);
return sqrt * sqrt == sum ? sum : 0;
}
public String factor(long n) {
Map<Long, Integer> map = new HashMap<>();
for (long k = 2; k * k <= n; k++) {
while (n % k == 0) {
if (map.containsKey(k)) map.put(k, map.get(k) + 1);
else map.put(k, 1);
n = n / k;
}
}
if (n > 1) map.put(n, 1);
return map.entrySet()
.stream()
.map(entry -> entry.getKey() + " - " + entry.getValue())
.collect(Collectors.joining(", "));
}
public int persistence(long number) {
if (number % 10 == number) return 0;
long multiplier = 1;
while (number > 0) {
multiplier *= number % 10;
number /= 10;
}
return persistence(multiplier) + 1;
}