Втора задача

  1. Ако прочетеш внимателно условието ще видиш следния ред:

    Обърнете внимание на факта, че всеки един от методите връща редактор. Това все пак не означава, че е задължително да създавате нов редактор, който да връщате. Решението дали да го правите, или да мутирате текущия е ваше.

    Тоест и двата подхода са валидни. Но си прав, че примерните тестове приемат само единия от двата подхода. Ще ги редактирам за да работят и с другия. Тестовете, с които ще проверим решенията след крайния срок приемат и двата подхода.

  2. Ако прочетеш условието до край ще видиш следния текст:

    Операциите Insert и Delete очакват position, offset и length в байтове, а не в символи. Обърнете внимание на това при работа с unicode символи.

    Тоест от това може да си извлечеш извода, че unicode символи са съвсем очаквани.

  3. Здравейте,

    ОК ли е за структурата описваща едно парченце от таблицата да използваме uint за offset и length, вместо int, с цел да си спестим някои досадни кастове на определени места? Често се налага да се правят някакви сравнения с аргументите на функциите (както са дадени в условието) и парченцата от таблицата, и в тези ситуации понякога единия тип е int, a другия uint...

  4. @Николай (Лазаров) - undo и redo трябва да работят с всеки вход, бил той и празен. Тоест трябва да връщат добавянето на празен и да извършват на ново добавянето на празен стринг.

    @Николай (Матеев) - ползвай всичко, което искаш в твоите структури. Стига да имплементираш интерфейса Editor.

    @Михаил, дай повече информация. Кой дебъгер, какво правиш? По грешката мога да предположа, че използваш XCode. Но за съжаление не знам нищо за него и дали изобщо е интегриран с някой дебъгер, който разбира Go. Бих ти препоръчал да прочетеш документацията на XCode. Друг вариант е да опиташ направо delve.

    @Мартин - може такива коментари все пак да ги оставяш. Възможно е да има и други хора, които са се объркали като теб и ще им е полезно да разберат до какъв извод си стигнал.

  5. Относно Unicode нещата, все пак не разбрах кое е очакваното поведение (1 или 2?):

    1) При триенето на n байта, има опасност последните няколко да са част от символ съставен от повече от един байт. Има опасност да отрежем част от този символ (част от байтовете му), и останалото ще бъде маймунки (garbage). Подобна ситуация би било, ако се опитаме да вмъкнем някакви символи между байтовете на символ състоящ се от няколко байта.

    2) При триенето на n байта, да се взима предвид, че може последните няколко да са част от няколко-байтов символ и да се изтрият и оставащите байтове на този последен символ. Какво би означавало това в случай на вмъкване между байтовете не съм сигурен.


    Какви са резултатите:

    1) По-грозно, но пък отговаря на условието, защото в условието се говори постоянно за байтове, а не за runes:

    "Операциите Insert и Delete очакват position, offset и length в байтове, а не в символи."

    2) По-чист вариант, но не отговаря на условието.

    Та, 1) или 2)?

    П.С.: Задачката е мега готинка, евалата!

  6. Здравейте, Относно redo и undo. Само еднократно redo и undo ли се допускат, или трябва да позволим да се върщат повече стъпки назад, чрез многократно извикване на undo, които после с redo можем да изпълним обратно. Тоест:

    Пример:

    1.f.Insert(2, "baba")

    2.f.Insert(5, "Dqdo")

    3.f.Insert(1, "Kvot takoa")

    4.f.Delete(2, 4)

    5.f.Insert(5, "Го е велик!")

    6.f.Undo()

    7.f.Undo()

    8.f.Undo()

    Като резултатът да е все едно сме изпълнили само:

    => f.Insert(2, "baba") f.Insert(5, "Dqdo")

    , тоест сме върнали 3 промени назад.

    После извикваме:

    9.f.Redo()

    10.f.Redo()

    Като резултатът да е все едно сме изпълнили:

    => f.Insert(2, "baba") f.Insert(5, "Dqdo") f.Insert(1, "Kvot takoa") f.Delete(2, 4)

    , тоест сме извършили отново 2 от върнатите промени.

  7. @Николай, всички отмествания са в байтове, както пише в условието. Ако се замислиш как би се използвала тази структура в истински редактор ще видиш, че няма никакви проблеми с unicode. Когато курсора на редактора винаги ще е межу някои символи на текста и вмъкването няма да бъде между различни байтове на един символ. По същия начин, триенето ще е за цели символи и отново няма как да се изтрият само някои байтове от символ, който е останал. Естествено, с такава структура ти ръчно би могъл да счупиш unicode в нея. Редактор не би могъл.

    @Траян, ако прочетеш условието ще видиш следния текст, който вече коментирахме тук:

    Обърнете внимание на факта, че всеки един от методите връща редактор. Това все пак не означава, че е задължително да създавате нов редактор, който да връщате. Решението дали да го правите, или да мутирате текущия е ваше.

    Тоест и двата подхода са валидни.

    Ако направиш "мутиращ" редактор, който връща себе си, е напълно валидно .Undo() и .Redo() да работят "многократно". Даже е единственото възможно решение. Долу f е мутиращ редактор:

    f := NewEditor("David")
    f.Insert(5, " Bowie")
    f.Insert(11, " is great!")
    f.Undo()
    f.Undo()
    f.Redo()
    f.Redo()
    f.Delete(11, 10)
    f.Undo()
    f.String() // David Bowie is great!
    

    Но ако правиш непроменим (immutable) редактор, който връща нови редактори, то извикването на един метод ще ти връща един и същи резултат колкото и пъти да го викаш. Това е дефиницията на "непроменим". Пример:

    f := NewEditor(...)
    // operations with f
    x := f.Undo()
    y := f.Undo()
    x == y // true
    

    Не ми се искаше да влизам в толкова подробности на този въпрос, но го приемете като бонус :D Мисля, че условието е достатъчно ясно.

  8. Здравейте,

    Опитвам се да предам решение и получавам отговор: синтактична грешка. Тъй като кодът ми се компилира и изпълнява при мен очевидно нямам синтактична грешка. Това проблем на системата ли е?

  9. @Георги и аз имах подобен проблем с предишното домашно, оказа се, че бях включил библиотека, която не използвах.

    Сега пак имам същия проблем, но този път не е от библиотеки.

  10. @Христо, провери дали си добавил интерфейса Editor като част от решението си. Проверката за синтактична грешка е go build code.go 2>&1, изпълнено с go1.11.1. Можеш да я видиш тук. За да я пробваш сам, погрижи се файла code.go да е единствения в директорията и да не използва библиотеки, различни от стандартната.

  11. @Doychin Да, добавил съм го. Когато спрямо изискванията премахна main функцията, но оставя main пакета, "go build code.go 2>&1" ми връща грешка, че трябва да има main функция в main пакета. Ако махна main пакета, иска файлът все пак да е в някакъв пакет(т. е. командата пак връща грешка). Единственият вариант е да има както main пакет, така и main функция, но това противоречи на условието да няма main функция.

    Пробвам да предам файл, който е в пакет main. Използва библиотеките "bytes" и "syscall"- това стандартни библиотеки ли са? Под този import е копиран интерфейса Editor от условието на задачата. Последван е от моя клас с предефинирани методи от Editor. След това е и main функцията. Файлът е сам в папката при build чрез bash.

    При мен се компилира( използвам IDE-то на JetBrains- GoLand, би трябвало да е най- новото, но едва ли е от значение, щом "go build code.go 2>&1" връща същия резултат). Версията на Go ми е go1.11.1. При предаване в заданието не се компилира.

    Изпращам ви кода си на e-mail-a ви във формата на архив. Може би аз съм слабоумен, ддз.

  12. @Хросто, разгледах домашното ти. Проблема ти е, че използваш syscall.INFINITE, която в случая не е дефинирана. Явно я има за твоята операционна система, но определено не е portable код, който можеш да очакваш да работи някъде другаде. С това има няколко проблема.

    Най - големия е, че със сигурност няма причина да правиш syscalls в твоя редактор. Виждам, че си се надявал това да е променлива за "безкрайност". Това може и да е вярно, но само в контекста на някои syscalls за някоя операционна система. Не е генерална концепция за "безкрайност", която можеш да използваш в който и да е друг контекст. Ако се загледаш, в пакета math има константи за maxu?int(8|16|32|64), които ще работят на всякаква операционна система. Няма нужда да намесваш syscalls.

    Второто е, че ако се зачетеш в документацията на пакета можеш да видиш следното:

    Package syscall contains an interface to the low-level operating system primitives. The details vary depending on the underlying system. [...] The primary use of syscall is inside other packages that provide a more portable interface to the system, such as "os", "time" and "net". Use those packages rather than this one if you can.

    Както и малко по - късно:

    Deprecated: this package is locked down.

    От това може да се предположи, че дори да имаше причина да правиш неща с операционната система, то този пакет почти със сигурност не е добър избор.

Трябва да сте влезли в системата, за да може да отговаряте на теми.