new tasks

This commit is contained in:
Filip Gralinski 2019-01-11 20:11:02 +01:00
parent 604f0496dc
commit af904867da
20 changed files with 958 additions and 0 deletions

47
automata/Task201Test.py Executable file
View File

@ -0,0 +1,47 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Zadanie 201
Napisz funkcję `is_initial_state_a_final_one(automaton)`, która
sprawdza, czy stan początkowy automatu jest równocześnie
stanem końcowym. Należy używać metod klasy (nie odwoływać
się bezpośrednio do pól!).
NAME: is_initial_state_a_final_one
PARAMS: automaton
RETURN: bool
POINTS: 2
"""
import unittest
from Task201 import is_initial_state_a_final_one
from deterministic_automaton import DeterministicAutomaton
class Task201Test(unittest.TestCase):
"""Testy do zadania 201"""
def test_simple(self):
"""Prosty test."""
automaton = DeterministicAutomaton()
state_a = automaton.add_state()
state_b = automaton.add_state()
automaton.mark_as_initial(state_b)
self.assertFalse(is_initial_state_a_final_one(automaton))
automaton.mark_as_final(state_a)
self.assertFalse(is_initial_state_a_final_one(automaton))
automaton.mark_as_final(state_b)
self.assertTrue(is_initial_state_a_final_one(automaton))
if __name__ == '__main__':
unittest.main()

49
automata/Task202Test.py Executable file
View File

@ -0,0 +1,49 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Zadanie 202
Napisz funkcję `get_number_of_final_states(automaton)`, która oblicza
liczbę stanów końcowych automatu. Należy używać metod klasy (nie
odwoływać się bezpośrednio do pól!).
NAME: get_number_of_final_states
PARAMS: automaton
RETURN: int
POINTS: 2
"""
import unittest
from Task202 import get_number_of_final_states
from deterministic_automaton import DeterministicAutomaton
class Task202Test(unittest.TestCase):
"""Testy do zadania 202"""
def test_simple(self):
"""Prosty test."""
automaton = DeterministicAutomaton()
state_a = automaton.add_state()
state_b = automaton.add_state()
state_c = automaton.add_state()
automaton.mark_as_initial(state_b)
self.assertEqual(get_number_of_final_states(automaton), 0)
automaton.mark_as_final(state_a)
self.assertEqual(get_number_of_final_states(automaton), 1)
automaton.mark_as_final(state_c)
automaton.mark_as_final(state_b)
self.assertEqual(get_number_of_final_states(automaton), 3)
if __name__ == '__main__':
unittest.main()

51
automata/Task203Test.py Executable file
View File

@ -0,0 +1,51 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Zadanie 203
Napisz funkcję `get_number_of_transitions(automaton, symbol)`, która
oblicza liczbę przejść automatu etykietowanych zadanym symbolem.
Należy używać metod klasy (nie odwoływać się bezpośrednio do pól!).
NAME: get_number_of_transitions
PARAMS: automaton, char
RETURN: int
POINTS: 3
"""
import unittest
from Task203 import get_number_of_transitions
from deterministic_automaton import DeterministicAutomaton
class Task203Test(unittest.TestCase):
"""Testy do zadania 203"""
def test_simple(self):
"""Prosty test."""
automaton = DeterministicAutomaton()
state_a = automaton.add_state()
state_b = automaton.add_state()
state_c = automaton.add_state()
automaton.mark_as_initial(state_b)
automaton.mark_as_final(state_a)
self.assertEqual(get_number_of_transitions(automaton, 'b'), 0)
automaton.add_transition(state_b, 'a', state_a)
self.assertEqual(get_number_of_transitions(automaton, 'a'), 1)
self.assertEqual(get_number_of_transitions(automaton, 'b'), 0)
automaton.add_transition(state_b, 'b', state_a)
automaton.add_transition(state_a, 'b', state_b)
automaton.add_transition(state_c, 'b', state_a)
self.assertEqual(get_number_of_transitions(automaton, 'b'), 3)
if __name__ == '__main__':
unittest.main()

52
automata/Task204Test.py Executable file
View File

@ -0,0 +1,52 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Zadanie 204
Napisz funkcję `get_number_of_loops(automaton, symbol)`, która
oblicza liczbę pętli (tj. przejść od stanu z powrotem do danego
stanu) w zadanym automacie etykietowanych zadanym symbolem.
NAME: get_number_of_loops
PARAMS: automaton, char
RETURN: int
POINTS: 2
"""
import unittest
from Task204 import get_number_of_loops
from deterministic_automaton import DeterministicAutomaton
class Task204Test(unittest.TestCase):
"""Testy do zadania 204"""
def test_simple(self):
"""Prosty test."""
automaton = DeterministicAutomaton()
state_a = automaton.add_state()
state_b = automaton.add_state()
state_c = automaton.add_state()
automaton.mark_as_initial(state_b)
automaton.mark_as_final(state_a)
self.assertEqual(get_number_of_loops(automaton, 'b'), 0)
automaton.add_transition(state_b, 'a', state_a)
self.assertEqual(get_number_of_loops(automaton, 'a'), 0)
self.assertEqual(get_number_of_loops(automaton, 'b'), 0)
automaton.add_transition(state_b, 'b', state_b)
automaton.add_transition(state_c, 'b', state_c)
automaton.add_transition(state_a, 'a', state_a)
automaton.add_transition(state_a, 'b', state_b)
self.assertEqual(get_number_of_loops(automaton, 'a'), 1)
self.assertEqual(get_number_of_loops(automaton, 'b'), 2)
if __name__ == '__main__':
unittest.main()

40
automata/Task205Test.py Executable file
View File

@ -0,0 +1,40 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Zadanie 205
Napisz funkcję `haha_automaton()`, która
tworzy i zwraca automat, który akceptuje śmiechy
tj. napisy typu "hahaha!!!", gdzie ha powtarza
się przynajmniej dwa razy, wykrzyknik występuje dowolną liczbę
razy (przynajmniej raz).
NAME: haha_automaton
PARAMS: -
RETURN: DeterministicAutomaton
POINTS: 8
"""
import unittest
from Task205 import haha_automaton
class Task205Test(unittest.TestCase):
"""Testy do zadania 205"""
def test_simple(self):
"""Prosty test."""
automaton = haha_automaton()
self.assertTrue(automaton.accepts("hahaha!!!!!!!!!"))
self.assertTrue(automaton.accepts("haha!"))
self.assertTrue(automaton.accepts("hahahaha!!"))
self.assertFalse(automaton.accepts("ha!!!!!"))
self.assertFalse(automaton.accepts("hahaha"))
self.assertFalse(automaton.accepts("hahoha"))
self.assertFalse(automaton.accepts("!!haha"))
if __name__ == '__main__':
unittest.main()

38
automata/Task206Test.py Executable file
View File

@ -0,0 +1,38 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Zadanie 206
Napisz funkcję `big_no_automaton()`, która tworzy i zwraca automat,
który akceptuje "Big NO!" tj. napisy typu "NOO...OO!", gdzie "O"
powtarza się przynajmniej 5 razy (zob.
http://tvtropes.org/pmwiki/pmwiki.php/Main/BigNo).
NAME: big_no_automaton
PARAMS: -
RETURN: DeterministicAutomaton
POINTS: 8
"""
import unittest
from Task206 import big_no_automaton
class Task206Test(unittest.TestCase):
"""Testy do zadania 206"""
def test_simple(self):
"""Prosty test."""
automaton = big_no_automaton()
self.assertTrue(automaton.accepts("NOOOOO!"))
self.assertTrue(automaton.accepts("NOOOOOOOOOOOOOOOO!"))
self.assertFalse(automaton.accepts("NOOOO!"))
self.assertFalse(automaton.accepts("NOOOOOO!!!!!!"))
self.assertFalse(automaton.accepts("NOOOOOO"))
self.assertFalse(automaton.accepts("ONOOOOO!"))
self.assertFalse(automaton.accepts(""))
if __name__ == '__main__':
unittest.main()

47
automata/Task207Test.py Executable file
View File

@ -0,0 +1,47 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Zadanie 207
Napisz funkcję `three_automaton()`, która
tworzy i zwraca automat, który akceptuje
napisy reprezentujące liczby podzielne przez 3. Automat
nie powinien akceptować napisów zaczynających
nieznaczącymi zerami (np. "033").
NAME: three_automaton
PARAMS: -
RETURN: DeterministicAutomaton
POINTS: 8
"""
import unittest
from Task207 import three_automaton
class Task207Test(unittest.TestCase):
"""Testy do zadania 207"""
def test_simple(self):
"""Prosty test."""
automaton = three_automaton()
self.assertTrue(automaton.accepts("3"))
self.assertTrue(automaton.accepts("0"))
self.assertTrue(automaton.accepts("12"))
self.assertTrue(automaton.accepts("324"))
self.assertTrue(automaton.accepts("333333"))
self.assertTrue(automaton.accepts("30003"))
self.assertTrue(automaton.accepts("513"))
self.assertFalse(automaton.accepts("00"))
self.assertFalse(automaton.accepts("012"))
self.assertFalse(automaton.accepts("0000324"))
self.assertFalse(automaton.accepts("1"))
self.assertFalse(automaton.accepts("2"))
self.assertFalse(automaton.accepts("5"))
self.assertFalse(automaton.accepts("1111"))
if __name__ == '__main__':
unittest.main()

49
automata/Task208Test.py Executable file
View File

@ -0,0 +1,49 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Zadanie 208
Napisz funkcję `twenty_five_automaton()`, która
tworzy i zwraca automat, który akceptuje
napisy reprezentujące liczby podzielne przez 25. Automat
może akceptować napisy zaczynające
nieznaczącymi zerami (np. "075"). Nie powinien akceptować natomiast
samego zera ("0").
NAME: twenty_five_automaton
PARAMS: -
RETURN: DeterministicAutomaton
POINTS: 8
"""
import unittest
from Task208 import twenty_five_automaton
class Task208Test(unittest.TestCase):
"""Testy do zadania 208"""
def test_simple(self):
"""Prosty test."""
automaton = twenty_five_automaton()
self.assertTrue(automaton.accepts("25"))
self.assertTrue(automaton.accepts("50"))
self.assertTrue(automaton.accepts("75"))
self.assertTrue(automaton.accepts("100"))
self.assertTrue(automaton.accepts("1098375"))
self.assertTrue(automaton.accepts("333325"))
self.assertTrue(automaton.accepts("17150"))
self.assertTrue(automaton.accepts("025"))
self.assertTrue(automaton.accepts("0000175"))
self.assertFalse(automaton.accepts("1"))
self.assertFalse(automaton.accepts("2"))
self.assertFalse(automaton.accepts("5"))
self.assertFalse(automaton.accepts("10"))
self.assertFalse(automaton.accepts("45"))
self.assertFalse(automaton.accepts("124"))
if __name__ == '__main__':
unittest.main()

40
automata/Task209Test.py Executable file
View File

@ -0,0 +1,40 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Zadanie 209
Napisz funkcję `monsters_automaton()`, która
tworzy i zwraca automat, który akceptuje
wyłącznie napisy "Godzilla", "Ghidora" oraz "Mothra"
i żadnych innych.
NAME: monsters_automaton
PARAMS: -
RETURN: DeterministicAutomaton
POINTS: 8
"""
import unittest
from Task209 import monsters_automaton
class Task209Test(unittest.TestCase):
"""Testy do zadania 209"""
def test_simple(self):
"""Prosty test."""
automaton = monsters_automaton()
self.assertTrue(automaton.accepts("Godzilla"))
self.assertTrue(automaton.accepts("Ghidora"))
self.assertTrue(automaton.accepts("Mothra"))
self.assertFalse(automaton.accepts("Biollante"))
self.assertFalse(automaton.accepts(""))
self.assertFalse(automaton.accepts("Godzil"))
self.assertFalse(automaton.accepts("Kojot"))
self.assertFalse(automaton.accepts("Godzra"))
if __name__ == '__main__':
unittest.main()

45
automata/Task210Test.py Executable file
View File

@ -0,0 +1,45 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Zadanie 210
Napisz funkcję `abc_automaton()`, która
tworzy i zwraca automat, który akceptuje
napisy składające z dowolnej liczby
znaków 'a', po których następuje dowolna liczba
znaków 'b', po których następuje dowolna liczba
znaków 'c'. "Dowolna" oznacza także zero.
NAME: abc_automaton
PARAMS: -
RETURN: DeterministicAutomaton
POINTS: 8
"""
import unittest
from Task210 import abc_automaton
class Task210Test(unittest.TestCase):
"""Testy do zadania 210"""
def test_simple(self):
"""Prosty test."""
automaton = abc_automaton()
self.assertTrue(automaton.accepts(""))
self.assertTrue(automaton.accepts("abc"))
self.assertTrue(automaton.accepts("aaaaaaaabccc"))
self.assertTrue(automaton.accepts("bbbccc"))
self.assertTrue(automaton.accepts("ac"))
self.assertTrue(automaton.accepts("abbbbbbbbbbbbbb"))
self.assertFalse(automaton.accepts("ba"))
self.assertFalse(automaton.accepts("cccbbbaaa"))
self.assertFalse(automaton.accepts("baba"))
self.assertFalse(automaton.accepts("abcca"))
if __name__ == '__main__':
unittest.main()

41
automata/Task211Test.py Executable file
View File

@ -0,0 +1,41 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Zadanie 211
Napisz funkcję `kot_automaton()`, która tworzy i zwraca automat, który
akceptuje napisy "kos", "kot", "kat", "lot", "lat" i nie akceptuje
żadnych innych napisów.
NAME: kot_automaton
PARAMS: -
RETURN: DeterministicAutomaton
POINTS: 8
"""
import unittest
from Task211 import kot_automaton
class Task211Test(unittest.TestCase):
"""Testy do zadania 211"""
def test_simple(self):
"""Prosty test."""
automaton = kot_automaton()
self.assertTrue(automaton.accepts("kos"))
self.assertTrue(automaton.accepts("kot"))
self.assertTrue(automaton.accepts("kat"))
self.assertTrue(automaton.accepts("lot"))
self.assertTrue(automaton.accepts("lat"))
self.assertFalse(automaton.accepts("ko"))
self.assertFalse(automaton.accepts(""))
self.assertFalse(automaton.accepts("los"))
self.assertFalse(automaton.accepts("kota"))
if __name__ == '__main__':
unittest.main()

41
automata/Task212Test.py Executable file
View File

@ -0,0 +1,41 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Zadanie 212
Napisz funkcję `negation_automaton()`, która tworzy i zwraca automat
akceptujący wszystkie napisy nad alfabetem "abcd"
z wyjątkiem napisu "abba".
NAME: negation_automaton
PARAMS: -
RETURN: DeterministicAutomaton
POINTS: 8
"""
import unittest
from Task212 import negation_automaton
class Task212Test(unittest.TestCase):
"""Testy do zadania 212"""
def test_simple(self):
"""Prosty test."""
automaton = negation_automaton()
self.assertTrue(automaton.accepts("abbb"))
self.assertTrue(automaton.accepts("baca"))
self.assertTrue(automaton.accepts("dddddd"))
self.assertTrue(automaton.accepts("abbaa"))
self.assertTrue(automaton.accepts("abb"))
self.assertTrue(automaton.accepts("ab"))
self.assertTrue(automaton.accepts(""))
self.assertFalse(automaton.accepts("abba"))
self.assertFalse(automaton.accepts("xa"))
if __name__ == '__main__':
unittest.main()

40
automata/Task213Test.py Executable file
View File

@ -0,0 +1,40 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Zadanie 213
Napisz funkcję `tricky_automaton()`, która tworzy i zwraca automat
akceptujący wszystkie napisy złożone z napisu "abc" powtórzonego
dowolną liczbę razy (ale przynajmniej raz) oraz napis "a".
NAME: tricky_automaton
PARAMS: -
RETURN: DeterministicAutomaton
POINTS: 8
"""
import unittest
from Task213 import tricky_automaton
class Task213Test(unittest.TestCase):
"""Testy do zadania 213"""
def test_simple(self):
"""Prosty test."""
automaton = tricky_automaton()
self.assertTrue(automaton.accepts("a"))
self.assertTrue(automaton.accepts("abc"))
self.assertTrue(automaton.accepts("abcabc"))
self.assertTrue(automaton.accepts("abcabcabcabcabc"))
self.assertFalse(automaton.accepts("ab"))
self.assertFalse(automaton.accepts(""))
self.assertFalse(automaton.accepts("abca"))
self.assertFalse(automaton.accepts("abcabca"))
if __name__ == '__main__':
unittest.main()

44
automata/Task214Test.py Executable file
View File

@ -0,0 +1,44 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Zadanie 214
Napisz funkcję `hex_automaton()`, która tworzy i zwraca automat
akceptujący napisy reprezentujące liczby szesnastkowo.
Cyfry szesnastkowe mogą być reprezentowane za pomocą małych
bądź wielkich liter, ale konsekwentnie ("a0f9" i "A0F9" ma być akceptowane,
"a0F9" i "A0f9" - nie). Liczba może zawierać zera nieznaczące na początku.
NAME: hex_automaton
PARAMS: -
RETURN: DeterministicAutomaton
POINTS: 8
"""
import unittest
from Task214 import hex_automaton
class Task214Test(unittest.TestCase):
"""Testy do zadania 214"""
def test_simple(self):
"""Prosty test."""
automaton = hex_automaton()
self.assertTrue(automaton.accepts("a0f9"))
self.assertTrue(automaton.accepts("A0F9"))
self.assertTrue(automaton.accepts("0"))
self.assertTrue(automaton.accepts("0B000"))
self.assertTrue(automaton.accepts("DDDD"))
self.assertTrue(automaton.accepts("baca"))
self.assertFalse(automaton.accepts("gg"))
self.assertFalse(automaton.accepts("a0F9"))
self.assertFalse(automaton.accepts("A0f9"))
self.assertFalse(automaton.accepts("Baca"))
if __name__ == '__main__':
unittest.main()

48
automata/Task215Test.py Executable file
View File

@ -0,0 +1,48 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Zadanie 215
Napisz funkcję `four_automaton()`, która
tworzy i zwraca automat, który akceptuje
napisy reprezentujące liczby podzielne przez 4. Automat
nie powinien akceptować napisów zaczynających
nieznaczącymi zerami (np. "044").
NAME: four_automaton
PARAMS: -
RETURN: DeterministicAutomaton
POINTS: 8
"""
import unittest
from Task215 import four_automaton
class Task215Test(unittest.TestCase):
"""Testy do zadania 215"""
def test_simple(self):
"""Prosty test."""
automaton = four_automaton()
self.assertTrue(automaton.accepts("4"))
self.assertTrue(automaton.accepts("0"))
self.assertTrue(automaton.accepts("12"))
self.assertTrue(automaton.accepts("324"))
self.assertTrue(automaton.accepts("1052"))
self.assertTrue(automaton.accepts("444444"))
self.assertFalse(automaton.accepts("012"))
self.assertFalse(automaton.accepts("0000324"))
self.assertFalse(automaton.accepts("5"))
self.assertFalse(automaton.accepts("1"))
self.assertFalse(automaton.accepts("3"))
self.assertFalse(automaton.accepts("34"))
self.assertFalse(automaton.accepts("1057"))
self.assertFalse(automaton.accepts("4454"))
if __name__ == '__main__':
unittest.main()

40
automata/Task216Test.py Executable file
View File

@ -0,0 +1,40 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Zadanie 216
Napisz funkcję `code_automaton()`, która
tworzy i zwraca automat, który akceptuje
kody pocztowe (ciągi cyfra-cyfra-minus-cyfra-cyfr-cyfra).
NAME: code_automaton
PARAMS: -
RETURN: DeterministicAutomaton
POINTS: 8
"""
import unittest
from Task216 import code_automaton
class Task216Test(unittest.TestCase):
"""Testy do zadania 216"""
def test_simple(self):
"""Prosty test."""
automaton = code_automaton()
self.assertTrue(automaton.accepts("61-909"))
self.assertTrue(automaton.accepts("22-340"))
self.assertTrue(automaton.accepts("00-000"))
self.assertTrue(automaton.accepts("99-999"))
self.assertFalse(automaton.accepts("61909"))
self.assertFalse(automaton.accepts("61-90"))
self.assertFalse(automaton.accepts("000-000"))
self.assertFalse(automaton.accepts(""))
if __name__ == '__main__':
unittest.main()

40
automata/Task217Test.py Executable file
View File

@ -0,0 +1,40 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Zadanie 217
Napisz funkcję `dna_automaton()`, która
tworzy i zwraca automat, który akceptuje
niepuste ciągi złozone z liter "A", "C", "G" i "T"
których długość jest wielokrotnością liczby 3.
NAME: dna_automaton
PARAMS: -
RETURN: DeterministicAutomaton
POINTS: 8
"""
import unittest
from Task217 import dna_automaton
class Task217Test(unittest.TestCase):
"""Testy do zadania 217"""
def test_simple(self):
"""Prosty test."""
automaton = dna_automaton()
self.assertTrue(automaton.accepts("AAACGT"))
self.assertTrue(automaton.accepts("ACA"))
self.assertTrue(automaton.accepts("ACAAAAGCAACAAAAGCA"))
self.assertTrue(automaton.accepts("TTT"))
self.assertFalse(automaton.accepts("TT"))
self.assertFalse(automaton.accepts("A"))
self.assertFalse(automaton.accepts("AAACG"))
self.assertFalse(automaton.accepts(""))
if __name__ == '__main__':
unittest.main()

42
automata/Task218Test.py Executable file
View File

@ -0,0 +1,42 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Zadanie 218
Napisz funkcję `binary_list_automaton()`, która
tworzy i zwraca automat, który akceptuje
napisy złożone z liczb zapisanych binarnie
(bez zbędnych zer na początku) oddzielonych dwukropkami.
Akceptowana powinna być także pojedyncza liczba.
NAME: binary_list_automaton
PARAMS: -
RETURN: DeterministicAutomaton
POINTS: 8
"""
import unittest
from Task218 import binary_list_automaton
class Task218Test(unittest.TestCase):
"""Testy do zadania 218"""
def test_simple(self):
"""Prosty test."""
automaton = binary_list_automaton()
self.assertTrue(automaton.accepts("100:11:11101"))
self.assertTrue(automaton.accepts("1"))
self.assertTrue(automaton.accepts("0:110"))
self.assertFalse(automaton.accepts(""))
self.assertFalse(automaton.accepts("010:110"))
self.assertFalse(automaton.accepts("2"))
self.assertFalse(automaton.accepts("100::11:11101"))
self.assertFalse(automaton.accepts("100:11:11101:"))
self.assertFalse(automaton.accepts(":100:11:11101"))
if __name__ == '__main__':
unittest.main()

45
automata/Task219Test.py Executable file
View File

@ -0,0 +1,45 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Zadanie 219
Napisz funkcję `alt_automaton()`, która
tworzy i zwraca automat, akceptujący
napisy złożone z "abc" powielonego dowolną liczbę razy
(w tym zero) oraz napisy złożone z "ab" powielonego
dowolną liczbę razy.
NAME: alt_automaton
PARAMS: -
RETURN: DeterministicAutomaton
POINTS: 8
"""
import unittest
from Task219 import alt_automaton
class Task219Test(unittest.TestCase):
"""Testy do zadania 219"""
def test_simple(self):
"""Prosty test."""
automaton = alt_automaton()
self.assertTrue(automaton.accepts("abababab"))
self.assertTrue(automaton.accepts("abcabc"))
self.assertTrue(automaton.accepts("abc"))
self.assertTrue(automaton.accepts("ab"))
self.assertTrue(automaton.accepts(""))
self.assertTrue(automaton.accepts("abab"))
self.assertTrue(automaton.accepts("abcabcabcabcabcabcabcabc"))
self.assertFalse(automaton.accepts("ba"))
self.assertFalse(automaton.accepts("abca"))
self.assertFalse(automaton.accepts("aba"))
self.assertFalse(automaton.accepts("ababc"))
self.assertFalse(automaton.accepts("abcab"))
if __name__ == '__main__':
unittest.main()

View File

@ -0,0 +1,119 @@
# -*- coding: utf-8 -*-
"""
Automat deterministyczny.
"""
class DeterministicAutomaton:
"""
Klasa reprezentująca deterministyczny automat skończenie stanowy.
"""
def __init__(self):
"""
Konstruktor.
"""
# Liczba wszystkich stanów,
# stany będą identyfikowane przez kolejne liczby:
# 0, 1, ..., number_of_states - 1
self.number_of_states = 0
# przejścia będą przechowywane w tablicy
# haszującej indeksowanej parą stan-znak,
# tj. transitions[(state_from, character)]
# przechowuje stan docelowy przy
# przejściu od stanu state_from przez znak
# character
self.transitions = { }
# stan początkowy
self.initial_state = None
# zbiór stanów końcowych
self.final_states = set()
# funkcje modyfikujące automat
def add_state(self):
"""
Dodaje nowy stan, zwraca numer utworzonego stanu
"""
self.number_of_states += 1
return self.number_of_states - 1
def add_transition(self, state_from, symbol, state_to):
"""
Dodaje przejście od stanu state_from przez znak symbol
do stanu state_to.
"""
self.transitions[(state_from, symbol)] = state_to
def mark_as_initial(self, state):
"""
Oznacza stan jako początkowy.
"""
self.initial_state = state
def mark_as_final(self, state):
"""
Oznacza stan jako końcowy.
"""
self.final_states.add(state)
# dostęp do automatu
def get_number_of_states(self):
"""
Zwraca liczbę stanów.
"""
return self.number_of_states
def get_initial_state(self):
"""
Zwraca stan początkowy.
"""
return self.initial_state
def is_final_state(self, state):
"""
Zwraca informacje, czy stan jest końcowy.
"""
return state in self.final_states
def get_target_state(self, state_from, symbol):
"""
Zwraca stan docelowy, przy przejściu od stanu state_from
przez symbol bądź wartość None, jeśli nie
ma takiego przejścia.
"""
return self.transitions.get((state_from, symbol))
def accepts(self, string):
"""
Sprawdza, czy automat akceptuje napis.
"""
current_state = self.get_initial_state()
for symbol in string:
current_state = self.get_target_state(current_state, symbol)
if current_state is None:
return False
return self.is_final_state(current_state)
if __name__ == '__main__':
AUTOMATON = DeterministicAutomaton()
INITIAL_STATE = AUTOMATON.add_state()
FINAL_STATE = AUTOMATON.add_state()
AUTOMATON.add_transition(INITIAL_STATE, 'x', FINAL_STATE)
AUTOMATON.mark_as_initial(INITIAL_STATE)
AUTOMATON.mark_as_final(FINAL_STATE)
print AUTOMATON.accepts("x") # wypisze True
print AUTOMATON.accepts("") # wypisze False
print AUTOMATON.accepts("ab") # wypisze False