Михаил обнови решението на 06.11.2018 14:22 (преди 9 месеца)
+package main
+
+type Operation interface {
+        Do()
+}
+type Insert struct {
+        f        func(p uint, t string) *MyEditor
+        position uint
+        text     string
+}
+type Delete struct {
+        f      func(o, l uint) *MyEditor
+        offset uint
+        length uint
+}
+
+func (d Delete) Do() {
+        d.f(d.offset, d.length)
+}
+func (i Insert) Do() {
+        i.f(i.position, i.text)
+}
+
+type Editor interface {
+        Insert(position uint, text string) Editor
+
+        Delete(offset, length uint) Editor
+
+        Undo() Editor
+
+        Redo() Editor
+
+        String() string
+}
+
+type piece struct {
+        origin bool
+        offset uint
+        length uint
+}
+
+type MyEditor struct {
+        origin string
+        add    string
+        table  []piece
+        curLen int
+
+        undoes []Operation
+        redoes []Operation
+}
+
+type del func(uint, uint) *MyEditor
+
+func (m *MyEditor) String() string {
+        var str string
+        for _, pie := range m.table {
+                if pie.origin {
+                        str += m.origin[pie.offset:(pie.offset + pie.length)]
+                } else {
+                        str += m.add[pie.offset:(pie.offset + pie.length)]
+                }
+        }
+        return str
+}
+func (m *MyEditor) modifyLen(len int) {
+        m.curLen = m.curLen + len
+}
+
+func (m *MyEditor) Redo() MyEditor {
+        if m.redoes != nil && len(m.redoes) > 0 {
+
+        }
+
+        return *m
+}
+
+func (m *MyEditor) Undo() MyEditor {
+        if m.undoes != nil && len(m.undoes) > 0 {
+                last := m.undoes[len(m.undoes)-1]
+                last.Do()
+                //        add opposite to redo
+        }
+        return *m
+}
+
+func (m *MyEditor) Delete(offset, len uint) *MyEditor {
+        currentLen := uint(m.curLen)
+
+        if currentLen < offset {
+                return m
+        }
+
+        if offset+len >= currentLen {
+                len = currentLen - offset
+        }
+
+        pieIndex, residualOffset := m.pieIndexAndResidualOffset(offset)
+        lastPieIndex, lastResidualOffset := m.pieIndexAndResidualOffset(offset + len)
+
+        first := piece{
+                origin: m.table[pieIndex].origin,
+                offset: m.table[pieIndex].offset,
+                length: residualOffset,
+        }
+        second := piece{
+                origin: m.table[lastPieIndex].origin,
+                offset: m.table[lastPieIndex].offset + lastResidualOffset,
+                length: m.table[lastPieIndex].length - lastResidualOffset,
+        }
+
+        m.modifyLen(-int(len))
+        parts := []piece{first, second}
+
+        prefix := m.table[:pieIndex]
+        how := lastPieIndex - pieIndex + 1
+        suffix := m.table[pieIndex+how:]
+        whole := append(prefix, append(parts, suffix...)...)
+        m.table = whole
+
+        var i Insert = Insert{m.Insert, offset, ""}
+        m.undoes = append(m.undoes, i)
+
+        return m
+}
+
+func (m *MyEditor) Insert(position uint, text string) *MyEditor {
+        currentLen := uint(m.curLen)
+
+        if position > currentLen {
+                position = currentLen
+        }
+        addOffset := uint(len(m.add))
+        m.add += text
+
+        m.modifyLen(len(text))
+
+        pieIndex, residualOffset := m.pieIndexAndResidualOffset(position)
+        currentPiece := m.table[pieIndex]
+
+        first := piece{
+                origin: currentPiece.origin,
+                offset: currentPiece.offset,
+                length: residualOffset,
+        }
+        second := piece{
+                origin: false,
+                offset: addOffset,
+                length: uint(len(text)),
+        }
+        third := piece{
+                origin: currentPiece.origin,
+                offset: residualOffset,
+                length: currentPiece.length - residualOffset,
+        }
+
+        parts := []piece{first, second, third}
+        prefix := m.table[:pieIndex]
+        suffix := m.table[pieIndex+1:]
+        whole := append(prefix, append(parts, suffix...)...)
+        m.table = whole
+
+        var d Delete = Delete{m.Delete, position, uint(len(text))}
+        m.undoes = append(m.undoes, d)
+        return m
+}
+func (m *MyEditor) pieIndexAndResidualOffset(offset uint) (int, uint) {
+        residualOffset := offset
+
+        for index, pie := range m.table {
+                if residualOffset <= pie.length {
+                        return index, residualOffset
+                }
+                residualOffset = residualOffset - pie.length
+        }
+        return 0, 0 // todo return last element no just 0,0
+
+}
+
+func NewEditor(text string) *MyEditor {
+        myEditor := new(MyEditor)
+        myEditor.origin = text
+        myEditor.curLen = len(text)
+        table := []piece{{true, 0, uint(len(text))}}
+        myEditor.table = table
+
+        return myEditor
+}
Решението не е готово!! Качвам го просто ако не успея да го довърша.
