Start a new Kumite
AllAgda (Beta)BF (Beta)CCFML (Beta)ClojureCOBOL (Beta)CoffeeScriptCommonLisp (Beta)CoqC++CrystalC#D (Beta)DartElixirElm (Beta)Erlang (Beta)Factor (Beta)Forth (Beta)Fortran (Beta)F#GoGroovyHaskellHaxe (Beta)Idris (Beta)JavaJavaScriptJulia (Beta)Kotlinλ Calculus (Beta)LeanLuaNASMNim (Beta)Objective-C (Beta)OCaml (Beta)Pascal (Beta)Perl (Beta)PHPPowerShell (Beta)Prolog (Beta)PureScript (Beta)PythonR (Beta)RacketRaku (Beta)Reason (Beta)RISC-V (Beta)RubyRustScalaShellSolidity (Beta)SQLSwiftTypeScriptVB (Beta)
Show only mine

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.

Driving Test Examiner on an Alien Planet

Problem Description

You work as a driving test examiner on an alien planet. Your task is to evaluate whether an examinee has passed the exam based on the data you receive and the rules described below.


Input Data

You receive two strings:

  1. Indications: Represents the signs and instructions encountered during the exam.
    Format: "t=time SYMBOL;"
    Example: "t=30 STOP;" means a STOP sign was encountered at second 30.

  2. Actions: The examinee's registered actions every second, showing speed and turns if any.
    Format: Speeds and turns separated by spaces.
    Example: "29 28 28< 27 29 27 0 0 0 0 23> 24 ..."


Legend of Indications and Expected Behavior

Indication Symbol Expected Behavior
STOP STOP Stop at least 3 seconds with no cars passing
STOP with cars STOP3 (3 cars) Stop 3 seconds + 2 seconds for each passing car
YIELD YIELD Stop ONLY if there are cars passing (2 seconds per car)
YIELD with cars YIELD2 (2 cars) Stop according to number of cars (2 seconds per car)
Speed Limit SL50 Do not exceed the speed limit until another SL appears
Turn TURNL, TURNR Turn left or right as indicated
Red Light REDLIGHT3 Stop for the specified number of seconds

Format of Actions

  • Data is recorded each and every second of the exam.
  • Turns are represented by < (left) and > (right).
    Example: 78> means at speed 78, a right turn was made.

Infractions and Evaluation

Minor Infractions (3 minors disqualify)

Infraction Description
Speeding Driving over speed limit for 3 consecutive seconds
Wrong turn Not turning, turning when not indicated or turning in the wrong direction

Eliminatory Infractions (1 eliminates immediately)

Infraction Description
Running a red light Not stopping or moving before the light turns green
STOP related infraction Not stopping at a STOP sign or stopping for less time than required
Running into traffic Not waiting necessary time for cars to pass at STOP or YIELD
Reckless driving Exceeding speed limit by more than 10 units at any time

Important Notes

  • There will always be a speed limit sign at t=1.
  • Inputs are always valid, no validation required.
  • Return true if the examinee passes the test, false otherwise.

Example Input

indications = "t=1 SL30 ; t=7 YIELD2 ; t=13 SL90 ; t=15 TURNR; t=21 REDLIGHT8 ; t=30 STOP;"
actions = "29 28 28 27 29 27 0 0 0 0 23 24 67 72 78> 85 87 86 84 89 0 0 0 0 0 0 0 0 25 0 0 0 34 56"
Code
Diff
  • import java.util.Arrays;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.function.BiConsumer;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    class DrivingTestEvaluator {
    	static Map<String, BiConsumer<Integer, String>> rules = new HashMap();
    	static int speedLimit = 0;
    	static int indexLastSpeedLimit = 1;
    	static int indexIndicationList = 0;
    	static int indexActionList = 0;
    	static int minorMistakes = 0;
    	static boolean isEliminated = false;
    	static int currentTime = 0;
    	static int secondsInfringement = 0;
    	static List<String> indicationList;
    	static List<String> actionList;
    
    	public static boolean evaluate(String indications, String actions) {
    		clearState();
    
    		indicationList = Arrays.stream(indications.split(";")).toList();
    
    		actionList = Arrays.stream(actions.split(" ")).toList();
    
    		refillRules();
    		for (String indication : indicationList) {
    			processIndication(indication);
    		}
    		return 3 > minorMistakes && !isEliminated;
    	}
    
    	private static void refillRules() {
    		rules.put("STOP", (DrivingTestEvaluator::processStop));
    		rules.put("SL", (DrivingTestEvaluator::processSpeedLimit));
    		rules.put("YIELD", (DrivingTestEvaluator::processYield));
    		rules.put("TURN", (DrivingTestEvaluator::processTurn));
    		rules.put("REDLIGHT", (DrivingTestEvaluator::processRedLight));
    	}
    
    	private static void processIndication(String indication) {
    		Pattern pattern = Pattern.compile("t=(\\d+)\\s+(\\S+)");
    		Matcher matcher = pattern.matcher(indication);
    		if (matcher.find()) {
    			Integer time = Integer.valueOf(matcher.group(1));
    			String instruction = matcher.group(2);
    			rules.keySet().stream().filter(instruction::contains).findFirst()
    					.ifPresent(key -> rules.get(key).accept(time, indication));
    		}
    	}
    
    	private static void processTurn(Integer t, String signal) {
    		String direction = "";
    		Pattern pattern = Pattern.compile("TURN([A-Z])");
    		Matcher matcher = pattern.matcher(signal);
    		if (matcher.find()) {
    			direction = matcher.group(1);
    		}
    		if (actionList.get(t - 1).endsWith(">") || actionList.get(t - 1).endsWith("<")) {
    			if (actionList.get(t - 1).endsWith(">") && direction.equals("L")
    					|| actionList.get(t - 1).endsWith("<") && direction.equals("R"))
    				minorMistakes++;
    		} else {
    			minorMistakes++;
    		}
    	}
    
    	private static void processRedLight(Integer time, String signal) {
    		Pattern pattern = Pattern.compile("REDLIGHT(\\d+)");
    		Matcher matcher = pattern.matcher(signal);
    		if (matcher.find()) {
    			processCorrectlyStopped(time, Integer.valueOf(matcher.group(1)));
    		}
    	}
    
    	private static void processYield(Integer time, String signal) {
    		Integer secondsToStop = 0;
    		Pattern pattern = Pattern.compile("YIELD(\\d+)");
    		Matcher matcher = pattern.matcher(signal);
    		if (matcher.find()) {
    			secondsToStop += (2 * Integer.valueOf(matcher.group(1)));
    			processCorrectlyStopped(time, secondsToStop);
    		} else {
    			if (Integer.parseInt(actionList.get(time - 1)) == 0)
    				isEliminated = true;
    		}
    
    	}
    
    	private static void processStop(Integer time, String signal) {
    		Integer secondsToStop = 3;
    		Pattern pattern = Pattern.compile("STOP(\\d+)");
    		Matcher matcher = pattern.matcher(signal);
    		if (matcher.find()) {
    			secondsToStop += Integer.parseInt(matcher.group(1)) * 2;
    		}
    		processCorrectlyStopped(time, secondsToStop);
    
    	}
    
    	private static void processCorrectlyStopped(Integer time, Integer secondsToStop) {
    		if (Integer.parseInt(actionList.get(time - 1)) > 0) {
    			isEliminated = true;
    			return;
    		}
    
    		while (secondsToStop != 0) {
    			if (time > actionList.size() || Integer.parseInt(actionList.get(time - 1)) > 0) {
    				isEliminated = true;
    				return;
    			}
    			time++;
    			secondsToStop--;
    		}
    	}
    
    	private static void processSpeedLimit(Integer time, String signal) {
    		Integer digits = 0;
    		for (int i = indexLastSpeedLimit; i < time; i++) {
    			String velocity = actionList.get(i);
    			Pattern pattern = Pattern.compile("(\\d+)");
    			Matcher matcher = pattern.matcher(velocity);
    			if (matcher.find()) {
    				digits = Integer.parseInt(matcher.group(1));
    			}
    
    			if (digits > speedLimit) {
    				secondsInfringement++;
    			} else {
    				secondsInfringement = 0;
    			}
    			if (secondsInfringement > 2)
    				minorMistakes++;
    		}
    		Pattern pattern = Pattern.compile("SL(\\d+)");
    		Matcher matcher = pattern.matcher(signal);
    		if (matcher.find()) {
    			speedLimit = Integer.valueOf(matcher.group(1));
    		}
    		indexLastSpeedLimit = time - 1;
    	}
    
    	private static void clearState() {
    		speedLimit = 0;
    		indexLastSpeedLimit = 1;
    		indexIndicationList = 0;
    		indexActionList = 0;
    		minorMistakes = 0;
    		isEliminated = false;
    		currentTime = 0;
    		secondsInfringement = 0;
    	}
    
    }
    
    • import java.util.Arrays;
    • import java.util.HashMap;
    • import java.util.List;
    • import java.util.Map;
    • import java.util.function.BiConsumer;
    • import java.util.regex.Matcher;
    • import java.util.regex.Pattern;
    • class DrivingTestEvaluator {
    • static Map<String, BiConsumer<Integer, String>> rules = new HashMap();
    • static int speedLimit = 0;
    • static int indexLastSpeedLimit = 1;
    • static int indexIndicationList = 0;
    • static int indexActionList = 0;
    • static int minorMistakes = 0;
    • static boolean isEliminated = false;
    • static int currentTime = 0;
    • static int secondsInfringement = 0;
    • static List<String> indicationList;
    • static List<String> actionList;
    • public static boolean evaluate(String indications, String actions) {
    • clearState();
    • indicationList = Arrays.stream(indications.split(";")).toList();
    • actionList = Arrays.stream(actions.split(" ")).toList();
    • refillRules();
    • for (String indication : indicationList) {
    • processIndication(indication);
    • }
    • return 3 > minorMistakes && !isEliminated;
    • }
    • private static void refillRules() {
    • rules.put("STOP", (DrivingTestEvaluator::processStop));
    • rules.put("SL", (DrivingTestEvaluator::processSpeedLimit));
    • rules.put("YIELD", (DrivingTestEvaluator::processYield));
    • rules.put("TURN", (DrivingTestEvaluator::processTurn));
    • rules.put("REDLIGHT", (DrivingTestEvaluator::processRedLight));
    • }
    • private static void processIndication(String indication) {
    • Pattern pattern = Pattern.compile("t=(\\d+)\\s+(\\S+)");
    • Matcher matcher = pattern.matcher(indication);
    • if (matcher.find()) {
    • Integer time = Integer.valueOf(matcher.group(1));
    • String instruction = matcher.group(2);
    • rules.keySet().stream().filter(instruction::contains).findFirst()
    • .ifPresent(key -> rules.get(key).accept(time, indication));
    • }
    • }
    • private static void processTurn(Integer t, String signal) {
    • String direction = "";
    • Pattern pattern = Pattern.compile("TURN([A-Z])");
    • Matcher matcher = pattern.matcher(signal);
    • if (matcher.find()) {
    • direction = matcher.group(1);
    • }
    • if (actionList.get(t - 1).endsWith(">") || actionList.get(t - 1).endsWith("<")) {
    • if (actionList.get(t - 1).endsWith(">") && direction.equals("L")
    • || actionList.get(t - 1).endsWith("<") && direction.equals("R"))
    • minorMistakes++;
    • } else {
    • minorMistakes++;
    • }
    • }
    • private static void processRedLight(Integer time, String signal) {
    • Pattern pattern = Pattern.compile("REDLIGHT(\\d+)");
    • Matcher matcher = pattern.matcher(signal);
    • if (matcher.find()) {
    • processCorrectlyStopped(time, Integer.valueOf(matcher.group(1)));
    • }
    • }
    • private static void processYield(Integer time, String signal) {
    • Integer secondsToStop = 0;
    • Pattern pattern = Pattern.compile("YIELD(\\d+)");
    • Matcher matcher = pattern.matcher(signal);
    • if (matcher.find()) {
    • secondsToStop += (2 * Integer.valueOf(matcher.group(1)));
    • processCorrectlyStopped(time, secondsToStop);
    • } else {
    • if (Integer.parseInt(actionList.get(time - 1)) == 0)
    • isEliminated = true;
    • }
    • }
    • private static void processStop(Integer time, String signal) {
    • Integer secondsToStop = 3;
    • Pattern pattern = Pattern.compile("STOP(\\d+)");
    • Matcher matcher = pattern.matcher(signal);
    • if (matcher.find()) {
    • secondsToStop += Integer.parseInt(matcher.group(1)) * 2;
    • }
    • processCorrectlyStopped(time, secondsToStop);
    • }
    • private static void processCorrectlyStopped(Integer time, Integer secondsToStop) {
    • if (Integer.parseInt(actionList.get(time - 1)) > 0) {
    • isEliminated = true;
    • return;
    • }
    • while (secondsToStop != 0) {
    • if (time > actionList.size() || Integer.parseInt(actionList.get(time - 1)) > 0) {
    • isEliminated = true;
    • return;
    • }
    • time++;
    • secondsToStop--;
    • }
    • }
    • private static void processSpeedLimit(Integer time, String signal) {
    • Integer digits = 0;
    • for (int i = indexLastSpeedLimit; i < time; i++) {
    • String velocity = actionList.get(i);
    • Pattern pattern = Pattern.compile("(\\d+)");
    • Matcher matcher = pattern.matcher(velocity);
    • if (matcher.find()) {
    • digits = Integer.parseInt(matcher.group(1));
    • }
    • if (digits > speedLimit) {
    • secondsInfringement++;
    • } else {
    • secondsInfringement = 0;
    • }
    • if (secondsInfringement > 2)
    • minorMistakes++;
    • }
    • Pattern pattern = Pattern.compile("SL(\\d+)");
    • Matcher matcher = pattern.matcher(signal);
    • if (matcher.find()) {
    • speedLimit = Integer.valueOf(matcher.group(1));
    • }
    • indexLastSpeedLimit = time - 1;
    • }
    • private static void clearState() {
    • speedLimit = 0;
    • indexLastSpeedLimit = 1;
    • indexIndicationList = 0;
    • indexActionList = 0;
    • minorMistakes = 0;
    • isEliminated = false;
    • currentTime = 0;
    • secondsInfringement = 0;
    • }
    • public class DrivingTestEvaluator {
    • static int knockoutFoul;
    • static int mildFoul;
    • static List<String> actions;
    • static int currentIndex;
    • public static boolean evaluate(String exam, String road) {
    • knockoutFoul = 0;
    • mildFoul = 0;
    • currentIndex = 0;
    • actions = Arrays.asList(exam.trim().split("\\s+"));
    • List<String> rules = Arrays.asList(road.trim().split("\\s+"));
    • for (String rule : rules) {
    • if (rule.startsWith("SL")) {
    • comprobateSpeedLimit(rule);
    • } else if (rule.startsWith("STOP")) {
    • comprobateStop(rule);
    • } else if (rule.startsWith("YIELD")) {
    • comprobateYield(rule);
    • } else if (rule.startsWith("TURN")) {
    • comprobateTurn(rule);
    • } else if (rule.startsWith("R")) {
    • comprobateRedLight(rule);
    • }
    • if (knockoutFoul > 0) return false;
    • }
    • return mildFoul < 3;
    • }
    • public static void comprobateSpeedLimit(String rule) {
    • String[] parts = rule.substring(2).split("_");
    • int speedLimit = Integer.parseInt(parts[0]);
    • int duration = Integer.parseInt(parts[1]);
    • int overLimitCounter = 0;
    • boolean minorCounted = false;
    • for (int i = 0; i < duration && currentIndex + i < actions.size(); i++) {
    • int speed = extractSpeed(actions.get(currentIndex + i));
    • if (speed > speedLimit + 10) {
    • knockoutFoul++;
    • return;
    • }
    • if (speed > speedLimit) {
    • overLimitCounter++;
    • } else {
    • overLimitCounter = 0;
    • }
    • if (overLimitCounter >= 3 && !minorCounted) {
    • mildFoul++;
    • minorCounted = true;
    • }
    • }
    • currentIndex += Math.min(duration, actions.size() - currentIndex);
    • }
    • public static void comprobateStop(String rule) {
    • int cars = rule.length() > 4 ? Integer.parseInt(rule.substring(4)) : 0;
    • int requiredStop = 3 + (2 * cars);
    • int stopCount = 0;
    • while (currentIndex < actions.size() && extractSpeed(actions.get(currentIndex)) == 0) {
    • stopCount++;
    • currentIndex++;
    • }
    • if (stopCount == 0) {
    • knockoutFoul++;
    • } else if (stopCount < requiredStop) {
    • if (stopCount >= 2 * cars) mildFoul++;
    • else knockoutFoul++;
    • }
    • }
    • public static void comprobateYield(String rule) {
    • int cars = rule.length() > 5 ? Integer.parseInt(rule.substring(5)) : 0;
    • int requiredStop = 2 * cars;
    • int stopCount = 0;
    • while (currentIndex < actions.size() && extractSpeed(actions.get(currentIndex)) == 0) {
    • stopCount++;
    • currentIndex++;
    • }
    • if (cars == 0) {
    • if (stopCount >= 2) knockoutFoul++;
    • } else {
    • if (stopCount < requiredStop) {
    • knockoutFoul++;
    • } else if (stopCount < requiredStop + 3) {
    • mildFoul++;
    • }
    • }
    • }
    • public static void comprobateTurn(String rule) {
    • String requiredDirection = rule.equals("TURNR") ? ">" : "<";
    • boolean turned = false;
    • for (int i = currentIndex; i < actions.size(); i++) {
    • if (actions.get(i).endsWith(requiredDirection)) {
    • turned = true;
    • currentIndex = i + 1;
    • break;
    • }
    • }
    • if (!turned) {
    • mildFoul++;
    • }
    • }
    • public static void comprobateRedLight(String rule) {
    • int duration = Integer.parseInt(rule.substring(1));
    • boolean failed = false;
    • for (int i = 0; i < duration && currentIndex + i < actions.size(); i++) {
    • if (extractSpeed(actions.get(currentIndex + i)) != 0) {
    • failed = true;
    • }
    • }
    • if (failed) {
    • knockoutFoul++;
    • }
    • currentIndex += Math.min(duration, actions.size() - currentIndex);
    • }
    • public static int extractSpeed(String action) {
    • if (action.endsWith("<") || action.endsWith(">")) {
    • return Integer.parseInt(action.substring(0, action.length() - 1));
    • }
    • return Integer.parseInt(action);
    • }
    • }

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
Lists
Code
Diff
  • #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;
    • });
    • }