#!/usr/bin/python3 import sys import re class automata: # class variables init def __init__(self): # dictionary of connections between nodes self.graph = {} # list of accepting states self.accepting_states = [] # list of current states self.state = ['0'] # print for debug purposes def __repr__(self): return('%s\n\n%s\n\n%s\n\n' % (self.graph, self.accepting_states, self.state)) # add node in open fst format def add_node(self, line): node = line.replace('\n', '').split(' ') if len(node) == 3: if node[0] in self.graph: # add value to existing node self.graph[node[0]].append({node[2]: node[1]}) else: # create new node self.graph[node[0]] = [{node[2]: node[1]}] elif len(node) == 1: # add accepting state self.accepting_states.append(node[0]) # check if string is accepted by automate def test_string(self, text): self.state = ['0'] text = text.replace('\n', '') # for all values in text for i in text: # for all actual states for q in self.state: # move state to its transition q = self.get_node_transition(q, i) # if the list is empty, return false if not self.state: return False # flatten list of states self.state = [item for sublist in self.state for item in sublist] print(self.state, i) # check if automata is in accepting state return self.check_if_accepted() # check if there is common part between states of automata and accepting states def check_if_accepted(self): return not set(self.state).isdisjoint(self.accepting_states) def get_node_transition(self, q, i): result = [] # if the node exists if self.graph[q]: # search through all its connections to find value for transition in self.graph[q]: print(transition, i) try: if transition[i]: # append next node result.append(transition[i]) except KeyError: # there is no value like that (element from the outside of alphabet) return [] # return list of next nodes return result auto = automata() for line in sys.stdin: auto.add_node(line) print(auto) f = open(sys.argv[1], 'r') for line in f: print(auto.test_string(line))