Йоан обнови решението на 05.11.2018 00:33 (преди 9 месеца)
+package main
+
+type Editor interface {
+        // Insert text starting from given position.
+        Insert(position uint, text string) Editor
+
+        // Delete length items from offset.
+        Delete(offset, length uint) Editor
+
+        // Undo reverts latest change.
+        Undo() Editor
+
+        // Redo re-applies latest undone change.
+        Redo() Editor
+
+        // String returns complete representation of what a file looks
+        // like after all manipulations.
+        String() string
+}
+
+type MyEditor struct {
+        pieceTable   []piece
+        originBuffer string
+        addBuffer    string
+        text         string
+}
+
+type piece struct {
+        origin bool
+        offset int
+        length int
+}
+
+// Insert text starting from given position.
+func (e *MyEditor) Insert(position uint, text string) Editor {
+        if position > uint(len(e.text)) {
+                position = uint(len(e.text))
+        }
+        e.text = e.text[:position] + text + e.text[position:]
+        //makeTable(e)
+        var p []piece
+        copy(e.pieceTable, p)
+        for i := 0; i < len(e.pieceTable); i++ {
+                if int(position) > /*=*/ e.pieceTable[i].offset && int(position) < e.pieceTable[i].offset+e.pieceTable[i].length {
+                        p1 := piece{origin: e.pieceTable[i].origin, offset: e.pieceTable[i].offset, length: int(position) - e.pieceTable[i].offset}
+                        p2 := piece{origin: false, offset: len(e.addBuffer), length: len(text)}
+                        p3 := piece{origin: e.pieceTable[i].origin, offset: int(position),
+                                length: e.pieceTable[i].offset + e.pieceTable[i].length - int(position)}
+                        p = append(p, p1, p2, p3)
+                        e.addBuffer += text
+                } else {
+                        p = append(p, e.pieceTable[i])
+                }
+        }
+        e.pieceTable = p
+        return e
+}
+
+// Delete length items from offset.
+func (e *MyEditor) Delete(offset, length uint) Editor {
+        if offset < uint(len(e.text)) {
+                if offset+length >= uint(len(e.text)) {
+                        e.text = e.text[:offset]
+                } else {
+                        e.text = e.text[:offset] + e.text[offset+length:]
+                }
+        }
+        var p []piece
+        copy(e.pieceTable, p)
+        for i := 0; i < len(e.pieceTable); i++ {
+                if e.pieceTable[i].offset < int(offset) && e.pieceTable[i].offset+e.pieceTable[i].length > int(offset)+int(length) {
+                        p1 := piece{origin: e.pieceTable[i].origin, offset: e.pieceTable[i].offset, length: int(offset) - e.pieceTable[i].offset}
+                        p2 := piece{origin: e.pieceTable[i].origin, offset: e.pieceTable[i].offset + p1.length + int(length), length: e.pieceTable[i].length - p1.length - int(length)}
+                        p = append(p, p1, p2)
+                } else {
+                        p = append(p, e.pieceTable[i])
+                }
+        }
+        e.pieceTable = p
+        return e
+}
+
+// Undo reverts latest change.
+func (e *MyEditor) Undo() Editor {
+        return e
+}
+
+// Redo re-applies latest undone change.
+func (e *MyEditor) Redo() Editor {
+        return e
+}
+
+// String returns complete representation of what a file looks
+// like after all manipulations.
+func (e *MyEditor) String() string {
+        return e.text
+}
+
+func (e *MyEditor) originString() string {
+        return e.originBuffer
+}
+
+func (e *MyEditor) addString() string {
+        return e.addBuffer
+}
+
+func NewEditor(str string) Editor {
+        e := new(MyEditor)
+        e.originBuffer = str
+        e.text = str
+        p := piece{origin: true, length: len(str)}
+        e.pieceTable = make([]piece, 0)
+        e.pieceTable = append(e.pieceTable, p)
+        return e
+}
