Kumite (ko͞omiˌtā) is the practice of taking techniques learned from Kata and applying them through the act of freestyle sparring.
You can create a new kumite by providing some initial code and optionally some test cases. From there other warriors can spar with you, by enhancing, refactoring and translating your code. There is no limit to how many warriors you can spar with.
A great use for kumite is to begin an idea for a kata as one. You can collaborate with other code warriors until you have it right, then you can convert it to a kata.
package cinco_kyu; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; public class DrivingTestEvaluator { public record Indication(int t, String type, int val) { } public record Action(int spd, boolean left, boolean right) { } public record Step(int time, Indication ind, Action act) { } enum WaitType { NONE, STOP, YIELD, REDLIGHT } static class State { int speedLimit = Integer.MAX_VALUE; int minor = 0; int overSpeedStreak = 0; WaitType waitType = WaitType.NONE; int waitUntil = 0; int waitVal = 0; } public static boolean evaluate(String exam, String road) { List<Indication> indications = parseIndications(exam); List<Action> actions = parseActions(road); Map<Integer, Indication> indMap = new HashMap<>(); for (Indication i : indications) { indMap.put(i.t(), i); } List<Step> steps = new ArrayList<>(); for (int i = 0; i < actions.size(); i++) { int time = i + 1; Indication ind = indMap.get(time); steps.add(new Step(time, ind, actions.get(i))); } State st = new State(); for (Step s : steps) { Indication ind = s.ind(); Action act = s.act(); if (ind != null) { switch (ind.type()) { case "SL" -> st.speedLimit = ind.val(); case "STOP" -> { if (act.spd() > 0) return false; st.waitType = WaitType.STOP; st.waitVal = ind.val(); st.waitUntil = s.time() + 3 + 2 * ind.val() - 1; } case "YIELD" -> { if (ind.val() > 0) { if (act.spd() > 0) return false; st.waitType = WaitType.YIELD; st.waitVal = ind.val(); st.waitUntil = s.time() + 2 * ind.val() - 1; } } case "REDLIGHT" -> { if (act.spd() > 0) return false; st.waitType = WaitType.REDLIGHT; st.waitVal = ind.val(); st.waitUntil = s.time() + ind.val() - 1; } case "TURNL" -> { if (!act.left()) { st.minor++; if (st.minor >= 3) return false; } } case "TURNR" -> { if (!act.right()) { st.minor++; if (st.minor >= 3) return false; } } } } if (st.waitType != WaitType.NONE) { if (s.time() <= st.waitUntil) { if (act.spd() > 0) { if (st.waitType == WaitType.STOP) { if (st.waitVal > 0) return false; else { st.minor++; if (st.minor >= 3) return false; } } else { return false; } st.waitType = WaitType.NONE; } } else { if (act.spd() == 0) return false; st.waitType = WaitType.NONE; } } if (act.spd() > st.speedLimit) { if (act.spd() > st.speedLimit + 10) return false; st.overSpeedStreak++; if (st.overSpeedStreak == 3) { st.overSpeedStreak = 0; st.minor++; if (st.minor >= 3) return false; } } else { st.overSpeedStreak = 0; } if (act.spd() == 0 && st.waitType == WaitType.NONE) return false; } if (st.waitType != WaitType.NONE) { if (st.waitType == WaitType.STOP) { if (st.waitVal == 0) { st.minor++; if (st.minor >= 3) return false; } else if (st.waitVal > 0) return false; } else return false; } return st.minor < 3; } private static List<Indication> parseIndications(String exam) { List<Indication> list = new ArrayList<>(); Pattern pattern = Pattern.compile("t=(\\d+)\\s+([A-Z]+)(\\d*)"); String[] parts = exam.split(";"); for (String s : parts) { s = s.trim(); Matcher matcher = pattern.matcher(s); if (matcher.find()) { int t = Integer.parseInt(matcher.group(1)); String type = matcher.group(2); int val = matcher.group(3).isEmpty() ? 0 : Integer.parseInt(matcher.group(3)); list.add(new Indication(t, type, val)); } } return list; } private static List<Action> parseActions(String road) { List<Action> actions = new ArrayList<>(); String[] tokens = road.trim().split("\\s+"); for (String s : tokens) { int spd = Integer.parseInt(s.replaceAll("[<>]", "")); boolean left = s.endsWith("<"); boolean right = s.endsWith(">"); actions.add(new Action(spd, left, right)); } return actions; } }
- package cinco_kyu;
import java.util.*;import java.util.function.Consumer;- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- public class DrivingTestEvaluator {
static Map<String, Consumer> rules = new HashMap();static int maxVelocity;static int indexExam;static int seconds = 0;static List<String> examList;static int minorInfractions = 0;public Map<String,String> evaluate(String indications, String exam) {int index = 0;refillRules();String[] indicationArray = indications.split(" ");examList = Arrays.stream(exam.split(" ")).toList();for (String step : indicationArray) {validateStep(step);}return Collections.singletonMap("","");- public record Indication(int t, String type, int val) { }
- public record Action(int spd, boolean left, boolean right) { }
- public record Step(int time, Indication ind, Action act) { }
- enum WaitType {
- NONE, STOP, YIELD, REDLIGHT
- }
private static void validateStep(String step) {rules.keySet().stream().filter(step::contains).findFirst().ifPresent(key -> rules.get(key).accept(step));- static class State {
- int speedLimit = Integer.MAX_VALUE;
- int minor = 0;
- int overSpeedStreak = 0;
- WaitType waitType = WaitType.NONE;
- int waitUntil = 0;
- int waitVal = 0;
- }
private void speedSituation(String velocity) {Pattern pattern = Pattern.compile("\\d+");Matcher matcher = pattern.matcher(velocity);if (matcher.find()) {maxVelocity = Integer.parseInt(matcher.group(1));- public static boolean evaluate(String exam, String road) {
- List<Indication> indications = parseIndications(exam);
- List<Action> actions = parseActions(road);
- Map<Integer, Indication> indMap = new HashMap<>();
- for (Indication i : indications) {
- indMap.put(i.t(), i);
- }
}private void stopSituation(String stop) {processStopLikeSituation(stop, 3);}- List<Step> steps = new ArrayList<>();
- for (int i = 0; i < actions.size(); i++) {
- int time = i + 1;
- Indication ind = indMap.get(time);
- steps.add(new Step(time, ind, actions.get(i)));
- }
private void yieldSituation(String yield) {processStopLikeSituation(yield, 0);}- State st = new State();
private void redLightSituation(String redLight) {processStopLikeSituation(redLight, 0);}private void turnSituation(String turn) {boolean exit = false;boolean isRight = false;try {while (!exit) {validSpeed();String action = examList.get(indexExam);if (action.length()==3) {isRight = validateTurnRigth(action);if (!isRight && turn.endsWith("R") || isRight && turn.endsWith("L")) minorInfractions++;exit = true;- for (Step s : steps) {
- Indication ind = s.ind();
- Action act = s.act();
- if (ind != null) {
- switch (ind.type()) {
- case "SL" -> st.speedLimit = ind.val();
- case "STOP" -> {
- if (act.spd() > 0) return false;
- st.waitType = WaitType.STOP;
- st.waitVal = ind.val();
- st.waitUntil = s.time() + 3 + 2 * ind.val() - 1;
- }
- case "YIELD" -> {
- if (ind.val() > 0) {
- if (act.spd() > 0) return false;
- st.waitType = WaitType.YIELD;
- st.waitVal = ind.val();
- st.waitUntil = s.time() + 2 * ind.val() - 1;
- }
- }
- case "REDLIGHT" -> {
- if (act.spd() > 0) return false;
- st.waitType = WaitType.REDLIGHT;
- st.waitVal = ind.val();
- st.waitUntil = s.time() + ind.val() - 1;
- }
- case "TURNL" -> {
- if (!act.left()) {
- st.minor++;
- if (st.minor >= 3) return false;
- }
- }
- case "TURNR" -> {
- if (!act.right()) {
- st.minor++;
- if (st.minor >= 3) return false;
- }
- }
if (examList.get(indexExam).equals("0")) break;indexExam++;- }
} catch (ExamFailedException e) {throw e;- }
}private boolean validateTurnRigth(String action) {return action.endsWith(">");}private void processStopLikeSituation(String input, int baseSeconds) {boolean exit = false;int secondsToStop = baseSeconds;Matcher matcher = Pattern.compile("\\d+").matcher(input);if (!input.contains("REDLIGHT") && matcher.find()) {secondsToStop += 2 * Integer.parseInt(matcher.group());}else if(matcher.find()){secondsToStop = Integer.parseInt(matcher.group());}try {while (!exit) {validSpeed();String action = examList.get(indexExam);if (action.length() > 3) throw new ExamFailedException();if (action.length() == 1) exit = hasStoppedCorrectly(secondsToStop);indexExam++;- if (st.waitType != WaitType.NONE) {
- if (s.time() <= st.waitUntil) {
- if (act.spd() > 0) {
- if (st.waitType == WaitType.STOP) {
- if (st.waitVal > 0) return false;
- else {
- st.minor++;
- if (st.minor >= 3) return false;
- }
- } else {
- return false;
- }
- st.waitType = WaitType.NONE;
- }
- } else {
- if (act.spd() == 0) return false;
- st.waitType = WaitType.NONE;
- }
- }
} catch (ExamFailedException e) {throw e;}}private boolean hasStoppedCorrectly(int seconsToStop) {boolean exit = false;while (!exit) {if (examList.get(indexExam).length() < 3 && Integer.parseInt(examList.get(indexExam)) == 0) {seconsToStop--;} else {if (seconsToStop != 0) {throw new ExamFailedException();- if (act.spd() > st.speedLimit) {
- if (act.spd() > st.speedLimit + 10) return false;
- st.overSpeedStreak++;
- if (st.overSpeedStreak == 3) {
- st.overSpeedStreak = 0;
- st.minor++;
- if (st.minor >= 3) return false;
- }
exit = true;- } else {
- st.overSpeedStreak = 0;
- }
indexExam++;}return true;}private void validSpeed() {Pattern pattern = Pattern.compile("^\\d+");Matcher matcher = pattern.matcher(examList.get(indexExam));if (Integer.parseInt(matcher.group(1)) > maxVelocity) {seconds++;} else {seconds = 0;- if (act.spd() == 0 && st.waitType == WaitType.NONE) return false;
- }
if (seconds > 2) minorInfractions++;if (Integer.parseInt(matcher.group(1)) > maxVelocity + 10) throw new ExamFailedException();}private static void refillRules() {- if (st.waitType != WaitType.NONE) {
- if (st.waitType == WaitType.STOP) {
- if (st.waitVal == 0) {
- st.minor++;
- if (st.minor >= 3) return false;
- } else if (st.waitVal > 0) return false;
- } else return false;
- }
- return st.minor < 3;
- }
- private static List<Indication> parseIndications(String exam) {
- List<Indication> list = new ArrayList<>();
- Pattern pattern = Pattern.compile("t=(\\d+)\\s+([A-Z]+)(\\d*)");
- String[] parts = exam.split(";");
- for (String s : parts) {
- s = s.trim();
- Matcher matcher = pattern.matcher(s);
- if (matcher.find()) {
- int t = Integer.parseInt(matcher.group(1));
- String type = matcher.group(2);
- int val = matcher.group(3).isEmpty() ? 0 : Integer.parseInt(matcher.group(3));
- list.add(new Indication(t, type, val));
- }
- }
- return list;
- }
static class ExamFailedException extends RuntimeException {public ExamFailedException() {super("Examen suspenso");- private static List<Action> parseActions(String road) {
- List<Action> actions = new ArrayList<>();
- String[] tokens = road.trim().split("\\s+");
- for (String s : tokens) {
- int spd = Integer.parseInt(s.replaceAll("[<>]", ""));
- boolean left = s.endsWith("<");
- boolean right = s.endsWith(">");
- actions.add(new Action(spd, left, right));
- }
- return actions;
- }
Trains and Trails
It's been a while since you saw your friends and you are eager to meet them.
You all agreed to meet at a point, but each one of your friends could arrive at a different station.
You've arrived early, so you are waiting for your friends to come.
Since you are impatient, and have nothing better to do, you try to guess the place and order in which your friends will arrive, if they do.
You know each one of them is in a different train, labeled from A to Z.
So you take a look at the map:
A----\ 1
------\
B--¡------------2
C-------) ---/
D-------/ 3
The map leyend reads:
Character | Description | Time Value |
---|---|---|
0-9 |
Different stations | |
A-Z |
Different trains your friends are in | |
) |
Indicates a tunel. The trains that enter it will be lost | |
- |
Indicates a rail for the train to move forward | 1 |
\ |
Indicates a turn. The train will move down and forward | 2 |
/ |
Indicates a turn. The train will move up and forward | 2 |
¡ |
Indicates a traffic light. The train will wait 1 turn and continue | 3 |
In this example we can see that all the trains will arrive at station 2. So the trains there will be :
- Train A takes 21 units of time to arrive
- Train B takes 16 units of time to arrive
- Train D takes 17 units of time to arrive
- Train C goes into a tunnel so we dont count it
Having this in mind, our result will be:
{
'2' : ( 'B', 'D', 'A' )
}
In java the result is a Map\<Character,List\<Character\>\>
Edge cases:
- If 2 trains take the same time to arrive at the station, they should be ordered alphaberically
- Collisions between trains do not affect them
- If the trains get out of the map, dont count them
import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.RepeatedTest; import java.util.Arrays; import java.util.Map; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Random; import java.lang.Math; import java.util.Map.Entry; import java.util.Comparator; class SolutionTest { private String printTracks (char[][] tracks) { return Arrays.stream(tracks) .map(String::valueOf) .map(s -> String.join(s,"\n"+s)) .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append) .toString(); } void pass(char[][] s, Map<Character, List<Character>> map) { assertEquals(map, TrainsAndRailways.travel(s), printTracks(s)); } void dontPass(char[][] s) { assertEquals(new java.util.HashMap<Character, List<Character>>(), TrainsAndRailways.travel(s), printTracks(s)); } @Test void exclusivePassTest() { pass(new char[][] {"A---------------1".toCharArray()}, Map.of('1', List.of('A'))); pass(new char[][] {"A----------¡-----1".toCharArray()}, Map.of('1', List.of('A'))); pass(new char[][] {"A-----------\\ -----------1".toCharArray(), " -------------/ ".toCharArray()}, Map.of('1', List.of('A'))); pass(new char[][] {"A-------- 1".toCharArray(), "B---------------2".toCharArray()}, Map.of('2', List.of('B'))); pass(new char[][] {"A----) 1".toCharArray(), "B-----------------2".toCharArray()}, Map.of('2', List.of('B'))); } @Test void exclusiveNotPassTest() { dontPass(new char[][] {"A-------- 1".toCharArray()}); dontPass(new char[][] {{}}); dontPass(new char[][] {"A----) 1".toCharArray()}); dontPass(new char[][] {"A----\\ ".toCharArray(), " --------1".toCharArray()}); dontPass(new char[][] {"A---------------------".toCharArray(), " 1".toCharArray()}); } private static char[][] generateRandomTracks() { char[][] matrix = new char[new Random().nextInt(5, 15)][new Random().nextInt(10, 25)]; int area = matrix.length * matrix[0].length; int numberOfStations = Math.min((int) new Random().nextDouble( 0.5 * matrix.length,matrix.length), 10); int numberOfTrains = Math.min((int) new Random().nextDouble( 0.5 * matrix.length,matrix.length), 26); int numberOfSemaphores = (int) new Random().nextDouble(area / 20, area / 8); int numberOfTunnels = (int) new Random().nextDouble(area / 30, area / 10); int numberOfLeftTracks = (int) new Random().nextDouble(area / 30, area / 15); int numberOfRightTracks = (int) new Random().nextDouble(area / 30, area / 15); List<Character> charsList = new ArrayList<Character>(); int i = 0; while (i < numberOfStations) { charsList.add(Character.forDigit(i++, 10)); } i = 0; while (i < numberOfTrains) { charsList.add((char) (i++ + 65)); } i = 0; while (i++ < numberOfSemaphores) { charsList.add('¡'); } i = 0; while (i++ < numberOfTunnels) { charsList.add(')'); } i = 0; while (i++ < numberOfLeftTracks) { charsList.add('/'); } i = 0; while (i++ < numberOfRightTracks) { charsList.add('\\'); } Collections.shuffle(charsList); int counter = 0; for (int x = 0; x < matrix.length; x++) { for (int y = 0; y < matrix[x].length; y++) { if ((charsList.get(counter) == '/' || charsList.get(counter) == '\\') && x != 0 && x != matrix.length - 1 && y != 0 && y != matrix[y].length) { matrix[x][y] = charsList.get(counter++); if (counter == charsList.size()) { counter = 0; } } } } for (int x = 0; x < matrix.length; x++) { for (int y = 0; y < matrix[x].length; y++) { if (matrix[x][y] == '\u0000') { matrix[x][y] = '-'; } } } return matrix; } @RepeatedTest(50) void randomTests() { char [][] matrix = generateRandomTracks(); assertEquals(travel(matrix), TrainsAndRailways.travel(matrix), printTracks(matrix)); } @Test void baseTest() { char[][] input = { {'A','-','-','-','-','-','\\','-','-','-','-','-','-','-','1'}, {'B','-','-','-','-','-','-','/',' '}, {' ',' ',' ',' ',' ',' ','-','-','-','-','-','2'}, {'C',' ','-','-','-','-','-','/',' '}, {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','3'}, {'D','-','-','-','-','-','-','-','-','-','-','-','-','-','4'} }; assertEquals(Map.of('1', List.of('B', 'A'), '4', List.of('D')), TrainsAndRailways.travel(input), printTracks(input)); char[][] input2 = { {'A', '-', '-', '¡', '\\', '¡', ' ', ' ', ' ', ' ', ' ', ' ', ' ', }, {'B', '-', '-', '-', '-', '\\', ' ', ' ', ' ', ' ', ' ', ' ', ' ', }, {' ', ' ', ' ', ' ', '-', '-', '\\', ' ', ' ', ' ', ' ', ' ', ' ', }, {'C', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '1', }, {'D', '-', '-', '-', '-', '-', '-', ')', ' ', ' ', ' ', ' ', ' ', }, {'E', '-', '-', '-', '/', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '2', }, }; assertEquals(Map.of('1', List.of('C', 'B', 'A')), TrainsAndRailways.travel(input2), printTracks(input2)); char[][] input3 = { {'A', '-', '-', '-', '\\', '-', '-', '-', '1', }, {' ', ' ', ' ', ' ', '-', '-', '-', '-', '2', }, {'B', '-', '¡', '-', '/', ' ', '-', '/', ' ', }, {'C', '-', '-', '/', ' ', '-', '/', ' ', ' ', }, {' ', ' ', ' ', ' ', '-', '/', ' ', ' ', ' ', }, {'D', '-', '-', '-', '/', ' ', ' ', ' ', ' ', }, }; assertEquals(Map.of('2', List.of('A', 'C', 'B', 'D')), TrainsAndRailways.travel(input3), printTracks(input3)); char[][] input4 = { {'A', '-', '-', '-', ')', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', }, {' ', ' ', ' ', ' ', '-', '\\', ' ', ' ', ' ', ' ', ' ', ' ', ' ', }, {'B', '-', '-', '-', '/', '-', '-', '-', '-', '\\', ' ', ' ', ' ', }, {'C', '-', '-', '¡', '-', '-', '-', '¡', '-', '-', '-', '-', '1', }, {'D', '-', '-', '-', '-', '-', '/', ' ', ' ', ' ', ' ', ' ', ' ', }, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '-', '2', }, {'E', '-', '-', '-', '\\', ' ', ' ', ' ', ' ', ' ', '-', '/', ' ', }, {' ', ' ', ' ', ' ', '-', '-', '-', '-', '-', '-', '/', ' ', ' ', }, {'F', '-', '-', '¡', '/', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', }, }; assertEquals(Map.of('1', List.of('B','D','C'), '2', List.of('E', 'F')), TrainsAndRailways.travel(input4), printTracks(input4)); } @Test void moreTest() { char[][] input = { {'A', '¡', '¡', '¡', '¡', '¡', '¡', '¡', '¡', '¡', '¡', '¡', '1', }, }; assertEquals(Map.of('1', List.of('A')), TrainsAndRailways.travel(input), printTracks(input)); char[][] input2 = { {'A', '¡', '¡', '¡', '¡', '¡', '\\', '¡', '¡', '¡', '¡', '¡', '1', }, {'B', '¡', '¡', '¡', '¡', '¡', '¡', '¡', '¡', '¡', '¡', '¡', '2', }, }; assertEquals(Map.of('2', List.of('A', 'B')), TrainsAndRailways.travel(input2), printTracks(input2)); } @Test void edgeCases() { char[][] input1 = { {'A', '1', }, {'B', '2', }, {'C', '3', }, {'D', '4', }, {'E', '5', }, {'F', '6', }, }; assertEquals(Map.of('1', List.of('A'),'2', List.of('B'), '3', List.of('C'),'4', List.of('D'), '5', List.of('E'),'6', List.of('F') ), TrainsAndRailways.travel(input1), printTracks(input1)); char[][] input2 = { {'-', '-', '-', '-', '-', '-', '-', '\\', '-'}, {'A', '-', '-', '-', '/', '-', '-', '\\', ' ', }, {'B', '-', '-', '-', '-', '-', '-', '-', '1', }, {'-', '-', '-', '-', '-', '-', '-', '-', '-'}, }; assertEquals(Map.of('1', List.of('B')), TrainsAndRailways.travel(input2), printTracks(input2)); char[][] input3 = { {'A', '-', '-', '¡', '1', '-', '-', '-', '2', }, }; assertEquals(Map.of('1', List.of('A')), TrainsAndRailways.travel(input3), printTracks(input3)); char[][] input4 = { {'A', '-', '-', '-', '-', '-', '\\', '-', '-', '-', '-', '-', '\\', ' ', }, {'B', '¡', '¡', '-', '-', '-', '-', '/', '-', '-', '-', '-', '-', '1', }, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', }, {'C', '-', '-', '-', '¡', '-', '-', '-', '-', '-', '-', '-', '-', '2', }, }; assertEquals(Map.of('1', List.of('A','B'), '2', List.of('C')), TrainsAndRailways.travel(input4), printTracks(input4)); char[][] input5 = { {'A', '-', '-', '-', '-', '-', '-', ')', ' ', ' ', ' ', }, {'C', '-', '-', '-', '-', '\\', ' ', ' ', ' ', ' ', ' ', }, {' ', ' ', ' ', ' ', ' ', '-', '-', '-', '-', '-', '1', }, {'B', '-', '-', '-', '-', '/', ' ', ' ', ' ', ' ', ' ', }, }; assertEquals(Map.of('1',List.of('B','C')), TrainsAndRailways.travel(input5), printTracks(input5)); } private Map<Character, List<Character>> travel(char[][] tracks) { Map<Character,List<Map.Entry<Character,Integer>>> result = new java.util.HashMap<>(); for (int row = 0; row < tracks.length; row++) { for (int column = 0; column < tracks[row].length; column++) { if (isTrain(tracks[row][column])) { Map.Entry<Character, Integer> train = new java.util.AbstractMap.SimpleEntry(tracks[row][column],0); goOnTraveling(tracks, row, column+1,train, result); } } } Map<Character,List<Character>> sortedShipOnStations = new java.util.HashMap<>(); result.forEach((k,v) -> sortedShipOnStations.put(k,sortTrains(v))); return sortedShipOnStations; } private boolean isTrain(char piece) { return piece >= 65 && piece <= 90; } private boolean isStation (char piece) { return piece >= 48 && piece <= 57; } private void goOnTraveling(char[][] tracks, int row, int column, Entry<Character, Integer> train, Map<Character, List<Map.Entry<Character, Integer>>> result) { while (column < tracks[row].length) { switch (tracks[row][column]) { case '¡': { train.setValue(train.getValue()+2); break; } case '-': { break; } case '/': { train.setValue(train.getValue()+1); row--; break; } case '\\': { train.setValue(train.getValue()+1); row++; break; } case ')': { return; } default: { if (isStation(tracks[row][column])) { result.putIfAbsent(tracks[row][column], new java.util.LinkedList<Map.Entry<Character,Integer>>()); result.get(tracks[row][column]).add(train); } return; } } train.setValue(train.getValue()+1); column++; } } private static List<Character> sortTrains (List<Entry<Character, Integer>> stationArrivals) { List<Character> orderedTrains = new java.util.LinkedList<>(); stationArrivals.forEach(e -> orderedTrains.add(e.getKey())); return stationArrivals.stream() .sorted(Comparator.comparing(Entry<Character, Integer>::getValue) .thenComparing(Entry::getKey)) .map(Map.Entry::getKey) .toList(); } }
- import org.junit.jupiter.api.Test;
- import static org.junit.jupiter.api.Assertions.assertEquals;
- import org.junit.jupiter.api.RepeatedTest;
- import java.util.Arrays;
- import java.util.Map;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.List;
- import java.util.Random;
- import java.lang.Math;
import java.util.Map;- import java.util.Map.Entry;
- import java.util.Comparator;
- class SolutionTest {
- private String printTracks (char[][] tracks) {
- return Arrays.stream(tracks)
- .map(String::valueOf)
- .map(s -> String.join(s,"\n"+s))
- .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append)
- .toString();
- }
- void pass(char[][] s, Map<Character, List<Character>> map) {
- assertEquals(map, TrainsAndRailways.travel(s), printTracks(s));
- }
- void dontPass(char[][] s) {
- assertEquals(new java.util.HashMap<Character, List<Character>>(), TrainsAndRailways.travel(s), printTracks(s));
- }
- @Test
- void exclusivePassTest() {
- pass(new char[][] {"A---------------1".toCharArray()}, Map.of('1', List.of('A')));
- pass(new char[][] {"A----------¡-----1".toCharArray()}, Map.of('1', List.of('A')));
- pass(new char[][] {"A-----------\\ -----------1".toCharArray(),
- " -------------/ ".toCharArray()}, Map.of('1', List.of('A')));
- pass(new char[][] {"A-------- 1".toCharArray(), "B---------------2".toCharArray()}, Map.of('2', List.of('B')));
- pass(new char[][] {"A----) 1".toCharArray(), "B-----------------2".toCharArray()}, Map.of('2', List.of('B')));
- }
- @Test
- void exclusiveNotPassTest() {
- dontPass(new char[][] {"A-------- 1".toCharArray()});
- dontPass(new char[][] {{}});
- dontPass(new char[][] {"A----) 1".toCharArray()});
- dontPass(new char[][] {"A----\\ ".toCharArray(),
- " --------1".toCharArray()});
- dontPass(new char[][] {"A---------------------".toCharArray(),
- " 1".toCharArray()});
- }
- private static char[][] generateRandomTracks() {
- char[][] matrix = new char[new Random().nextInt(5, 15)][new Random().nextInt(10, 25)];
- int area = matrix.length * matrix[0].length;
- int numberOfStations = Math.min((int) new Random().nextDouble( 0.5 * matrix.length,matrix.length), 10);
- int numberOfTrains = Math.min((int) new Random().nextDouble( 0.5 * matrix.length,matrix.length), 26);
- int numberOfSemaphores = (int) new Random().nextDouble(area / 20, area / 8);
- int numberOfTunnels = (int) new Random().nextDouble(area / 30, area / 10);
- int numberOfLeftTracks = (int) new Random().nextDouble(area / 30, area / 15);
- int numberOfRightTracks = (int) new Random().nextDouble(area / 30, area / 15);
- List<Character> charsList = new ArrayList<Character>();
- int i = 0;
- while (i < numberOfStations) {
- charsList.add(Character.forDigit(i++, 10));
- }
- i = 0;
- while (i < numberOfTrains) {
- charsList.add((char) (i++ + 65));
- }
- i = 0;
- while (i++ < numberOfSemaphores) {
- charsList.add('¡');
- }
- i = 0;
- while (i++ < numberOfTunnels) {
- charsList.add(')');
- }
- i = 0;
- while (i++ < numberOfLeftTracks) {
- charsList.add('/');
- }
- i = 0;
- while (i++ < numberOfRightTracks) {
- charsList.add('\\');
- }
- Collections.shuffle(charsList);
- int counter = 0;
- for (int x = 0; x < matrix.length; x++) {
- for (int y = 0; y < matrix[x].length; y++) {
- if ((charsList.get(counter) == '/' || charsList.get(counter) == '\\') && x != 0 && x != matrix.length - 1 && y != 0 && y != matrix[y].length) {
- matrix[x][y] = charsList.get(counter++);
- if (counter == charsList.size()) {
- counter = 0;
- }
- }
- }
- }
- for (int x = 0; x < matrix.length; x++) {
- for (int y = 0; y < matrix[x].length; y++) {
- if (matrix[x][y] == '\u0000') {
- matrix[x][y] = '-';
- }
- }
- }
- return matrix;
- }
- @RepeatedTest(50)
- void randomTests() {
- char [][] matrix = generateRandomTracks();
- assertEquals(travel(matrix), TrainsAndRailways.travel(matrix), printTracks(matrix));
- }
- @Test
- void baseTest() {
- char[][] input = {
- {'A','-','-','-','-','-','\\','-','-','-','-','-','-','-','1'},
- {'B','-','-','-','-','-','-','/',' '},
- {' ',' ',' ',' ',' ',' ','-','-','-','-','-','2'},
- {'C',' ','-','-','-','-','-','/',' '},
- {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','3'},
- {'D','-','-','-','-','-','-','-','-','-','-','-','-','-','4'}
- };
- assertEquals(Map.of('1', List.of('B', 'A'), '4', List.of('D')), TrainsAndRailways.travel(input), printTracks(input));
- char[][] input2 = {
- {'A', '-', '-', '¡', '\\', '¡', ' ', ' ', ' ', ' ', ' ', ' ', ' ', },
- {'B', '-', '-', '-', '-', '\\', ' ', ' ', ' ', ' ', ' ', ' ', ' ', },
- {' ', ' ', ' ', ' ', '-', '-', '\\', ' ', ' ', ' ', ' ', ' ', ' ', },
- {'C', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '1', },
- {'D', '-', '-', '-', '-', '-', '-', ')', ' ', ' ', ' ', ' ', ' ', },
- {'E', '-', '-', '-', '/', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '2', },
- };
- assertEquals(Map.of('1', List.of('C', 'B', 'A')), TrainsAndRailways.travel(input2), printTracks(input2));
- char[][] input3 = {
- {'A', '-', '-', '-', '\\', '-', '-', '-', '1', },
- {' ', ' ', ' ', ' ', '-', '-', '-', '-', '2', },
- {'B', '-', '¡', '-', '/', ' ', '-', '/', ' ', },
- {'C', '-', '-', '/', ' ', '-', '/', ' ', ' ', },
- {' ', ' ', ' ', ' ', '-', '/', ' ', ' ', ' ', },
- {'D', '-', '-', '-', '/', ' ', ' ', ' ', ' ', },
- };
- assertEquals(Map.of('2', List.of('A', 'C', 'B', 'D')), TrainsAndRailways.travel(input3), printTracks(input3));
- char[][] input4 = {
- {'A', '-', '-', '-', ')', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', },
- {' ', ' ', ' ', ' ', '-', '\\', ' ', ' ', ' ', ' ', ' ', ' ', ' ', },
- {'B', '-', '-', '-', '/', '-', '-', '-', '-', '\\', ' ', ' ', ' ', },
- {'C', '-', '-', '¡', '-', '-', '-', '¡', '-', '-', '-', '-', '1', },
- {'D', '-', '-', '-', '-', '-', '/', ' ', ' ', ' ', ' ', ' ', ' ', },
- {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '-', '2', },
- {'E', '-', '-', '-', '\\', ' ', ' ', ' ', ' ', ' ', '-', '/', ' ', },
- {' ', ' ', ' ', ' ', '-', '-', '-', '-', '-', '-', '/', ' ', ' ', },
- {'F', '-', '-', '¡', '/', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', },
- };
- assertEquals(Map.of('1', List.of('B','D','C'), '2', List.of('E', 'F')), TrainsAndRailways.travel(input4), printTracks(input4));
- }
- @Test
- void moreTest() {
- char[][] input = {
- {'A', '¡', '¡', '¡', '¡', '¡', '¡', '¡', '¡', '¡', '¡', '¡', '1', },
- };
- assertEquals(Map.of('1', List.of('A')), TrainsAndRailways.travel(input), printTracks(input));
- char[][] input2 = {
- {'A', '¡', '¡', '¡', '¡', '¡', '\\', '¡', '¡', '¡', '¡', '¡', '1', },
- {'B', '¡', '¡', '¡', '¡', '¡', '¡', '¡', '¡', '¡', '¡', '¡', '2', },
- };
- assertEquals(Map.of('2', List.of('A', 'B')), TrainsAndRailways.travel(input2), printTracks(input2));
- }
- @Test
- void edgeCases() {
- char[][] input1 = {
- {'A', '1', },
- {'B', '2', },
- {'C', '3', },
- {'D', '4', },
- {'E', '5', },
- {'F', '6', },
- };
- assertEquals(Map.of('1', List.of('A'),'2', List.of('B'),
- '3', List.of('C'),'4', List.of('D'),
- '5', List.of('E'),'6', List.of('F')
- ), TrainsAndRailways.travel(input1), printTracks(input1));
- char[][] input2 = {
- {'-', '-', '-', '-', '-', '-', '-', '\\', '-'},
- {'A', '-', '-', '-', '/', '-', '-', '\\', ' ', },
- {'B', '-', '-', '-', '-', '-', '-', '-', '1', },
- {'-', '-', '-', '-', '-', '-', '-', '-', '-'},
- };
- assertEquals(Map.of('1', List.of('B')), TrainsAndRailways.travel(input2), printTracks(input2));
- char[][] input3 = {
- {'A', '-', '-', '¡', '1', '-', '-', '-', '2', },
- };
- assertEquals(Map.of('1', List.of('A')), TrainsAndRailways.travel(input3), printTracks(input3));
- char[][] input4 = {
- {'A', '-', '-', '-', '-', '-', '\\', '-', '-', '-', '-', '-', '\\', ' ', },
- {'B', '¡', '¡', '-', '-', '-', '-', '/', '-', '-', '-', '-', '-', '1', },
- {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', },
- {'C', '-', '-', '-', '¡', '-', '-', '-', '-', '-', '-', '-', '-', '2', },
- };
- assertEquals(Map.of('1', List.of('A','B'), '2', List.of('C')), TrainsAndRailways.travel(input4), printTracks(input4));
- char[][] input5 = {
- {'A', '-', '-', '-', '-', '-', '-', ')', ' ', ' ', ' ', },
- {'C', '-', '-', '-', '-', '\\', ' ', ' ', ' ', ' ', ' ', },
- {' ', ' ', ' ', ' ', ' ', '-', '-', '-', '-', '-', '1', },
- {'B', '-', '-', '-', '-', '/', ' ', ' ', ' ', ' ', ' ', },
- };
- assertEquals(Map.of('1',List.of('B','C')), TrainsAndRailways.travel(input5), printTracks(input5));
- }
- private Map<Character, List<Character>> travel(char[][] tracks) {
- Map<Character,List<Map.Entry<Character,Integer>>> result = new java.util.HashMap<>();
- for (int row = 0; row < tracks.length; row++) {
- for (int column = 0; column < tracks[row].length; column++) {
- if (isTrain(tracks[row][column])) {
- Map.Entry<Character, Integer> train = new java.util.AbstractMap.SimpleEntry(tracks[row][column],0);
- goOnTraveling(tracks, row, column+1,train, result);
- }
- }
- }
- Map<Character,List<Character>> sortedShipOnStations = new java.util.HashMap<>();
- result.forEach((k,v) -> sortedShipOnStations.put(k,sortTrains(v)));
- return sortedShipOnStations;
- }
- private boolean isTrain(char piece) {
- return piece >= 65 && piece <= 90;
- }
- private boolean isStation (char piece) {
- return piece >= 48 && piece <= 57;
- }
- private void goOnTraveling(char[][] tracks, int row, int column, Entry<Character, Integer> train, Map<Character, List<Map.Entry<Character, Integer>>> result) {
- while (column < tracks[row].length) {
- switch (tracks[row][column]) {
- case '¡': {
- train.setValue(train.getValue()+2);
- break;
- }
- case '-': {
- break;
- }
- case '/': {
- train.setValue(train.getValue()+1);
- row--;
- break;
- }
- case '\\': {
- train.setValue(train.getValue()+1);
- row++;
- break;
- }
- case ')': {
- return;
- }
- default: {
- if (isStation(tracks[row][column])) {
- result.putIfAbsent(tracks[row][column], new java.util.LinkedList<Map.Entry<Character,Integer>>());
- result.get(tracks[row][column]).add(train);
- }
- return;
- }
- }
- train.setValue(train.getValue()+1);
- column++;
- }
- }
- private static List<Character> sortTrains (List<Entry<Character, Integer>> stationArrivals) {
- List<Character> orderedTrains = new java.util.LinkedList<>();
- stationArrivals.forEach(e -> orderedTrains.add(e.getKey()));
- return stationArrivals.stream()
- .sorted(Comparator.comparing(Entry<Character, Integer>::getValue)
- .thenComparing(Entry::getKey))
- .map(Map.Entry::getKey)
- .toList();
- }
- }
#include <vector> void re_arrange(std::vector<int>& data) { std::sort(data.begin(), data.end(), [](int a, int b) { bool isAEven = a % 2 == 0; bool isBEven = b % 2 == 0; if (isAEven != isBEven) { return isAEven; } return a < b; }); }
- #include <vector>
- void re_arrange(std::vector<int>& data) {
std::sort(data.begin(), data.end(), [](int x, int y) { return std::make_pair(x % 2 != 0, x) < std::make_pair(y % 2 != 0, y); });- std::sort(data.begin(), data.end(), [](int a, int b) {
- bool isAEven = a % 2 == 0;
- bool isBEven = b % 2 == 0;
- if (isAEven != isBEven) {
- return isAEven;
- }
- return a < b;
- });
- }
-- Moonscript! above_two: -> true
def above_two(_):return True- -- Moonscript!
- above_two: -> true
--[=[ import above_two from require "moon_solution" it "Test Cases", -> for i = 0, 5 assert.is.true above_two i --]=] require "setup"
import codewars_test as test# TODO Write testsimport solution # or from solution import example- --[=[
- import above_two from require "moon_solution"
# test.assert_equals(actual, expected, [optional] message)@test.describe("Example")def test_group():@test.it("test case")def test_case():test.assert_equals(above_two(0), True)test.assert_equals(above_two(1), True)test.assert_equals(above_two(2), True)test.assert_equals(above_two(3), True)test.assert_equals(above_two(4), True)test.assert_equals(above_two(5), True)- it "Test Cases", ->
- for i = 0, 5
- assert.is.true above_two i
- --]=] require "setup"