Фабрика за регулярни изрази
- Краен срок:
- 31.12.2014 23:59
- Точки:
- 10
Срокът за предаване на решения е отминал
В тази задача ще трябва да симулирате работата на фабрика за регулярни изрази. Всяка фабрика разполага с базови регулярни изрази, които ще наричаме матриали. Всяка фабрика има ограничено количество от материали и може конкурентно да получава поръчки от клиентите си. Поръчките се изпълняват конкурентно от работниците на фабриката. Всеки работник изпълнява само една поръчка в даден момент и всяка поръчка се изпълнява само веднъж и от точно един работник. Фабриката има фиксиран брой работници, който се задава при създаването ѝ.
Поръчките се изпълняват в реда, в който са били получени. След като завърши изпълнението на някоя от тях, то незабавно се връща резултат на клиента. Всяка поръчка има статус, който може да бъде проверяван по всяко време. Възможните статуси са:
const (
DOES_NOT_EXIST = iota
ENQUEUED
IN_PROGRESS
UNABLE_TO_PRODUCE
DONE
)
Зa целта ще ви трябват следните типове и техните методи:
Поръчка
Поръчката съдържа множество от думи. При създаване на нова поръчка за нея се
генерира уникален идентификационен номер. За да твърдим, че е изпълнена успешно
е нужно да получим като резултат регулярен израз, който match-ва всяка една от
думите в множеството. Всеки произведен регулярен израз трябва да започва с ^
и да завършва с $
. Разполагате с неограничено количество и от двата символа и
няма нужда да ги пазите в склад. Статусът на поръчката трябва да се държи
актуален, което означава, че фабриката трябва да се грижи да го променя когато
е необходимо.
type Order struct {
Id string
Status int //Състояние, което се обновява от фабриката
Words []string // Думи, за които трябва да бъде произведен
// регулярен израз
Result string // Произведеният регулярен израз
Channel chan *Order // Канал, по който да бъде върната
// поръчката, когато бъде приключена
}
func NewOrder(words []string, channel chan *Order) *Order
Създава нова поръчка с подадените думи и канал. Тази функция трябва да генерира уникално Id.
Фабрика (type Factory)
Фабриката ще приема поръчки от клиентите, ще ги изпълнява и ще връща резултат щом приключи. При създаването се задава колко работници има, това е еквивалентно на броя поръчки, които могат да бъдат изпълнявани във всеки момент, тъй като един работник може да изпълнява само една поръчка в даден момент. Поръчка може да бъде изпълнена, ако фабриката разполага с необходимите материали, в противен случай се съобщава на клиента, че не може да бъде изпълнена. След изпълнението трябва материалите използвани за поръчката да бъдат изкарани от склада. Операциите за добавяне и премахване на материали трябва да бъдат "thread-safe".
func NewFactory(workers uint8) *Factory
Създава фабрика с подадения брой работници и започва да изпълнява поръчки.
func (f *Factory) Enqueue(order *Order)
Добавя поръчката в списъка на чакащите да бъдат изпълнени.
func (f *Factory) StartProducing()
Започва да изпълнява поръчки.
func (f *Factory) StopProducing()
Прекратява производството като изпълнява само поръчките със статус
IN_PROGRESS
.
func (f *Factory) StorageAdd(materials map[string]uint16)
Приема map
с материал: количество
и добавя съответните материали
и техните количества в склада.
Пример:
materials := map[string]uint16{
`[a-z0-9]{2,4}`: 3,
`[aeouiy]`: 2,
}
factory.StorageAdd(materials)
func (f *Factory) generateRegexp(words []string) (string, error)
Генерира регулярен израз (или връща грешка при недостатъчно материали), който match-ва
всички думи в слайса words
. Върнатият регулярен израз трябва да започва с ^
и да
завършва с $
.
Клиент (type Client)
Клиентите изпращат поръчки към фабриката и чакат да получат резултат. Те могат да проверяват какво се случва с поръчките им във всеки момент.
type Client struct {
Name string
Orders map[string]*Order // Всички поръчки от този клиент
// където ключът е Order.Id
Channel chan *Order // Канал, по който клиентът
// получава поръчка в момента,
// в който тя бъде приключена
}
func NewClient(name string) *Client
Създава нов клиент с подаденото име.
func (c *Client) Order(factory *Factory, words []string) string
Създава нова поръчка с думи, изпраща я на подадената фабрика и връща id
-то на поръчката.
func (c *Client) CheckStatus(id string) int
Проверява статуса на клиентска поръчка с подаденото id
.
Примери
factory := NewFactory(3)
factory.StorageAdd(map[string]uint16{
`..2`: 1,
`\w{3}`: 1,
`bam`: 2,
`che`: 1,
`(kop|bob|top)`: 1,
})
client := NewClient("Robcho")
client.Order(factory, []string{"kopche", "bobche", "topche"})