chars = new ArrayList<>(s.length());
85 |
86 | for (int i = 0; i < s.length(); i++) {
87 | chars.add(i, null);
88 | }
89 |
90 | for (int i = 0; i < s.length(); i++) {
91 | chars.set(currIndex, s.charAt(i));
92 |
93 | currIndex += (n - 1) * 2;
94 |
95 | if (currRow > 0 && currRow < n - 1) {
96 | int addIndex = currIndex - (currRow * 2);
97 |
98 | if (addIndex < s.length() && (i + 1 < s.length())) {
99 | chars.set(addIndex, s.charAt(++i));
100 | }
101 | }
102 |
103 | if (currIndex >= s.length()) {
104 | if (currRow == 0) rowDirection = 1;
105 | if (currRow == n - 1) rowDirection = -1;
106 |
107 | currRow += rowDirection;
108 | currIndex = currRow;
109 | }
110 | }
111 |
112 | final StringBuilder sb = new StringBuilder();
113 |
114 | for (Character c : chars) {
115 | sb.append(c);
116 | }
117 |
118 | return new String(sb);
119 | }
120 |
121 | @Test
122 | public void encodeSampleTests() {
123 | String[][] encodes = {{"WEAREDISCOVEREDFLEEATONCE", "WECRLTEERDSOEEFEAOCAIVDEN"}, // 3 rails
124 | {"Hello, World!", "Hoo!el,Wrdl l"}, // 3 rails
125 | {"Hello, World!", "H !e,Wdloollr"}, // 4 rails
126 | {"", ""} // 3 rails (even if...)
127 | };
128 | int[] rails = {3, 3, 4, 3};
129 | for (int i = 0; i < encodes.length; i++) {
130 | assertEquals(encodes[i][1], RailFenceCipher.encode(encodes[i][0], rails[i]));
131 | }
132 | }
133 |
134 | @Test
135 | public void decodeSampleTests() {
136 | String[][] decodes = {{"WECRLTEERDSOEEFEAOCAIVDEN", "WEAREDISCOVEREDFLEEATONCE"}, // 3 rails
137 | {"H !e,Wdloollr", "Hello, World!"}, // 4 rails
138 | {"", ""} // 3 rails (even if...)
139 | };
140 | int[] rails = {3, 4, 3};
141 | for (int i=0 ; i < decodes.length ; i++) {
142 | assertEquals(decodes[i][1], RailFenceCipher.decode(decodes[i][0], rails[i]));
143 | }
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/src/main/java/kyu4/Boggle.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu4;
2 |
3 | /**
4 | * 4 kyu - Boggle World Checker
5 | *
6 | * https://www.codewars.com/kata/57680d0128ed87c94f000bfd/
7 | *
8 | * Details:
9 | *
10 | * Write a function that determines whether a string is a valid guess in a Boggle board, as per the
11 | * rules of Boggle.
12 | *
13 | * A Boggle board is a 2D array of individual characters, e.g.:
14 | *
15 | * [ ['I','L','A','W'],
16 | * ['B','N','G','E'],
17 | * ['I','U','A','O'],
18 | * ['A','S','R','L'] ]
19 | *
20 | * Valid guesses are strings which can be formed by connecting adjacent cells (horizontally,
21 | * vertically, or diagonally) without re-using any previously used cells.
22 | *
23 | * For example, in the above board "BINGO", "LINGO", and "ILNBIA" would all be valid guesses, while
24 | * "BUNGIE", "BINS", and "SINUS" would not.
25 | *
26 | * Your function should take two arguments (a 2D array and a string) and return true or false
27 | * depending on whether the string is found in the array as per Boggle rules.
28 | *
29 | * Test cases will provide various array and string sizes (squared arrays up to 150x150 and strings
30 | * up to 150 uppercase letters). You do not have to check whether the string is a real word or not,
31 | * only if it's a valid guess.
32 | */
33 |
34 | public class Boggle {
35 | private final char[][] board;
36 | private final String word;
37 |
38 | public Boggle(final char[][] board, final String word) {
39 | this.board = board;
40 | this.word = word;
41 | }
42 |
43 | public boolean check() {
44 | if (word == null || word.isEmpty()) {
45 | return false;
46 | }
47 | int[][] usedCoords = new int[board.length][board[0].length];
48 |
49 | for (int y = 0; y < board.length; y++) {
50 | for (int x = 0; x < board[y].length; x++) {
51 | if (board[y][x] == word.charAt(0) && isMatch(x, y, 1, usedCoords))
52 | return true;
53 | }
54 | }
55 | return false;
56 | }
57 |
58 | private boolean isMatch(int prevX, int prevY, int currentIndex, int[][] usedCoords) {
59 | if (currentIndex >= word.length()) return true;
60 |
61 | char currentChar = word.charAt(currentIndex);
62 | usedCoords[prevY][prevX] = 1;
63 |
64 | for (int y = prevY - 1; y <= prevY + 1; y++) {
65 | for (int x = prevX - 1; x <= prevX + 1; x++) {
66 | if (y >= 0 && x >= 0 && y < board.length && x < board[y].length) {
67 | if (board[y][x] == currentChar && usedCoords[y][x] != 1 &&
68 | isMatch(x, y, currentIndex + 1, usedCoords))
69 | return true;
70 | }
71 | }
72 | }
73 |
74 | usedCoords[prevY][prevX] = 0;
75 |
76 | return false;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/main/java/kyu4/ConwayLife.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu4;
2 |
3 | /**
4 | * 4 kyu - Conway's Game of Life - Unlimited Edition
5 | *
6 | * https://www.codewars.com/kata/52423db9add6f6fc39000354
7 | *
8 | * Given a 2D array and a number of generations, compute n timesteps of Conway's Game of Life.
9 | *
10 | * The rules of the game are:
11 | *
12 | * Any live cell with fewer than two live neighbours dies, as if caused by underpopulation.
13 | * Any live cell with more than three live neighbours dies, as if by overcrowding.
14 | * Any live cell with two or three live neighbours lives on to the next generation.
15 | * Any dead cell with exactly three live neighbours becomes a live cell.
16 | *
17 | * Each cell's neighborhood is the 8 cells immediately around it (i.e. Moore Neighborhood).
18 | * The universe is infinite in both the x and y dimensions and all cells are initially dead -
19 | * except for those specified in the arguments. The return value should be a 2d array cropped
20 | * around all of the living cells. (If there are no living cells, then return [[]].)
21 | */
22 |
23 | public class ConwayLife {
24 | private static int height;
25 | private static int width;
26 |
27 | public static int[][] getGeneration(int[][] cells, int generations) {
28 | if (generations < 0) {
29 | return cells;
30 | }
31 |
32 | height = cells.length;
33 | width = cells[0].length;
34 | int[][] result = cells;
35 |
36 | for (int i = 0; i < generations; i++) {
37 | result = nextGeneration(result);
38 | }
39 |
40 | return result;
41 | }
42 |
43 | private static final int[][] nextGeneration(int[][] currGen) {
44 | int[][] expand = expand(currGen);
45 | int[][] nextGen = new int[height][width];
46 |
47 | for (int y = 0; y < height; y++) {
48 | for (int x = 0; x < width; x++) {
49 | final int neighbors = countAliveNeighbors(expand, x, y);
50 | if (neighbors == 3 && expand[y][x] == 0) {
51 | nextGen[y][x] = 1;
52 | } else if ((neighbors > 3 || neighbors < 2) && expand[y][x] == 1) {
53 | nextGen[y][x] = 0;
54 | } else {
55 | nextGen[y][x] = expand[y][x];
56 | }
57 | }
58 | }
59 | nextGen = crop(nextGen);
60 |
61 | return nextGen;
62 | }
63 |
64 | private static final int[][] expand(int[][] cells) {
65 | height += 2;
66 | width += 2;
67 | int[][] cellsExp = new int[height][width];
68 |
69 | for (int y = 0; y < cells.length; y++) {
70 | for (int x = 0; x < cells[y].length; x++) {
71 | cellsExp[y + 1][x + 1] = cells[y][x];
72 | }
73 | }
74 |
75 | return cellsExp;
76 | }
77 |
78 | private static final int countAliveNeighbors(int[][] cells, int currX, int currY) {
79 | int result = 0;
80 |
81 | for (int y = currY - 1; y <= currY + 1; y++) {
82 | for (int x = currX - 1; x <= currX + 1; x++) {
83 | if (y >= 0 && y < cells.length && x >= 0 && x < cells[0].length) {
84 | if (y == currY && x == currX) {
85 | continue;
86 | }
87 | if (cells[y][x] == 1) {
88 | result++;
89 | }
90 | }
91 | }
92 | }
93 | return result;
94 | }
95 |
96 | public static int[][] crop(int[][] cells) {
97 | int minY = cells.length;
98 | int minX = cells[0].length;
99 | int maxY = 0;
100 | int maxX = 0;
101 |
102 | for (int y = 0; y < cells.length; y++) {
103 | for (int x = 0; x < cells[0].length; x++) {
104 | if (cells[y][x] == 1) {
105 | maxY = y > maxY ? y : maxY;
106 | maxX = x > maxX ? x : maxX;
107 | minY = y < minY ? y : minY;
108 | minX = x < minX ? x : minX;
109 | }
110 | }
111 | }
112 |
113 | maxY++;
114 | maxX++;
115 | height = maxY - minY;
116 | width = maxX - minX;
117 |
118 | int[][] cellsCrop = new int[height][width];
119 | for (int y = minY; y < maxY; y++) {
120 | for (int x = minX; x < maxX; x++) {
121 | cellsCrop[y - minY][x - minX] = cells[y][x];
122 | }
123 | }
124 |
125 | return cellsCrop;
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/src/main/java/kyu4/HowManyNumbers.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu4;
2 |
3 | /**
4 | * 4 kyu - How many numbers III?
5 | *
6 | * https://www.codewars.com/kata/5877e7d568909e5ff90017e6
7 | *
8 | * Details:
9 | *
10 | * We want to generate all the numbers of three digits where:
11 | * - the sum of their digits is equal to 10.
12 | * - their digits are in increasing order (the numbers may have two or more equal contiguous digits)
13 | *
14 | * The numbers that fulfill the two above constraints are: 118, 127, 136, 145, 226, 235, 244, 334
15 | *
16 | * Make a function that receives two arguments:
17 | * - the sum of digits value
18 | * - the desired number of digits for the numbers
19 | *
20 | * The function should output an array with three values: [1,2,3]
21 | * 1 - the total number of possible numbers
22 | * 2 - the minimum number
23 | * 3 - the maximum number
24 | */
25 |
26 | import org.junit.jupiter.api.Test;
27 |
28 | import java.util.ArrayList;
29 | import java.util.Arrays;
30 | import java.util.List;
31 |
32 | import static org.junit.jupiter.api.Assertions.assertEquals;
33 |
34 | public class HowManyNumbers {
35 | private static long count;
36 | private static long min;
37 | private static long max;
38 |
39 | public static List findAll(final int sumDigits, final int numDigits) {
40 | count = 0;
41 | min = 0;
42 | max = 0;
43 |
44 | recursiveSearch(0L, 1, sumDigits, numDigits);
45 |
46 | ArrayList result = new ArrayList<>();
47 |
48 | if (count > 0) {
49 | result.add(count);
50 | result.add(min);
51 | result.add(max);
52 | }
53 |
54 | return result;
55 | }
56 |
57 | private static void recursiveSearch(Long currNum, int prevDigit, int sumLeft, int digitsLeft) {
58 | if (sumLeft == 0 && digitsLeft == 0) {
59 | if (count == 0) min = currNum;
60 | min = min < currNum ? min : currNum;
61 | max = max > currNum ? max : currNum;
62 | count++;
63 | } else if (digitsLeft != 0) {
64 | for (int i = prevDigit; i < 10; i++) {
65 | recursiveSearch(10 * currNum + i, i,sumLeft - i, digitsLeft - 1);
66 | }
67 | }
68 | }
69 |
70 |
71 | /**
72 | * Though this code works it is not effective
73 | *
74 | public static List findAll(final int sumDigits, final int numDigits) {
75 | StringBuilder sb = new StringBuilder();
76 |
77 | while (sb.length() != numDigits) {
78 | sb.append("1");
79 | }
80 |
81 | long currentLong = Long.parseLong(sb.toString());
82 | long lastLong = currentLong * 9;
83 | long count = 0, firstMatch = 0, lastMatch = 0;
84 |
85 |
86 | while (currentLong <= lastLong) {
87 | int currDigit, prevDigit = -1, digitSum = 0;
88 | // int currentPosition = 1;
89 | long i = currentLong;
90 | boolean isValid = true;
91 |
92 | while (i > 0) {
93 | currDigit = (int) i % 10;
94 | if (prevDigit != -1 && prevDigit < currDigit) {
95 | isValid = false;
96 | //currentLong += currentPosition * i % 10;
97 | break;
98 | } else if (digitSum > sumDigits) {
99 | isValid = false;
100 | break;
101 | } else {
102 | i /= 10;
103 | //currentPosition *= 10;
104 | digitSum += currDigit;
105 | prevDigit = currDigit;
106 | }
107 | }
108 | if (sumDigits != digitSum) {
109 | isValid = false;
110 | }
111 |
112 | if (isValid) {
113 | if (firstMatch == 0) firstMatch = currentLong;
114 | lastMatch = currentLong;
115 | count++;
116 | }
117 | currentLong++;
118 | }
119 |
120 | List result = new ArrayList<>();
121 | if (count > 0) {
122 | result.add(count);
123 | result.add(firstMatch);
124 | result.add(lastMatch);
125 | }
126 |
127 | return result;
128 | }
129 | */
130 |
131 | @Test
132 | public void exampleTests() {
133 | assertEquals(Arrays.asList(8L, 118L, 334L), HowManyNumbers.findAll(10, 3));
134 | assertEquals(Arrays.asList(1L, 999L, 999L), HowManyNumbers.findAll(27, 3));
135 | assertEquals(new ArrayList(), HowManyNumbers.findAll(84, 4));
136 | assertEquals(Arrays.asList(123L, 116999L, 566666L), HowManyNumbers.findAll(35, 6));
137 | }
138 |
139 | @Test
140 | public void hardTests() {
141 | assertEquals(Arrays.asList(409L, 11112999L, 44444445L),
142 | HowManyNumbers.findAll(33, 8));
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/src/main/java/kyu4/LongestSlideDown.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu4;
2 |
3 | /**
4 | * 4 kyu - Pyramid Slide Down
5 | *
6 | * https://www.codewars.com/kata/551f23362ff852e2ab000037
7 | *
8 | * Details:
9 | *
10 | * Pyramids are amazing! Both in architectural and mathematical sense. If you have a computer, you
11 | * can mess with pyramids even if you are not in Egypt at the time. For example, let's consider the
12 | * following problem. Imagine that you have a pyramid built of numbers, like this one here:
13 | *
14 | * /3/
15 | * \7\ 4
16 | * 2 \4\ 6
17 | * 8 5 \9\ 3
18 | *
19 | * Here comes the task...
20 | *
21 | * Let's say that the 'slide down' is the maximum sum of consecutive numbers from the top to the
22 | * bottom of the pyramid. As you can see, the longest 'slide down' is 3 + 7 + 4 + 9 = 23
23 | *
24 | * Your task is to write a function longestSlideDown (in ruby: longest_slide_down) that takes a
25 | * pyramid representation as argument and returns its' largest 'slide down'. For example,
26 | */
27 |
28 | import static org.junit.Assert.assertEquals;
29 | import org.junit.Test;
30 |
31 | public class LongestSlideDown {
32 | public static int longestSlideDown(int[][] pyramid) {
33 | int[][] max = pyramid;
34 |
35 | for (int y = pyramid.length-2; y >= 0; y--) {
36 | for (int x = 0; x < pyramid[y].length; x++) {
37 | max[y][x] = pyramid[y][x] + Math.max(pyramid[y + 1][x], pyramid[y + 1][x + 1]);
38 | }
39 | }
40 |
41 | return max[0][0];
42 | }
43 |
44 | /** Brute force times out
45 | public static int longestSlideDown(int[][] pyramid) {
46 | return branchSlide(pyramid, 0, 0, 0);
47 | }
48 |
49 | private static final int branchSlide(int[][] pyramid, int sum, int y, int x) {
50 | sum += pyramid[y][x];
51 | if (++y == pyramid.length) {
52 | return sum;
53 | } else {
54 | return Math.max(branchSlide(pyramid, sum, y, x), branchSlide(pyramid, sum, y, x + 1));
55 | }
56 | }
57 | */
58 |
59 | @Test
60 | public void test() {
61 | int[][] test = new int[][] {{75},
62 | {95, 64},
63 | {17, 47, 82},
64 | {18, 35, 87, 10},
65 | {20, 4, 82, 47, 65},
66 | {19, 1, 23, 75, 3, 34},
67 | {88, 2, 77, 73, 7, 63, 67},
68 | {99, 65, 4, 28, 6, 16, 70, 92},
69 | {41, 41, 26, 56, 83, 40, 80, 70, 33},
70 | {41, 48, 72, 33, 47, 32, 37, 16, 94, 29},
71 | {53, 71, 44, 65, 25, 43, 91, 52, 97, 51, 14},
72 | {70, 11, 33, 28, 77, 73, 17, 78, 39, 68, 17, 57},
73 | {91, 71, 52, 38, 17, 14, 91, 43, 58, 50, 27, 29, 48},
74 | {63, 66, 4, 68, 89, 53, 67, 30, 73, 16, 69, 87, 40, 31},
75 | {4, 62, 98, 27, 23, 9, 70, 98, 73, 93, 38, 53, 60, 4, 23},
76 | };
77 | assertEquals(1074, LongestSlideDown.longestSlideDown(test));
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/main/java/kyu4/SecretDetective.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu4;
2 |
3 | /**
4 | * 4 kyu - Recover a secret string from random triplets
5 | *
6 | * https://www.codewars.com/kata/53f40dff5f9d31b813000774/train/java
7 | *
8 | * Details:
9 | *
10 | * There is a secret string which is unknown to you. Given a collection of random triplets from the string, recover the
11 | * original string.
12 | *
13 | * A triplet here is defined as a sequence of three letters such that each letter occurs somewhere before the next in
14 | * the given string. "whi" is a triplet for the string "whatisup".
15 | *
16 | * As a simplification, you may assume that no letter occurs more than once in the secret string.
17 | *
18 | * You can assume nothing about the triplets given to you other than that they are valid triplets and that they contain
19 | * sufficient information to deduce the original string. In particular, this means that the secret string will never
20 | * contain letters that do not occur in one of the triplets given to you.
21 | */
22 |
23 | import org.junit.jupiter.api.Test;
24 |
25 | import java.util.ArrayList;
26 | import java.util.List;
27 |
28 | import static org.junit.Assert.assertEquals;
29 |
30 | public class SecretDetective {
31 | public String recoverSecret(char[][] triplets) {
32 | List res = new ArrayList<>();
33 |
34 | for (char[] triplet : triplets) {
35 | final char x = triplet[0];
36 | final char y = triplet[1];
37 | final char z = triplet[2];
38 |
39 | if (!res.contains(x)) {
40 | res.add(0, x);
41 | }
42 |
43 | if (!res.contains(y)) {
44 | res.add(res.indexOf(x), y);
45 | }
46 |
47 | if (res.contains(y) && res.indexOf(y) < res.indexOf(x)) {
48 | final int index = res.indexOf(y);
49 | res.remove(index);
50 | res.add(res.indexOf(x) + 1, y);
51 | }
52 |
53 | if (!res.contains(z)) {
54 | res.add(res.indexOf(y), z);
55 | }
56 |
57 | if (res.contains(z) && res.indexOf(z) < res.indexOf(y)) {
58 | final int index = res.indexOf(z);
59 | res.remove(index);
60 | res.add(res.indexOf(y) + 1, z);
61 | }
62 | }
63 |
64 | final StringBuilder sb = new StringBuilder();
65 |
66 | for (Character c : res) {
67 | sb.append(c);
68 | }
69 |
70 | return new String(sb);
71 | }
72 |
73 |
74 | /**
75 | * Test section
76 | */
77 |
78 | @Test
79 | public void secret1() {
80 | SecretDetective detective = new SecretDetective();
81 | char[][] triplets = {
82 | {'t','u','p'},
83 | {'w','h','i'},
84 | {'t','s','u'},
85 | {'a','t','s'},
86 | {'h','a','p'},
87 | {'t','i','s'},
88 | {'w','h','s'}
89 | };
90 | assertEquals("whatisup", detective.recoverSecret(triplets));
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/src/main/java/kyu4/SnailSort.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu4;
2 |
3 | /**
4 | * 4 kyu - Snail Sort
5 | *
6 | * https://www.codewars.com/kata/521c2db8ddc89b9b7a0000c1/
7 | *
8 | * Details:
9 | *
10 | * Given an n x n array, return the array elements arranged from outermost elements to the middle
11 | * element, traveling clockwise.
12 | */
13 |
14 | import org.junit.Assert;
15 | import org.junit.Test;
16 |
17 | import java.util.Arrays;
18 | import static java.util.stream.Collectors.joining;
19 |
20 | public class SnailSort {
21 | public static int[] snail(int[][] array) {
22 | if (array == null || array.length == 0 || array.length == 1 && array[0].length == 0) {
23 | return new int[0];
24 | }
25 |
26 | final int height = array.length;
27 | final int width = array[0].length;
28 | final int lastY = height / 2;
29 | final int lastX = width % 2 == 0 ? width / 2 - 1 : width / 2;
30 |
31 | int y = 0, x = 0, dirX = 1, dirY = 0, i = 0;
32 | int leftBorder = -1, rightBorder = width;
33 | int upperBorder = -1, lowerBorder = height;
34 | int[] output = new int[height * width];
35 |
36 | while (true) {
37 | if (x == rightBorder && y == upperBorder + 1) {
38 | x--;
39 | y++;
40 | dirX = 0;
41 | dirY = 1;
42 | upperBorder++;
43 | } else if (x == leftBorder && y == lowerBorder - 1) {
44 | x++;
45 | y--;
46 | dirX = 0;
47 | dirY = -1;
48 | lowerBorder--;
49 | } else if (y == lowerBorder && x == rightBorder - 1) {
50 | y--;
51 | x--;
52 | dirX = -1;
53 | dirY = 0;
54 | rightBorder--;
55 | } else if (y == upperBorder && x == leftBorder + 1) {
56 | y++;
57 | x++;
58 | dirX = 1;
59 | dirY = 0;
60 | leftBorder++;
61 | }
62 | output[i] = array[y][x];
63 |
64 | if (y == lastY && x == lastX) {
65 | break;
66 | }
67 |
68 | x += dirX;
69 | y += dirY;
70 | i++;
71 | }
72 |
73 | return output;
74 | }
75 |
76 | @Test
77 | public void SnailTest1() {
78 | int[][] array
79 | = {{1, 2, 3},
80 | {4, 5, 6},
81 | {7, 8, 9}};
82 | int[] r = {1, 2, 3, 6, 9, 8, 7, 4, 5};
83 | test(array, r);
84 | }
85 |
86 | public String int2dToString(int[][] a) {
87 | return Arrays.stream(a).map(row -> Arrays.toString(row)).collect(joining("\n"));
88 | }
89 |
90 | public void test(int[][] array, int[] result) {
91 | String text = int2dToString(array) + " should be sorted to " + Arrays.toString(result);
92 | System.out.println(text);
93 | Assert.assertArrayEquals( result, snail(array));
94 | }
95 |
96 | }
97 |
--------------------------------------------------------------------------------
/src/main/java/kyu4/StringsMix.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu4;
2 |
3 | /**
4 | * 4 kyu - Strings mix
5 | *
6 | * https://www.codewars.com/kata/5629db57620258aa9d000014
7 | *
8 | * Details:
9 | *
10 | * Given two strings s1 and s2, we want to visualize how different the two strings are. We will
11 | * only take into account the lowercase letters (a to z). First let us count the frequency of each
12 | * lowercase letters in s1 and s2.
13 | *
14 | * s1 = "A aaaa bb c"
15 | *
16 | * s2 = "& aaa bbb c d"
17 | *
18 | * s1 has 4 'a', 2 'b', 1 'c'
19 | *
20 | * s2 has 3 'a', 3 'b', 1 'c', 1 'd'
21 | *
22 | * So the maximum for 'a' in s1 and s2 is 4 from s1; the maximum for 'b' is 3 from s2. In the
23 | * following we will not consider letters when the maximum of their occurrences is less than or
24 | * equal to 1.
25 | *
26 | * We can resume the differences between s1 and s2 in the following string: "1:aaaa/2:bbb" where
27 | * 1 in 1:aaaa stands for string s1 and aaaa because the maximum for a is 4. In the same manner
28 | * 2:bbb stands for string s2 and bbb because the maximum for b is 3.
29 | *
30 | * The task is to produce a string in which each lowercase letters of s1 or s2 appears as many
31 | * times as its maximum if this maximum is strictly greater than 1; these letters will be prefixed
32 | * by the number of the string where they appear with their maximum value and :. If the maximum is
33 | * in s1 as well as in s2 the prefix is =:.
34 | *
35 | * In the result, substrings (a substring is for example 2:nnnnn or 1:hhh; it contains the prefix)
36 | * will be in decreasing order of their length and when they have the same length sorted in
37 | * ascending lexicographic order (letters and digits - more precisely sorted by codepoint);
38 | * the different groups will be separated by '/'. See examples and "Example Tests".
39 | */
40 |
41 | import org.junit.Test;
42 |
43 | import java.nio.CharBuffer;
44 | import java.util.ArrayList;
45 | import java.util.Comparator;
46 | import java.util.List;
47 | import java.util.Map;
48 | import java.util.function.Function;
49 | import java.util.stream.Collectors;
50 |
51 | import static org.junit.Assert.assertEquals;
52 |
53 | public class StringsMix {
54 | public static String mix(String s1, String s2) {
55 | if (s1.equals(s2)) {
56 | return "";
57 | }
58 |
59 | final Map charactersFromS1 = calculateCharacterFrequency(s1);
60 | final Map charactersFromS2 = calculateCharacterFrequency(s2);
61 | final List allCharacters = new ArrayList<>(charactersFromS1.keySet());
62 |
63 | for (char c : new ArrayList<>(charactersFromS2.keySet())) {
64 | if (!allCharacters.contains(c)) {
65 | allCharacters.add(c);
66 | }
67 | }
68 |
69 | List result = new ArrayList<>();
70 |
71 | for (int i = 0; i < allCharacters.size(); i++) {
72 | final StringBuilder sb = new StringBuilder();
73 | final char current = allCharacters.get(i);
74 | final long frequency_1 = charactersFromS1.getOrDefault(current, 0L);
75 | final long frequency_2 = charactersFromS2.getOrDefault(current, 0L);
76 | final long frequency = Math.max(frequency_1, frequency_2);
77 |
78 | if (frequency_1 == frequency_2) {
79 | sb.append('=');
80 | } else {
81 | sb.append(frequency_1 > frequency_2 ? '1' : '2');
82 | }
83 | sb.append(':');
84 |
85 | for (int j = 0; j < frequency; j++) {
86 | sb.append(current);
87 | }
88 |
89 | result.add(sb.toString());
90 | }
91 |
92 | return result.stream()
93 | .sorted(Comparator.comparing(String::length)
94 | .reversed()
95 | .thenComparing(s -> s.length() == 0 ? -1 : s.charAt(0))
96 | .thenComparing(Function.identity()))
97 | .collect(Collectors.joining("/"));
98 | }
99 |
100 | private static Map calculateCharacterFrequency(String s) {
101 | return CharBuffer.wrap(s.toCharArray())
102 | .chars()
103 | .mapToObj(ch -> (char) ch)
104 | .filter(c -> Character.isAlphabetic(c))
105 | .filter(c -> Character.toUpperCase(c) != c)
106 | .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
107 | .entrySet()
108 | .stream()
109 | .filter(e -> e.getValue() > 1)
110 | .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
111 | }
112 |
113 | @Test
114 | public void test() {
115 | System.out.println("Mix Fixed Tests");
116 | assertEquals("1:aaa/1:nnn/1:gg/2:ee/2:ff/2:ii/2:oo/2:rr/2:ss/2:tt",
117 | mix(" In many languages", " there's a pair of functions"));
118 | }
119 | }
--------------------------------------------------------------------------------
/src/main/java/kyu4/StripComments.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu4;
2 |
3 | /**
4 | * 4 kyu - Strip Comments
5 | *
6 | * https://www.codewars.com/kata/51c8e37cee245da6b40000bd/
7 | *
8 | * Details:
9 | *
10 | * Complete the solution so that it strips all text that follows any of a set of comment markers
11 | * passed in. Any whitespace at the end of the line should also be stripped out.
12 | */
13 |
14 | import static org.junit.Assert.assertEquals;
15 |
16 | import org.junit.Test;
17 |
18 | public class StripComments {
19 | public static String stripComments(String text, String[] commentSymbols) {
20 | if (text.length() == 0 || text.isEmpty()) {
21 | return null;
22 | }
23 |
24 | final StringBuilder sb = new StringBuilder();
25 | final String[] lines = text.split("\n");
26 |
27 | for (int i = 0; i < lines.length; i++) {
28 | final String s = lines[i];
29 | final StringBuilder helper = new StringBuilder();
30 | int commentStartPosition = s.length();
31 |
32 | if (commentStartPosition !=0) {
33 | for (String comment : commentSymbols) {
34 | if (s.contains(comment)) {
35 | commentStartPosition = Math.min(commentStartPosition, s.indexOf(comment));
36 | }
37 | }
38 | helper.append(s, 0, commentStartPosition);
39 | }
40 |
41 | while (helper.length() !=0 && helper.charAt(helper.length() - 1) == ' ') {
42 | helper.setLength(helper.length() - 1);
43 | }
44 |
45 | helper.append("\n");
46 | sb.append(helper);
47 | }
48 |
49 | if (sb.length() != 0) {
50 | sb.setLength(sb.length() - 1);
51 | }
52 |
53 | return new String(sb);
54 | }
55 |
56 | @Test
57 | public void stripComments() throws Exception {
58 | assertEquals(
59 | "apples, pears\ngrapes\nbananas",
60 | StripComments.stripComments("apples, pears # and bananas\ngrapes\nbananas !apples", new String[]{"#", "!"})
61 | );
62 |
63 | assertEquals(
64 | "a\nc\nd",
65 | StripComments.stripComments("a #b\nc\nd $e f g", new String[]{"#", "$"})
66 | );
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/kyu4/SudokuSolutionValidator.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu4;
2 |
3 | /**
4 | * 4 kyu - Sudoku Solution Validator
5 | *
6 | * https://www.codewars.com/kata/529bf0e9bdf7657179000008/
7 | *
8 | * Details:
9 | *
10 | * Sudoku is a game played on a 9x9 grid. The goal of the game is to fill all cells of the grid
11 | * with digits from 1 to 9, so that each column, each row, and each of the nine 3x3 sub-grids
12 | * (also known as blocks) contain all of the digits from 1 to 9.
13 | * (More info at: http://en.wikipedia.org/wiki/Sudoku)
14 | *
15 | * Sudoku Solution Validator
16 | *
17 | * Write a function validSolution/ValidateSolution/valid_solution() that accepts a 2D array
18 | * representing a Sudoku board, and returns true if it is a valid solution, or false otherwise.
19 | * The cells of the sudoku board may also contain 0's, which will represent empty cells. Boards
20 | * containing one or more zeroes are considered to be invalid solutions.
21 | *
22 | * The board is always 9 cells by 9 cells, and every cell only contains integers from 0 to 9.
23 | */
24 |
25 | import java.util.ArrayList;
26 | import java.util.Collections;
27 |
28 | import org.junit.Test;
29 |
30 | import static org.junit.Assert.assertEquals;
31 |
32 | public class SudokuSolutionValidator {
33 | private static int size;
34 | private static ArrayList values;
35 |
36 | public static boolean check(int[][] sudoku) {
37 | size = sudoku.length;
38 | values = new ArrayList<>(size);
39 | return check(sudoku, true) && check(sudoku, false) && blocksCheck(sudoku);
40 | }
41 |
42 | private final static boolean blocksCheck(int[][] sudoku) {
43 | for (int y = 0; y < size; y += 3) {
44 | for (int x = 0; x < size; x += 3) {
45 | for (int j = y; j < y + 3; j++) {
46 | for (int i = x; i < x + 3; i++) {
47 | values.add(sudoku[j][i]);
48 | }
49 | }
50 | System.out.println(values.size());
51 |
52 | if (!validateSection()) {
53 | return false;
54 | }
55 | }
56 | }
57 | return true;
58 | }
59 |
60 | private final static boolean validateSection() {
61 | if (values.size() != size) {
62 | return false;
63 | }
64 |
65 | Collections.sort(values);
66 |
67 | if (values.get(0) != 1) {
68 | return false;
69 | }
70 |
71 | for (int i = 1; i < size; i++) {
72 | if (values.get(i) - values.get(i-1) != 1) {
73 | return false;
74 | }
75 | }
76 |
77 | values.clear();
78 |
79 | return true;
80 | }
81 |
82 | private final static boolean check(int[][] sudoku, boolean isFlipped) {
83 | for (int y = 0; y < size; y++) {
84 | for (int x = 0; x < size; x++) {
85 | int i;
86 | int j;
87 |
88 | if (isFlipped) {
89 | i = x;
90 | j = y;
91 | } else {
92 | i = y;
93 | j = x;
94 | }
95 |
96 | if (sudoku[i][j] == 0) {
97 | return false;
98 | }
99 | values.add(sudoku[i][j]);
100 | }
101 |
102 | if (!validateSection()) {
103 | return false;
104 | }
105 | }
106 |
107 | return true;
108 | }
109 |
110 | @Test
111 | public void exampleTest() {
112 | int[][] sudoku = {
113 | {9, 8, 7, 2, 3, 1, 5, 4, 6},
114 | {6, 5, 4, 8, 9, 7, 2, 1, 3},
115 | {3, 2, 1, 5, 6, 4, 8, 7, 9},
116 | {7, 6, 5, 9, 1, 8, 3, 2, 4},
117 | {4, 3, 2, 6, 7, 5, 9, 8, 1},
118 | {1, 9, 8, 3, 4, 2, 6, 5, 7},
119 | {8, 7, 6, 1, 2, 9, 4, 3, 5},
120 | {5, 4, 3, 7, 8, 6, 1, 9, 2},
121 | {2, 1, 9, 4, 5, 3, 7, 6, 8}
122 | };
123 | assertEquals(true, check(sudoku));
124 |
125 | sudoku[0][0]++;
126 | sudoku[1][1]++;
127 | sudoku[0][1]--;
128 | sudoku[1][0]--;
129 |
130 | assertEquals(false, check(sudoku));
131 |
132 | sudoku[0][0]--;
133 | sudoku[1][1]--;
134 | sudoku[0][1]++;
135 | sudoku[1][0]++;
136 |
137 | sudoku[4][4] = 0;
138 |
139 | assertEquals(false, check(sudoku));
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/src/main/java/kyu4/TimeFormatter.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu4;
2 |
3 | /**
4 | * 4 kyu - Human readable duration format
5 | *
6 | * https://www.codewars.com/kata/52742f58faf5485cae000b9a/train/java
7 | *
8 | * Details:
9 | *
10 | * our task in order to complete this Kata is to write a function which formats a duration, given
11 | * as a number of seconds, in a human-friendly way.
12 | *
13 | * The function must accept a non-negative integer. If it is zero, it just returns "now".
14 | * Otherwise, the duration is expressed as a combination of years, days, hours, minutes and
15 | * seconds.
16 | *
17 | * For the purpose of this Kata, a year is 365 days and a day is 24 hours.
18 | *
19 | * Note that spaces are important.
20 | * Detailed rules
21 | *
22 | * The resulting expression is made of components like 4 seconds, 1 year, etc. In general, a
23 | * positive integer and one of the valid units of time, separated by a space. The unit of time is
24 | * used in plural if the integer is greater than 1.
25 | *
26 | * The components are separated by a comma and a space (", "). Except the last component, which is
27 | * separated by " and ", just like it would be written in English.
28 | *
29 | * A more significant units of time will occur before than a least significant one. Therefore, 1
30 | * second and 1 year is not correct, but 1 year and 1 second is.
31 | *
32 | * Different components have different unit of times. So there is not repeated units like in 5
33 | * seconds and 1 second.
34 | *
35 | * A component will not appear at all if its value happens to be zero. Hence, 1 minute and 0
36 | * seconds is not valid, but it should be just 1 minute.
37 | *
38 | * A unit of time must be used "as much as possible". It means that the function should not return
39 | * 61 seconds, but 1 minute and 1 second instead. Formally, the duration specified by of a
40 | * component must not be greater than any valid more significant unit of time.
41 | */
42 |
43 | import org.junit.jupiter.api.Test;
44 |
45 | import java.util.*;
46 |
47 | import static org.junit.jupiter.api.Assertions.assertEquals;
48 |
49 | public class TimeFormatter {
50 | static class TimeUnit {
51 | private String name;
52 | private int value;
53 |
54 | TimeUnit(String name, int value) {
55 | this.name = name;
56 | this.value = value;
57 | }
58 | }
59 |
60 | public static String formatDuration(int seconds) {
61 | if (seconds <= 0) {
62 | return "now";
63 | }
64 |
65 | List time = new ArrayList<>();
66 | time.add(new TimeUnit("year", (seconds / (60 * 60 * 24 * 365))));
67 | time.add(new TimeUnit("day", (seconds / (60 * 60 * 24)) % 365));
68 | time.add(new TimeUnit("hour", (seconds / (60 * 60)) % 24));
69 | time.add(new TimeUnit("minute", (seconds / 60) % 60));
70 | time.add(new TimeUnit("second", seconds % 60));
71 |
72 | time.removeIf(timeUnit -> timeUnit.value == 0);
73 |
74 | StringBuilder sb = new StringBuilder();
75 |
76 | for (int i = 0; i < time.size(); i++) {
77 | final TimeUnit unit = time.get(i);
78 |
79 | sb.append(unit.value)
80 | .append(" ")
81 | .append(unit.name);
82 |
83 | if (unit.value > 1) {
84 | sb.append("s");
85 | } else if (i < time.size() - 2) {
86 | sb.append(", ");
87 | } else if (i == time.size() - 2) {
88 | sb.append(" and ");
89 | }
90 | }
91 |
92 | return new String(sb);
93 | }
94 |
95 | @Test
96 | public void exampleTests() {
97 | assertEquals("1 second", TimeFormatter.formatDuration(1));
98 | assertEquals("1 minute and 2 seconds", TimeFormatter.formatDuration(62));
99 | assertEquals("2 minutes", TimeFormatter.formatDuration(120));
100 | assertEquals("1 hour", TimeFormatter.formatDuration(3600));
101 | assertEquals("1 hour, 1 minute and 2 seconds", TimeFormatter.formatDuration(3662));
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/main/java/kyu4/TopWords.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu4;
2 |
3 | /**
4 | * 4 kyu - Most frequently used words in a text
5 | *
6 | * https://www.codewars.com/kata/51e056fe544cf36c410000fb/
7 | *
8 | * Details:
9 | *
10 | * Write a function that, given a string of text (possibly with punctuation and line-breaks),
11 | * returns an array of the top-3 most occurring words, in descending order of the number of occurrences.
12 | * Assumptions:
13 | *
14 | * A word is a string of letters (A to Z) optionally containing one or more apostrophes (') in
15 | * ASCII. (No need to handle fancy punctuation.)
16 | * Matches should be case-insensitive, and the words in the result should be lowercased.
17 | * Ties may be broken arbitrarily.
18 | * If a text contains fewer than three unique words, then either the top-2 or top-1 words
19 | * should be returned, or an empty array if a text contains no words.
20 | */
21 |
22 | import java.util.*;
23 | import java.util.regex.Matcher;
24 | import java.util.regex.Pattern;
25 | import java.util.stream.Collectors;
26 |
27 | public class TopWords {
28 | public static final int LIMIT = 3;
29 |
30 | public static List top3(String string) {
31 | final Map wordsCount = new HashMap<>();
32 |
33 | Pattern pattern = Pattern.compile("[A-Za-z][A-Za-z']*");
34 | Matcher matcher = pattern.matcher(string);
35 | while (matcher.find()) {
36 | String s = matcher.group().toLowerCase();
37 | wordsCount.put(s, wordsCount.getOrDefault(s, 1) + 1);
38 | }
39 |
40 | List> topWords = new ArrayList<>(wordsCount.entrySet());
41 | topWords.sort(Map.Entry.comparingByValue());
42 | ArrayList result = new ArrayList<>();
43 | int j = 0;
44 | for (int i = topWords.size() - 1; i >= 0; i--) {
45 | String s = topWords.get(i).getKey();
46 | if (j > 2 || s == null || s.length() == 0) {
47 | break;
48 | }
49 | if (Character.isAlphabetic(s.charAt(0))) {
50 | result.add(j, topWords.get(i).getKey());
51 | j++;
52 | }
53 | }
54 |
55 | result.trimToSize();
56 | return result;
57 | }
58 |
59 | public static List top3_streams(String string) {
60 | final Pattern pattern = Pattern.compile("[A-Za-z][A-Za-z']*");
61 | final Matcher matcher = pattern.matcher(string.toLowerCase());
62 | final Map wordsCount = new HashMap<>();
63 |
64 | while (matcher.find()) {
65 | String s = matcher.group();
66 | wordsCount.put(s, wordsCount.getOrDefault(s, 1) + 1);
67 | }
68 |
69 | return wordsCount.entrySet().stream()
70 | .sorted(Comparator.comparing(Map.Entry::getValue, Comparator.reverseOrder()))
71 | .limit(LIMIT)
72 | .map(Map.Entry::getKey)
73 | .collect(Collectors.toList());
74 | }
75 | }
--------------------------------------------------------------------------------
/src/main/java/kyu5/DoubleCola.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu5;
2 |
3 | /**
4 | * 5 kyu - Double Cola
5 | *
6 | * https://www.codewars.com/kata/551dd1f424b7a4cdae0001f0
7 | *
8 | * Details:
9 | *
10 | * Sheldon, Leonard, Penny, Rajesh and Howard are in the queue for a "Double Cola" drink vending
11 | * machine; there are no other people in the queue. The first one in the queue (Sheldon) buys a
12 | * can, drinks it and doubles! The resulting two Sheldons go to the end of the queue. Then the
13 | * next in the queue (Leonard) buys a can, drinks it and gets to the end of the queue as two
14 | * Leonards, and so on.
15 | *
16 | * For example, Penny drinks the third can of cola and the queue will look like this:
17 | *
18 | * Rajesh, Howard, Sheldon, Sheldon, Leonard, Leonard, Penny, Penny
19 | *
20 | * Write a program that will return the name of the person who will drink the n-th cola.
21 | * Input
22 | *
23 | * The input data consist of an array which contains at least 1 name, and single integer n which
24 | * may go as high as the biggest number your language of choice supports (if there's such limit,
25 | * of course).
26 | * Output / Examples
27 | *
28 | * Return the single line — the name of the person who drinks the n-th can of cola. The cans are
29 | * numbered starting from 1.
30 | */
31 |
32 | import org.junit.Test;
33 |
34 | import static org.junit.Assert.assertEquals;
35 |
36 | public class DoubleCola {
37 | public static String WhoIsNext(String[] names, int n) {
38 | int i = n;
39 | i--;
40 |
41 | final int len = names.length;
42 | while (i >= len) {
43 | i = (int) Math.floor((i - names.length) / 2);
44 | }
45 |
46 | return names[i];
47 | }
48 |
49 | @Test
50 | public void test1() {
51 | String[] names = new String[]{"Sheldon", "Leonard", "Penny", "Rajesh", "Howard"};
52 | int n = 1;
53 | assertEquals("Sheldon", WhoIsNext(names, n));
54 | }
55 |
56 | @Test
57 | public void test2() {
58 | String[] names = new String[]{"Sheldon", "Leonard", "Penny", "Rajesh", "Howard"};
59 | int n = 6;
60 | assertEquals("Sheldon", WhoIsNext(names, n));
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/main/java/kyu5/FactorialDecomposition.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu5;
2 |
3 | /**
4 | * 5 kyu - Factorial Decomposition
5 | *
6 | * https://www.codewars.com/kata/5a045fee46d843effa000070
7 | *
8 | * Details:
9 | *
10 | * The aim of the kata is to decompose n! (factorial n) into its prime factors.
11 | *
12 | * Prime numbers should be in increasing order. When the exponent of a prime is 1 don't put the
13 | * exponent.
14 | *
15 | * Notes
16 | *
17 | * - the function is decomp(n) and should return the decomposition of n! into its prime factors
18 | * in increasing order of the primes, as a string.
19 | * - factorial can be a very big number (4000! has 12674 digits, n will go from 300 to 4000).
20 | * - In Fortran - as in any other language - the returned string is not permitted to contain
21 | * any redundant trailing whitespace: you can use dynamically allocated character strings.
22 | */
23 |
24 | import org.junit.jupiter.api.Test;
25 |
26 | import java.util.*;
27 |
28 | import static org.junit.jupiter.api.Assertions.assertEquals;
29 |
30 | public class FactorialDecomposition {
31 | public static String decomp(int n) {
32 | if (n == 1) {
33 | return "1";
34 | }
35 |
36 | LinkedHashMap decomposition = new LinkedHashMap<>();
37 |
38 | for (int i = 2; i <= n; i++) {
39 | int currentNum = i;
40 | int counter = 0;
41 |
42 | for (int k = 2; k <= i; ) {
43 | final int remainder = currentNum % k;
44 |
45 | if (remainder != 0 || currentNum <= 1) {
46 | if (counter !=0) {
47 | if (decomposition.containsKey(k)) {
48 | decomposition.put(k,decomposition.get(k) + counter);
49 | } else {
50 | decomposition.put(k, counter);
51 | }
52 | }
53 |
54 | k++;
55 | counter = 0;
56 | } else {
57 | counter++;
58 | currentNum /= k;
59 | }
60 | }
61 | }
62 |
63 | final StringBuilder sb = new StringBuilder();
64 |
65 | for (final Map.Entry entry : decomposition.entrySet()) {
66 | if (sb.length() != 0) {
67 | sb.append(" * ");
68 | }
69 |
70 | sb.append(entry.getKey());
71 |
72 | if (entry.getValue() != 1) {
73 | sb.append("^").append(entry.getValue());
74 | }
75 | }
76 |
77 | return new String(sb);
78 | }
79 |
80 | @Test
81 | public void test() {
82 | assertEquals("2^15 * 3^6 * 5^3 * 7^2 * 11 * 13 * 17", decomp(17));
83 | assertEquals("2^3 * 3 * 5", decomp(5));
84 | assertEquals("2^19 * 3^9 * 5^4 * 7^3 * 11^2 * 13 * 17 * 19", decomp(22));
85 | assertEquals("2^11 * 3^5 * 5^2 * 7^2 * 11 * 13", decomp(14));
86 | assertEquals("2^22 * 3^10 * 5^6 * 7^3 * 11^2 * 13 * 17 * 19 * 23", decomp(25));
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/main/java/kyu5/HumanReadableTime.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu5;
2 |
3 | /**
4 | * 5 kyu - Human Readable time
5 | *
6 | * https://www.codewars.com/kata/52685f7382004e774f0001f7
7 | *
8 | * Details:
9 | *
10 | * Write a function, which takes a non-negative integer (seconds) as input and returns the time
11 | * in a human-readable format (HH:MM:SS)
12 | *
13 | * HH = hours, padded to 2 digits, range: 00 - 99
14 | * MM = minutes, padded to 2 digits, range: 00 - 59
15 | * SS = seconds, padded to 2 digits, range: 00 - 59
16 | *
17 | * The maximum time never exceeds 359999 (99:59:59)
18 | *
19 | * You can find some examples in the test fixtures.
20 | */
21 |
22 | import org.junit.Test;
23 |
24 | import static org.junit.Assert.assertEquals;
25 |
26 | public class HumanReadableTime {
27 | public static String makeReadable(int seconds) {
28 | int minutes = seconds / 60;
29 | int hours = minutes / 60;
30 | minutes -= hours * 60;
31 | return String.format("%02d:%02d:%02d", hours, minutes, seconds % 60);
32 | }
33 |
34 | @Test
35 | public void tests() {
36 | assertEquals("makeReadable(0)", "00:00:00", HumanReadableTime.makeReadable(0));
37 | assertEquals("makeReadable(5)", "00:00:05", HumanReadableTime.makeReadable(5));
38 | assertEquals("makeReadable(60)", "00:01:00", HumanReadableTime.makeReadable(60));
39 | assertEquals("makeReadable(86399)", "23:59:59", HumanReadableTime.makeReadable(86399));
40 | assertEquals("makeReadable(359999)", "99:59:59", HumanReadableTime.makeReadable(359999));
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/kyu5/MergeIn2048.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu5;
2 |
3 | /**
4 | * 5 kyu - Merge in 2048
5 | *
6 | * https://www.codewars.com/kata/55e1990978c60e5052000011
7 | *
8 | * Details:
9 | *
10 | * Remember the game 2048?
11 | *
12 | * The main part of this game is merging identical tiles in a row.
13 | *
14 | * Implement a function that models the process of merging all of the tile values in a single
15 | * row.
16 | * This function takes the array line as a parameter and returns a new array with the tile
17 | * values from line slid towards the front of the array (index 0) and merged.
18 | *
19 | * A given tile can only merge once.
20 | * Empty grid squares are represented as zeros.
21 | * Your function should work on arrays containing arbitrary number of elements.
22 | */
23 |
24 | import org.junit.Test;
25 | import static org.junit.Assert.assertArrayEquals;
26 |
27 | public class MergeIn2048 {
28 | public static int[] merge(int[] line) {
29 | if (line == null || line.length == 0) {
30 | return new int[0];
31 | }
32 |
33 | compress(line);
34 | final boolean isMerged = add(line);
35 |
36 | if (isMerged) {
37 | compress(line);
38 | }
39 |
40 | return line;
41 | }
42 |
43 | private final static void compress(int[] row) {
44 | for (int i = 0; i < row.length; i++) {
45 | if (row[i] == 0) {
46 | for (int j = i; j < row.length; j++) {
47 | if (row[j] != 0) {
48 | row[i] = row[j];
49 | row[j] = 0;
50 | break;
51 | }
52 | }
53 | }
54 | }
55 | }
56 |
57 | private final static boolean add(int[] row) {
58 | boolean isMerged = false;
59 |
60 | for (int i = 0; i < row.length-1 ; i++) {
61 | if (row[i] == row[i + 1] && row[i] != 0) {
62 | row[i] = row[i] * 2;
63 | row[i+1] = 0;
64 | i++;
65 | isMerged = true;
66 | }
67 | }
68 |
69 | return isMerged;
70 | }
71 |
72 | @Test
73 | public void sampleTests() {
74 | assertArrayEquals(new int[] {4,2,0,0}, merge(new int[] {2,0,2,2}));
75 | assertArrayEquals(new int[] {4,4,0,0}, merge(new int[] {2,0,2,4}));
76 | assertArrayEquals(new int[] {4,0,0,0}, merge(new int[] {0,0,2,2}));
77 | }
78 | }
79 |
80 |
--------------------------------------------------------------------------------
/src/main/java/kyu5/Scramblies.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu5;
2 |
3 | /**
4 | * 5 kyu - Scramblies
5 | *
6 | * https://www.codewars.com/kata/55c04b4cc56a697bb0000048
7 | *
8 | * Details:
9 | *
10 | * Complete the function scramble(str1, str2) that returns true if a portion of str1 characters
11 | * can be rearranged to match str2, otherwise returns false.
12 | *
13 | * Notes:
14 | *
15 | * Only lower case letters will be used (a-z). No punctuation or digits will be included.
16 | * Performance needs to be considered
17 | */
18 |
19 | import java.util.HashMap;
20 | import java.util.Map;
21 |
22 | public class Scramblies {
23 |
24 | public static boolean scramble(String str1, String str2) {
25 | if (str2 == null || str2.length() == 0) {
26 | return true;
27 | }
28 | HashMap s1 = new HashMap<>();
29 | HashMap s2 = new HashMap<>();
30 |
31 | for (char ch : str1.toCharArray()) {
32 | char current = Character.toLowerCase(ch);
33 | s1.put(current, s1.getOrDefault(current, 0) + 1);
34 | }
35 |
36 | for (char ch : str2.toCharArray()) {
37 | char current = Character.toLowerCase(ch);
38 | s2.put(current, s2.getOrDefault(current, 0) + 1);
39 | }
40 |
41 | for (Map.Entry entry : s2.entrySet()) {
42 | try {
43 | if (entry.getValue() > s1.get(entry.getKey())) {
44 | return false;
45 | }
46 | } catch (NullPointerException e) {
47 | return false;
48 | }
49 | }
50 |
51 | return true;
52 | }
53 | }
--------------------------------------------------------------------------------
/src/main/java/kyu5/SimplePigLatin.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu5;
2 |
3 | /**
4 | * 5 kyu - Simple Pig Latin
5 | *
6 | * https://www.codewars.com/kata/520b9d2ad5c005041100000f
7 | *
8 | * Details:
9 | *
10 | * Move the first letter of each word to the end of it,
11 | * then add "ay" to the end of the word. Leave punctuation marks untouched.
12 | */
13 |
14 | import org.junit.Test;
15 |
16 | import java.util.regex.Pattern;
17 |
18 | import static org.junit.Assert.assertEquals;
19 |
20 | public class SimplePigLatin {
21 | public static String pigIt(String str) {
22 | if (str == null || str.length() == 0) {
23 | return null;
24 | }
25 |
26 | final String[] words = str.split("\\s");
27 | final StringBuilder sb = new StringBuilder();
28 |
29 | for (String s : words) {
30 | if (Pattern.matches("\\p{IsPunctuation}", s)) {
31 | sb.append(s)
32 | .append(" ");
33 | } else {
34 | sb.append(s.substring(1))
35 | .append(s.charAt(0))
36 | .append("ay ");
37 | }
38 | }
39 |
40 | while (sb.charAt(sb.length() - 1) == ' ') {
41 | sb.setLength(sb.length() - 1);
42 | }
43 |
44 | return new String(sb);
45 | }
46 |
47 | @Test
48 | public void fixedTests() {
49 | assertEquals("igPay atinlay siay oolcay", pigIt("Pig latin is cool"));
50 | assertEquals("hisTay siay ymay tringsay", pigIt("This is my string"));
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/kyu5/SnakesLadders.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu5;
2 |
3 | /**
4 | * 5 kyu - Snakes and Ladders
5 | *
6 | * https://www.codewars.com/kata/587136ba2eefcb92a9000027
7 | *
8 | * Details:
9 | *
10 | * Snakes and Ladders is an ancient Indian board game regarded today as a worldwide classic. It is
11 | * played between two or more players on a gameboard having numbered, gridded squares. A number
12 | * of "ladders" and "snakes" are pictured on the board, each connecting two specific board
13 | * squares. (Source Wikipedia)
14 | *
15 | * Your task is to make a simple class called SnakesLadders. The test cases will call the method
16 | * play(die1, die2) independently of the state of the game or the player turn. The variables die1
17 | * and die2 are the die thrown in a turn and are both integers between 1 and 6. The player will
18 | * move the sum of die1 and die2.
19 | *
20 | * Rules:
21 | * 1. There are two players and both start off the board on square 0.
22 | * 2. Player 1 starts and alternates with player 2.
23 | * 3. You follow the numbers up the board in order 1=>100
24 | * 4. If the value of both die are the same then that player will have another go.
25 | * 5. Climb up ladders. The ladders on the game board allow you to move upwards and get ahead
26 | * faster. If you land exactly on a square that shows an image of the bottom of a ladder, then
27 | * you may move the player all the way up to the square at the top of the ladder. (even if you
28 | * roll a double).
29 | * 6. Slide down snakes. Snakes move you back on the board because you have to slide down them.
30 | * If you land exactly at the top of a snake, slide move the player all the way to the square
31 | * at the bottom of the snake or chute. (even if you roll a double).
32 | * 7. Land exactly on the last square to win. The first person to reach the highest square on
33 | * the board wins. But there's a twist! If you roll too high, your player "bounces" off the
34 | * last square and moves back. You can only win by rolling the exact number needed to land on
35 | * the last square. For example, if you are on square 98 and roll a five, move your game piece
36 | * to 100 (two moves), then "bounce" back to 99, 98, 97 (three, four then five moves.)
37 | * 8. If the Player rolled a double and lands on the finish square “100” without any remaining
38 | * moves then the Player wins the game and does not have to roll again.
39 | */
40 |
41 | import java.util.ArrayList;
42 |
43 | public class SnakesLadders {
44 | private ArrayList players = new ArrayList<>();
45 | private ArrayList modifiers = new ArrayList<>();
46 | private boolean isGameStopped;
47 |
48 | public SnakesLadders() {
49 | players.add(new Player(1, true));
50 | players.add(new Player(2));
51 |
52 | modifiers.add(new Ladder(2,38));
53 | modifiers.add(new Ladder(7,14));
54 | modifiers.add(new Ladder(8,31));
55 | modifiers.add(new Ladder(7,14));
56 | modifiers.add(new Ladder(8,31));
57 | modifiers.add(new Ladder(15,26));
58 | modifiers.add(new Ladder(21,42));
59 | modifiers.add(new Ladder(28,84));
60 | modifiers.add(new Ladder(36,44));
61 | modifiers.add(new Ladder(51,67));
62 | modifiers.add(new Ladder(71,91));
63 | modifiers.add(new Ladder(78,98));
64 | modifiers.add(new Ladder(87,94));
65 |
66 | modifiers.add(new Slope(16,6));
67 | modifiers.add(new Slope(46,25));
68 | modifiers.add(new Slope(49,11));
69 | modifiers.add(new Slope(62,19));
70 | modifiers.add(new Slope(64,60));
71 | modifiers.add(new Slope(74,53));
72 | modifiers.add(new Slope(89,68));
73 | modifiers.add(new Slope(92,88));
74 | modifiers.add(new Slope(95,75));
75 | modifiers.add(new Slope(99,80));
76 |
77 | isGameStopped = false;
78 | }
79 |
80 | class Ladder {
81 | private int startX, endX;
82 |
83 | public Ladder(int startX, int endX) {
84 | this.startX = startX;
85 | this.endX = endX;
86 | }
87 | }
88 |
89 | class Slope extends Ladder {
90 | public Slope(int startX, int endX) {
91 | super(startX, endX);
92 | }
93 | }
94 |
95 | class Player {
96 | private int id, x;
97 | private boolean isWinner, isCurrentTurn;
98 |
99 | public Player(int id) {
100 | this.id = id;
101 | }
102 |
103 | public Player(int id, boolean isCurrentTurn) {
104 | this.id = id;
105 | this.isCurrentTurn = isCurrentTurn;
106 | }
107 | }
108 |
109 | private String currentState(Player p) {
110 | if (p.x == 100 && !isGameStopped) {
111 | p.isWinner = true;
112 | isGameStopped = true;
113 | return String.format("Player %d Wins!", p.id);
114 | } else {
115 | if (isGameStopped) {
116 | return ("Game over!");
117 | }
118 | return String.format("Player %d is on square %d", p.id, p.x);
119 | }
120 | }
121 |
122 | private void checkPosition(Player p) {
123 | modifiers.forEach(m -> {
124 | if (m.startX == p.x) {
125 | p.x = m.endX;
126 | }
127 | });
128 | }
129 |
130 | public String play(int die1, int die2) {
131 | for (int i = 0; i < players.size(); i++) {
132 | if (players.get(i).isCurrentTurn) {
133 | players.get(i).x += die1 + die2;
134 |
135 | if (players.get(i).x > 100) {
136 | players.get(i).x = 100 - (players.get(i).x - 100);
137 | }
138 |
139 | checkPosition(players.get(i));
140 |
141 | if (die1 != die2) {
142 | players.get(i).isCurrentTurn = false;
143 |
144 | if (i != players.size() - 1) {
145 | players.get(i + 1).isCurrentTurn = true;
146 | } else {
147 | players.get(0).isCurrentTurn = true;
148 | }
149 | }
150 | return currentState(players.get(i));
151 | }
152 | }
153 | return null;
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/src/main/java/kyu5/WhatsThePerfectPowerAnyway.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu5;
2 |
3 | /**
4 | * 5 kyu - What's the Perfect Power anyway?
5 | *
6 | * https://www.codewars.com/kata/54d4c8b08776e4ad92000835
7 | *
8 | * Details:
9 | *
10 | * A perfect power is a classification of positive integers:
11 | *
12 | * In mathematics, a perfect power is a positive integer that can be expressed as an integer
13 | * power of another positive integer. More formally, n is a perfect power if there exist
14 | * natural numbers m > 1, and k > 1 such that mk = n.
15 | *
16 | * Your task is to check wheter a given integer is a perfect power. If it is a perfect power,
17 | * return a pair m and k with mk = n as a proof. Otherwise return Nothing, Nil, null, NULL, None
18 | * or your language's equivalent.
19 | *
20 | * Note: For a perfect power, there might be several pairs. For example 81 = 3^4 = 9^2, so (3,4)
21 | * and (9,2) are valid solutions. However, the tests take care of this, so if a number is a perfect
22 | * power, return any pair that proves it.
23 | */
24 |
25 | import org.junit.Assert;
26 | import org.junit.jupiter.api.Test;
27 |
28 | import java.util.Random;
29 |
30 | import static java.lang.Math.log;
31 |
32 |
33 | public class WhatsThePerfectPowerAnyway {
34 | public static int[] isPerfectPower(int n) {
35 | final double sqrt = Math.sqrt(n);
36 | for (int i = 2, j = 2; i <= sqrt; ) {
37 | final int currentPow = (int) Math.pow(i, j);
38 |
39 | if (currentPow == n) {
40 | return new int[]{i, j};
41 | } else if (currentPow > n) {
42 | i++;
43 | j = 2;
44 | } else {
45 | j++;
46 | }
47 | }
48 | return null;
49 | }
50 |
51 | private static int ipow(int b, int e) {
52 | int i = b;
53 | int p = 1;
54 | for (; e > 0; e >>= 1) {
55 | if ((e & 1) == 1) p *= i;
56 | i *= i;
57 | }
58 | return p;
59 | }
60 |
61 | @Test
62 | public void test0() {
63 | Assert.assertNull("0 is not a perfect number", isPerfectPower(0));
64 | }
65 |
66 | @Test
67 | public void test1() {
68 | Assert.assertNull("1 is not a perfect number", isPerfectPower(1));
69 | }
70 |
71 | @Test
72 | public void test2() {
73 | Assert.assertNull("2 is not a perfect number", isPerfectPower(2));
74 | }
75 |
76 | @Test
77 | public void test3() {
78 | Assert.assertNull("3 is not a perfect number", isPerfectPower(3));
79 | }
80 |
81 | @Test
82 | public void test4() {
83 | Assert.assertArrayEquals("4 = 2^2", new int[]{2, 2}, isPerfectPower(4));
84 | }
85 |
86 | @Test
87 | public void test5() {
88 | Assert.assertNull("5 is not a perfect power", isPerfectPower(5));
89 | }
90 |
91 | @Test
92 | public void test8() {
93 | Assert.assertArrayEquals("8 = 2^3", new int[]{2, 3}, isPerfectPower(8));
94 | }
95 |
96 | @Test
97 | public void test9() {
98 | Assert.assertArrayEquals("9 = 3^2", new int[]{3, 2}, isPerfectPower(9));
99 | }
100 |
101 | @Test
102 | public void testUpTo500() {
103 | int[] pp = {4, 8, 9, 16, 25, 27, 32, 36, 49, 64, 81, 100, 121, 125, 128, 144, 169, 196, 216, 225, 243, 256, 289, 324, 343, 361, 400, 441, 484};
104 | for (int i : pp) Assert.assertNotNull(i + " is a perfect power", isPerfectPower(i));
105 | }
106 |
107 | @Test
108 | public void testRandomPerfectPowers() {
109 | Random rnd = new Random();
110 | for (int i = 0; i < 100; i++) {
111 | int m = rnd.nextInt(254) + 2;
112 | int k = (int) (rnd.nextDouble() * (log(Integer.MAX_VALUE) / log(m) - 2.0) + 2.0);
113 | int l = ipow(m, k);
114 | int[] r = isPerfectPower(l);
115 | Assert.assertNotNull(l + " is a perfect power", r);
116 | Assert.assertEquals(r[0] + "^" + r[1] + "!=" + l, l, ipow(r[0], r[1]));
117 | }
118 | }
119 |
120 | @Test
121 | public void testRandomNumbers() {
122 | Random rnd = new Random();
123 | for (int i = 0; i < 100; i++) {
124 | int l = rnd.nextInt(Integer.MAX_VALUE);
125 | int[] r = isPerfectPower(l);
126 | if (r != null) Assert.assertEquals(r[0] + "^" + r[1] + "!=" + l, l, ipow(r[0], r[1]));
127 | }
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/src/main/java/kyu6/AreTheyTheSame.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu6;
2 |
3 | /**
4 | * 6 kyu - Are they the "same"?
5 | *
6 | * https://www.codewars.com/kata/550498447451fbbd7600041c
7 | *
8 | * Details:
9 | *
10 | * Given two arrays a and b write a function comp(a, b) (compSame(a, b) in Clojure) that checks
11 | * whether the two arrays have the "same" elements, with the same multiplicities. "Same" means,
12 | * here, that the elements in b are the elements in a squared, regardless of the order.
13 | */
14 |
15 | import java.util.Arrays;
16 |
17 | public class AreTheyTheSame {
18 | public static boolean comp(int[] a, int[] b) {
19 | if (a == null || b == null) {
20 | return false;
21 | } else if (a.length == 0 || b.length == 0) {
22 | return a.length == b.length;
23 | } else {
24 | for (int i = 0; i < a.length; i++) {
25 | a[i] = Math.abs(a[i]);
26 | }
27 |
28 | for (int i = 0; i < b.length; i++) {
29 | b[i] = (int)Math.sqrt(b[i]);
30 | }
31 |
32 | Arrays.sort(a);
33 | Arrays.sort(b);
34 |
35 | for (int i = 0; i < a.length; i++) {
36 | if (a[i] != b[i]) {
37 | return false;
38 | }
39 | }
40 | }
41 | return true;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/kyu6/BreakCamelCase.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu6;
2 |
3 | /**
4 | * 6 kyu - Break camelCase
5 | *
6 | * https://www.codewars.com/kata/5208f99aee097e6552000148
7 | *
8 | * Details:
9 | *
10 | * Complete the solution so that the function will break up camel casing, using a space between
11 | * words.
12 | */
13 |
14 | public class BreakCamelCase {
15 | public static String camelCase(String input) {
16 | return input.replaceAll("([A-Z])", " $1");
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/kyu6/BuyingACar.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu6;
2 |
3 | /**
4 | * 6 kyu - Bying a car
5 | *
6 | * https://www.codewars.com/kata/554a44516729e4d80b000012/train/java
7 | *
8 | * Details:
9 | *
10 | * Let us begin with an example:
11 | *
12 | * A man has a rather old car being worth $2000. He saw a secondhand car being worth $8000. He
13 | * wants to keep his old car until he can buy the secondhand one.
14 | *
15 | * He thinks he can save $1000 each month but the prices of his old car and of the new one decrease
16 | * of 1.5 percent per month. Furthermore this percent of loss increases of 0.5 percent at the end
17 | * of every two months. Our man finds it difficult to make all these calculations.
18 | *
19 | * Can you help him?
20 | *
21 | * How many months will it take him to save up enough money to buy the car he wants, and how much
22 | * money will he have left over?
23 | */
24 |
25 | import org.junit.jupiter.api.Assertions;
26 | import org.junit.jupiter.api.Test;
27 |
28 | public class BuyingACar {
29 | public static int[] nbMonths(int startPriceOld, int startPriceNew, int savingPerMonth, double percentLossByMonth) {
30 | if (startPriceNew <= startPriceOld) {
31 | return new int[]{0, startPriceOld - startPriceNew};
32 | }
33 |
34 | double lossByMonth = percentLossByMonth;
35 | int passedMonths = 0;
36 | double currentDelta = startPriceOld - startPriceNew;
37 | double savingsLeft;
38 |
39 | do {
40 | passedMonths++;
41 |
42 | if (passedMonths % 2 == 0) {
43 | lossByMonth += 0.5;
44 | }
45 |
46 | currentDelta *= (1 - lossByMonth / 100);
47 | savingsLeft = passedMonths * savingPerMonth + currentDelta;
48 |
49 | System.out.println(String.format("End month: %d: percentLoss %.2f available %.3f",
50 | passedMonths, lossByMonth, savingsLeft));
51 | } while (savingsLeft < 0);
52 |
53 | return new int[]{passedMonths, (int) Math.round(savingsLeft)};
54 | }
55 |
56 |
57 | @Test
58 | void test1() {
59 | int[] r = new int[] { 6, 766 };
60 | Assertions.assertArrayEquals(r, nbMonths(2000, 8000, 1000, 1.5));
61 | }
62 | @Test
63 | void test2() {
64 | int[] r = new int[] { 0, 4000 };
65 | Assertions.assertArrayEquals(r, nbMonths(12000, 8000, 1000, 1.5));
66 | }
67 | @Test
68 | void test3() {
69 | int[] r = new int[] { 0, 0 };
70 | Assertions.assertArrayEquals(r, nbMonths(8000, 8000, 1000, 1.5));
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/main/java/kyu6/CamelCaseMethod.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu6;
2 |
3 | /**
4 | * 6 kyu - CamelCase Method
5 | *
6 | * https://www.codewars.com/kata/587731fda577b3d1b0001196
7 | *
8 | * Details:
9 | *
10 | * Write simple .camelCase method (camel_case function in PHP, CamelCase in C# or camelCase in
11 | * Java) for strings. All words must have their first letter capitalized without spaces.
12 | */
13 |
14 | import org.junit.Test;
15 |
16 | import static org.junit.Assert.assertEquals;
17 |
18 | public class CamelCaseMethod {
19 | public static String camelCase(String str) {
20 | final StringBuilder sb = new StringBuilder();
21 | boolean isPreviousCharSpace = false;
22 |
23 | for (int i = 0; i < str.length(); i++) {
24 | final char current = str.charAt(i);
25 |
26 | if ((i == 0 || isPreviousCharSpace) && !Character.isWhitespace(current)) {
27 | sb.append(Character.toUpperCase(current));
28 | isPreviousCharSpace = false;
29 | } else if (Character.isWhitespace(current)) {
30 | isPreviousCharSpace = true;
31 | } else {
32 | sb.append(current);
33 | }
34 | }
35 |
36 | return sb.toString();
37 | }
38 |
39 | @Test
40 | public void testTwoWords() {
41 | assertEquals("TestCase", camelCase("test case"));
42 | }
43 |
44 | @Test
45 | public void testThreeWords() {
46 | assertEquals("CamelCaseMethod", camelCase("camel case method"));
47 | }
48 |
49 | @Test
50 | public void testLeadingSpace() {
51 | assertEquals("CamelCaseWord", camelCase(" camel case word"));
52 | }
53 |
54 | @Test
55 | public void testTrailingSpace() {
56 | assertEquals("SayHello", camelCase("say hello "));
57 | }
58 |
59 | @Test
60 | public void testSingleLetter() {
61 | assertEquals("Z", camelCase("z"));
62 | }
63 |
64 | @Test
65 | public void testTwoSpacesBetweenWords() {
66 | assertEquals("AbC", camelCase("ab c"));
67 | }
68 |
69 | @Test
70 | public void testEmptyString() {
71 | assertEquals("", camelCase(""));
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/main/java/kyu6/ConsecutiveFib.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu6;
2 |
3 | /**
4 | * 6 kyu - Product of consecutive Fib numbers
5 | *
6 | * https://www.codewars.com/kata/5541f58a944b85ce6d00006a
7 | *
8 | * Details:
9 | *
10 | * The Fibonacci numbers are the numbers in the following integer sequence (Fn):
11 | * 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, ...
12 | *
13 | * such as
14 | * F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1.
15 | *
16 | * Given a number, say prod (for product), we search two Fibonacci numbers F(n) and F(n+1)
17 | * verifying
18 | * F(n) * F(n+1) = prod.
19 | *
20 | * Your function productFib takes an integer (prod) and returns an array:
21 | * [F(n), F(n+1), true] or {F(n), F(n+1), 1} or (F(n), F(n+1), True)
22 | *
23 | * depending on the language if
24 | * F(n) * F(n+1) = prod.
25 | *
26 | * If you don't find two consecutive F(m) verifying F(m) * F(m+1) = prod you will return
27 | * [F(m), F(m+1), false] or {F(n), F(n+1), 0} or (F(n), F(n+1), False)
28 | *
29 | * F(m) being the smallest one such as F(m) * F(m+1) > prod.
30 | */
31 |
32 | public class ConsecutiveFib {
33 | public static long[] productFib(long prod) {
34 | long a = 0;
35 | long b = 1;
36 |
37 | while (a * b <= prod) {
38 | if ((a * b) == prod) {
39 | return new long[]{a, b, 1};
40 | }
41 |
42 | final long buff = a;
43 | a = b;
44 | b += buff;
45 | }
46 | return new long[]{a, b, 0};
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/kyu6/ConvertStringToCamelCase.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu6;
2 |
3 | /**
4 | * 6 kyu - Convert string to camel case
5 | *
6 | * https://www.codewars.com/kata/517abf86da9663f1d2000003
7 | *
8 | * Details:
9 | *
10 | * Complete the method/function so that it converts dash/underscore delimited words into camel
11 | * casing. The first word within the output should be capitalized only if the original word was
12 | * capitalized (known as Upper Camel Case, also often referred to as Pascal case).
13 | */
14 |
15 | public class ConvertStringToCamelCase {
16 | public static String toCamelCase(String s) {
17 | final String regex = "([^a-zA-Z']+)'*\\1*";
18 | final String[] split = s.split(regex);
19 | final StringBuilder sb = new StringBuilder();
20 |
21 | for (int i = 0; i < split.length; i++) {
22 | if (i == 0) {
23 | sb.append(split[i]);
24 | } else if (split[i].length()>0){
25 | sb.append(split[i].replaceFirst(split[i].substring(0, 1), split[i].substring(0, 1).toUpperCase()));
26 | }
27 | }
28 | return new String(sb);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/kyu6/DigitalRoot.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu6;
2 | /**
3 | * Digital root
4 | *
5 | * https://www.codewars.com/kata/541c8630095125aba6000c00
6 | *
7 | * Details:
8 | *
9 | * Digital root is the recursive sum of all the digits in a number.
10 | *
11 | * Given n, take the sum of the digits of n. If that value has more than one digit,
12 | * continue reducing in this way until a single-digit number is produced.
13 | * This is only applicable to the natural numbers.
14 | */
15 |
16 | import org.junit.Test;
17 |
18 | import static org.junit.Assert.assertEquals;
19 |
20 | public class DigitalRoot {
21 | public static int digital_root(int n) {
22 | int i = n;
23 | if (i / 10 == 0) {
24 | return i;
25 | } else {
26 | int sum = 0;
27 | while (i > 0) {
28 | sum += i % 10;
29 | i /= 10;
30 | }
31 | return digital_root(sum);
32 | }
33 | }
34 |
35 | @Test
36 | public void tests() {
37 | assertEquals("Nope!", 7, digital_root(16));
38 | assertEquals("Nope!", 6, digital_root(456));
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/kyu6/Dubstep.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu6;
2 |
3 | /**
4 | * 6 kyu - Dubstep
5 | *
6 | * https://www.codewars.com/kata/551dc350bf4e526099000ae5
7 | *
8 | * Details:
9 | *
10 | * Polycarpus works as a DJ in the best Berland nightclub, and he often uses dubstep music in his
11 | * performance. Recently, he has decided to take a couple of old songs and make dubstep remixes
12 | * from them.
13 | *
14 | * Let's assume that a song consists of some number of words (that don't contain WUB). To make the
15 | * dubstep remix of this song, Polycarpus inserts a certain number of words "WUB" before the first
16 | * word of the song (the number may be zero), after the last word (the number may be zero), and
17 | * between words (at least one between any pair of neighbouring words), and then the boy glues
18 | * together all the words, including "WUB", in one string and plays the song at the club.
19 | *
20 | * For example, a song with words "I AM X" can transform into a dubstep remix as
21 | * "WUBWUBIWUBAMWUBWUBX" and cannot transform into "WUBWUBIAMWUBX".
22 | *
23 | * Recently, Jonny has heard Polycarpus's new dubstep track, but since he isn't into modern music,
24 | * he decided to find out what was the initial song that Polycarpus remixed. Help Jonny restore
25 | * the original song.
26 | * Input
27 | *
28 | * The input consists of a single non-empty string, consisting only of uppercase English letters,
29 | * the string's length doesn't exceed 200 characters
30 | * Output
31 | *
32 | * Return the words of the initial song that Polycarpus used to make a dubsteb remix. Separate
33 | * the words with a space.
34 | */
35 |
36 | import org.junit.Test;
37 |
38 | import static org.junit.Assert.assertEquals;
39 |
40 | public class Dubstep {
41 | public static String SongDecoder(String song) {
42 | String s = song;
43 |
44 | s = s.replaceAll("WUB", " ")
45 | .replaceAll("\\s+", " ");
46 |
47 | return s.trim();
48 | }
49 |
50 | @Test
51 | public void test1() {
52 | assertEquals("ABC", new Dubstep().SongDecoder("WUBWUBABCWUB"));
53 | }
54 | @Test
55 | public void test2()
56 | {
57 | assertEquals("R L", new Dubstep().SongDecoder("RWUBWUBWUBLWUB"));
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/kyu6/DuplicateEncoder.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu6;
2 |
3 | /**
4 | * 6 kyu - Duplicate Encoder
5 | *
6 | * https://www.codewars.com/kata/54b42f9314d9229fd6000d9c
7 | *
8 | * Details:
9 | *
10 | * The goal of this exercise is to convert a string to a new string where each character in the new
11 | * string is "(" if that character appears only once in the original string, or ")" if that
12 | * character appears more than once in the original string. Ignore capitalization when determining
13 | * if a character is a duplicate.
14 | */
15 |
16 | import java.util.ArrayList;
17 | import java.util.Collections;
18 |
19 | public class DuplicateEncoder {
20 | public static String encode(String word) {
21 | final ArrayList chars = new ArrayList<>();
22 | final StringBuilder line = new StringBuilder();
23 |
24 | for (char c : word.toLowerCase().toCharArray()) {
25 | chars.add(c);
26 | }
27 |
28 | for (int i = 0; i < chars.size(); i++) {
29 | if (Collections.frequency(chars,chars.get(i)) > 1) {
30 | line.append(")");
31 | } else {
32 | line.append("(");
33 | }
34 | }
35 |
36 | return new String(line);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/kyu6/EncryptThis.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu6;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 |
7 | /**
8 | * 6 kyu - Encrypt this!
9 | *
10 | * https://www.codewars.com/kata/5848565e273af816fb000449
11 | *
12 | * Details:
13 | * Encrypt this!
14 | *
15 | * You want to create secret messages which can be deciphered by the Decipher this!
16 | * Here are the conditions:
17 | *
18 | * Your message is a string containing space separated words.
19 | * You need to encrypt each word in the message using the following rules:
20 | * The first letter needs to be converted to its ASCII code.
21 | * The second letter needs to be switched with the last letter
22 | * Keepin' it simple: There are no special characters in input.
23 | */
24 |
25 | public class EncryptThis {
26 | public static String encryptThis(String text) {
27 | if (text == null || text.isEmpty()) {
28 | return "";
29 | }
30 |
31 | final String[] words = text.split(" ");
32 | final StringBuilder sb = new StringBuilder();
33 |
34 | for (String word : words) {
35 | if (!word.isEmpty()) {
36 | final int firstChar = word.charAt(0);
37 | sb.append(firstChar);
38 |
39 | if (word.length() > 3) {
40 | final String helper = word.charAt(word.length() - 1) +
41 | word.substring(2, word.length() - 1) +
42 | word.charAt(1);
43 | sb.append(helper);
44 | } else if (word.length() == 3) {
45 | sb.append(word.charAt(2));
46 | sb.append(word.charAt(1));
47 | } else if (word.length() == 2) {
48 | sb.append(word.charAt(1));
49 | }
50 |
51 | sb.append(" ");
52 | }
53 | }
54 |
55 | sb.setLength(sb.length()-1);
56 |
57 | return new String(sb);
58 | }
59 |
60 | @Test
61 | public void exampleTests() {
62 | assertEquals("",
63 | encryptThis(""));
64 |
65 | assertEquals("65 119esi 111dl 111lw 108dvei 105n 97n 111ka",
66 | encryptThis("A wise old owl lived in an oak"));
67 |
68 | assertEquals("84eh 109ero 104e 115wa 116eh 108sse 104e 115eokp",
69 | encryptThis("The more he saw the less he spoke"));
70 |
71 | assertEquals("84eh 108sse 104e 115eokp 116eh 109ero 104e 104dare",
72 | encryptThis("The less he spoke the more he heard"));
73 |
74 | assertEquals("87yh 99na 119e 110to 97ll 98e 108eki 116tah 119esi 111dl 98dri",
75 | encryptThis("Why can we not all be like that wise old bird"));
76 |
77 | assertEquals("84kanh 121uo 80roti 102ro 97ll 121ruo 104ple",
78 | encryptThis("Thank you Piotr for all your help"));
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/main/java/kyu6/EnoughIsEnough.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu6;
2 |
3 | /** 6 kyu - Delete occurrences of an element if it occurs more than n times
4 | *
5 | * https://www.codewars.com/kata/554ca54ffa7d91b236000023
6 | *
7 | * Details:
8 | *
9 | * Alice and Bob were on a holiday. Both of them took many pictures of the places they've been, and
10 | * now they want to show Charlie their entire collection. However, Charlie doesn't like these
11 | * sessions, since the motive usually repeats. He isn't fond of seeing the Eiffel tower 40 times.
12 | * He tells them that he will only sit during the session if they show the same motive at most N
13 | * times. Luckily, Alice and Bob are able to encode the motive as a number. Can you help them to
14 | * remove numbers such that their list contains each number only up to N times, without changing
15 | * the order?
16 | * Task
17 | *
18 | * Given a list lst and a number N, create a new list that contains each number of lst at most N
19 | * times without reordering. For example if N = 2, and the input is [1,2,3,1,2,1,2,3], you take
20 | * [1,2,3,1,2], drop the next [1,2] since this would lead to 1 and 2 being in the result 3 times,
21 | * and then take 3, which leads to [1,2,3,1,2,3].
22 | */
23 |
24 | import java.util.*;
25 |
26 | public class EnoughIsEnough {
27 | public static int[] deleteNth(int[] elements, int maxOccurrences) {
28 | if (elements.length == 0 || maxOccurrences == 0) {
29 | return new int[0];
30 | }
31 |
32 | final List elemList = new ArrayList<>(elements.length);
33 | final ArrayList filteredElements = new ArrayList<>();
34 |
35 | for (int e : elements) {
36 | elemList.add(e);
37 | }
38 |
39 | for (int e : elements) {
40 | if (filteredElements.contains(e)) {
41 | final int currentCount = Collections.frequency(filteredElements,e);
42 |
43 | if (currentCount < maxOccurrences) {
44 | filteredElements.add(e);
45 | }
46 | } else {
47 | filteredElements.add(e);
48 | }
49 | }
50 |
51 | int[] result = new int[filteredElements.size()];
52 |
53 | for (int i = 0; i < filteredElements.size(); i++) {
54 | result[i] = filteredElements.get(i);
55 | }
56 |
57 | return result;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/kyu6/ExtractFileName.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu6;
2 |
3 | /**
4 | * 6 kyu - extract file name
5 | *
6 | * https://www.codewars.com/kata/597770e98b4b340e5b000071
7 | *
8 | * Details:
9 | *
10 | * You have to extract a portion of the file name as follows:
11 | *
12 | * Assume it will start with date represented as long number
13 | * Followed by an underscore
14 | * You'll have then a filename with an extension
15 | * it will always have an extra extension at the end
16 | */
17 |
18 | import java.util.regex.Matcher;
19 | import java.util.regex.Pattern;
20 |
21 | public class ExtractFileName {
22 | public static String extractFileName(String dirtyFileName) {
23 | final Pattern pattern = Pattern.compile("_(.+)\\.");
24 | final Matcher matcher = pattern.matcher(dirtyFileName);
25 |
26 | matcher.find();
27 |
28 | return matcher.group(1);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/kyu6/FindOdd.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu6;
2 |
3 | /**
4 | * https://www.codewars.com/kata/54da5a58ea159efa38000836
5 | *
6 | * Find the odd int
7 | *
8 | * Details:
9 | *
10 | * Given an array, find the integer that appears an odd number of times.
11 | *
12 | * There will always be only one integer that appears an odd number of times.
13 | */
14 |
15 | import org.junit.Test;
16 |
17 | import java.util.Arrays;
18 |
19 | import static org.junit.Assert.assertEquals;
20 |
21 |
22 | public class FindOdd {
23 | public static int findIt(int[] input) {
24 | return Arrays.stream(input)
25 | .distinct()
26 | .filter(a -> Arrays.stream(input)
27 | .filter(b -> a == b).count() % 2 > 0)
28 | .reduce((a, b) -> {
29 | throw new IllegalStateException();
30 | })
31 | .getAsInt();
32 | }
33 |
34 | @Test
35 | public void findTest() {
36 | assertEquals(5, FindOdd.findIt(new int[]{20, 1, -1, 2, -2, 3, 3, 5, 5, 1, 2, 4, 20, 4, -1, -2, 5}));
37 | assertEquals(-1, FindOdd.findIt(new int[]{1, 1, 2, -2, 5, 2, 4, 4, -1, -2, 5}));
38 | assertEquals(5, FindOdd.findIt(new int[]{20, 1, 1, 2, 2, 3, 3, 5, 5, 4, 20, 4, 5}));
39 | assertEquals(10, FindOdd.findIt(new int[]{10}));
40 | assertEquals(10, FindOdd.findIt(new int[]{1, 1, 1, 1, 1, 1, 10, 1, 1, 1, 1}));
41 | assertEquals(1, FindOdd.findIt(new int[]{5, 4, 3, 2, 1, 5, 4, 3, 2, 10, 10}));
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/kyu6/FindUniqueNumber.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu6;
2 |
3 | /**
4 | * 6 kyu - Find the unique number
5 | *
6 | * https://www.codewars.com/kata/585d7d5adb20cf33cb000235/
7 | *
8 | * Details:
9 | *
10 | * There is an array with some numbers. All numbers are equal except for one. Try to find it!
11 | *
12 | * It’s guaranteed that array contains at least 3 numbers.
13 | *
14 | * The tests contain some very huge arrays, so think about performance.
15 | */
16 |
17 | import org.junit.Test;
18 |
19 | import java.util.Arrays;
20 |
21 | import static org.junit.Assert.assertEquals;
22 |
23 | public class FindUniqueNumber {
24 | private double precision = 0.0000000000001;
25 |
26 | public static double findUniq(double arr[]) {
27 | return Arrays.stream(arr)
28 | .distinct()
29 | .filter(a -> Arrays.stream(arr)
30 | .filter(b -> a == b).count() == 1)
31 | .reduce((a, b) -> {
32 | throw new IllegalStateException();
33 | })
34 | .getAsDouble();
35 | }
36 |
37 | @Test
38 | public void sampleTestCases() {
39 | assertEquals(1.0, findUniq(new double[]{0, 1, 0}), precision);
40 | assertEquals(2.0, findUniq(new double[]{1, 1, 1, 2, 1, 1}), precision);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/kyu6/GiveMeADiamond.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu6;
2 |
3 | /**
4 | * 6 kyu - Give me a Diamond
5 | *
6 | * https://www.codewars.com/kata/5503013e34137eeeaa001648
7 | *
8 | * Details:
9 | *
10 | * Jamie is a programmer, and James' girlfriend. She likes diamonds, and wants a diamond string
11 | * from James. Since James doesn't know how to make this happen, he needs your help.
12 | * Task
13 | *
14 | * You need to return a string that looks like a diamond shape when printed on the screen, using
15 | * asterisk (*) characters. Trailing spaces should be removed, and every line must be terminated
16 | * with a newline character (\n).
17 | *
18 | * Return null/nil/None/... if the input is an even number or negative, as it is not possible to
19 | * print a diamond of even or negative size.
20 | */
21 |
22 | public class GiveMeADiamond {
23 | public static final String DIAMOND = "*";
24 | public static final String SPACE = " ";
25 |
26 | public static String print(int n) {
27 | if (n <= 0 || n % 2 == 0) {
28 | return null;
29 | } else {
30 | final StringBuilder result = new StringBuilder();
31 |
32 | for (int i = 0; i < n; i++) {
33 | final int spaces = n/2 - i > 0 ? n/2 - i : i - n/2;
34 | final int diamonds = i <= n/2 ? 1+i*2 : -1 + (Math.abs(i - n) << 1);
35 |
36 | if (spaces != 0) {
37 | result.append(String.format(String.format("%%%ds", spaces), " ").replace(" ", SPACE));
38 | }
39 |
40 | result.append(String.format(String.format("%%%ds", diamonds), " ").replace(" ", DIAMOND));
41 | result.append("\n");
42 | }
43 | return new String(result);
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/kyu6/IsANumberPrime.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu6;
2 |
3 | /**
4 | * 6 kyu - Is a number prime?
5 | *
6 | * https://www.codewars.com/kata/5262119038c0985a5b00029f
7 | *
8 | * Details:
9 | *
10 | * Define a function that takes an integer argument and returns logical value true or false
11 | * depending on if the integer is a prime.
12 | *
13 | * Per Wikipedia, a prime number (or a prime) is a natural number greater than 1 that has no
14 | * positive divisors other than 1 and itself.
15 | */
16 |
17 | public class IsANumberPrime {
18 | public static boolean isPrime(int num) {
19 | if (num < 2) {
20 | return false;
21 | } else if (num == 2) {
22 | return true;
23 | } else {
24 | final int limit = (int) Math.sqrt(num);
25 | for (int i = 2; i <= limit; i++) {
26 | if (num % i == 0) {
27 | return false;
28 | }
29 | }
30 | }
31 | return true;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/kyu6/MultiplesOf3And5.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu6;
2 |
3 | /**
4 | * 6 kyu - Multiples of 3 or 5
5 | *
6 | * https://www.codewars.com/kata/514b92a657cdc65150000006
7 | *
8 | * Details:
9 | *
10 | * If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9.
11 | * The sum of these multiples is 23.
12 | *
13 | * Finish the solution so that it returns the sum of all the multiples of 3 or 5 below the number
14 | * passed in.
15 | *
16 | * Note: If the number is a multiple of both 3 and 5, only count it once.
17 | */
18 |
19 | import org.junit.Test;
20 |
21 | import java.util.stream.IntStream;
22 |
23 | import static org.junit.Assert.assertEquals;
24 |
25 | public class MultiplesOf3And5 {
26 | public static int solution(int number) {
27 | return IntStream.range(1, number)
28 | .filter(n -> n % 3 == 0 || n % 5 == 0)
29 | .sum();
30 | }
31 |
32 | @Test
33 | public void test() {
34 | assertEquals(1404932684, solution(1000000));
35 | }
36 | }
--------------------------------------------------------------------------------
/src/main/java/kyu6/PersistentBugger.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu6;
2 |
3 | /**
4 | * 6 kyu - Persistent Bugger
5 | *
6 | * https://www.codewars.com/kata/55bf01e5a717a0d57e0000ec
7 | *
8 | * Details:
9 | *
10 | * Write a function, persistence, that takes in a positive parameter num and returns its
11 | * multiplicative persistence, which is the number of times you must multiply the digits in num
12 | * until you reach a single digit.
13 | */
14 |
15 | import org.junit.Assert;
16 | import org.junit.Test;
17 |
18 | public class PersistentBugger {
19 | public static int persistence(final long n) {
20 | return persistenceCount(n, 0);
21 | }
22 |
23 | public static int persistenceCount(long n, int currentCount) {
24 | long l = n;
25 | if (l < 10) {
26 | return currentCount;
27 | }
28 |
29 | long nextN = 1;
30 | while (l != 0) {
31 | nextN *= l % 10;
32 | l /= 10;
33 | }
34 |
35 | return persistenceCount(nextN, ++currentCount);
36 | }
37 |
38 | @Test
39 | public void basicTests() {
40 | System.out.println("****** Basic Tests ******");
41 | Assert.assertEquals(3, persistence(39));
42 | Assert.assertEquals(0, persistence(4));
43 | Assert.assertEquals(2, persistence(25));
44 | Assert.assertEquals(4, persistence(999));
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/kyu6/ReverseWords.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu6;
2 |
3 | /**
4 | * 6 kyu - Stop gninnipS My sdroW!
5 | *
6 | * https://www.codewars.com/kata/5264d2b162488dc400000001
7 | *
8 | * Details:
9 | *
10 | * Write a function that takes in a string of one or more words, and returns the same string, but
11 | * with all five or more letter words reversed (Just like the name of this Kata). Strings passed
12 | * in will consist of only letters and spaces. Spaces will be included only when more than one
13 | * word is present.
14 | *
15 | * Examples: spinWords( "Hey fellow warriors" ) => returns "Hey wollef sroirraw" spinWords
16 | * ( "This is a test") => returns "This is a test" spinWords( "This is another test" )
17 | * => returns "This is rehtona test"
18 | *
19 | */
20 |
21 | import org.junit.Test;
22 | import static org.junit.Assert.assertEquals;
23 |
24 | public class ReverseWords {
25 | public String spinWords(String sentence) {
26 | final String[] words = sentence.split("\\s+");
27 | final StringBuilder sb = new StringBuilder();
28 |
29 | for (String word : words) {
30 | final StringBuilder helper = new StringBuilder(word);
31 |
32 | if (helper.length() >= 5) {
33 | helper.reverse();
34 | }
35 |
36 | sb.append(helper);
37 | sb.append(" ");
38 | }
39 |
40 | return new String(sb).trim();
41 | }
42 |
43 | @Test
44 | public void test() {
45 | assertEquals("emocleW", spinWords("Welcome"));
46 | assertEquals("Hey wollef sroirraw", spinWords("Hey fellow warriors"));
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/kyu6/TakeATenMinuteWalk.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu6;
2 |
3 | /**
4 | * 6 kyu - Take a Ten Minute Walk
5 | *
6 | * https://www.codewars.com/kata/54da539698b8a2ad76000228
7 | *
8 | * Details:
9 | *
10 | * You live in the city of Cartesia where all roads are laid out in a perfect grid. You arrived ten
11 | * minutes too early to an appointment, so you decided to take the opportunity to go for a short
12 | * walk. The city provides its citizens with a Walk Generating App on their phones -- every time
13 | * you press the button it sends you an array of one-letter strings representing directions to
14 | * walk (eg. ['n', 's', 'w', 'e']). You always walk only a single block in a direction and you know
15 | * it takes you one minute to traverse one city block, so create a function that will return true
16 | * if the walk the app gives you will take you exactly ten minutes (you don't want to be early or
17 | * late!) and will, of course, return you to your starting point. Return false otherwise.
18 | *
19 | * Note: you will always receive a valid array containing a random assortment of direction
20 | * letters ('n', 's', 'e', or 'w' only). It will never give you an empty array (that's not
21 | * a walk, that's standing still!).
22 | */
23 |
24 | public class TakeATenMinuteWalk {
25 |
26 | public static boolean isValid(char[] walk) {
27 | if (walk.length != 10) {
28 | return false;
29 | }
30 |
31 | int x = 0;
32 | int y = 0;
33 |
34 | for (Character c : walk) {
35 | switch (c) {
36 | case 'n':
37 | y++;
38 | break;
39 | case 's':
40 | y--;
41 | break;
42 | case 'e':
43 | x--;
44 | break;
45 | case 'w':
46 | x++;
47 | break;
48 | default :
49 | break;
50 | }
51 | }
52 |
53 | return x == 0 && y == 0;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/java/kyu6/VasyaClerk.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu6;
2 |
3 | /**
4 | * 6 kyu - Vasya Clerk
5 | *
6 | * https://www.codewars.com/kata/555615a77ebc7c2c8a0000b8
7 | *
8 | * Details:
9 | *
10 | * The new "Avengers" movie has just been released! There are a lot of people at the cinema box
11 | * office standing in a huge line.
12 | * Each of them has a single 100, 50 or 25 dollar bill. An "Avengers" ticket costs 25 dollars.
13 | *
14 | * Vasya is currently working as a clerk. He wants to sell a ticket to every single person in this
15 | * line.
16 | *
17 | * Can Vasya sell a ticket to every person and give change if he initially has no money and sells
18 | * the tickets strictly in the order people queue?
19 | *
20 | * Return YES, if Vasya can sell a ticket to every person and give change with the bills he has at
21 | * hand at that moment. Otherwise return NO.
22 | */
23 |
24 | public class VasyaClerk {
25 | public static final int PRICE = 25;
26 |
27 | public static String Tickets(int[] peopleInLine) {
28 | int countQuarter = 0;
29 | int countFifty = 0;
30 |
31 | for (int i : peopleInLine) {
32 | if (i == PRICE) {
33 | countQuarter++;
34 | } else if (i == 50) {
35 | countQuarter--;
36 |
37 | if (countQuarter < 0) {
38 | return "NO";
39 | }
40 |
41 | countFifty++;
42 | } else if (i == 100) {
43 | if (countFifty == 0) {
44 | countQuarter -= 3;
45 | } else {
46 | countQuarter--;
47 | countFifty--;
48 | }
49 | if (countQuarter < 0 || countFifty < 0) {
50 | return "NO";
51 | }
52 | }
53 | }
54 | return "YES";
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/kyu6/WhereIsMyParent.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu6;
2 |
3 | /**
4 | * 6 kyu - Where is my parent?!(cry)
5 | *
6 | * https://www.codewars.com/kata/58539230879867a8cd00011c
7 | *
8 | * Details:
9 | *
10 | * Mothers arranged a dance party for the children in school. At that party, there are only mothers
11 | * and their children.All are having great fun on the dance floor when suddenly all the lights went
12 | * out. It's a dark night and no one can see each other. But you were flying nearby and you can see
13 | * in the dark and have ability to teleport people anywhere you want.
14 | * Legend:
15 | * -Uppercase letters stands for mothers, lowercase stand for their children, i.e. "A" mother's
16 | * children are "aaaa".
17 | * -Function input: String contains only letters, uppercase letters are unique.
18 | *
19 | * Task:
20 | * Place all people in alphabetical order where Mothers are followed by their children, i.e.
21 | * "aAbaBb" => "AaaBbb".
22 | */
23 |
24 | import java.util.ArrayList;
25 | import java.util.Collections;
26 |
27 | public class WhereIsMyParent {
28 | public static String findChildren(final String text) {
29 | final ArrayList chars = new ArrayList<>();
30 |
31 | for (Character ch : text.toCharArray()) {
32 | chars.add(ch);
33 | }
34 |
35 | Collections.sort(chars);
36 |
37 | final StringBuilder sb = new StringBuilder();
38 |
39 | for (int i = 0; i < chars.size(); i++) {
40 | final char currChar = chars.get(i);
41 | final char lowChar = Character.toLowerCase(currChar);
42 | if (lowChar != currChar) {
43 | sb.append(currChar);
44 |
45 | if (chars.get(i) != chars.get(i + 1)) {
46 | final int frequency = Collections.frequency(chars, lowChar);
47 |
48 | if (frequency > 0) {
49 | for (int j = 0; j < frequency; j++) {
50 | sb.append(lowChar);
51 | }
52 | }
53 | }
54 | }
55 | }
56 | return new String(sb);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/java/kyu6/WhoLikesIt.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu6;
2 |
3 | /**
4 | * 6 kyu - Who likes it?
5 | *
6 | * https://www.codewars.com/kata/5266876b8f4bf2da9b000362
7 | *
8 | * Details:
9 | *
10 | * ou probably know the "like" system from Facebook and other pages. People can "like" blog posts,
11 | * pictures or other items. We want to create the text that should be displayed next to such an
12 | * item.
13 | *
14 | * Implement a function likes :: [String] -> String, which must take in input array, containing the
15 | * names of people who like an item. It must return the display text as shown in the examples
16 | */
17 |
18 | public class WhoLikesIt {
19 | public static String whoLikesIt(String... names) {
20 | final int len = names.length;
21 |
22 | switch (len) {
23 | case 0:
24 | return "no one likes this";
25 | case 1:
26 | return String.format("%s likes this", names[0]);
27 | case 2:
28 | return String.format("%s and %s like this", names[0], names[1]);
29 | case 3:
30 | return String.format("%s, %s and %s like this", names[0], names[1], names[2]);
31 | default:
32 | return String.format("%s, %s and %d others like this", names[0], names[1], len-2);
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/kyu7/ColouredTriangles.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu7;
2 |
3 | /**
4 | * 7 kyu - Coloured Triangles
5 | *
6 | * https://www.codewars.com/kata/5a25ac6ac5e284cfbe000111
7 | *
8 | * Details:
9 | *
10 | *
11 | * If you finish this kata, you can try Insane Coloured Triangles by Bubbler, which is a much
12 | * harder version of this one.
13 | *
14 | * A coloured triangle is created from a row of colours, each of which is red, green or blue.
15 | * Successive rows, each containing one fewer colour than the last, are generated by considering
16 | * the two touching colours in the previous row. If these colours are identical, the same colour
17 | * is used in the new row. If they are different, the missing colour is used in the new row. This
18 | * is continued until the final row, with only a single colour, is generated.
19 | *
20 | * You will be given the first row of the triangle as a string and its your job to return the final
21 | * colour which would appear in the bottom row as a string. In the case of the example above, you
22 | * would the given RRGBRGBB you should return G.
23 | *
24 | * The input string will only contain the uppercase letters R, G, B and there will be at least
25 | * one letter so you do not have to test for invalid input.
26 | * If you are only given one colour as the input, return that colour.
27 | *
28 | * Adapted from the 2017 British Informatics Olympiad
29 | */
30 |
31 | import org.junit.Test;
32 | import static org.junit.Assert.assertEquals;
33 |
34 | public class ColouredTriangles {
35 | public static char triangle(final String row) {
36 | if (row.length() == 1) return row.charAt(0);
37 |
38 | int currentLength = row.length();
39 | String previousRow = row;
40 |
41 |
42 | while (currentLength != 1) {
43 | final StringBuilder currentRow = new StringBuilder();
44 |
45 | for (int i = 0; i < previousRow.length() - 1; i++) {
46 | final char first = previousRow.charAt(i);
47 | final char second = previousRow.charAt(i + 1);
48 | if (first == second) {
49 | currentRow.append(first);
50 | } else currentRow.append(estimateColor(first,second));
51 | }
52 |
53 | currentLength--;
54 | previousRow = currentRow.toString();
55 | }
56 | return previousRow.charAt(0);
57 | }
58 |
59 | private static char estimateColor(final char first, final char second) {
60 | boolean isR = first == 'R' || second == 'R';
61 | boolean isG = first == 'G' || second == 'G';
62 |
63 | if (!isR) {
64 | return 'R';
65 | } else if (!isG) {
66 | return 'G';
67 | }
68 |
69 | return 'B';
70 | }
71 |
72 | @Test
73 | public void examples() {
74 | // assertEquals("expected", "actual");
75 | assertEquals('R', triangle("GB"));
76 | assertEquals('R', triangle("RRR"));
77 | assertEquals('B', triangle("RGBG"));
78 | assertEquals('G', triangle("RBRGBRB"));
79 | assertEquals('G', triangle("RBRGBRBGGRRRBGBBBGG"));
80 | assertEquals('B', triangle("B"));
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/main/java/kyu7/HalvingSum.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu7;
2 |
3 | /**
4 | * 7 kyu - Halving Sum
5 | *
6 | * https://www.codewars.com/kata/5a58d46cfd56cb4e8600009d
7 | *
8 | * Details:
9 | *
10 | * Given a positive integer n, calculate the following sum:
11 | *
12 | * n + n/2 + n/4 + n/8 + ...
13 | *
14 | * All elements of the sum are the results of integer division.
15 | */
16 |
17 | public class HalvingSum {
18 | public int halvingSum(int n) {
19 | return n == 0 ? 0 : n + halvingSum( n / 2);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/kyu7/JadenCasingStrings.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu7;
2 |
3 | /**
4 | * 7 kyu - Jaden Case Strings
5 | *
6 | * https://www.codewars.com/kata/5390bac347d09b7da40006f6
7 | *
8 | * Details:
9 | *
10 | * Jaden Smith, the son of Will Smith, is the star of films such as The Karate Kid (2010) and
11 | * After Earth (2013). Jaden is also known for some of his philosophy that he delivers via Twitter.
12 | * When writing on Twitter, he is known for almost always capitalizing every word. For simplicity,
13 | * you'll have to capitalize each word, check out how contractions are expected to be in the
14 | * example below.
15 | *
16 | * Your task is to convert strings to how they would be written by Jaden Smith.
17 | * The strings are actual quotes from Jaden Smith, but they are not capitalized in the same way he
18 | * originally typed them.
19 | *
20 | * Example:
21 | *
22 | * Not Jaden-Cased: "How can mirrors be real if our eyes aren't real"
23 | * Jaden-Cased: "How Can Mirrors Be Real If Our Eyes Aren't Real"
24 | *
25 | * Note that the Java version expects a return value of null for an empty string or null.
26 | */
27 |
28 | import java.util.ArrayList;
29 | import java.util.List;
30 |
31 | public class JadenCasingStrings {
32 |
33 | public String toJadenCase(String phrase) {
34 | try {
35 | if (phrase.isEmpty()) {return null;
36 | } else {
37 | final List list = new ArrayList<>();
38 | final StringBuilder a = new StringBuilder();
39 |
40 | for (int i = 0; i < phrase.length(); i++) {
41 | final char c = phrase.charAt(i);
42 | char d = 0;
43 |
44 | if (i > 1) {
45 | d = phrase.charAt(i - 1);
46 | }
47 |
48 | if (i == 0 || Character.isWhitespace(d)) {
49 | list.add(Character.toUpperCase(c));
50 | } else {
51 | list.add(c);
52 | }
53 | }
54 |
55 | for (Character character : list) {
56 | a.append(character);
57 | }
58 |
59 | return a.toString();
60 | }
61 | }
62 | catch (RuntimeException e) {
63 | return null;
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/main/java/kyu7/LargestFiveDigit.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu7;
2 |
3 | /**
4 | * 7 kyu - Largest 5 digit number in a series
5 | *
6 | * https://www.codewars.com/kata/51675d17e0c1bed195000001
7 | *
8 | * Details:
9 | *
10 | * In the following 6 digit number:
11 | *
12 | * 283910
13 | *
14 | * 91 is the greatest sequence of 2 consecutive digits.
15 | *
16 | * In the following 10 digit number:
17 | *
18 | * 1234567890
19 | *
20 | * 67890 is the greatest sequence of 5 consecutive digits.
21 | *
22 | * Complete the solution so that it returns the greatest sequence of five consecutive digits found
23 | * within the number given. The number will be passed in as a string of only digits. It should
24 | * return a five digit integer. The number passed may be as large as 1000 digits.
25 | */
26 |
27 | public class LargestFiveDigit {
28 | public static int solve(final String digits) {
29 | int result = 0;
30 |
31 | for (int i = 0; i < digits.length() - 4; i++) {
32 | final int compare = Integer.parseInt(digits.substring(i, i+5));
33 | result = Math.max(result, compare);
34 | }
35 |
36 | return result;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/kyu7/MultiplesOfN.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu7;
2 |
3 | /**
4 | * 7 kyu - Return the first M multiples of N
5 | *
6 | * https://www.codewars.com/kata/593c9175933500f33400003e
7 | *
8 | * Details:
9 | *
10 | * Implement a function, multiples(m, n), which returns an array of the first m multiples of the
11 | * real number n.
12 | * Assume that m is a positive integer.
13 | */
14 |
15 | public class MultiplesOfN {
16 | public static int[] multiples(int m, int n) {
17 | int[] result = new int[m];
18 |
19 | for (int i = 0; i < m; ) {
20 | result[i] = n * ++i;
21 | }
22 |
23 | return result;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/kyu7/PrinterErrors.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu7;
2 |
3 | /**
4 | * 7 kyu - Printer Errors
5 | *
6 | * https://www.codewars.com/kata/56541980fa08ab47a0000040
7 | *
8 | * Details:
9 | *
10 | * In a factory a printer prints labels for boxes. For one kind of boxes the printer has to use
11 | * colors which, for the sake of simplicity, are named with letters from a to m.
12 | *
13 | * The colors used by the printer are recorded in a control string. For example a "good" control
14 | * string would be aaabbbbhaijjjm meaning that the printer used three times color a, four times
15 | * color b, one time color h then one time color a...
16 | *
17 | * Sometimes there are problems: lack of colors, technical malfunction and a "bad" control string
18 | * is produced e.g. aaaxbbbbyyhwawiwjjjwwm with letters not from a to m.
19 | *
20 | * You have to write a function printer_error which given a string will output the error rate of
21 | * the printer as a string representing a rational whose numerator is the number of errors and the
22 | * denominator the length of the control string. Don't reduce this fraction to a simpler expression.
23 | *
24 | * The string has a length greater or equal to one and contains only letters from ato z.
25 | */
26 |
27 | public class PrinterErrors {
28 | public static String printerError(String s) {
29 | int count = 0;
30 |
31 | for (int i = 0; i < s.length(); i++) {
32 | if ("nopqrstuvwxyz".indexOf(s.charAt(i)) >= 0) {
33 | count++;
34 | }
35 | }
36 |
37 | return String.format("%d/%d", count, s.length());
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/kyu7/SplitInParts.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu7;
2 |
3 | /**
4 | * 7 kyu - Split In Parts
5 | *
6 | * https://www.codewars.com/kata/5650ab06d11d675371000003
7 | *
8 | * Details:
9 | *
10 | * The aim of this kata is to split a given string into different strings of equal size (note size
11 | * of strings is passed to the method)
12 | */
13 |
14 | public class SplitInParts {
15 | public static String splitInParts(String s, int partLength) {
16 | final StringBuilder sb = new StringBuilder();
17 |
18 | for (int i = 0; i <= s.length() - s.length() % partLength - partLength; i += partLength) {
19 | if (i > 0) {
20 | sb.append(" ");
21 | }
22 | sb.append(s, i, i + partLength);
23 | }
24 |
25 | if (s.length() % partLength != 0) {
26 | sb.append(" ")
27 | .append(s.substring(s.length() - s.length()%partLength));
28 | }
29 |
30 | return new String(sb);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/kyu7/SumOfNumbers.java:
--------------------------------------------------------------------------------
1 | package main.java.kyu7;
2 |
3 | /**
4 | * 7 kyu - Beginner Series #3 Sum of Numbers
5 | *
6 | * https://www.codewars.com/kata/55f2b110f61eb01779000053
7 | *
8 | * Details:
9 | *
10 | * Given two integers a and b, which can be positive or negative, find the sum of all the numbers
11 | * between including them too and return it. If the two numbers are equal return a or b.
12 | *
13 | * Note: a and b are not ordered!
14 | */
15 |
16 | public class SumOfNumbers {
17 | public int getSum(int a, int b) {
18 | int result = 0;
19 |
20 | for (int i = Math.min(a,b); i <= Math.max(a,b); i++) {
21 | result += i;
22 | }
23 |
24 | return result;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------