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:
-
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. -
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 |
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 |
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
- Each second records speed.
- 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 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 |
Ignored STOP | Not stopping at a STOP sign |
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"
package cinco_kyu; 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; public 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; } }
- package cinco_kyu;
import java.util.ArrayList;- 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;
- public 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;
- }
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;}}- 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));
- }
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;- 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));
- }
- }
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));- 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--;
- }
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));- 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));
- }
return actions;- indexLastSpeedLimit = time - 1;
- }
}- private static void clearState() {
- speedLimit = 0;
- indexLastSpeedLimit = 1;
- indexIndicationList = 0;
- indexActionList = 0;
- minorMistakes = 0;
- isEliminated = false;
- currentTime = 0;
- secondsInfringement = 0;
- }
- }
package cinco_kyu; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Random; import org.junit.jupiter.api.RepeatedTest; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; public class SolutionTest { @Test void SampleTest() { assertTrue(DrivingTestEvaluator.evaluate( "t=1 SL30;t=5 TURNR;t=6 SL35;t=14 STOP1;", "28 27 30 29 25> 33 30 31 30 29 32 30 31 0 0 0 0 0" )); assertFalse(DrivingTestEvaluator.evaluate( "t=1 SL30;t=5 TURNR;t=6 SL35;t=14 STOP1;", "28 27 30 29 25> 33 30 31 30 29 32 30 31 0 0 50 0 0" )); assertTrue(DrivingTestEvaluator.evaluate( "t=1 SL50;t=3 SL30;t=7 TURNR;t=8 TURNL;", "48 49 28 30 29 30 25> 20<" )); assertTrue(DrivingTestEvaluator.evaluate( "t=1 SL30;t=5 TURNR;t=6 SL35;t=13 YIELD2;", "28 29 30 30 25> 32 33 31 30 34 30 33 0 0 0 0" )); assertFalse(DrivingTestEvaluator.evaluate( "t=1 SL30;t=5 TURNR;t=6 SL35;t=13 YIELD2;", "28 29 30 30 25> 32 33 31 30 34 30 33 10 9 8 7" )); } @Test void ComplexesTest() { assertTrue(DrivingTestEvaluator.evaluate( "t=1 SL25;t=5 TURNL;t=6 SL30;t=9 SL20;t=13 TURNR;t=14 SL40;t=22 STOP1;", "25 24 25 20 18< 22 30 28 18 20 19 20 19> 38 39 35 40 39 40 38 40 0 0 0 0 0" )); assertTrue(DrivingTestEvaluator.evaluate( "t=1 SL30;t=6 TURNL;t=7 SL40;t=13 SL25;t=17 TURNR;t=18 SL50;t=26 SL35;t=30 STOP1;", "30 29 30 28 26 25< 35 38 40 39 40 38 22 24 23 25 20> 45 48 50 49 50 45 47 49 30 32 35 34 0 0 0 0 0" )); assertFalse(DrivingTestEvaluator.evaluate( "t=1 SL20;t=5 TURNR;t=6 SL30;t=11 SL45;t=17 TURNL;t=18 SL50;t=25 SL40;t=29 STOP1;", "20 19 18 17 15> 25 30 29 28 27 50 47 46 48 45 44 45 43 49 50 48 49 45 38 39 37 40 10 5 5 5 5" )); assertTrue(DrivingTestEvaluator.evaluate( "t=1 SL25;t=5 STOP1;t=10 SL20;", "25 24 25 23 0 0 0 0 0 18 20 19 20" )); assertTrue(DrivingTestEvaluator.evaluate( "t=1 SL25;t=5 TURNL;t=6 SL30;t=9 SL20;t=13 TURNR;t=14 SL40;t=22 STOP1;", "25 24 25 26 25< 30 28 30 22 20 19 20 19> 38 39 35 40 39 40 38 40 0 0 0 0 0" )); assertTrue(DrivingTestEvaluator.evaluate( "t=1 SL30;t=6 TURNL;t=7 SL40;t=13 SL25;t=17 TURNR;t=18 SL50;t=26 SL35;t=30 STOP1;", "30 29 30 31 30 25 35 38 40 39 40 38 22 24 23 25 20 20 45 48 50 49 50 45 47 49 30 32 35 0 0 0 0 0" )); assertTrue(DrivingTestEvaluator.evaluate( "t=1 SL50;t=11 TURNL;t=12 STOP1;", "50 49 50 48 47 46 45 44 43 42 30< 0 0 0 0 0" )); assertFalse(DrivingTestEvaluator.evaluate( "t=1 SL30;t=6 TURNL;t=7 SL40;t=13 YIELD;t=14 SL25;t=18 TURNR;t=19 SL50;t=27 SL35;t=31 STOP1;", "30 29 30 31 30 25 35 38 40 39 40 38 0 0 25 24 23 25 20 50 49 50 48 50 49 50 50 35 34 35 0 0 0 0 0" )); assertFalse(DrivingTestEvaluator.evaluate( "t=1 SL25;t=5 TURNL;t=6 SL30;t=9 YIELD;t=10 SL20;t=14 TURNR;t=15 SL40;t=23 STOP1;", "25 24 25 26 25< 30 28 30 0 0 20 19 18 20 19> 38 39 35 40 39 40 0 0 0 0 0" )); assertTrue(DrivingTestEvaluator.evaluate( "t=1 SL25;t=5 TURNL;t=6 SL30;t=9 YIELD2;t=11 SL20;t=15 TURNR;t=16 SL40;t=24 STOP1;", "25 24 25 26 25< 30 28 30 0 0 0 0 22 20 19 20 19 38 39 35 40 39 40 0 0 0 0 0" )); } @Test void StopTest() { assertTrue(DrivingTestEvaluator.evaluate("t=1 STOP;", "0 0 0")); assertTrue(DrivingTestEvaluator.evaluate("t=1 STOP3;", "0 0 0 0 0 0 0 0 0")); assertTrue(DrivingTestEvaluator.evaluate("t=1 STOP1;", "0 0 0 0 0")); assertFalse(DrivingTestEvaluator.evaluate("t=1 STOP3;", "0 0 0 0 2 2 2 2 2")); assertFalse(DrivingTestEvaluator.evaluate("t=1 STOP1;", "0 0")); assertFalse(DrivingTestEvaluator.evaluate("t=1 STOP2;", "0 0 0 0 0 0")); } @Test void TurnTest() { assertTrue(DrivingTestEvaluator.evaluate("t=1 TURNR;t=2 SL25;", "20> 25")); assertTrue(DrivingTestEvaluator.evaluate( "t=1 TURNR;t=2 SL25;t=3 TURNR;t=4 SL25;t=5 TURNL;t=6 SL25;", "22> 25 23> 25 15< 25" )); assertTrue(DrivingTestEvaluator.evaluate( "t=1 TURNR;t=2 SL25;t=3 SL25;t=4 TURNR;t=5 SL25;t=6 TURNL;t=7 SL25;t=8 TURNR;t=9 SL25;t=10 TURNR;t=11 SL25;", "10> 25 24 19> 25 18< 25 22> 25 23> 25" )); assertFalse(DrivingTestEvaluator.evaluate( "t=1 TURNL;t=2 SL25;t=3 TURNR;t=4 SL25;t=5 TURNL;t=6 SL25;t=7 TURNL;t=8 SL25;t=9 TURNR;t=10 SL25;", "20 25 19 25 18 25 17 25 16 25" )); assertTrue(DrivingTestEvaluator.evaluate("t=1 TURNR;t=2 SL25;", "30< 25")); assertFalse(DrivingTestEvaluator.evaluate( "t=1 TURNL;t=2 SL25;t=3 TURNR;t=4 SL25;t=5 TURNR;t=6 SL25;t=7 TURNL;t=8 SL25;t=9 TURNR;t=10 SL25;", "22 25 23 25 21 25 19 25 18> 25" )); } @Test void SpeedLimitTest() { assertTrue(DrivingTestEvaluator.evaluate( "t=1 SL20;t=6 TURNR;t=7 SL40;t=13 STOP1;t=18 SL50", "20 19 18 17 20 15> 38 40 39 40 38 37 0 0 0 0 0 48 45" )); assertFalse(DrivingTestEvaluator.evaluate( "t=1 SL30;t=6 SL40;t=13 STOP1;", "30 29 28 27 30 35 45 39 40 38 37 0 0 0 0 0" )); assertTrue(DrivingTestEvaluator.evaluate( "t=1 SL50;t=11 TURNL;", "50 49 50 48 47 46 45 44 43 42 30<" )); assertTrue(DrivingTestEvaluator.evaluate( "t=1 SL50;t=11 TURNL;", "50 49 50 48 47 60 45 44 43 42 30" )); } @Test void YieldTest() { assertTrue(DrivingTestEvaluator.evaluate( "t=1 YIELD;t=1 SL25;t=6 STOP1;", "20 22 25 24 23 0 0 0 0 0" )); assertFalse(DrivingTestEvaluator.evaluate( "t=1 YIELD;t=3 SL25;t=8 STOP1;", "0 15 20 22 25 24 23 0 0 0 0 0" )); assertTrue(DrivingTestEvaluator.evaluate( "t=1 YIELD2;t=5 SL30;t=9 TURNR;", "0 0 0 0 28 29 30 25 22>" )); assertFalse(DrivingTestEvaluator.evaluate( "t=1 YIELD2;t=4 SL30;t=9 TURNR;", "0 10 0 0 28 29 30 25 22>" )); } @RepeatedTest(200) void RandomTest() { String indications = generateIndications(); String actions = generateActions(indications); System.out.println(indications); System.out.println(actions); System.out.println("-------------------------------------------------------------------"); assertTrue(DrivingTestEvaluator.evaluate(indications, actions)); } public static String generateIndications() { ArrayList<String> types = new ArrayList<>(Arrays.asList("SL", "TURNL", "TURNR", "YIELD", "STOP", "REDLIGHT")); StringBuilder sb = new StringBuilder(); Random random = new Random(); // tiempo real considerando duración de señales int currentTime = 1; sb.append("t=").append(currentTime).append(" SL").append(random.nextInt(50) + 20).append(";"); String prev = "SL"; for (int i = 0; i < 8; i++) { Collections.shuffle(types); String actual = types.get(0); while ("SL".equals(actual) && "SL".equals(prev)) { Collections.shuffle(types); actual = types.get(0); } // Tiempo aleatorio antes de la próxima señal int timeGap = random.nextInt(4) + 1; currentTime += timeGap; sb.append("t=").append(currentTime).append(" ").append(actual); // Dependiendo del tipo, pse extiende el tiempo real if ("SL".equals(actual)) { int limit = random.nextInt(50) + 20; sb.append(limit); } else if ("YIELD".equals(actual)) { int cars = random.nextInt(5); if (cars > 0) sb.append(cars); currentTime += cars * 2; } else if ("STOP".equals(actual)) { int cars = random.nextInt(5); if (cars > 0) sb.append(cars); currentTime += 3 + cars * 2; } else if ("REDLIGHT".equals(actual)) { int seconds = random.nextInt(5) + 1; sb.append(seconds); currentTime += seconds; } sb.append(";"); prev = actual; } return sb.toString().trim(); } public static String generateActions(String indications) { String[] trafficSigns = indications.split(";"); List<String> actions = new ArrayList<>(); Random random = new Random(); int currentSecond = 1; int speedLimit = 80; for (String signEntry : trafficSigns) { signEntry = signEntry.trim(); if (signEntry.isEmpty()) continue; String[] parts = signEntry.split(" "); int time = Integer.parseInt(parts[0].substring(2)); String sign = parts[1]; // Generación de velocidades aleatorias while (currentSecond < time) { int limit = speedLimit + 1; int v = Math.max(1, random.nextInt(limit)); actions.add(String.valueOf(v)); currentSecond++; } // Procesamiento de señales específicas if (sign.startsWith("SL")) { speedLimit = Integer.parseInt(sign.substring(2)); actions.add(String.valueOf(random.nextInt(speedLimit + 1))); currentSecond++; } else if (sign.startsWith("YIELD")) { int cars = (sign.length() > 5) ? Integer.parseInt(sign.substring(5)) : 0; int secs = cars * 2; for (int j = 0; j < secs; j++) { actions.add("0"); currentSecond++; } } else if (sign.startsWith("STOP")) { int cars = (sign.length() > 4) ? Integer.parseInt(sign.substring(4)) : 0; int secs = 3 + 2 * cars; for (int j = 0; j < secs; j++) { actions.add("0"); currentSecond++; } } else if (sign.startsWith("REDLIGHT")) { int secs = Integer.parseInt(sign.substring(8)); for (int j = 0; j < secs; j++) { actions.add("0"); currentSecond++; } } else if (sign.equals("TURNL")) { actions.add(random.nextInt(speedLimit + 1) + "<"); currentSecond++; } else if (sign.equals("TURNR")) { actions.add(random.nextInt(speedLimit + 1) + ">"); currentSecond++; } } return String.join(" ", actions); } }
import static org.junit.jupiter.api.Assertions.*;- package cinco_kyu;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collections;
import java.util.HashMap;- import java.util.List;
import java.util.Map;- import java.util.Random;
import java.util.regex.Matcher;import java.util.regex.Pattern;- import org.junit.jupiter.api.RepeatedTest;
- import org.junit.jupiter.api.Test;
class SolutionTest {- import static org.junit.jupiter.api.Assertions.assertFalse;
- import static org.junit.jupiter.api.Assertions.assertTrue;
- public class SolutionTest {
- @Test
- void SampleTest() {
- assertTrue(DrivingTestEvaluator.evaluate(
"t=1 SL30;t=5 TURNR;t=6 SL35;t=14 STOP1;","28 27 30 29 25> 33 30 31 30 29 32 30 31 0 0 0 0 0"- "t=1 SL30;t=5 TURNR;t=6 SL35;t=14 STOP1;",
- "28 27 30 29 25> 33 30 31 30 29 32 30 31 0 0 0 0 0"
- ));
- assertFalse(DrivingTestEvaluator.evaluate(
"t=1 SL30;t=5 TURNR;t=6 SL35;t=14 STOP1;","28 27 30 29 25> 33 30 31 30 29 32 30 31 0 0 50 0 0"- "t=1 SL30;t=5 TURNR;t=6 SL35;t=14 STOP1;",
- "28 27 30 29 25> 33 30 31 30 29 32 30 31 0 0 50 0 0"
- ));
- assertTrue(DrivingTestEvaluator.evaluate(
"t=1 SL50;t=3 SL30;t=7 TURNR;t=8 TURNL;","48 49 28 30 29 30 25> 20<"- "t=1 SL50;t=3 SL30;t=7 TURNR;t=8 TURNL;",
- "48 49 28 30 29 30 25> 20<"
- ));
- assertTrue(DrivingTestEvaluator.evaluate(
"t=1 SL30;t=5 TURNR;t=6 SL35;t=13 YIELD2;","28 29 30 30 25> 32 33 31 30 34 30 33 0 0 0 0"- "t=1 SL30;t=5 TURNR;t=6 SL35;t=13 YIELD2;",
- "28 29 30 30 25> 32 33 31 30 34 30 33 0 0 0 0"
- ));
- assertFalse(DrivingTestEvaluator.evaluate(
"t=1 SL30;t=5 TURNR;t=6 SL35;t=13 YIELD2;","28 29 30 30 25> 32 33 31 30 34 30 33 10 9 8 7"- "t=1 SL30;t=5 TURNR;t=6 SL35;t=13 YIELD2;",
- "28 29 30 30 25> 32 33 31 30 34 30 33 10 9 8 7"
- ));
- }
- @Test
void ComplexesTest() {- void ComplexesTest() {
- assertTrue(DrivingTestEvaluator.evaluate(
"t=1 SL25;t=5 TURNL;t=6 SL30;t=9 SL20;t=13 TURNR;t=14 SL40;t=22 STOP1;","25 24 25 20 18< 22 30 28 18 20 19 20 19> 38 39 35 40 39 40 38 40 0 0 0 0 0"- "t=1 SL25;t=5 TURNL;t=6 SL30;t=9 SL20;t=13 TURNR;t=14 SL40;t=22 STOP1;",
- "25 24 25 20 18< 22 30 28 18 20 19 20 19> 38 39 35 40 39 40 38 40 0 0 0 0 0"
- ));
- assertTrue(DrivingTestEvaluator.evaluate(
"t=1 SL30;t=6 TURNL;t=7 SL40;t=13 SL25;t=17 TURNR;t=18 SL50;t=26 SL35;t=30 STOP1;","30 29 30 28 26 25< 35 38 40 39 40 38 22 24 23 25 20> 45 48 50 49 50 45 47 49 30 32 35 34 0 0 0 0 0"- "t=1 SL30;t=6 TURNL;t=7 SL40;t=13 SL25;t=17 TURNR;t=18 SL50;t=26 SL35;t=30 STOP1;",
- "30 29 30 28 26 25< 35 38 40 39 40 38 22 24 23 25 20> 45 48 50 49 50 45 47 49 30 32 35 34 0 0 0 0 0"
- ));
assertTrue(DrivingTestEvaluator.evaluate("t=1 SL20;t=5 TURNR;t=6 SL30;t=11 SL45;t=17 TURNL;t=18 SL50;t=25 SL40;t=29 STOP1;","20 19 18 17 15> 25 30 29 28 27 50 47 46 48 45 44 45 43 49 50 48 49 45 38 39 37 40 10 5 5 5 5"- assertFalse(DrivingTestEvaluator.evaluate(
- "t=1 SL20;t=5 TURNR;t=6 SL30;t=11 SL45;t=17 TURNL;t=18 SL50;t=25 SL40;t=29 STOP1;",
- "20 19 18 17 15> 25 30 29 28 27 50 47 46 48 45 44 45 43 49 50 48 49 45 38 39 37 40 10 5 5 5 5"
- ));
- assertTrue(DrivingTestEvaluator.evaluate(
"t=1 SL25;t=5 STOP1;t=10 SL20;","25 24 25 23 0 0 0 0 0 18 20 19 20"- "t=1 SL25;t=5 STOP1;t=10 SL20;",
- "25 24 25 23 0 0 0 0 0 18 20 19 20"
- ));
- assertTrue(DrivingTestEvaluator.evaluate(
"t=1 SL25;t=5 TURNL;t=6 SL30;t=9 SL20;t=13 TURNR;t=14 SL40;t=22 STOP1;","25 24 25 26 25< 30 28 30 22 20 19 20 19> 38 39 35 40 39 40 38 40 0 0 0 0 0"- "t=1 SL25;t=5 TURNL;t=6 SL30;t=9 SL20;t=13 TURNR;t=14 SL40;t=22 STOP1;",
- "25 24 25 26 25< 30 28 30 22 20 19 20 19> 38 39 35 40 39 40 38 40 0 0 0 0 0"
- ));
- assertTrue(DrivingTestEvaluator.evaluate(
"t=1 SL30;t=6 TURNL;t=7 SL40;t=13 SL25;t=17 TURNR;t=18 SL50;t=26 SL35;t=30 STOP1;","30 29 30 31 30 25 35 38 40 39 40 38 22 24 23 25 20 20 45 48 50 49 50 45 47 49 30 32 35 34 0 0 0 0 0"- "t=1 SL30;t=6 TURNL;t=7 SL40;t=13 SL25;t=17 TURNR;t=18 SL50;t=26 SL35;t=30 STOP1;",
- "30 29 30 31 30 25 35 38 40 39 40 38 22 24 23 25 20 20 45 48 50 49 50 45 47 49 30 32 35 0 0 0 0 0"
- ));
- assertTrue(DrivingTestEvaluator.evaluate(
"t=1 SL50;t=11 TURNL;t=12 STOP1;","50 49 50 48 47 46 45 44 43 42 30< 0 0 0 0 0"- "t=1 SL50;t=11 TURNL;t=12 STOP1;",
- "50 49 50 48 47 46 45 44 43 42 30< 0 0 0 0 0"
- ));
- assertFalse(DrivingTestEvaluator.evaluate(
"t=1 SL30;t=6 TURNL;t=7 SL40;t=13 YIELD;t=14 SL25;t=18 TURNR;t=19 SL50;t=27 SL35;t=31 STOP1;","30 29 30 31 30 25 35 38 40 39 40 38 0 0 25 24 23 25 20 50 49 50 48 50 49 50 50 35 34 35 0 0 0 0 0"- "t=1 SL30;t=6 TURNL;t=7 SL40;t=13 YIELD;t=14 SL25;t=18 TURNR;t=19 SL50;t=27 SL35;t=31 STOP1;",
- "30 29 30 31 30 25 35 38 40 39 40 38 0 0 25 24 23 25 20 50 49 50 48 50 49 50 50 35 34 35 0 0 0 0 0"
- ));
- assertFalse(DrivingTestEvaluator.evaluate(
"t=1 SL25;t=5 TURNL;t=6 SL30;t=9 YIELD;t=10 SL20;t=14 TURNR;t=15 SL40;t=23 STOP1;","25 24 25 26 25< 30 28 30 0 0 20 19 18 20 19> 38 39 35 40 39 40 0 0 0 0 0"- "t=1 SL25;t=5 TURNL;t=6 SL30;t=9 YIELD;t=10 SL20;t=14 TURNR;t=15 SL40;t=23 STOP1;",
- "25 24 25 26 25< 30 28 30 0 0 20 19 18 20 19> 38 39 35 40 39 40 0 0 0 0 0"
- ));
- assertTrue(DrivingTestEvaluator.evaluate(
"t=1 SL25;t=5 TURNL;t=6 SL30;t=9 YIELD2;t=11 SL20;t=15 TURNR;t=16 SL40;t=24 STOP1;","25 24 25 26 25< 30 28 30 0 0 0 0 22 20 19 20 19 38 39 35 40 39 40 0 0 0 0 0"- "t=1 SL25;t=5 TURNL;t=6 SL30;t=9 YIELD2;t=11 SL20;t=15 TURNR;t=16 SL40;t=24 STOP1;",
- "25 24 25 26 25< 30 28 30 0 0 0 0 22 20 19 20 19 38 39 35 40 39 40 0 0 0 0 0"
- ));
- }
- @Test
- void StopTest() {
- assertTrue(DrivingTestEvaluator.evaluate("t=1 STOP;", "0 0 0"));
- assertTrue(DrivingTestEvaluator.evaluate("t=1 STOP3;", "0 0 0 0 0 0 0 0 0"));
- assertTrue(DrivingTestEvaluator.evaluate("t=1 STOP1;", "0 0 0 0 0"));
- assertFalse(DrivingTestEvaluator.evaluate("t=1 STOP3;", "0 0 0 0 2 2 2 2 2"));
- assertFalse(DrivingTestEvaluator.evaluate("t=1 STOP1;", "0 0"));
- assertFalse(DrivingTestEvaluator.evaluate("t=1 STOP2;", "0 0 0 0 0 0"));
- }
- @Test
- void TurnTest() {
- assertTrue(DrivingTestEvaluator.evaluate("t=1 TURNR;t=2 SL25;", "20> 25"));
- assertTrue(DrivingTestEvaluator.evaluate(
"t=1 TURNR;t=2 SL25;t=3 TURNR;t=4 SL25;t=5 TURNL;t=6 SL25;","22> 25 23> 25 15< 25"- "t=1 TURNR;t=2 SL25;t=3 TURNR;t=4 SL25;t=5 TURNL;t=6 SL25;",
- "22> 25 23> 25 15< 25"
- ));
- assertTrue(DrivingTestEvaluator.evaluate(
"t=1 TURNR;t=2 SL25;t=3 SL25;t=4 TURNR;t=5 SL25;t=6 TURNL;t=7 SL25;t=8 TURNR;t=9 SL25;t=10 TURNR;t=11 SL25;","10> 25 24 19> 25 18< 25 22> 25 23> 25"- "t=1 TURNR;t=2 SL25;t=3 SL25;t=4 TURNR;t=5 SL25;t=6 TURNL;t=7 SL25;t=8 TURNR;t=9 SL25;t=10 TURNR;t=11 SL25;",
- "10> 25 24 19> 25 18< 25 22> 25 23> 25"
- ));
- assertFalse(DrivingTestEvaluator.evaluate(
"t=1 TURNL;t=2 SL25;t=3 TURNR;t=4 SL25;t=5 TURNL;t=6 SL25;t=7 TURNL;t=8 SL25;t=9 TURNR;t=10 SL25;","20 25 19 25 18 25 17 25 16 25"- "t=1 TURNL;t=2 SL25;t=3 TURNR;t=4 SL25;t=5 TURNL;t=6 SL25;t=7 TURNL;t=8 SL25;t=9 TURNR;t=10 SL25;",
- "20 25 19 25 18 25 17 25 16 25"
- ));
- assertTrue(DrivingTestEvaluator.evaluate("t=1 TURNR;t=2 SL25;", "30< 25"));
- assertFalse(DrivingTestEvaluator.evaluate(
"t=1 TURNL;t=2 SL25;t=3 TURNR;t=4 SL25;t=5 TURNR;t=6 SL25;t=7 TURNL;t=8 SL25;t=9 TURNR;t=10 SL25;","22 25 23 25 21 25 19 25 18> 25"- "t=1 TURNL;t=2 SL25;t=3 TURNR;t=4 SL25;t=5 TURNR;t=6 SL25;t=7 TURNL;t=8 SL25;t=9 TURNR;t=10 SL25;",
- "22 25 23 25 21 25 19 25 18> 25"
- ));
- }
- @Test
- void SpeedLimitTest() {
- assertTrue(DrivingTestEvaluator.evaluate(
"t=1 SL20;t=6 TURNR;t=7 SL40;t=13 STOP1;t=18 SL50","20 19 18 17 20 15> 38 40 39 40 38 37 0 0 0 0 0 48 45"- "t=1 SL20;t=6 TURNR;t=7 SL40;t=13 STOP1;t=18 SL50",
- "20 19 18 17 20 15> 38 40 39 40 38 37 0 0 0 0 0 48 45"
- ));
- assertFalse(DrivingTestEvaluator.evaluate(
"t=1 SL30;t=6 SL40;t=13 STOP1;","30 29 28 27 30 35 45 39 40 38 37 0 0 0 0 0"- "t=1 SL30;t=6 SL40;t=13 STOP1;",
- "30 29 28 27 30 35 45 39 40 38 37 0 0 0 0 0"
- ));
- assertTrue(DrivingTestEvaluator.evaluate(
"t=1 SL50;t=11 TURNL;","50 49 50 48 47 46 45 44 43 42 30<"- "t=1 SL50;t=11 TURNL;",
- "50 49 50 48 47 46 45 44 43 42 30<"
- ));
- assertTrue(DrivingTestEvaluator.evaluate(
"t=1 SL50;t=11 TURNL;","50 49 50 48 47 60 45 44 43 42 30"- "t=1 SL50;t=11 TURNL;",
- "50 49 50 48 47 60 45 44 43 42 30"
- ));
- }
- @Test
- void YieldTest() {
- assertTrue(DrivingTestEvaluator.evaluate(
"t=1 YIELD;t=1 SL25;t=6 STOP1;","20 22 25 24 23 0 0 0 0 0"- "t=1 YIELD;t=1 SL25;t=6 STOP1;",
- "20 22 25 24 23 0 0 0 0 0"
- ));
- assertFalse(DrivingTestEvaluator.evaluate(
"t=1 YIELD;t=3 SL25;t=8 STOP1;","0 15 20 22 25 24 23 0 0 0 0 0"- "t=1 YIELD;t=3 SL25;t=8 STOP1;",
- "0 15 20 22 25 24 23 0 0 0 0 0"
- ));
- assertTrue(DrivingTestEvaluator.evaluate(
"t=1 YIELD2;t=5 SL30;t=9 TURNR;","0 0 0 0 28 29 30 25 22>"- "t=1 YIELD2;t=5 SL30;t=9 TURNR;",
- "0 0 0 0 28 29 30 25 22>"
- ));
- assertFalse(DrivingTestEvaluator.evaluate(
"t=1 YIELD2;t=4 SL30;t=9 TURNR;","0 10 0 0 28 29 30 25 22>"- "t=1 YIELD2;t=4 SL30;t=9 TURNR;",
- "0 10 0 0 28 29 30 25 22>"
- ));
- }
- @RepeatedTest(200)
- void RandomTest() {
- String indications = generateIndications();
- String actions = generateActions(indications);
- System.out.println(indications);
- System.out.println(actions);
- System.out.println("-------------------------------------------------------------------");
- assertTrue(DrivingTestEvaluator.evaluate(indications, actions));
- }
- public static String generateIndications() {
- ArrayList<String> types = new ArrayList<>(Arrays.asList("SL", "TURNL", "TURNR", "YIELD", "STOP", "REDLIGHT"));
- StringBuilder sb = new StringBuilder();
- Random random = new Random();
- // tiempo real considerando duración de señales
- int currentTime = 1;
- sb.append("t=").append(currentTime).append(" SL").append(random.nextInt(50) + 20).append(";");
- String prev = "SL";
- for (int i = 0; i < 8; i++) {
- Collections.shuffle(types);
- String actual = types.get(0);
- while ("SL".equals(actual) && "SL".equals(prev)) {
- Collections.shuffle(types);
- actual = types.get(0);
- }
- // Tiempo aleatorio antes de la próxima señal
- int timeGap = random.nextInt(4) + 1;
- currentTime += timeGap;
- sb.append("t=").append(currentTime).append(" ").append(actual);
- // Dependiendo del tipo, pse extiende el tiempo real
- if ("SL".equals(actual)) {
- int limit = random.nextInt(50) + 20;
- sb.append(limit);
- } else if ("YIELD".equals(actual)) {
- int cars = random.nextInt(5);
- if (cars > 0) sb.append(cars);
- currentTime += cars * 2;
- } else if ("STOP".equals(actual)) {
- int cars = random.nextInt(5);
- if (cars > 0) sb.append(cars);
currentTime += 3 + cars * 2;- currentTime += 3 + cars * 2;
- } else if ("REDLIGHT".equals(actual)) {
- int seconds = random.nextInt(5) + 1;
- sb.append(seconds);
- currentTime += seconds;
- }
- sb.append(";");
- prev = actual;
- }
- return sb.toString().trim();
- }
- public static String generateActions(String indications) {
- String[] trafficSigns = indications.split(";");
- List<String> actions = new ArrayList<>();
- Random random = new Random();
- int currentSecond = 1;
int speedLimit = 80;- int speedLimit = 80;
- for (String signEntry : trafficSigns) {
- signEntry = signEntry.trim();
- if (signEntry.isEmpty()) continue;
- String[] parts = signEntry.split(" ");
- int time = Integer.parseInt(parts[0].substring(2));
- String sign = parts[1];
- // Generación de velocidades aleatorias
- while (currentSecond < time) {
- int limit = speedLimit + 1;
- int v = Math.max(1, random.nextInt(limit));
- actions.add(String.valueOf(v));
- currentSecond++;
- }
- // Procesamiento de señales específicas
- if (sign.startsWith("SL")) {
- speedLimit = Integer.parseInt(sign.substring(2));
- actions.add(String.valueOf(random.nextInt(speedLimit + 1)));
- currentSecond++;
- } else if (sign.startsWith("YIELD")) {
- int cars = (sign.length() > 5) ? Integer.parseInt(sign.substring(5)) : 0;
- int secs = cars * 2;
- for (int j = 0; j < secs; j++) {
- actions.add("0");
- currentSecond++;
- }
- } else if (sign.startsWith("STOP")) {
- int cars = (sign.length() > 4) ? Integer.parseInt(sign.substring(4)) : 0;
- int secs = 3 + 2 * cars;
- for (int j = 0; j < secs; j++) {
- actions.add("0");
- currentSecond++;
- }
- } else if (sign.startsWith("REDLIGHT")) {
- int secs = Integer.parseInt(sign.substring(8));
- for (int j = 0; j < secs; j++) {
- actions.add("0");
- currentSecond++;
- }
- } else if (sign.equals("TURNL")) {
- actions.add(random.nextInt(speedLimit + 1) + "<");
- currentSecond++;
- } else if (sign.equals("TURNR")) {
- actions.add(random.nextInt(speedLimit + 1) + ">");
- currentSecond++;
- }
- }
- return String.join(" ", actions);
- }
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;
- }
package cinco_kyu; import java.util.*; import java.util.function.Consumer; 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("",""); } private static void validateStep(String step) { rules.keySet().stream().filter(step::contains).findFirst().ifPresent(key -> rules.get(key).accept(step)); } private void speedSituation(String velocity) { Pattern pattern = Pattern.compile("\\d+"); Matcher matcher = pattern.matcher(velocity); if (matcher.find()) { maxVelocity = Integer.parseInt(matcher.group(1)); } } private void stopSituation(String stop) { processStopLikeSituation(stop, 3); } private void yieldSituation(String yield) { processStopLikeSituation(yield, 0); } 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; } 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++; } } 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(); } exit = true; } 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 (seconds > 2) minorInfractions++; if (Integer.parseInt(matcher.group(1)) > maxVelocity + 10) throw new ExamFailedException(); } private static void refillRules() { } static class ExamFailedException extends RuntimeException { public ExamFailedException() { super("Examen suspenso"); } } }
public class DrivingTestEvaluator{public static boolean evaluate(String road, String exam){//your code heree- package cinco_kyu;
return true;- import java.util.*;
- import java.util.function.Consumer;
- 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("","");
- }
- private static void validateStep(String step) {
- rules.keySet().stream().filter(step::contains).findFirst().ifPresent(key -> rules.get(key).accept(step));
- }
- private void speedSituation(String velocity) {
- Pattern pattern = Pattern.compile("\\d+");
- Matcher matcher = pattern.matcher(velocity);
- if (matcher.find()) {
- maxVelocity = Integer.parseInt(matcher.group(1));
- }
- }
- private void stopSituation(String stop) {
- processStopLikeSituation(stop, 3);
- }
- private void yieldSituation(String yield) {
- processStopLikeSituation(yield, 0);
- }
- 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;
- }
- 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++;
- }
- } 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();
- }
- exit = true;
- }
- 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 (seconds > 2) minorInfractions++;
- if (Integer.parseInt(matcher.group(1)) > maxVelocity + 10) throw new ExamFailedException();
- }
- private static void refillRules() {
- }
- static class ExamFailedException extends RuntimeException {
- public ExamFailedException() {
- super("Examen suspenso");
- }
- }