Skip to content

Instantly share code, notes, and snippets.

@vadim8kiselev
Last active September 6, 2017 20:40
Show Gist options
  • Save vadim8kiselev/e319143c4e1f4a254b3f23b6ef827409 to your computer and use it in GitHub Desktop.
Save vadim8kiselev/e319143c4e1f4a254b3f23b6ef827409 to your computer and use it in GitHub Desktop.
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