Михаил обнови решението на 06.12.2015 14:48 (преди над 2 години)
+package solution
+
+import (
+        "encoding/json"
+        "encoding/xml"
+        "errors"
+        "fmt"
+        "sync"
+)
+
+type Library interface {
+        AddBookJSON(data []byte) (int, error)
+
+        AddBookXML(data []byte) (int, error)
+
+        Hello() (chan<- LibraryRequest, <-chan LibraryResponse)
+}
+
+type LibraryRequest interface {
+        GetType() int
+
+        GetISBN() string
+}
+
+type LibraryResponse interface {
+        GetBook() (fmt.Stringer, error)
+
+        GetAvailability() (available int, registered int)
+}
+
+type Librarian struct {
+        input  chan LibraryRequest
+        output chan LibraryResponse
+}
+
+func (l *Librarian) Animate(library *LibraryOfAlexandria, librarians chan Librarian) {
+        go func() {
+                for request := range l.input {
+                        isbn := request.GetISBN()
+
+                        response := new(Response)
+                        switch request.GetType() {
+                        case 1: // Borrow
+                                if book, ok := library.Books[isbn]; !ok {
+                                        response.Err = errors.New("Непозната книга " + isbn)
+                                } else if book.Available < 1 {
+                                        response.Err = errors.New("Няма наличност на книга " + isbn)
+                                } else {
+                                        book.Available -= 1
+                                }
+                        case 2: // Return
+                                if book, ok := library.Books[isbn]; !ok {
+                                        response.Err = errors.New("Непозната книга " + isbn)
+                                } else if book.Available >= 4 {
+                                        response.Err = errors.New("Всички копия са налични " + isbn)
+                                } else {
+                                        book.Available += 1
+                                }
+                        case 3: // Availability
+                                if book, ok := library.Books[isbn]; !ok {
+                                        response.Err = errors.New("Непозната книга " + isbn)
+                                } else if book.Available >= 4 {
+                                        response.Err = errors.New("Всички копия са налични " + isbn)
+                                }
+                        }
+
+                        if book, ok := library.Books[isbn]; ok {
+                                response.Book = book.Book
+                                response.Available = book.Available
+                                response.All = book.All
+                        } else {
+                                response.All = 0
+                                response.Available = 0
+                        }
+
+                        l.output <- response
+                }
+
+                l.input = make(chan LibraryRequest)
+                librarians <- *l
+        }()
+}
+
+type BookCopies struct {
+        Book
+        Available, All int
+}
+
+type LibraryOfAlexandria struct {
+        Books      map[string]*BookCopies
+        booksLock  sync.Mutex
+        librarians chan Librarian
+}
+
+func (lib LibraryOfAlexandria) AddBookJSON(data []byte) (int, error) {
+        var book Book
+        if err := json.Unmarshal(data, &book); err != nil {
+                return 0, err
+        }
+
+        return lib.addBook(book)
+}
+
+func (lib LibraryOfAlexandria) AddBookXML(data []byte) (int, error) {
+        var book Book
+        if err := xml.Unmarshal(data, &book); err != nil {
+                return 0, err
+        }
+
+        return lib.addBook(book)
+}
+
+func (lib *LibraryOfAlexandria) addBook(book Book) (int, error) {
+        lib.booksLock.Lock()
+
+        if lib.Books[book.ISBN] == nil {
+                lib.Books[book.ISBN] = new(BookCopies)
+                lib.Books[book.ISBN].Book = book
+        } else if lib.Books[book.ISBN].All >= 4 {
+                return 0, errors.New("Има 4 копия на книга " + book.ISBN)
+        }
+
+        lib.Books[book.ISBN].Available += 1
+        lib.Books[book.ISBN].All += 1
+
+        lib.booksLock.Unlock()
+
+        return lib.Books[book.ISBN].All, nil
+}
+
+func (lib LibraryOfAlexandria) Hello() (chan<- LibraryRequest, <-chan LibraryResponse) {
+        var librarian Librarian
+        var ok bool
+        // try take from the pool until we get a librarian
+        for librarian, ok = <-lib.librarians; !ok; {
+        }
+
+        return librarian.input, librarian.output
+}
+
+type Request struct {
+        RequestType int
+        Book
+}
+
+func (req Request) GetType() int {
+        return req.RequestType
+}
+
+func (req Request) GetISBN() string {
+        return req.ISBN
+}
+
+type Response struct {
+        Book
+        Err            error
+        Available, All int
+}
+
+func (res *Response) GetBook() (fmt.Stringer, error) {
+        return res.Book, res.Err
+}
+
+func (res *Response) GetAvailability() (available int, registered int) {
+        return res.Available, res.All
+}
+
+type Author struct {
+        FirstName string `json:"first_name" xml:"author>first_name"`
+        LastName  string `json:"last_name" xml:"author>last_name"`
+}
+
+type Book struct {
+        ISBN    string `xml:"isbn,attr"`
+        Title   string `xml:"title"`
+        Author  `json:"author"`
+        Ratings []int
+}
+
+func (b Book) String() string {
+        return fmt.Sprintf("[%s] %s от %s %s", b.ISBN, b.Title, b.Author.FirstName, b.Author.LastName)
+}
+
+func NewLibrary(librarians int) LibraryOfAlexandria {
+        library := &LibraryOfAlexandria{Books: make(map[string]*BookCopies), librarians: make(chan Librarian, librarians)}
+
+        for i := 0; i < librarians; i++ {
+                librarian := &Librarian{input: make(chan LibraryRequest), output: make(chan LibraryResponse)}
+                library.librarians <- *librarian
+                librarian.Animate(library, library.librarians)
+        }
+
+        return *library
+}
пакета ти трябва да е main не solution
