Решение на Piece table от Мартин Врачев

Обратно към всички решения

Към профила на Мартин Врачев

Резултати

  • 3 точки от тестове
  • 0 бонус точки
  • 3 точки общо
  • 2 успешни тест(а)
  • 6 неуспешни тест(а)

Код

package main
import (
"fmt"
)
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 Piece struct {
origin bool // Does the piece belongs to the origin slice
offset int // The start of the piece
length int // The length of the piece
}
type Table struct {
rows []Piece
origin string // the original content of the file
add string // the new words in the file
}
type SimpleEditor struct {
table Table
functions []Function
}
func newPiece(isOrigin bool, offset, length int) Piece {
return Piece{origin: isOrigin, offset: offset, length: length}
}
func (s *SimpleEditor) newRow(piece Piece) {
s.table.rows = append(s.table.rows, piece)
}
func NewEditor(origin string) Editor {
var piece Piece = newPiece(true, 0, len(origin))
var editor SimpleEditor
editor.newRow(piece)
editor.table.origin = origin
return &editor
}
// Find the index of the row in the table where the position belongs
func findPosRowIndex(position int, rows []Piece) int {
if len(rows) <= 0 {
return -100
}
var currEnd int
resultIndex := -1
for index, piece := range rows {
currEnd += piece.length
fmt.Println("The currEnd + pieceLenght are: ", currEnd)
if position < currEnd {
resultIndex = index
break
}
}
return resultIndex
}
// ------------------------- Insertion -------------------------
func (s *SimpleEditor) addElementAtIndex(index int, elem Piece) {
rightPart := make([]Piece, len(s.table.rows[:index]))
leftPart := make([]Piece, len(s.table.rows[index:]))
copy(rightPart, s.table.rows[:index])
copy(leftPart, s.table.rows[index:])
if len(rightPart) == 0 {
//fmt.Println("Add here the elem: ", elem)
tempSlice := []Piece{elem}
s.table.rows = append(tempSlice, s.table.rows...)
} else {
rightPart = append(rightPart, elem)
s.table.rows = append(rightPart, leftPart...)
}
//fmt.Println("Print the rows in addElement in index function: ", s.table.rows)
}
func (s *SimpleEditor) addAtEnd(text string) {
elem := newPiece(false, len(s.table.add), len(text))
s.table.add += text
s.table.rows = append(s.table.rows, elem)
}
func (s *SimpleEditor) addAtBegin(text string) {
newRow := newPiece(false, len(s.table.add), len(text))
tempSlice := []Piece{newRow}
s.table.rows = append(tempSlice, s.table.rows...)
}
func (s *SimpleEditor) insertInMiddle(position, rowIndex int, text string) {
var isOriginCurrent bool = s.table.rows[rowIndex].origin
var currRowLength = s.table.rows[rowIndex].length
s.table.rows[rowIndex].length = position
//fmt.Println("Before adding: ", s.table.rows)
newAddRow := newPiece(false, len(s.table.add), len(text))
s.table.add += text
s.addElementAtIndex(rowIndex+1, newAddRow)
//fmt.Println("After adding the first element: ", s.table.rows)
var newOffset = s.table.rows[rowIndex].length
newSplitedRow := newPiece(isOriginCurrent, newOffset, currRowLength-newOffset)
s.addElementAtIndex(rowIndex+2, newSplitedRow)
//fmt.Println("The slice in the end of Insert is: ", s.table.rows)
}
// Insert text starting from given position.
func (s *SimpleEditor) Insert(position uint, text string) Editor {
truePos := int(position)
rowIndex := findPosRowIndex(truePos, s.table.rows)
if rowIndex == -1 {
rowIndex = len(s.table.rows) + 1
}
//fmt.Println("The position is: ", rowIndex)
if rowIndex >= len(s.table.rows) {
s.addAtEnd(text)
s.table.add += text
fmt.Println("The slice in the end of Insert is: ", s.table.rows)
} else if truePos == 0 {
s.addAtBegin(text)
s.table.add += text
fmt.Println("The slice in the end of Insert is: ", s.table.rows)
} else {
s.insertInMiddle(truePos, rowIndex, text)
}
s.deleteRowsWithZeroLength()
return s
}
// ------------------------- Deletion -------------------------
func (s *SimpleEditor) deleteAtIndex(index int) {
if index+1 == len(s.table.rows) {
s.table.rows = s.table.rows[:index-1]
} else {
s.table.rows = append(s.table.rows[:index], s.table.rows[index+1:]...)
}
}
func (s *SimpleEditor) deleteRowsWithZeroLength() {
for index, piece := range s.table.rows {
if piece.length == 0 {
s.deleteAtIndex(index)
}
}
}
func (s *SimpleEditor) deleteRowsInBetween(delLength, begin, end int) int {
rightPart := make([]Piece, len(s.table.rows[:begin]))
leftPart := make([]Piece, len(s.table.rows[end:]))
copy(rightPart, s.table.rows[:begin])
copy(leftPart, s.table.rows[end:])
s.table.rows = append(rightPart, leftPart...)
return delLength
}
func (s *SimpleEditor) deleteInSameRow(trueOffset, trueLength, startIndex int) {
pastLength := s.table.rows[startIndex].length
s.table.rows[startIndex].length = trueOffset
isOrigin := s.table.rows[startIndex].origin
newOffset := trueOffset + trueLength
newLength := pastLength - (trueLength + s.table.rows[startIndex].length)
s.addElementAtIndex(startIndex+1, newPiece(isOrigin, newOffset, newLength))
}
func (s *SimpleEditor) Delete(offset, length uint) Editor {
trueOffset := int(offset)
trueLength := int(length)
starDelIndex := findPosRowIndex(trueOffset, s.table.rows)
endDelIndex := findPosRowIndex(trueLength+trueOffset, s.table.rows)
if starDelIndex == -1 {
return s
} else if endDelIndex == -1 {
s.deleteRowsInBetween(trueLength, starDelIndex, len(s.table.rows))
} else if starDelIndex == endDelIndex {
s.deleteInSameRow(trueOffset, trueLength, starDelIndex)
} else {
trueLength = s.deleteRowsInBetween(trueLength, starDelIndex, endDelIndex)
pastEndPos := s.table.rows[starDelIndex].offset + s.table.rows[starDelIndex].length
fmt.Println(pastEndPos)
// Here all redundant rows are removed
s.table.rows[starDelIndex].length -= trueLength
s.table.rows[starDelIndex].offset = pastEndPos - s.table.rows[starDelIndex].length
}
fmt.Println(s.table.rows)
s.deleteRowsWithZeroLength()
return s
}
// ------------------------- Undo -------------------------
type Function struct {
isInsert bool
offsetOrPos uint
textToAdd string
lengthToDel uint
}
func (s *SimpleEditor) newInsertFuncInStack(position uint, text string) {
var newFuncInsert Function = Function{isInsert: true, offsetOrPos: position, textToAdd: text}
s.functions = append(s.functions, newFuncInsert)
}
func (s *SimpleEditor) newDelFunction(offset, length uint) {
var newFuncDel Function = Function{isInsert: false, offsetOrPos: offset, lengthToDel: length}
s.functions = append(s.functions, newFuncDel)
}
func (s *SimpleEditor) Undo() Editor {
return s
}
func (s *SimpleEditor) Redo() Editor {
return s
}
// ------------------------- String -------------------------
// String returns complete representation of what a file looks
// like after all manipulations.
func (s *SimpleEditor) String() string {
var result string
fmt.Println("The editor rows are: ", s.table.rows)
fmt.Println("The origin array: ", s.table.origin)
fmt.Println("The add array: ", s.table.add)
for _, piece := range s.table.rows {
offsetIndex := piece.offset
length := piece.length
fmt.Println("Piece is: ", piece)
if piece.origin {
result += s.table.origin[offsetIndex : length+offsetIndex]
} else {
result += s.table.add[offsetIndex : length+offsetIndex]
}
}
return result
}

Лог от изпълнението

The currEnd + pieceLenght are:  20
The editor rows are:  [{true 0 16} {false 0 8} {true 16 4}]
The origin array:  A large span of text
The add array:  English 
Piece is:  {true 0 16}
Piece is:  {false 0 8}
Piece is:  {true 16 4}
The currEnd + pieceLenght are:  16
The currEnd + pieceLenght are:  16
[{true 0 2} {true 8 8} {false 0 8} {true 16 4}]
The editor rows are:  [{true 0 2} {true 8 8} {false 0 8} {true 16 4}]
The origin array:  A large span of text
The add array:  English 
Piece is:  {true 0 2}
Piece is:  {true 8 8}
Piece is:  {false 0 8}
Piece is:  {true 16 4}
The currEnd + pieceLenght are:  2
The currEnd + pieceLenght are:  10
The currEnd + pieceLenght are:  18
The currEnd + pieceLenght are:  2
The currEnd + pieceLenght are:  10
The currEnd + pieceLenght are:  18
The currEnd + pieceLenght are:  22
20
[{true 0 2} {true 8 8} {true 24 -4}]
The editor rows are:  [{true 0 2} {true 8 8} {true 24 -4}]
The origin array:  A large span of text
The add array:  English 
Piece is:  {true 0 2}
Piece is:  {true 8 8}
Piece is:  {true 24 -4}
--- FAIL: TestExampleFromReadme (0.00s)
panic: runtime error: slice bounds out of range [recovered]
	panic: runtime error: slice bounds out of range

goroutine 6 [running]:
testing.tRunner.func1(0xc0000b2100)
	/usr/local/go/src/testing/testing.go:792 +0x387
panic(0x513280, 0x61bff0)
	/usr/local/go/src/runtime/panic.go:513 +0x1b9
_/tmp/d20181107-53-1hanix5.(*SimpleEditor).String(0xc00009a0a0, 0xa, 0x8)
	/tmp/d20181107-53-1hanix5/solution.go:266 +0x41d
_/tmp/d20181107-53-1hanix5.TestExampleFromReadme(0xc0000b2100)
	/tmp/d20181107-53-1hanix5/solution_test.go:15 +0x1cd
testing.tRunner(0xc0000b2100, 0x540f48)
	/usr/local/go/src/testing/testing.go:827 +0xbf
created by testing.(*T).Run
	/usr/local/go/src/testing/testing.go:878 +0x353
exit status 2
FAIL	_/tmp/d20181107-53-1hanix5	0.004s
The editor rows are:  [{true 0 14}]
The origin array:  A span of text
The add array:  
Piece is:  {true 0 14}
The currEnd + pieceLenght are:  14
The slice in the end of Insert is:  [{true 0 14} {false 0 1}]
The editor rows are:  [{true 0 14} {false 0 1}]
The origin array:  A span of text
The add array:  !!
Piece is:  {true 0 14}
Piece is:  {false 0 1}
The editor rows are:  [{true 0 14} {false 0 1}]
The origin array:  A span of text
The add array:  !!
Piece is:  {true 0 14}
Piece is:  {false 0 1}
The currEnd + pieceLenght are:  14
The currEnd + pieceLenght are:  15
The currEnd + pieceLenght are:  14
The currEnd + pieceLenght are:  15
The editor rows are:  [{true 0 14} {false 0 1}]
The origin array:  A span of text
The add array:  !!
Piece is:  {true 0 14}
Piece is:  {false 0 1}
The currEnd + pieceLenght are:  14
The currEnd + pieceLenght are:  14
The currEnd + pieceLenght are:  15
[]
The editor rows are:  []
The origin array:  A span of text
The add array:  !!
--- FAIL: TestOutOfBound (0.00s)
    solution_test.go:75: Expect: "A span of"; got ""
FAIL
exit status 1
FAIL	_/tmp/d20181107-53-1hanix5	0.002s
The editor rows are:  [{true 0 20}]
The origin array:  A large span of text
The add array:  
Piece is:  {true 0 20}
The editor rows are:  [{true 0 20}]
The origin array:  A large span of text
The add array:  
Piece is:  {true 0 20}
The currEnd + pieceLenght are:  20
The editor rows are:  [{true 0 16} {false 0 8} {true 16 4}]
The origin array:  A large span of text
The add array:  English 
Piece is:  {true 0 16}
Piece is:  {false 0 8}
Piece is:  {true 16 4}
The currEnd + pieceLenght are:  16
The currEnd + pieceLenght are:  16
[{true 0 2} {true 8 8} {false 0 8} {true 16 4}]
The editor rows are:  [{true 0 2} {true 8 8} {false 0 8} {true 16 4}]
The origin array:  A large span of text
The add array:  English 
Piece is:  {true 0 2}
Piece is:  {true 8 8}
Piece is:  {false 0 8}
Piece is:  {true 16 4}
--- FAIL: TestUndo (0.00s)
    solution_test.go:75: Expect: "A large span of English text"; got "A span of English text"
FAIL
exit status 1
FAIL	_/tmp/d20181107-53-1hanix5	0.002s
The currEnd + pieceLenght are:  20
The currEnd + pieceLenght are:  16
The currEnd + pieceLenght are:  16
[{true 0 2} {true 8 8} {false 0 8} {true 16 4}]
The currEnd + pieceLenght are:  2
The currEnd + pieceLenght are:  10
The currEnd + pieceLenght are:  18
The currEnd + pieceLenght are:  2
The currEnd + pieceLenght are:  10
The currEnd + pieceLenght are:  18
The currEnd + pieceLenght are:  22
20
[{true 0 2} {true 8 8} {true 24 -4}]
The editor rows are:  [{true 0 2} {true 8 8} {true 24 -4}]
The origin array:  A large span of text
The add array:  English 
Piece is:  {true 0 2}
Piece is:  {true 8 8}
Piece is:  {true 24 -4}
--- FAIL: TestSeveralUndos (0.00s)
panic: runtime error: slice bounds out of range [recovered]
	panic: runtime error: slice bounds out of range

goroutine 5 [running]:
testing.tRunner.func1(0xc0000c0100)
	/usr/local/go/src/testing/testing.go:792 +0x387
panic(0x513280, 0x61bff0)
	/usr/local/go/src/runtime/panic.go:513 +0x1b9
_/tmp/d20181107-53-1hanix5.(*SimpleEditor).String(0xc0000aa0a0, 0xa, 0x8)
	/tmp/d20181107-53-1hanix5/solution.go:266 +0x41d
_/tmp/d20181107-53-1hanix5.TestSeveralUndos(0xc0000c0100)
	/tmp/d20181107-53-1hanix5/solution_test.go:39 +0x12d
testing.tRunner(0xc0000c0100, 0x540f70)
	/usr/local/go/src/testing/testing.go:827 +0xbf
created by testing.(*T).Run
	/usr/local/go/src/testing/testing.go:878 +0x353
exit status 2
FAIL	_/tmp/d20181107-53-1hanix5	0.004s
The currEnd + pieceLenght are:  20
The currEnd + pieceLenght are:  16
The currEnd + pieceLenght are:  16
[{true 0 2} {true 8 8} {false 0 8} {true 16 4}]
The editor rows are:  [{true 0 2} {true 8 8} {false 0 8} {true 16 4}]
The origin array:  A large span of text
The add array:  English 
Piece is:  {true 0 2}
Piece is:  {true 8 8}
Piece is:  {false 0 8}
Piece is:  {true 16 4}
The editor rows are:  [{true 0 2} {true 8 8} {false 0 8} {true 16 4}]
The origin array:  A large span of text
The add array:  English 
Piece is:  {true 0 2}
Piece is:  {true 8 8}
Piece is:  {false 0 8}
Piece is:  {true 16 4}
PASS
ok  	_/tmp/d20181107-53-1hanix5	0.002s
The currEnd + pieceLenght are:  20
The currEnd + pieceLenght are:  16
The currEnd + pieceLenght are:  16
[{true 0 2} {true 8 8} {false 0 8} {true 16 4}]
The currEnd + pieceLenght are:  2
The currEnd + pieceLenght are:  10
The currEnd + pieceLenght are:  18
The currEnd + pieceLenght are:  2
The currEnd + pieceLenght are:  10
The currEnd + pieceLenght are:  18
The currEnd + pieceLenght are:  22
20
[{true 0 2} {true 8 8} {true 24 -4}]
The editor rows are:  [{true 0 2} {true 8 8} {true 24 -4}]
The origin array:  A large span of text
The add array:  English 
Piece is:  {true 0 2}
Piece is:  {true 8 8}
Piece is:  {true 24 -4}
--- FAIL: TestSeveralRedos (0.00s)
panic: runtime error: slice bounds out of range [recovered]
	panic: runtime error: slice bounds out of range

goroutine 6 [running]:
testing.tRunner.func1(0xc0000b0100)
	/usr/local/go/src/testing/testing.go:792 +0x387
panic(0x513280, 0x61bff0)
	/usr/local/go/src/runtime/panic.go:513 +0x1b9
_/tmp/d20181107-53-1hanix5.(*SimpleEditor).String(0xc00009a0a0, 0x556f20, 0xc00009a0a0)
	/tmp/d20181107-53-1hanix5/solution.go:266 +0x41d
_/tmp/d20181107-53-1hanix5.TestSeveralRedos(0xc0000b0100)
	/tmp/d20181107-53-1hanix5/solution_test.go:55 +0x169
testing.tRunner(0xc0000b0100, 0x540f68)
	/usr/local/go/src/testing/testing.go:827 +0xbf
created by testing.(*T).Run
	/usr/local/go/src/testing/testing.go:878 +0x353
exit status 2
FAIL	_/tmp/d20181107-53-1hanix5	0.004s
The currEnd + pieceLenght are:  20
The currEnd + pieceLenght are:  16
The currEnd + pieceLenght are:  16
[{true 0 0} {true 2 14} {false 0 8} {true 16 4}]
The editor rows are:  [{true 2 14} {false 0 8} {true 16 4}]
The origin array:  A large span of text
The add array:  English 
Piece is:  {true 2 14}
Piece is:  {false 0 8}
Piece is:  {true 16 4}
The editor rows are:  [{true 2 14} {false 0 8} {true 16 4}]
The origin array:  A large span of text
The add array:  English 
Piece is:  {true 2 14}
Piece is:  {false 0 8}
Piece is:  {true 16 4}
PASS
ok  	_/tmp/d20181107-53-1hanix5	0.002s
The currEnd + pieceLenght are:  88
The currEnd + pieceLenght are:  88
[{true 0 49} {true 52 36}]
The currEnd + pieceLenght are:  49
The currEnd + pieceLenght are:  85
The editor rows are:  [{true 0 49} {true 52 49} {false 0 41} {true 49 -13}]
The origin array:  Жълтата дюля беше щастлива и замръзна като гьон.
The add array:  , че пухът, който цъфна,
Piece is:  {true 0 49}
Piece is:  {true 52 49}
--- FAIL: TestUnicode (0.00s)
panic: runtime error: slice bounds out of range [recovered]
	panic: runtime error: slice bounds out of range

goroutine 5 [running]:
testing.tRunner.func1(0xc0000c0100)
	/usr/local/go/src/testing/testing.go:792 +0x387
panic(0x513280, 0x61bff0)
	/usr/local/go/src/runtime/panic.go:513 +0x1b9
_/tmp/d20181107-53-1hanix5.(*SimpleEditor).String(0xc0000aa0a0, 0x31, 0x53f209)
	/tmp/d20181107-53-1hanix5/solution.go:266 +0x41d
_/tmp/d20181107-53-1hanix5.TestUnicode(0xc0000c0100)
	/tmp/d20181107-53-1hanix5/solution_test.go:70 +0xfd
testing.tRunner(0xc0000c0100, 0x540f80)
	/usr/local/go/src/testing/testing.go:827 +0xbf
created by testing.(*T).Run
	/usr/local/go/src/testing/testing.go:878 +0x353
exit status 2
FAIL	_/tmp/d20181107-53-1hanix5	0.004s

История (1 версия и 0 коментара)

Мартин обнови решението на 07.11.2018 15:22 (преди 9 месеца)

+package main
+
+import (
+ "fmt"
+)
+
+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 Piece struct {
+ origin bool // Does the piece belongs to the origin slice
+ offset int // The start of the piece
+ length int // The length of the piece
+}
+
+type Table struct {
+ rows []Piece
+ origin string // the original content of the file
+ add string // the new words in the file
+}
+
+type SimpleEditor struct {
+ table Table
+ functions []Function
+}
+
+func newPiece(isOrigin bool, offset, length int) Piece {
+ return Piece{origin: isOrigin, offset: offset, length: length}
+}
+
+func (s *SimpleEditor) newRow(piece Piece) {
+
+ s.table.rows = append(s.table.rows, piece)
+}
+
+func NewEditor(origin string) Editor {
+
+ var piece Piece = newPiece(true, 0, len(origin))
+ var editor SimpleEditor
+
+ editor.newRow(piece)
+ editor.table.origin = origin
+
+ return &editor
+}
+
+// Find the index of the row in the table where the position belongs
+func findPosRowIndex(position int, rows []Piece) int {
+
+ if len(rows) <= 0 {
+ return -100
+ }
+ var currEnd int
+ resultIndex := -1
+ for index, piece := range rows {
+
+ currEnd += piece.length
+ fmt.Println("The currEnd + pieceLenght are: ", currEnd)
+ if position < currEnd {
+ resultIndex = index
+ break
+ }
+ }
+ return resultIndex
+}
+
+// ------------------------- Insertion -------------------------
+
+func (s *SimpleEditor) addElementAtIndex(index int, elem Piece) {
+ rightPart := make([]Piece, len(s.table.rows[:index]))
+ leftPart := make([]Piece, len(s.table.rows[index:]))
+ copy(rightPart, s.table.rows[:index])
+ copy(leftPart, s.table.rows[index:])
+ if len(rightPart) == 0 {
+ //fmt.Println("Add here the elem: ", elem)
+ tempSlice := []Piece{elem}
+ s.table.rows = append(tempSlice, s.table.rows...)
+ } else {
+ rightPart = append(rightPart, elem)
+ s.table.rows = append(rightPart, leftPart...)
+ }
+ //fmt.Println("Print the rows in addElement in index function: ", s.table.rows)
+}
+
+func (s *SimpleEditor) addAtEnd(text string) {
+ elem := newPiece(false, len(s.table.add), len(text))
+ s.table.add += text
+ s.table.rows = append(s.table.rows, elem)
+}
+
+func (s *SimpleEditor) addAtBegin(text string) {
+ newRow := newPiece(false, len(s.table.add), len(text))
+ tempSlice := []Piece{newRow}
+ s.table.rows = append(tempSlice, s.table.rows...)
+}
+
+func (s *SimpleEditor) insertInMiddle(position, rowIndex int, text string) {
+
+ var isOriginCurrent bool = s.table.rows[rowIndex].origin
+ var currRowLength = s.table.rows[rowIndex].length
+ s.table.rows[rowIndex].length = position
+
+ //fmt.Println("Before adding: ", s.table.rows)
+ newAddRow := newPiece(false, len(s.table.add), len(text))
+ s.table.add += text
+ s.addElementAtIndex(rowIndex+1, newAddRow)
+
+ //fmt.Println("After adding the first element: ", s.table.rows)
+ var newOffset = s.table.rows[rowIndex].length
+ newSplitedRow := newPiece(isOriginCurrent, newOffset, currRowLength-newOffset)
+ s.addElementAtIndex(rowIndex+2, newSplitedRow)
+
+ //fmt.Println("The slice in the end of Insert is: ", s.table.rows)
+}
+
+// Insert text starting from given position.
+func (s *SimpleEditor) Insert(position uint, text string) Editor {
+
+ truePos := int(position)
+ rowIndex := findPosRowIndex(truePos, s.table.rows)
+ if rowIndex == -1 {
+ rowIndex = len(s.table.rows) + 1
+ }
+ //fmt.Println("The position is: ", rowIndex)
+ if rowIndex >= len(s.table.rows) {
+
+ s.addAtEnd(text)
+ s.table.add += text
+ fmt.Println("The slice in the end of Insert is: ", s.table.rows)
+ } else if truePos == 0 {
+
+ s.addAtBegin(text)
+ s.table.add += text
+ fmt.Println("The slice in the end of Insert is: ", s.table.rows)
+ } else {
+ s.insertInMiddle(truePos, rowIndex, text)
+ }
+ s.deleteRowsWithZeroLength()
+ return s
+}
+
+// ------------------------- Deletion -------------------------
+
+func (s *SimpleEditor) deleteAtIndex(index int) {
+ if index+1 == len(s.table.rows) {
+ s.table.rows = s.table.rows[:index-1]
+ } else {
+ s.table.rows = append(s.table.rows[:index], s.table.rows[index+1:]...)
+ }
+}
+
+func (s *SimpleEditor) deleteRowsWithZeroLength() {
+
+ for index, piece := range s.table.rows {
+ if piece.length == 0 {
+ s.deleteAtIndex(index)
+ }
+ }
+}
+
+func (s *SimpleEditor) deleteRowsInBetween(delLength, begin, end int) int {
+
+ rightPart := make([]Piece, len(s.table.rows[:begin]))
+ leftPart := make([]Piece, len(s.table.rows[end:]))
+ copy(rightPart, s.table.rows[:begin])
+ copy(leftPart, s.table.rows[end:])
+ s.table.rows = append(rightPart, leftPart...)
+
+ return delLength
+}
+
+func (s *SimpleEditor) deleteInSameRow(trueOffset, trueLength, startIndex int) {
+ pastLength := s.table.rows[startIndex].length
+ s.table.rows[startIndex].length = trueOffset
+ isOrigin := s.table.rows[startIndex].origin
+ newOffset := trueOffset + trueLength
+ newLength := pastLength - (trueLength + s.table.rows[startIndex].length)
+ s.addElementAtIndex(startIndex+1, newPiece(isOrigin, newOffset, newLength))
+}
+
+func (s *SimpleEditor) Delete(offset, length uint) Editor {
+ trueOffset := int(offset)
+ trueLength := int(length)
+ starDelIndex := findPosRowIndex(trueOffset, s.table.rows)
+ endDelIndex := findPosRowIndex(trueLength+trueOffset, s.table.rows)
+
+ if starDelIndex == -1 {
+ return s
+ } else if endDelIndex == -1 {
+ s.deleteRowsInBetween(trueLength, starDelIndex, len(s.table.rows))
+
+ } else if starDelIndex == endDelIndex {
+ s.deleteInSameRow(trueOffset, trueLength, starDelIndex)
+ } else {
+ trueLength = s.deleteRowsInBetween(trueLength, starDelIndex, endDelIndex)
+ pastEndPos := s.table.rows[starDelIndex].offset + s.table.rows[starDelIndex].length
+ fmt.Println(pastEndPos)
+ // Here all redundant rows are removed
+ s.table.rows[starDelIndex].length -= trueLength
+ s.table.rows[starDelIndex].offset = pastEndPos - s.table.rows[starDelIndex].length
+ }
+ fmt.Println(s.table.rows)
+ s.deleteRowsWithZeroLength()
+ return s
+}
+
+// ------------------------- Undo -------------------------
+
+type Function struct {
+ isInsert bool
+ offsetOrPos uint
+ textToAdd string
+ lengthToDel uint
+}
+
+func (s *SimpleEditor) newInsertFuncInStack(position uint, text string) {
+ var newFuncInsert Function = Function{isInsert: true, offsetOrPos: position, textToAdd: text}
+ s.functions = append(s.functions, newFuncInsert)
+}
+
+func (s *SimpleEditor) newDelFunction(offset, length uint) {
+ var newFuncDel Function = Function{isInsert: false, offsetOrPos: offset, lengthToDel: length}
+ s.functions = append(s.functions, newFuncDel)
+}
+
+func (s *SimpleEditor) Undo() Editor {
+
+ return s
+}
+
+func (s *SimpleEditor) Redo() Editor {
+
+ return s
+}
+
+// ------------------------- String -------------------------
+
+// String returns complete representation of what a file looks
+// like after all manipulations.
+func (s *SimpleEditor) String() string {
+
+ var result string
+ fmt.Println("The editor rows are: ", s.table.rows)
+ fmt.Println("The origin array: ", s.table.origin)
+ fmt.Println("The add array: ", s.table.add)
+ for _, piece := range s.table.rows {
+ offsetIndex := piece.offset
+ length := piece.length
+ fmt.Println("Piece is: ", piece)
+ if piece.origin {
+ result += s.table.origin[offsetIndex : length+offsetIndex]
+ } else {
+ result += s.table.add[offsetIndex : length+offsetIndex]
+ }
+ }
+ return result
+}