Last active
September 6, 2017 20:40
-
-
Save vadim8kiselev/e319143c4e1f4a254b3f23b6ef827409 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package vadim; | |
import com.fasterxml.jackson.databind.ObjectMapper; | |
import java.io.File; | |
import java.io.IOException; | |
import java.util.ArrayList; | |
import java.util.Arrays; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.Set; | |
import java.util.stream.Collectors; | |
public class Main { | |
public static void main(String[] args) throws IOException { | |
Automata.AutomataInputEntity inputEntity = | |
new ObjectMapper().readValue(new File("input.json"), Automata.AutomataInputEntity.class); | |
Automata automata = Automata.createBuilder() | |
.setInitialState(inputEntity.getInitialState()) | |
.setFinalState(inputEntity.getFinalState()) | |
.setMatrixOfTransitions(inputEntity.getMatrixOfTransitions()) | |
.build(); | |
try { | |
String response = automata.automate(inputEntity.getAlphabet()); | |
System.out.println(response); | |
} catch (Automata.AutomataException exception) { | |
System.err.println(exception.getMessage()); | |
} | |
} | |
} | |
class Automata { | |
private Set<String> initialState; | |
private Set<String> finalState; | |
private Map<String, Map<String, Set<String>>> matrixOfTransitions; | |
private Automata() { | |
// private constructor | |
} | |
public String automate(String input) { | |
// Resolve input | |
List<String> alphabet = resolveInput(input); | |
// Process automata algorithm | |
Set<String> currentState = processAlgorithm(alphabet); | |
// Validate current state | |
validateCurrentState(currentState); | |
// OK | |
return "Everything is ok"; | |
} | |
private List<String> resolveInput(String input) { | |
return new ArrayList<>(Arrays.asList(input.split(""))); | |
} | |
private Set<String> processAlgorithm(List<String> alphabet) { | |
Set<String> currentState = initialState; | |
for (String symbol : alphabet) { | |
currentState.addAll(currentState.stream() | |
.map(state -> { | |
Map<String, Set<String>> map = matrixOfTransitions.get(state); | |
if (!map.containsKey(symbol)) { | |
throw new AutomataException("Unknown transition: " + symbol); | |
} | |
return map.get(symbol); | |
}) | |
.flatMap(Set::stream) | |
.collect(Collectors.toList())); | |
} | |
return currentState; | |
} | |
private void validateCurrentState(Set<String> state) { | |
if (!isFinalState(state)) { | |
throw new AutomataException("Automata has stopped with not final state"); | |
} | |
} | |
private boolean isFinalState(Set<String> state) { | |
return !finalState.stream() | |
.filter(state::contains) | |
.collect(Collectors.toList()) | |
.isEmpty(); | |
} | |
public static Automata.Builder createBuilder() { | |
return new Automata().new Builder(); | |
} | |
public class Builder { | |
public Builder setInitialState(Set<String> initialStates) { | |
Automata.this.initialState = initialStates; | |
return this; | |
} | |
public Builder setFinalState(Set<String> finalStates) { | |
Automata.this.finalState = finalStates; | |
return this; | |
} | |
public Builder setMatrixOfTransitions(Map<String, Map<String, Set<String>>> matrix) { | |
Automata.this.matrixOfTransitions = matrix; | |
return this; | |
} | |
public Automata build() { | |
return Automata.this; | |
} | |
} | |
public static class AutomataInputEntity { | |
private String alphabet; | |
private Set<String> initialState; | |
private Set<String> finalState; | |
private Map<String, Map<String, Set<String>>> matrixOfTransitions; | |
public String getAlphabet() { | |
return alphabet; | |
} | |
public void setAlphabet(String alphabet) { | |
this.alphabet = alphabet; | |
} | |
public Set<String> getInitialState() { | |
return initialState; | |
} | |
public void setInitialState(Set<String> initialState) { | |
this.initialState = initialState; | |
} | |
public Set<String> getFinalState() { | |
return finalState; | |
} | |
public void setFinalState(Set<String> finalState) { | |
this.finalState = finalState; | |
} | |
public Map<String, Map<String, Set<String>>> getMatrixOfTransitions() { | |
return matrixOfTransitions; | |
} | |
public void setMatrixOfTransitions(Map<String, Map<String, Set<String>>> matrixOfTransitions) { | |
this.matrixOfTransitions = matrixOfTransitions; | |
} | |
} | |
public class AutomataException extends RuntimeException { | |
public AutomataException(String message) { | |
super(message); | |
} | |
} | |
} | |
/* | |
{ | |
"alphabet": "rrbb", | |
"initialState": [ | |
"1" | |
], | |
"finalState": [ | |
"9" | |
], | |
"matrixOfTransitions": { | |
"1": { | |
"r": [ | |
"2" | |
], | |
"b": [ | |
"4" | |
] | |
}, | |
"2": { | |
"r": [ | |
"3" | |
], | |
"b": [ | |
"5" | |
] | |
}, | |
"3": { | |
"b": [ | |
"6" | |
] | |
}, | |
"4": { | |
"r": [ | |
"5" | |
], | |
"b": [ | |
"7" | |
] | |
}, | |
"5": { | |
"r": [ | |
"6" | |
], | |
"b": [ | |
"8" | |
] | |
}, | |
"6": { | |
"b": [ | |
"9" | |
] | |
}, | |
"7": { | |
"r": [ | |
"8" | |
] | |
}, | |
"8": { | |
"r": [ | |
"9" | |
] | |
}, | |
"9": { | |
} | |
} | |
} | |
*/ | |
/* | |
<dependency> | |
<groupId>com.fasterxml.jackson.core</groupId> | |
<artifactId>jackson-databind</artifactId> | |
<version>2.6.3</version> | |
</dependency> | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment