forked from filipg/pjfz-2020
New tasks
This commit is contained in:
parent
4798649c00
commit
dc687cb1a4
47
automata/Task201Test.py
Executable file
47
automata/Task201Test.py
Executable 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
49
automata/Task202Test.py
Executable 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
51
automata/Task203Test.py
Executable 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
52
automata/Task204Test.py
Executable 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
40
automata/Task205Test.py
Executable 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
38
automata/Task206Test.py
Executable 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
47
automata/Task207Test.py
Executable 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
49
automata/Task208Test.py
Executable 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
40
automata/Task209Test.py
Executable 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
45
automata/Task210Test.py
Executable 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
41
automata/Task211Test.py
Executable 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
41
automata/Task212Test.py
Executable 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
40
automata/Task213Test.py
Executable 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
44
automata/Task214Test.py
Executable 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
48
automata/Task215Test.py
Executable 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
40
automata/Task216Test.py
Executable 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
40
automata/Task217Test.py
Executable 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
42
automata/Task218Test.py
Executable 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
45
automata/Task219Test.py
Executable 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()
|
119
automata/deterministic_automaton.py
Normal file
119
automata/deterministic_automaton.py
Normal 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
|
2
blend.sh
2
blend.sh
@ -15,7 +15,7 @@ cp -R $STUDENT_DIR/* arena/
|
|||||||
ln -s ../$STUDENT_DIR/.git arena/.git
|
ln -s ../$STUDENT_DIR/.git arena/.git
|
||||||
|
|
||||||
mkdir -p arena/regexp
|
mkdir -p arena/regexp
|
||||||
#mkdir -p arena/automata
|
mkdir -p arena/automata
|
||||||
|
|
||||||
rm -rf arena/odp arena/$PREFIX
|
rm -rf arena/odp arena/$PREFIX
|
||||||
|
|
||||||
|
12
vars
12
vars
@ -9,15 +9,15 @@ POINT_LIMIT=15
|
|||||||
|
|
||||||
typeset -A TIME_LIMITS
|
typeset -A TIME_LIMITS
|
||||||
set -A TIME_LIMITS \
|
set -A TIME_LIMITS \
|
||||||
"1" "2021-01-02 10:00:00 +0100" \
|
"1" "2021-01-08 10:00:00 +0100" \
|
||||||
"2" "2020-01-31 23:59:59 +0100" \
|
"2" "2020-01-15 23:59:59 +0100" \
|
||||||
"3" "2021-01-05 13:00:00 +0100"
|
"3" "2021-01-08 13:00:00 +0100"
|
||||||
|
|
||||||
typeset -A HOME_TIME_LIMITS
|
typeset -A HOME_TIME_LIMITS
|
||||||
set -A HOME_TIME_LIMITS \
|
set -A HOME_TIME_LIMITS \
|
||||||
"1" "2021-01-02 10:45:00 +0100" \
|
"1" "2021-01-08 10:00:00 +0100" \
|
||||||
"2" "2020-01-31 23:59:59 +0100" \
|
"2" "2020-01-15 23:59:59 +0100" \
|
||||||
"3" "2021-01-05 13:00:00 +0100"
|
"3" "2021-01-08 13:00:00 +0100"
|
||||||
|
|
||||||
|
|
||||||
typeset -A HOME_POINT_LIMITS
|
typeset -A HOME_POINT_LIMITS
|
||||||
|
Loading…
Reference in New Issue
Block a user