Решение на Piece table от Траян Троев

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

Към профила на Траян Троев

Резултати

  • 9 точки от тестове
  • 0 бонус точки
  • 9 точки общо
  • 7 успешни тест(а)
  • 1 неуспешни тест(а)

Код

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 pieceTable struct {
origin bool
offset int
length int
}
type transition struct {
from []pieceTable
to []pieceTable
}
type editorImplementation struct {
origin string
add string
pceTbl []pieceTable
textLenght uint
transitionsBackward []transition
transitionsForward []transition
}
func (editor editorImplementation) Insert(position uint, text string) Editor {
if position > editor.textLenght {
position = editor.textLenght
}
editor.transitionsForward = []transition{}
editor.textLenght += uint(len(text))
idx := 0
pieceOffset := position
for idx = 0; idx < len(editor.pceTbl) && pieceOffset >= uint(editor.pceTbl[idx].length); idx++ {
pieceOffset -= uint(editor.pceTbl[idx].length)
}
if pieceOffset == 0 {
var oldPieces []pieceTable
newPiece := pieceTable{false, len(editor.add), len(text)}
editor.pceTbl = append(editor.pceTbl, newPiece)
copy(editor.pceTbl[idx+1:], editor.pceTbl[idx:len(editor.pceTbl)])
editor.pceTbl[idx] = newPiece
newPieces := append([]pieceTable{}, newPiece)
oldPieces = []pieceTable{pieceTable{false, idx, -1}}
editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
} else {
oldPieces := append([]pieceTable{}, editor.pceTbl[idx])
firstPieceOfDividedElement := pieceTable{editor.pceTbl[idx].origin,
editor.pceTbl[idx].offset, int(pieceOffset)}
newGluePiece := pieceTable{false, len(editor.add), len(text)}
secondPieceOfDividedElement := pieceTable{editor.pceTbl[idx].origin,
editor.pceTbl[idx].offset + int(pieceOffset),
editor.pceTbl[idx].length - int(pieceOffset)}
newPieces := append([]pieceTable{}, firstPieceOfDividedElement, newGluePiece, secondPieceOfDividedElement)
editor.pceTbl = append(editor.pceTbl, firstPieceOfDividedElement, secondPieceOfDividedElement)
copy(editor.pceTbl[idx+3:], editor.pceTbl[idx+1:])
editor.pceTbl[idx] = firstPieceOfDividedElement
editor.pceTbl[idx+1] = newGluePiece
editor.pceTbl[idx+2] = secondPieceOfDividedElement
editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
}
editor.add += text
return editor
}
func (editor editorImplementation) Delete(offset, length uint) Editor {
if offset < editor.textLenght && length > 0 {
if offset+length > editor.textLenght {
length = editor.textLenght - offset
}
editor.textLenght -= length
idx := 0
endIdx := 0
for idx = 0; idx < len(editor.pceTbl) && offset >= uint(editor.pceTbl[idx].length); idx++ {
offset -= uint(editor.pceTbl[idx].length)
}
endIdx = idx
if length > uint(editor.pceTbl[idx].length)-offset {
length -= uint(editor.pceTbl[idx].length) - offset
for endIdx = idx + 1; endIdx < len(editor.pceTbl) && length >= uint(editor.pceTbl[endIdx].length); endIdx++ {
length -= uint(editor.pceTbl[endIdx].length)
}
}
if offset == 0 {
var oldPieces []pieceTable
if idx == 0 && endIdx > 0 {
oldPieces = append(oldPieces, editor.pceTbl[idx:endIdx]...)
} else if idx != 0 && endIdx != 0 {
oldPieces = append([]pieceTable{}, editor.pceTbl[idx-1:endIdx-1]...)
}
var newPieces []pieceTable
editor.pceTbl = append(editor.pceTbl[:idx], editor.pceTbl[endIdx:]...)
if len(editor.pceTbl) > idx {
oldPieces = append(oldPieces, editor.pceTbl[idx])
copy(editor.pceTbl[:], append(editor.pceTbl[:idx], editor.pceTbl[idx+1:]...))
editor.pceTbl = append(editor.pceTbl[:len(editor.pceTbl)-1])
newPieces = append([]pieceTable{}, pieceTable{false, idx, -1})
}
editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
} else {
if idx == endIdx {
oldPieces := append([]pieceTable{}, editor.pceTbl[idx])
firstPieceOfDividedElement := pieceTable{editor.pceTbl[idx].origin,
editor.pceTbl[idx].offset,
int(offset)}
secondPieceOfDividedElement := pieceTable{editor.pceTbl[idx].origin,
editor.pceTbl[idx].offset + int(offset) + int(length),
editor.pceTbl[idx].length - (int(offset) + int(length))}
newPieces := append([]pieceTable{}, firstPieceOfDividedElement, secondPieceOfDividedElement)
editor.pceTbl = append(editor.pceTbl, firstPieceOfDividedElement)
copy(editor.pceTbl[idx+2:], editor.pceTbl[idx+1:])
editor.pceTbl[idx] = firstPieceOfDividedElement
editor.pceTbl[idx+1] = secondPieceOfDividedElement
editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
} else {
oldPieces := append([]pieceTable{}, editor.pceTbl[idx:endIdx]...)
editor.pceTbl = append(editor.pceTbl[:idx+1], editor.pceTbl[endIdx:]...)
firstOfTheFirstPiece := pieceTable{editor.pceTbl[idx].origin,
editor.pceTbl[idx].offset,
int(offset)}
newPieces := append([]pieceTable{}, firstOfTheFirstPiece)
if length != 0 {
oldPieces = append(oldPieces, editor.pceTbl[idx+1])
secondOfTheSecondPiece := pieceTable{editor.pceTbl[idx+1].origin,
editor.pceTbl[idx+1].offset + int(length),
editor.pceTbl[idx+1].length - int(length)}
editor.pceTbl[idx+1] = secondOfTheSecondPiece
newPieces = append(newPieces, secondOfTheSecondPiece)
}
editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
editor.pceTbl[idx] = firstOfTheFirstPiece
}
}
}
return editor
}
func (editor editorImplementation) Undo() Editor {
if len(editor.transitionsBackward) > 0 {
backwTransitionsLastIndex := len(editor.transitionsBackward) - 1
undoTransition := editor.transitionsBackward[backwTransitionsLastIndex]
startIdx := 0
endIdx := 0
if undoTransition.from[0].length != -1 {
if undoTransition.to[0].length != -1 {
for idx := 0; idx < len(editor.pceTbl); idx++ {
if undoTransition.to[0] == editor.pceTbl[idx] {
startIdx = idx
idx = len(editor.pceTbl)
}
}
endIdx = startIdx + len(undoTransition.to)
editor.pceTbl = append(editor.pceTbl[:startIdx], editor.pceTbl[endIdx:]...)
for idx := 0; idx < len(undoTransition.from); idx++ {
editor.pceTbl = append(editor.pceTbl, pieceTable{})
}
copy(editor.pceTbl[startIdx+len(undoTransition.from):], editor.pceTbl[startIdx:])
copy(editor.pceTbl[startIdx:startIdx+len(undoTransition.from)], undoTransition.from)
} else {
startIdx = undoTransition.to[0].offset
for idx := 0; idx < len(undoTransition.from); idx++ {
editor.pceTbl = append(editor.pceTbl, pieceTable{})
}
copy(editor.pceTbl[startIdx+len(undoTransition.from):], editor.pceTbl[startIdx:])
copy(editor.pceTbl[undoTransition.to[0].offset:undoTransition.to[0].offset+len(undoTransition.from)],
undoTransition.from[:])
}
editor.transitionsForward = append(editor.transitionsForward, undoTransition)
editor.transitionsBackward = editor.transitionsBackward[:backwTransitionsLastIndex]
} else {
editor.pceTbl = append(editor.pceTbl[:undoTransition.from[0].offset], editor.pceTbl[undoTransition.from[0].offset+1:]...)
editor.transitionsForward = append(editor.transitionsForward, undoTransition)
editor.transitionsBackward = editor.transitionsBackward[:backwTransitionsLastIndex]
}
}
return editor
}
func (editor editorImplementation) Redo() Editor {
if len(editor.transitionsForward) > 0 {
forwTransitionsLastIndex := len(editor.transitionsForward) - 1
redoTransition := editor.transitionsForward[forwTransitionsLastIndex]
startIdx := 0
endIdx := 0
if redoTransition.from[0].length != -1 {
if redoTransition.to[0].length != -1 {
for idx := 0; idx < len(editor.pceTbl); idx++ {
if redoTransition.from[0] == editor.pceTbl[idx] {
startIdx = idx
idx = len(editor.pceTbl)
}
}
endIdx = startIdx + len(redoTransition.from)
editor.pceTbl = append(editor.pceTbl[:startIdx], editor.pceTbl[endIdx:]...)
for idx := 0; idx < len(redoTransition.to); idx++ {
editor.pceTbl = append(editor.pceTbl, pieceTable{})
}
copy(editor.pceTbl[startIdx+len(redoTransition.to):], editor.pceTbl[startIdx:])
copy(editor.pceTbl[startIdx:startIdx+len(redoTransition.to)], redoTransition.to)
} else {
editor.pceTbl = append(editor.pceTbl[:redoTransition.to[0].offset], editor.pceTbl[redoTransition.to[0].offset+1:]...)
}
} else {
startIdx = redoTransition.from[0].offset
for idx := 0; idx < len(redoTransition.to); idx++ {
editor.pceTbl = append(editor.pceTbl, pieceTable{})
}
copy(editor.pceTbl[startIdx+len(redoTransition.to):], editor.pceTbl[startIdx:])
copy(editor.pceTbl[redoTransition.from[0].offset:redoTransition.from[0].offset+len(redoTransition.to)],
redoTransition.to[:])
}
editor.transitionsBackward = append(editor.transitionsBackward, redoTransition)
editor.transitionsForward = editor.transitionsForward[:forwTransitionsLastIndex]
}
return editor
}
func (editor editorImplementation) String() string {
resultText := ""
for idx := 0; idx < len(editor.pceTbl); idx++ {
if editor.pceTbl[idx].origin == true {
resultText += editor.origin[editor.pceTbl[idx].offset:(editor.pceTbl[idx].offset + editor.pceTbl[idx].length)]
} else {
resultText += editor.add[editor.pceTbl[idx].offset:(editor.pceTbl[idx].offset + editor.pceTbl[idx].length)]
}
}
return resultText
}
func NewEditor(editorContent string) Editor {
var editor = editorImplementation{origin: editorContent, add: "",
pceTbl: []pieceTable{{
true, 0, len(editorContent)}},
textLenght: uint(len(editorContent))}
return editor
}

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

PASS
ok  	_/tmp/d20181107-53-68deg5	0.002s
PASS
ok  	_/tmp/d20181107-53-68deg5	0.002s
PASS
ok  	_/tmp/d20181107-53-68deg5	0.002s
PASS
ok  	_/tmp/d20181107-53-68deg5	0.002s
PASS
ok  	_/tmp/d20181107-53-68deg5	0.002s
PASS
ok  	_/tmp/d20181107-53-68deg5	0.002s
--- FAIL: TestOpAfterUndoInvalidatesRedo (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(0x515240, 0x61cff0)
	/usr/local/go/src/runtime/panic.go:513 +0x1b9
_/tmp/d20181107-53-68deg5.editorImplementation.Redo(0x53cbe0, 0x14, 0x53a5db, 0x8, 0xc00001c320, 0x0, 0x3, 0x1a, 0xc00000e360, 0x1, ...)
	/tmp/d20181107-53-68deg5/solution.go:211 +0x8d3
_/tmp/d20181107-53-68deg5.TestOpAfterUndoInvalidatesRedo(0xc0000b2100)
	/tmp/d20181107-53-68deg5/solution_test.go:63 +0x1ac
testing.tRunner(0xc0000b2100, 0x542d90)
	/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-68deg5	0.005s
PASS
ok  	_/tmp/d20181107-53-68deg5	0.002s

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

Траян обнови решението на 07.11.2018 16:13 (преди 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 pieceTable struct {
+ origin bool
+ offset int
+ length int
+}
+
+type transition struct {
+ from []pieceTable
+ to []pieceTable
+}
+
+type editor1 struct {
+ origin string
+ add string
+ pceTbl []pieceTable
+ textLenght uint
+ transitionsBackward []transition
+ transitionsForward []transition
+}
+
+func (editor editor1) Insert(position uint, text string) Editor {
+ if position > editor.textLenght {
+ position = editor.textLenght
+ }
+ editor.transitionsForward = []transition{}
+ editor.textLenght += uint(len(text))
+ i := 0
+ pieceOffset := position
+ for i = 0; i < len(editor.pceTbl) && pieceOffset >= uint(editor.pceTbl[i].length); i++ {
+ pieceOffset -= uint(editor.pceTbl[i].length)
+ }
+ if pieceOffset == 0 {
+ var oldPieces []pieceTable
+ newPiece := pieceTable{false, len(editor.add), len(text)}
+ editor.pceTbl = append(editor.pceTbl, newPiece)
+ copy(editor.pceTbl[i+1:], editor.pceTbl[i:len(editor.pceTbl)])
+ editor.pceTbl[i] = newPiece
+ newPieces := append([]pieceTable{}, newPiece)
+ oldPieces = []pieceTable{pieceTable{false, i, -1}}
+ editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
+ } else {
+ oldPieces := append([]pieceTable{}, editor.pceTbl[i])
+ firstPieceOfDividedElement := pieceTable{editor.pceTbl[i].origin,
+ editor.pceTbl[i].offset, int(pieceOffset)}
+ newGluePiece := pieceTable{false, len(editor.add), len(text)}
+ secondPieceOfDividedElement := pieceTable{editor.pceTbl[i].origin,
+ editor.pceTbl[i].offset + int(pieceOffset),
+ editor.pceTbl[i].length - int(pieceOffset)}
+ newPieces := append([]pieceTable{}, firstPieceOfDividedElement, newGluePiece, secondPieceOfDividedElement)
+ editor.pceTbl = append(editor.pceTbl, firstPieceOfDividedElement, secondPieceOfDividedElement)
+ copy(editor.pceTbl[i+3:], editor.pceTbl[i+1:])
+ editor.pceTbl[i] = firstPieceOfDividedElement
+ editor.pceTbl[i+1] = newGluePiece
+ editor.pceTbl[i+2] = secondPieceOfDividedElement
+ editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
+ }
+ editor.add += text
+ return editor
+}
+
+func (editor editor1) Delete(offset, length uint) Editor {
+ if offset < editor.textLenght && length > 0 {
+ if offset+length > editor.textLenght {
+ length = editor.textLenght - offset
+ }
+ editor.textLenght -= length
+ idx := 0
+ endIdx := 0
+ for idx = 0; idx < len(editor.pceTbl) && offset >= uint(editor.pceTbl[idx].length); idx++ {
+ offset -= uint(editor.pceTbl[idx].length)
+ }
+ endIdx = idx
+ if length > uint(editor.pceTbl[idx].length)-offset {
+ length -= uint(editor.pceTbl[idx].length) - offset
+ for endIdx = idx + 1; endIdx < len(editor.pceTbl) && length >= uint(editor.pceTbl[endIdx].length); endIdx++ {
+ length -= uint(editor.pceTbl[endIdx].length)
+ }
+ }
+ if offset == 0 {
+ var oldPieces []pieceTable
+ if idx == 0 && endIdx > 0 {
+ oldPieces = append(oldPieces, editor.pceTbl[idx:endIdx]...)
+ } else if idx != 0 && endIdx != 0 {
+ oldPieces = append([]pieceTable{}, editor.pceTbl[idx-1:endIdx-1]...)
+ }
+ var newPieces []pieceTable
+ editor.pceTbl = append(editor.pceTbl[:idx], editor.pceTbl[endIdx:]...)
+ if len(editor.pceTbl) > idx {
+ oldPieces = append(oldPieces, editor.pceTbl[idx])
+ copy(editor.pceTbl[:], append(editor.pceTbl[:idx], editor.pceTbl[idx+1:]...))
+ editor.pceTbl = append(editor.pceTbl[:len(editor.pceTbl)-1])
+ newPieces = append([]pieceTable{}, pieceTable{false, idx, -1})
+ }
+ editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
+ } else {
+ if idx == endIdx {
+ oldPieces := append([]pieceTable{}, editor.pceTbl[idx])
+ firstPieceOfDividedElement := pieceTable{editor.pceTbl[idx].origin,
+ editor.pceTbl[idx].offset,
+ int(offset)}
+ secondPieceOfDividedElement := pieceTable{editor.pceTbl[idx].origin,
+ editor.pceTbl[idx].offset + int(offset) + int(length),
+ editor.pceTbl[idx].length - (int(offset) + int(length))}
+ newPieces := append([]pieceTable{}, firstPieceOfDividedElement, secondPieceOfDividedElement)
+
+ editor.pceTbl = append(editor.pceTbl, firstPieceOfDividedElement)
+ copy(editor.pceTbl[idx+2:], editor.pceTbl[idx+1:])
+ editor.pceTbl[idx] = firstPieceOfDividedElement
+ editor.pceTbl[idx+1] = secondPieceOfDividedElement
+ editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
+ } else {
+ oldPieces := append([]pieceTable{}, editor.pceTbl[idx:endIdx]...)
+ editor.pceTbl = append(editor.pceTbl[:idx+1], editor.pceTbl[endIdx:]...)
+ firstOfTheFirstPiece := pieceTable{editor.pceTbl[idx].origin,
+ editor.pceTbl[idx].offset,
+ int(offset)}
+ newPieces := append([]pieceTable{}, firstOfTheFirstPiece)
+ if length != 0 {
+ oldPieces = append(oldPieces, editor.pceTbl[idx+1])
+ secondOfTheSecondPiece := pieceTable{editor.pceTbl[idx+1].origin,
+ editor.pceTbl[idx+1].offset + int(length),
+ editor.pceTbl[idx+1].length - int(length)}
+ editor.pceTbl[idx+1] = secondOfTheSecondPiece
+ newPieces = append(newPieces, secondOfTheSecondPiece)
+ }
+ editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
+ editor.pceTbl[idx] = firstOfTheFirstPiece
+ }
+ }
+ }
+ return editor
+}
+
+func (editor editor1) Undo() Editor {
+ if len(editor.transitionsBackward) > 0 {
+ backwTransitionsLastIndex := len(editor.transitionsBackward) - 1
+ undoTransition := editor.transitionsBackward[backwTransitionsLastIndex]
+ startIdx := 0
+ endIdx := 0
+ if undoTransition.from[0].length != -1 {
+ if undoTransition.to[0].length != -1 {
+ for i := 0; i < len(editor.pceTbl); i++ {
+ if undoTransition.to[0] == editor.pceTbl[i] {
+ startIdx = i
+ i = len(editor.pceTbl)
+ }
+ }
+ endIdx = startIdx + len(undoTransition.to)
+ editor.pceTbl = append(editor.pceTbl[:startIdx], editor.pceTbl[endIdx:]...)
+ for idx := 0; idx < len(undoTransition.from); idx++ {
+ editor.pceTbl = append(editor.pceTbl, pieceTable{})
+ }
+ copy(editor.pceTbl[startIdx+len(undoTransition.from):], editor.pceTbl[startIdx:])
+ copy(editor.pceTbl[startIdx:startIdx+len(undoTransition.from)], undoTransition.from)
+ } else {
+ startIdx = undoTransition.to[0].offset
+ for idx := 0; idx < len(undoTransition.from); idx++ {
+ editor.pceTbl = append(editor.pceTbl, pieceTable{})
+ }
+
+ copy(editor.pceTbl[startIdx+len(undoTransition.from):], editor.pceTbl[startIdx:])
+ copy(editor.pceTbl[undoTransition.to[0].offset:undoTransition.to[0].offset+len(undoTransition.from)],
+ undoTransition.from[:])
+ }
+ editor.transitionsForward = append(editor.transitionsForward, undoTransition)
+ editor.transitionsBackward = editor.transitionsBackward[:backwTransitionsLastIndex]
+ } else {
+ editor.pceTbl = append(editor.pceTbl[:undoTransition.from[0].offset], editor.pceTbl[undoTransition.from[0].offset+1:]...)
+ editor.transitionsForward = append(editor.transitionsForward, undoTransition)
+ editor.transitionsBackward = editor.transitionsBackward[:backwTransitionsLastIndex]
+ }
+ }
+ return editor
+}
+
+func (editor editor1) Redo() Editor {
+ if len(editor.transitionsForward) > 0 {
+ forwTransitionsLastIndex := len(editor.transitionsForward) - 1
+ redoTransition := editor.transitionsForward[forwTransitionsLastIndex]
+ startIdx := 0
+ endIdx := 0
+ if redoTransition.from[0].length != -1 {
+ if redoTransition.to[0].length != -1 {
+ for i := 0; i < len(editor.pceTbl); i++ {
+ if redoTransition.from[0] == editor.pceTbl[i] {
+ startIdx = i
+ i = len(editor.pceTbl)
+ }
+ }
+ endIdx = startIdx + len(redoTransition.from)
+
+ editor.pceTbl = append(editor.pceTbl[:startIdx], editor.pceTbl[endIdx:]...)
+
+ for idx := 0; idx < len(redoTransition.to); idx++ {
+ editor.pceTbl = append(editor.pceTbl, pieceTable{})
+ }
+ copy(editor.pceTbl[startIdx+len(redoTransition.to):], editor.pceTbl[startIdx:])
+ copy(editor.pceTbl[startIdx:startIdx+len(redoTransition.to)], redoTransition.to)
+ } else {
+ editor.pceTbl = append(editor.pceTbl[:redoTransition.to[0].offset], editor.pceTbl[redoTransition.to[0].offset+1:]...)
+ }
+ } else {
+ startIdx = redoTransition.from[0].offset
+ for idx := 0; idx < len(redoTransition.to); idx++ {
+ editor.pceTbl = append(editor.pceTbl, pieceTable{})
+ }
+
+ copy(editor.pceTbl[startIdx+len(redoTransition.to):], editor.pceTbl[startIdx:])
+ copy(editor.pceTbl[redoTransition.from[0].offset:redoTransition.from[0].offset+len(redoTransition.to)],
+ redoTransition.to[:])
+ }
+ editor.transitionsBackward = append(editor.transitionsBackward, redoTransition)
+ editor.transitionsForward = editor.transitionsForward[:forwTransitionsLastIndex]
+ }
+ return editor
+}
+
+func (editor editor1) String() string {
+ resultText := ""
+ for i := 0; i < len(editor.pceTbl); i++ {
+ if editor.pceTbl[i].origin == true {
+ resultText += editor.origin[editor.pceTbl[i].offset:(editor.pceTbl[i].offset + editor.pceTbl[i].length)]
+ } else {
+ resultText += editor.add[editor.pceTbl[i].offset:(editor.pceTbl[i].offset + editor.pceTbl[i].length)]
+ }
+ }
+ return resultText
+}
+
+func (editor editor1) GetAdd() string {
+ return editor.add
+}
+
+func (editor editor1) GetOriginLen() int {
+ return len(editor.origin)
+}
+
+func (editor editor1) GetAddLen() int {
+ return len(editor.add)
+}
+
+func NewEditor(editorContent string) Editor {
+ var editor = editor1{origin: editorContent, add: "",
+ pceTbl: []pieceTable{{
+ true, 0, len(editorContent)}},
+ textLenght: uint(len(editorContent))}
+ return editor
+}

Траян обнови решението на 07.11.2018 16:15 (преди 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 pieceTable struct {
origin bool
offset int
length int
}
type transition struct {
from []pieceTable
to []pieceTable
}
type editor1 struct {
origin string
add string
pceTbl []pieceTable
textLenght uint
transitionsBackward []transition
transitionsForward []transition
}
func (editor editor1) Insert(position uint, text string) Editor {
if position > editor.textLenght {
position = editor.textLenght
}
editor.transitionsForward = []transition{}
editor.textLenght += uint(len(text))
i := 0
pieceOffset := position
for i = 0; i < len(editor.pceTbl) && pieceOffset >= uint(editor.pceTbl[i].length); i++ {
pieceOffset -= uint(editor.pceTbl[i].length)
}
if pieceOffset == 0 {
var oldPieces []pieceTable
newPiece := pieceTable{false, len(editor.add), len(text)}
editor.pceTbl = append(editor.pceTbl, newPiece)
copy(editor.pceTbl[i+1:], editor.pceTbl[i:len(editor.pceTbl)])
editor.pceTbl[i] = newPiece
newPieces := append([]pieceTable{}, newPiece)
oldPieces = []pieceTable{pieceTable{false, i, -1}}
editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
} else {
oldPieces := append([]pieceTable{}, editor.pceTbl[i])
firstPieceOfDividedElement := pieceTable{editor.pceTbl[i].origin,
editor.pceTbl[i].offset, int(pieceOffset)}
newGluePiece := pieceTable{false, len(editor.add), len(text)}
secondPieceOfDividedElement := pieceTable{editor.pceTbl[i].origin,
editor.pceTbl[i].offset + int(pieceOffset),
editor.pceTbl[i].length - int(pieceOffset)}
newPieces := append([]pieceTable{}, firstPieceOfDividedElement, newGluePiece, secondPieceOfDividedElement)
editor.pceTbl = append(editor.pceTbl, firstPieceOfDividedElement, secondPieceOfDividedElement)
copy(editor.pceTbl[i+3:], editor.pceTbl[i+1:])
editor.pceTbl[i] = firstPieceOfDividedElement
editor.pceTbl[i+1] = newGluePiece
editor.pceTbl[i+2] = secondPieceOfDividedElement
editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
}
editor.add += text
return editor
}
func (editor editor1) Delete(offset, length uint) Editor {
if offset < editor.textLenght && length > 0 {
if offset+length > editor.textLenght {
length = editor.textLenght - offset
}
editor.textLenght -= length
idx := 0
endIdx := 0
for idx = 0; idx < len(editor.pceTbl) && offset >= uint(editor.pceTbl[idx].length); idx++ {
offset -= uint(editor.pceTbl[idx].length)
}
endIdx = idx
if length > uint(editor.pceTbl[idx].length)-offset {
length -= uint(editor.pceTbl[idx].length) - offset
for endIdx = idx + 1; endIdx < len(editor.pceTbl) && length >= uint(editor.pceTbl[endIdx].length); endIdx++ {
length -= uint(editor.pceTbl[endIdx].length)
}
}
if offset == 0 {
var oldPieces []pieceTable
if idx == 0 && endIdx > 0 {
oldPieces = append(oldPieces, editor.pceTbl[idx:endIdx]...)
} else if idx != 0 && endIdx != 0 {
oldPieces = append([]pieceTable{}, editor.pceTbl[idx-1:endIdx-1]...)
}
var newPieces []pieceTable
editor.pceTbl = append(editor.pceTbl[:idx], editor.pceTbl[endIdx:]...)
if len(editor.pceTbl) > idx {
oldPieces = append(oldPieces, editor.pceTbl[idx])
copy(editor.pceTbl[:], append(editor.pceTbl[:idx], editor.pceTbl[idx+1:]...))
editor.pceTbl = append(editor.pceTbl[:len(editor.pceTbl)-1])
newPieces = append([]pieceTable{}, pieceTable{false, idx, -1})
}
editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
} else {
if idx == endIdx {
oldPieces := append([]pieceTable{}, editor.pceTbl[idx])
firstPieceOfDividedElement := pieceTable{editor.pceTbl[idx].origin,
editor.pceTbl[idx].offset,
int(offset)}
secondPieceOfDividedElement := pieceTable{editor.pceTbl[idx].origin,
editor.pceTbl[idx].offset + int(offset) + int(length),
editor.pceTbl[idx].length - (int(offset) + int(length))}
newPieces := append([]pieceTable{}, firstPieceOfDividedElement, secondPieceOfDividedElement)
editor.pceTbl = append(editor.pceTbl, firstPieceOfDividedElement)
copy(editor.pceTbl[idx+2:], editor.pceTbl[idx+1:])
editor.pceTbl[idx] = firstPieceOfDividedElement
editor.pceTbl[idx+1] = secondPieceOfDividedElement
editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
} else {
oldPieces := append([]pieceTable{}, editor.pceTbl[idx:endIdx]...)
editor.pceTbl = append(editor.pceTbl[:idx+1], editor.pceTbl[endIdx:]...)
firstOfTheFirstPiece := pieceTable{editor.pceTbl[idx].origin,
editor.pceTbl[idx].offset,
int(offset)}
newPieces := append([]pieceTable{}, firstOfTheFirstPiece)
if length != 0 {
oldPieces = append(oldPieces, editor.pceTbl[idx+1])
secondOfTheSecondPiece := pieceTable{editor.pceTbl[idx+1].origin,
editor.pceTbl[idx+1].offset + int(length),
editor.pceTbl[idx+1].length - int(length)}
editor.pceTbl[idx+1] = secondOfTheSecondPiece
newPieces = append(newPieces, secondOfTheSecondPiece)
}
editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
editor.pceTbl[idx] = firstOfTheFirstPiece
}
}
}
return editor
}
func (editor editor1) Undo() Editor {
if len(editor.transitionsBackward) > 0 {
backwTransitionsLastIndex := len(editor.transitionsBackward) - 1
undoTransition := editor.transitionsBackward[backwTransitionsLastIndex]
startIdx := 0
endIdx := 0
if undoTransition.from[0].length != -1 {
if undoTransition.to[0].length != -1 {
for i := 0; i < len(editor.pceTbl); i++ {
if undoTransition.to[0] == editor.pceTbl[i] {
startIdx = i
i = len(editor.pceTbl)
}
}
endIdx = startIdx + len(undoTransition.to)
editor.pceTbl = append(editor.pceTbl[:startIdx], editor.pceTbl[endIdx:]...)
for idx := 0; idx < len(undoTransition.from); idx++ {
editor.pceTbl = append(editor.pceTbl, pieceTable{})
}
copy(editor.pceTbl[startIdx+len(undoTransition.from):], editor.pceTbl[startIdx:])
copy(editor.pceTbl[startIdx:startIdx+len(undoTransition.from)], undoTransition.from)
} else {
startIdx = undoTransition.to[0].offset
for idx := 0; idx < len(undoTransition.from); idx++ {
editor.pceTbl = append(editor.pceTbl, pieceTable{})
}
copy(editor.pceTbl[startIdx+len(undoTransition.from):], editor.pceTbl[startIdx:])
copy(editor.pceTbl[undoTransition.to[0].offset:undoTransition.to[0].offset+len(undoTransition.from)],
undoTransition.from[:])
}
editor.transitionsForward = append(editor.transitionsForward, undoTransition)
editor.transitionsBackward = editor.transitionsBackward[:backwTransitionsLastIndex]
} else {
editor.pceTbl = append(editor.pceTbl[:undoTransition.from[0].offset], editor.pceTbl[undoTransition.from[0].offset+1:]...)
editor.transitionsForward = append(editor.transitionsForward, undoTransition)
editor.transitionsBackward = editor.transitionsBackward[:backwTransitionsLastIndex]
}
}
return editor
}
func (editor editor1) Redo() Editor {
if len(editor.transitionsForward) > 0 {
forwTransitionsLastIndex := len(editor.transitionsForward) - 1
redoTransition := editor.transitionsForward[forwTransitionsLastIndex]
startIdx := 0
endIdx := 0
if redoTransition.from[0].length != -1 {
if redoTransition.to[0].length != -1 {
for i := 0; i < len(editor.pceTbl); i++ {
if redoTransition.from[0] == editor.pceTbl[i] {
startIdx = i
i = len(editor.pceTbl)
}
}
endIdx = startIdx + len(redoTransition.from)
-
editor.pceTbl = append(editor.pceTbl[:startIdx], editor.pceTbl[endIdx:]...)
-
for idx := 0; idx < len(redoTransition.to); idx++ {
editor.pceTbl = append(editor.pceTbl, pieceTable{})
}
copy(editor.pceTbl[startIdx+len(redoTransition.to):], editor.pceTbl[startIdx:])
copy(editor.pceTbl[startIdx:startIdx+len(redoTransition.to)], redoTransition.to)
} else {
editor.pceTbl = append(editor.pceTbl[:redoTransition.to[0].offset], editor.pceTbl[redoTransition.to[0].offset+1:]...)
}
} else {
startIdx = redoTransition.from[0].offset
for idx := 0; idx < len(redoTransition.to); idx++ {
editor.pceTbl = append(editor.pceTbl, pieceTable{})
}
-
copy(editor.pceTbl[startIdx+len(redoTransition.to):], editor.pceTbl[startIdx:])
copy(editor.pceTbl[redoTransition.from[0].offset:redoTransition.from[0].offset+len(redoTransition.to)],
redoTransition.to[:])
}
editor.transitionsBackward = append(editor.transitionsBackward, redoTransition)
editor.transitionsForward = editor.transitionsForward[:forwTransitionsLastIndex]
}
return editor
}
func (editor editor1) String() string {
resultText := ""
for i := 0; i < len(editor.pceTbl); i++ {
if editor.pceTbl[i].origin == true {
resultText += editor.origin[editor.pceTbl[i].offset:(editor.pceTbl[i].offset + editor.pceTbl[i].length)]
} else {
resultText += editor.add[editor.pceTbl[i].offset:(editor.pceTbl[i].offset + editor.pceTbl[i].length)]
}
}
return resultText
}
func (editor editor1) GetAdd() string {
return editor.add
}
func (editor editor1) GetOriginLen() int {
return len(editor.origin)
}
func (editor editor1) GetAddLen() int {
return len(editor.add)
}
func NewEditor(editorContent string) Editor {
var editor = editor1{origin: editorContent, add: "",
pceTbl: []pieceTable{{
true, 0, len(editorContent)}},
textLenght: uint(len(editorContent))}
return editor
}

Траян обнови решението на 07.11.2018 16:23 (преди 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 pieceTable struct {
origin bool
offset int
length int
}
type transition struct {
from []pieceTable
to []pieceTable
}
type editor1 struct {
origin string
add string
pceTbl []pieceTable
textLenght uint
transitionsBackward []transition
transitionsForward []transition
}
func (editor editor1) Insert(position uint, text string) Editor {
if position > editor.textLenght {
position = editor.textLenght
}
editor.transitionsForward = []transition{}
editor.textLenght += uint(len(text))
- i := 0
+ idx := 0
pieceOffset := position
- for i = 0; i < len(editor.pceTbl) && pieceOffset >= uint(editor.pceTbl[i].length); i++ {
- pieceOffset -= uint(editor.pceTbl[i].length)
+ for idx = 0; idx < len(editor.pceTbl) && pieceOffset >= uint(editor.pceTbl[idx].length); idx++ {
+ pieceOffset -= uint(editor.pceTbl[idx].length)
}
if pieceOffset == 0 {
var oldPieces []pieceTable
newPiece := pieceTable{false, len(editor.add), len(text)}
editor.pceTbl = append(editor.pceTbl, newPiece)
- copy(editor.pceTbl[i+1:], editor.pceTbl[i:len(editor.pceTbl)])
- editor.pceTbl[i] = newPiece
+ copy(editor.pceTbl[idx+1:], editor.pceTbl[idx:len(editor.pceTbl)])
+ editor.pceTbl[idx] = newPiece
newPieces := append([]pieceTable{}, newPiece)
- oldPieces = []pieceTable{pieceTable{false, i, -1}}
+ oldPieces = []pieceTable{pieceTable{false, idx, -1}}
editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
} else {
- oldPieces := append([]pieceTable{}, editor.pceTbl[i])
- firstPieceOfDividedElement := pieceTable{editor.pceTbl[i].origin,
- editor.pceTbl[i].offset, int(pieceOffset)}
+ oldPieces := append([]pieceTable{}, editor.pceTbl[idx])
+ firstPieceOfDividedElement := pieceTable{editor.pceTbl[idx].origin,
+ editor.pceTbl[idx].offset, int(pieceOffset)}
newGluePiece := pieceTable{false, len(editor.add), len(text)}
- secondPieceOfDividedElement := pieceTable{editor.pceTbl[i].origin,
- editor.pceTbl[i].offset + int(pieceOffset),
- editor.pceTbl[i].length - int(pieceOffset)}
+ secondPieceOfDividedElement := pieceTable{editor.pceTbl[idx].origin,
+ editor.pceTbl[idx].offset + int(pieceOffset),
+ editor.pceTbl[idx].length - int(pieceOffset)}
newPieces := append([]pieceTable{}, firstPieceOfDividedElement, newGluePiece, secondPieceOfDividedElement)
editor.pceTbl = append(editor.pceTbl, firstPieceOfDividedElement, secondPieceOfDividedElement)
- copy(editor.pceTbl[i+3:], editor.pceTbl[i+1:])
- editor.pceTbl[i] = firstPieceOfDividedElement
- editor.pceTbl[i+1] = newGluePiece
- editor.pceTbl[i+2] = secondPieceOfDividedElement
+ copy(editor.pceTbl[idx+3:], editor.pceTbl[idx+1:])
+ editor.pceTbl[idx] = firstPieceOfDividedElement
+ editor.pceTbl[idx+1] = newGluePiece
+ editor.pceTbl[idx+2] = secondPieceOfDividedElement
editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
}
editor.add += text
return editor
}
func (editor editor1) Delete(offset, length uint) Editor {
if offset < editor.textLenght && length > 0 {
if offset+length > editor.textLenght {
length = editor.textLenght - offset
}
editor.textLenght -= length
idx := 0
endIdx := 0
for idx = 0; idx < len(editor.pceTbl) && offset >= uint(editor.pceTbl[idx].length); idx++ {
offset -= uint(editor.pceTbl[idx].length)
}
endIdx = idx
if length > uint(editor.pceTbl[idx].length)-offset {
length -= uint(editor.pceTbl[idx].length) - offset
for endIdx = idx + 1; endIdx < len(editor.pceTbl) && length >= uint(editor.pceTbl[endIdx].length); endIdx++ {
length -= uint(editor.pceTbl[endIdx].length)
}
}
if offset == 0 {
var oldPieces []pieceTable
if idx == 0 && endIdx > 0 {
oldPieces = append(oldPieces, editor.pceTbl[idx:endIdx]...)
} else if idx != 0 && endIdx != 0 {
oldPieces = append([]pieceTable{}, editor.pceTbl[idx-1:endIdx-1]...)
}
var newPieces []pieceTable
editor.pceTbl = append(editor.pceTbl[:idx], editor.pceTbl[endIdx:]...)
if len(editor.pceTbl) > idx {
oldPieces = append(oldPieces, editor.pceTbl[idx])
copy(editor.pceTbl[:], append(editor.pceTbl[:idx], editor.pceTbl[idx+1:]...))
editor.pceTbl = append(editor.pceTbl[:len(editor.pceTbl)-1])
newPieces = append([]pieceTable{}, pieceTable{false, idx, -1})
}
editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
} else {
if idx == endIdx {
oldPieces := append([]pieceTable{}, editor.pceTbl[idx])
firstPieceOfDividedElement := pieceTable{editor.pceTbl[idx].origin,
editor.pceTbl[idx].offset,
int(offset)}
secondPieceOfDividedElement := pieceTable{editor.pceTbl[idx].origin,
editor.pceTbl[idx].offset + int(offset) + int(length),
editor.pceTbl[idx].length - (int(offset) + int(length))}
newPieces := append([]pieceTable{}, firstPieceOfDividedElement, secondPieceOfDividedElement)
editor.pceTbl = append(editor.pceTbl, firstPieceOfDividedElement)
copy(editor.pceTbl[idx+2:], editor.pceTbl[idx+1:])
editor.pceTbl[idx] = firstPieceOfDividedElement
editor.pceTbl[idx+1] = secondPieceOfDividedElement
editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
} else {
oldPieces := append([]pieceTable{}, editor.pceTbl[idx:endIdx]...)
editor.pceTbl = append(editor.pceTbl[:idx+1], editor.pceTbl[endIdx:]...)
firstOfTheFirstPiece := pieceTable{editor.pceTbl[idx].origin,
editor.pceTbl[idx].offset,
int(offset)}
newPieces := append([]pieceTable{}, firstOfTheFirstPiece)
if length != 0 {
oldPieces = append(oldPieces, editor.pceTbl[idx+1])
secondOfTheSecondPiece := pieceTable{editor.pceTbl[idx+1].origin,
editor.pceTbl[idx+1].offset + int(length),
editor.pceTbl[idx+1].length - int(length)}
editor.pceTbl[idx+1] = secondOfTheSecondPiece
newPieces = append(newPieces, secondOfTheSecondPiece)
}
editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
editor.pceTbl[idx] = firstOfTheFirstPiece
}
}
}
return editor
}
func (editor editor1) Undo() Editor {
if len(editor.transitionsBackward) > 0 {
backwTransitionsLastIndex := len(editor.transitionsBackward) - 1
undoTransition := editor.transitionsBackward[backwTransitionsLastIndex]
startIdx := 0
endIdx := 0
if undoTransition.from[0].length != -1 {
if undoTransition.to[0].length != -1 {
- for i := 0; i < len(editor.pceTbl); i++ {
- if undoTransition.to[0] == editor.pceTbl[i] {
- startIdx = i
- i = len(editor.pceTbl)
+ for idx := 0; idx < len(editor.pceTbl); idx++ {
+ if undoTransition.to[0] == editor.pceTbl[idx] {
+ startIdx = idx
+ idx = len(editor.pceTbl)
}
}
endIdx = startIdx + len(undoTransition.to)
editor.pceTbl = append(editor.pceTbl[:startIdx], editor.pceTbl[endIdx:]...)
for idx := 0; idx < len(undoTransition.from); idx++ {
editor.pceTbl = append(editor.pceTbl, pieceTable{})
}
copy(editor.pceTbl[startIdx+len(undoTransition.from):], editor.pceTbl[startIdx:])
copy(editor.pceTbl[startIdx:startIdx+len(undoTransition.from)], undoTransition.from)
} else {
startIdx = undoTransition.to[0].offset
for idx := 0; idx < len(undoTransition.from); idx++ {
editor.pceTbl = append(editor.pceTbl, pieceTable{})
}
copy(editor.pceTbl[startIdx+len(undoTransition.from):], editor.pceTbl[startIdx:])
copy(editor.pceTbl[undoTransition.to[0].offset:undoTransition.to[0].offset+len(undoTransition.from)],
undoTransition.from[:])
}
editor.transitionsForward = append(editor.transitionsForward, undoTransition)
editor.transitionsBackward = editor.transitionsBackward[:backwTransitionsLastIndex]
} else {
editor.pceTbl = append(editor.pceTbl[:undoTransition.from[0].offset], editor.pceTbl[undoTransition.from[0].offset+1:]...)
editor.transitionsForward = append(editor.transitionsForward, undoTransition)
editor.transitionsBackward = editor.transitionsBackward[:backwTransitionsLastIndex]
}
}
return editor
}
func (editor editor1) Redo() Editor {
if len(editor.transitionsForward) > 0 {
forwTransitionsLastIndex := len(editor.transitionsForward) - 1
redoTransition := editor.transitionsForward[forwTransitionsLastIndex]
startIdx := 0
endIdx := 0
if redoTransition.from[0].length != -1 {
if redoTransition.to[0].length != -1 {
- for i := 0; i < len(editor.pceTbl); i++ {
- if redoTransition.from[0] == editor.pceTbl[i] {
- startIdx = i
- i = len(editor.pceTbl)
+ for idx := 0; idx < len(editor.pceTbl); idx++ {
+ if redoTransition.from[0] == editor.pceTbl[idx] {
+ startIdx = idx
+ idx = len(editor.pceTbl)
}
}
endIdx = startIdx + len(redoTransition.from)
editor.pceTbl = append(editor.pceTbl[:startIdx], editor.pceTbl[endIdx:]...)
for idx := 0; idx < len(redoTransition.to); idx++ {
editor.pceTbl = append(editor.pceTbl, pieceTable{})
}
copy(editor.pceTbl[startIdx+len(redoTransition.to):], editor.pceTbl[startIdx:])
copy(editor.pceTbl[startIdx:startIdx+len(redoTransition.to)], redoTransition.to)
} else {
editor.pceTbl = append(editor.pceTbl[:redoTransition.to[0].offset], editor.pceTbl[redoTransition.to[0].offset+1:]...)
}
} else {
startIdx = redoTransition.from[0].offset
for idx := 0; idx < len(redoTransition.to); idx++ {
editor.pceTbl = append(editor.pceTbl, pieceTable{})
}
copy(editor.pceTbl[startIdx+len(redoTransition.to):], editor.pceTbl[startIdx:])
copy(editor.pceTbl[redoTransition.from[0].offset:redoTransition.from[0].offset+len(redoTransition.to)],
redoTransition.to[:])
}
editor.transitionsBackward = append(editor.transitionsBackward, redoTransition)
editor.transitionsForward = editor.transitionsForward[:forwTransitionsLastIndex]
}
return editor
}
func (editor editor1) String() string {
resultText := ""
- for i := 0; i < len(editor.pceTbl); i++ {
- if editor.pceTbl[i].origin == true {
- resultText += editor.origin[editor.pceTbl[i].offset:(editor.pceTbl[i].offset + editor.pceTbl[i].length)]
+ for idx := 0; idx < len(editor.pceTbl); idx++ {
+ if editor.pceTbl[idx].origin == true {
+ resultText += editor.origin[editor.pceTbl[idx].offset:(editor.pceTbl[idx].offset + editor.pceTbl[idx].length)]
} else {
- resultText += editor.add[editor.pceTbl[i].offset:(editor.pceTbl[i].offset + editor.pceTbl[i].length)]
+ resultText += editor.add[editor.pceTbl[idx].offset:(editor.pceTbl[idx].offset + editor.pceTbl[idx].length)]
}
}
return resultText
}
func (editor editor1) GetAdd() string {
return editor.add
}
func (editor editor1) GetOriginLen() int {
return len(editor.origin)
}
func (editor editor1) GetAddLen() int {
return len(editor.add)
}
func NewEditor(editorContent string) Editor {
var editor = editor1{origin: editorContent, add: "",
pceTbl: []pieceTable{{
true, 0, len(editorContent)}},
textLenght: uint(len(editorContent))}
return editor
}

Траян обнови решението на 07.11.2018 16:24 (преди 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 pieceTable struct {
origin bool
offset int
length int
}
type transition struct {
from []pieceTable
to []pieceTable
}
-type editor1 struct {
+type editorImplementation struct {
origin string
add string
pceTbl []pieceTable
textLenght uint
transitionsBackward []transition
transitionsForward []transition
}
-func (editor editor1) Insert(position uint, text string) Editor {
+func (editor editorImplementation) Insert(position uint, text string) Editor {
if position > editor.textLenght {
position = editor.textLenght
}
editor.transitionsForward = []transition{}
editor.textLenght += uint(len(text))
idx := 0
pieceOffset := position
for idx = 0; idx < len(editor.pceTbl) && pieceOffset >= uint(editor.pceTbl[idx].length); idx++ {
pieceOffset -= uint(editor.pceTbl[idx].length)
}
if pieceOffset == 0 {
var oldPieces []pieceTable
newPiece := pieceTable{false, len(editor.add), len(text)}
editor.pceTbl = append(editor.pceTbl, newPiece)
copy(editor.pceTbl[idx+1:], editor.pceTbl[idx:len(editor.pceTbl)])
editor.pceTbl[idx] = newPiece
newPieces := append([]pieceTable{}, newPiece)
oldPieces = []pieceTable{pieceTable{false, idx, -1}}
editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
} else {
oldPieces := append([]pieceTable{}, editor.pceTbl[idx])
firstPieceOfDividedElement := pieceTable{editor.pceTbl[idx].origin,
editor.pceTbl[idx].offset, int(pieceOffset)}
newGluePiece := pieceTable{false, len(editor.add), len(text)}
secondPieceOfDividedElement := pieceTable{editor.pceTbl[idx].origin,
editor.pceTbl[idx].offset + int(pieceOffset),
editor.pceTbl[idx].length - int(pieceOffset)}
newPieces := append([]pieceTable{}, firstPieceOfDividedElement, newGluePiece, secondPieceOfDividedElement)
editor.pceTbl = append(editor.pceTbl, firstPieceOfDividedElement, secondPieceOfDividedElement)
copy(editor.pceTbl[idx+3:], editor.pceTbl[idx+1:])
editor.pceTbl[idx] = firstPieceOfDividedElement
editor.pceTbl[idx+1] = newGluePiece
editor.pceTbl[idx+2] = secondPieceOfDividedElement
editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
}
editor.add += text
return editor
}
-func (editor editor1) Delete(offset, length uint) Editor {
+func (editor editorImplementation) Delete(offset, length uint) Editor {
if offset < editor.textLenght && length > 0 {
if offset+length > editor.textLenght {
length = editor.textLenght - offset
}
editor.textLenght -= length
idx := 0
endIdx := 0
for idx = 0; idx < len(editor.pceTbl) && offset >= uint(editor.pceTbl[idx].length); idx++ {
offset -= uint(editor.pceTbl[idx].length)
}
endIdx = idx
if length > uint(editor.pceTbl[idx].length)-offset {
length -= uint(editor.pceTbl[idx].length) - offset
for endIdx = idx + 1; endIdx < len(editor.pceTbl) && length >= uint(editor.pceTbl[endIdx].length); endIdx++ {
length -= uint(editor.pceTbl[endIdx].length)
}
}
if offset == 0 {
var oldPieces []pieceTable
if idx == 0 && endIdx > 0 {
oldPieces = append(oldPieces, editor.pceTbl[idx:endIdx]...)
} else if idx != 0 && endIdx != 0 {
oldPieces = append([]pieceTable{}, editor.pceTbl[idx-1:endIdx-1]...)
}
var newPieces []pieceTable
editor.pceTbl = append(editor.pceTbl[:idx], editor.pceTbl[endIdx:]...)
if len(editor.pceTbl) > idx {
oldPieces = append(oldPieces, editor.pceTbl[idx])
copy(editor.pceTbl[:], append(editor.pceTbl[:idx], editor.pceTbl[idx+1:]...))
editor.pceTbl = append(editor.pceTbl[:len(editor.pceTbl)-1])
newPieces = append([]pieceTable{}, pieceTable{false, idx, -1})
}
editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
} else {
if idx == endIdx {
oldPieces := append([]pieceTable{}, editor.pceTbl[idx])
firstPieceOfDividedElement := pieceTable{editor.pceTbl[idx].origin,
editor.pceTbl[idx].offset,
int(offset)}
secondPieceOfDividedElement := pieceTable{editor.pceTbl[idx].origin,
editor.pceTbl[idx].offset + int(offset) + int(length),
editor.pceTbl[idx].length - (int(offset) + int(length))}
newPieces := append([]pieceTable{}, firstPieceOfDividedElement, secondPieceOfDividedElement)
editor.pceTbl = append(editor.pceTbl, firstPieceOfDividedElement)
copy(editor.pceTbl[idx+2:], editor.pceTbl[idx+1:])
editor.pceTbl[idx] = firstPieceOfDividedElement
editor.pceTbl[idx+1] = secondPieceOfDividedElement
editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
} else {
oldPieces := append([]pieceTable{}, editor.pceTbl[idx:endIdx]...)
editor.pceTbl = append(editor.pceTbl[:idx+1], editor.pceTbl[endIdx:]...)
firstOfTheFirstPiece := pieceTable{editor.pceTbl[idx].origin,
editor.pceTbl[idx].offset,
int(offset)}
newPieces := append([]pieceTable{}, firstOfTheFirstPiece)
if length != 0 {
oldPieces = append(oldPieces, editor.pceTbl[idx+1])
secondOfTheSecondPiece := pieceTable{editor.pceTbl[idx+1].origin,
editor.pceTbl[idx+1].offset + int(length),
editor.pceTbl[idx+1].length - int(length)}
editor.pceTbl[idx+1] = secondOfTheSecondPiece
newPieces = append(newPieces, secondOfTheSecondPiece)
}
editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
editor.pceTbl[idx] = firstOfTheFirstPiece
}
}
}
return editor
}
-func (editor editor1) Undo() Editor {
+func (editor editorImplementation) Undo() Editor {
if len(editor.transitionsBackward) > 0 {
backwTransitionsLastIndex := len(editor.transitionsBackward) - 1
undoTransition := editor.transitionsBackward[backwTransitionsLastIndex]
startIdx := 0
endIdx := 0
if undoTransition.from[0].length != -1 {
if undoTransition.to[0].length != -1 {
for idx := 0; idx < len(editor.pceTbl); idx++ {
if undoTransition.to[0] == editor.pceTbl[idx] {
startIdx = idx
idx = len(editor.pceTbl)
}
}
endIdx = startIdx + len(undoTransition.to)
editor.pceTbl = append(editor.pceTbl[:startIdx], editor.pceTbl[endIdx:]...)
for idx := 0; idx < len(undoTransition.from); idx++ {
editor.pceTbl = append(editor.pceTbl, pieceTable{})
}
copy(editor.pceTbl[startIdx+len(undoTransition.from):], editor.pceTbl[startIdx:])
copy(editor.pceTbl[startIdx:startIdx+len(undoTransition.from)], undoTransition.from)
} else {
startIdx = undoTransition.to[0].offset
for idx := 0; idx < len(undoTransition.from); idx++ {
editor.pceTbl = append(editor.pceTbl, pieceTable{})
}
copy(editor.pceTbl[startIdx+len(undoTransition.from):], editor.pceTbl[startIdx:])
copy(editor.pceTbl[undoTransition.to[0].offset:undoTransition.to[0].offset+len(undoTransition.from)],
undoTransition.from[:])
}
editor.transitionsForward = append(editor.transitionsForward, undoTransition)
editor.transitionsBackward = editor.transitionsBackward[:backwTransitionsLastIndex]
} else {
editor.pceTbl = append(editor.pceTbl[:undoTransition.from[0].offset], editor.pceTbl[undoTransition.from[0].offset+1:]...)
editor.transitionsForward = append(editor.transitionsForward, undoTransition)
editor.transitionsBackward = editor.transitionsBackward[:backwTransitionsLastIndex]
}
}
return editor
}
-func (editor editor1) Redo() Editor {
+func (editor editorImplementation) Redo() Editor {
if len(editor.transitionsForward) > 0 {
forwTransitionsLastIndex := len(editor.transitionsForward) - 1
redoTransition := editor.transitionsForward[forwTransitionsLastIndex]
startIdx := 0
endIdx := 0
if redoTransition.from[0].length != -1 {
if redoTransition.to[0].length != -1 {
for idx := 0; idx < len(editor.pceTbl); idx++ {
if redoTransition.from[0] == editor.pceTbl[idx] {
startIdx = idx
idx = len(editor.pceTbl)
}
}
endIdx = startIdx + len(redoTransition.from)
editor.pceTbl = append(editor.pceTbl[:startIdx], editor.pceTbl[endIdx:]...)
for idx := 0; idx < len(redoTransition.to); idx++ {
editor.pceTbl = append(editor.pceTbl, pieceTable{})
}
copy(editor.pceTbl[startIdx+len(redoTransition.to):], editor.pceTbl[startIdx:])
copy(editor.pceTbl[startIdx:startIdx+len(redoTransition.to)], redoTransition.to)
} else {
editor.pceTbl = append(editor.pceTbl[:redoTransition.to[0].offset], editor.pceTbl[redoTransition.to[0].offset+1:]...)
}
} else {
startIdx = redoTransition.from[0].offset
for idx := 0; idx < len(redoTransition.to); idx++ {
editor.pceTbl = append(editor.pceTbl, pieceTable{})
}
copy(editor.pceTbl[startIdx+len(redoTransition.to):], editor.pceTbl[startIdx:])
copy(editor.pceTbl[redoTransition.from[0].offset:redoTransition.from[0].offset+len(redoTransition.to)],
redoTransition.to[:])
}
editor.transitionsBackward = append(editor.transitionsBackward, redoTransition)
editor.transitionsForward = editor.transitionsForward[:forwTransitionsLastIndex]
}
return editor
}
-func (editor editor1) String() string {
+func (editor editorImplementation) String() string {
resultText := ""
for idx := 0; idx < len(editor.pceTbl); idx++ {
if editor.pceTbl[idx].origin == true {
resultText += editor.origin[editor.pceTbl[idx].offset:(editor.pceTbl[idx].offset + editor.pceTbl[idx].length)]
} else {
resultText += editor.add[editor.pceTbl[idx].offset:(editor.pceTbl[idx].offset + editor.pceTbl[idx].length)]
}
}
return resultText
}
-func (editor editor1) GetAdd() string {
+func (editor editorImplementation) GetAdd() string {
return editor.add
}
-func (editor editor1) GetOriginLen() int {
+func (editor editorImplementation) GetOriginLen() int {
return len(editor.origin)
}
-func (editor editor1) GetAddLen() int {
+func (editor editorImplementation) GetAddLen() int {
return len(editor.add)
}
func NewEditor(editorContent string) Editor {
- var editor = editor1{origin: editorContent, add: "",
+ var editor = editorImplementation{origin: editorContent, add: "",
pceTbl: []pieceTable{{
true, 0, len(editorContent)}},
textLenght: uint(len(editorContent))}
return editor
}

Траян обнови решението на 07.11.2018 16:50 (преди 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 pieceTable struct {
origin bool
offset int
length int
}
type transition struct {
from []pieceTable
to []pieceTable
}
type editorImplementation struct {
origin string
add string
pceTbl []pieceTable
textLenght uint
transitionsBackward []transition
transitionsForward []transition
}
func (editor editorImplementation) Insert(position uint, text string) Editor {
if position > editor.textLenght {
position = editor.textLenght
}
editor.transitionsForward = []transition{}
editor.textLenght += uint(len(text))
idx := 0
pieceOffset := position
for idx = 0; idx < len(editor.pceTbl) && pieceOffset >= uint(editor.pceTbl[idx].length); idx++ {
pieceOffset -= uint(editor.pceTbl[idx].length)
}
if pieceOffset == 0 {
var oldPieces []pieceTable
newPiece := pieceTable{false, len(editor.add), len(text)}
editor.pceTbl = append(editor.pceTbl, newPiece)
copy(editor.pceTbl[idx+1:], editor.pceTbl[idx:len(editor.pceTbl)])
editor.pceTbl[idx] = newPiece
newPieces := append([]pieceTable{}, newPiece)
oldPieces = []pieceTable{pieceTable{false, idx, -1}}
editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
} else {
oldPieces := append([]pieceTable{}, editor.pceTbl[idx])
firstPieceOfDividedElement := pieceTable{editor.pceTbl[idx].origin,
editor.pceTbl[idx].offset, int(pieceOffset)}
newGluePiece := pieceTable{false, len(editor.add), len(text)}
secondPieceOfDividedElement := pieceTable{editor.pceTbl[idx].origin,
editor.pceTbl[idx].offset + int(pieceOffset),
editor.pceTbl[idx].length - int(pieceOffset)}
newPieces := append([]pieceTable{}, firstPieceOfDividedElement, newGluePiece, secondPieceOfDividedElement)
editor.pceTbl = append(editor.pceTbl, firstPieceOfDividedElement, secondPieceOfDividedElement)
copy(editor.pceTbl[idx+3:], editor.pceTbl[idx+1:])
editor.pceTbl[idx] = firstPieceOfDividedElement
editor.pceTbl[idx+1] = newGluePiece
editor.pceTbl[idx+2] = secondPieceOfDividedElement
editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
}
editor.add += text
return editor
}
func (editor editorImplementation) Delete(offset, length uint) Editor {
if offset < editor.textLenght && length > 0 {
if offset+length > editor.textLenght {
length = editor.textLenght - offset
}
editor.textLenght -= length
idx := 0
endIdx := 0
for idx = 0; idx < len(editor.pceTbl) && offset >= uint(editor.pceTbl[idx].length); idx++ {
offset -= uint(editor.pceTbl[idx].length)
}
endIdx = idx
if length > uint(editor.pceTbl[idx].length)-offset {
length -= uint(editor.pceTbl[idx].length) - offset
for endIdx = idx + 1; endIdx < len(editor.pceTbl) && length >= uint(editor.pceTbl[endIdx].length); endIdx++ {
length -= uint(editor.pceTbl[endIdx].length)
}
}
if offset == 0 {
var oldPieces []pieceTable
if idx == 0 && endIdx > 0 {
oldPieces = append(oldPieces, editor.pceTbl[idx:endIdx]...)
} else if idx != 0 && endIdx != 0 {
oldPieces = append([]pieceTable{}, editor.pceTbl[idx-1:endIdx-1]...)
}
var newPieces []pieceTable
editor.pceTbl = append(editor.pceTbl[:idx], editor.pceTbl[endIdx:]...)
if len(editor.pceTbl) > idx {
oldPieces = append(oldPieces, editor.pceTbl[idx])
copy(editor.pceTbl[:], append(editor.pceTbl[:idx], editor.pceTbl[idx+1:]...))
editor.pceTbl = append(editor.pceTbl[:len(editor.pceTbl)-1])
newPieces = append([]pieceTable{}, pieceTable{false, idx, -1})
}
editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
} else {
if idx == endIdx {
oldPieces := append([]pieceTable{}, editor.pceTbl[idx])
firstPieceOfDividedElement := pieceTable{editor.pceTbl[idx].origin,
editor.pceTbl[idx].offset,
int(offset)}
secondPieceOfDividedElement := pieceTable{editor.pceTbl[idx].origin,
editor.pceTbl[idx].offset + int(offset) + int(length),
editor.pceTbl[idx].length - (int(offset) + int(length))}
newPieces := append([]pieceTable{}, firstPieceOfDividedElement, secondPieceOfDividedElement)
editor.pceTbl = append(editor.pceTbl, firstPieceOfDividedElement)
copy(editor.pceTbl[idx+2:], editor.pceTbl[idx+1:])
editor.pceTbl[idx] = firstPieceOfDividedElement
editor.pceTbl[idx+1] = secondPieceOfDividedElement
editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
} else {
oldPieces := append([]pieceTable{}, editor.pceTbl[idx:endIdx]...)
editor.pceTbl = append(editor.pceTbl[:idx+1], editor.pceTbl[endIdx:]...)
firstOfTheFirstPiece := pieceTable{editor.pceTbl[idx].origin,
editor.pceTbl[idx].offset,
int(offset)}
newPieces := append([]pieceTable{}, firstOfTheFirstPiece)
if length != 0 {
oldPieces = append(oldPieces, editor.pceTbl[idx+1])
secondOfTheSecondPiece := pieceTable{editor.pceTbl[idx+1].origin,
editor.pceTbl[idx+1].offset + int(length),
editor.pceTbl[idx+1].length - int(length)}
editor.pceTbl[idx+1] = secondOfTheSecondPiece
newPieces = append(newPieces, secondOfTheSecondPiece)
}
editor.transitionsBackward = append(editor.transitionsBackward, transition{oldPieces, newPieces})
editor.pceTbl[idx] = firstOfTheFirstPiece
}
}
}
return editor
}
func (editor editorImplementation) Undo() Editor {
if len(editor.transitionsBackward) > 0 {
backwTransitionsLastIndex := len(editor.transitionsBackward) - 1
undoTransition := editor.transitionsBackward[backwTransitionsLastIndex]
startIdx := 0
endIdx := 0
if undoTransition.from[0].length != -1 {
if undoTransition.to[0].length != -1 {
for idx := 0; idx < len(editor.pceTbl); idx++ {
if undoTransition.to[0] == editor.pceTbl[idx] {
startIdx = idx
idx = len(editor.pceTbl)
}
}
endIdx = startIdx + len(undoTransition.to)
editor.pceTbl = append(editor.pceTbl[:startIdx], editor.pceTbl[endIdx:]...)
for idx := 0; idx < len(undoTransition.from); idx++ {
editor.pceTbl = append(editor.pceTbl, pieceTable{})
}
copy(editor.pceTbl[startIdx+len(undoTransition.from):], editor.pceTbl[startIdx:])
copy(editor.pceTbl[startIdx:startIdx+len(undoTransition.from)], undoTransition.from)
} else {
startIdx = undoTransition.to[0].offset
for idx := 0; idx < len(undoTransition.from); idx++ {
editor.pceTbl = append(editor.pceTbl, pieceTable{})
}
copy(editor.pceTbl[startIdx+len(undoTransition.from):], editor.pceTbl[startIdx:])
copy(editor.pceTbl[undoTransition.to[0].offset:undoTransition.to[0].offset+len(undoTransition.from)],
undoTransition.from[:])
}
editor.transitionsForward = append(editor.transitionsForward, undoTransition)
editor.transitionsBackward = editor.transitionsBackward[:backwTransitionsLastIndex]
} else {
editor.pceTbl = append(editor.pceTbl[:undoTransition.from[0].offset], editor.pceTbl[undoTransition.from[0].offset+1:]...)
editor.transitionsForward = append(editor.transitionsForward, undoTransition)
editor.transitionsBackward = editor.transitionsBackward[:backwTransitionsLastIndex]
}
}
return editor
}
func (editor editorImplementation) Redo() Editor {
if len(editor.transitionsForward) > 0 {
forwTransitionsLastIndex := len(editor.transitionsForward) - 1
redoTransition := editor.transitionsForward[forwTransitionsLastIndex]
startIdx := 0
endIdx := 0
if redoTransition.from[0].length != -1 {
if redoTransition.to[0].length != -1 {
for idx := 0; idx < len(editor.pceTbl); idx++ {
if redoTransition.from[0] == editor.pceTbl[idx] {
startIdx = idx
idx = len(editor.pceTbl)
}
}
endIdx = startIdx + len(redoTransition.from)
editor.pceTbl = append(editor.pceTbl[:startIdx], editor.pceTbl[endIdx:]...)
for idx := 0; idx < len(redoTransition.to); idx++ {
editor.pceTbl = append(editor.pceTbl, pieceTable{})
}
copy(editor.pceTbl[startIdx+len(redoTransition.to):], editor.pceTbl[startIdx:])
copy(editor.pceTbl[startIdx:startIdx+len(redoTransition.to)], redoTransition.to)
} else {
editor.pceTbl = append(editor.pceTbl[:redoTransition.to[0].offset], editor.pceTbl[redoTransition.to[0].offset+1:]...)
}
} else {
startIdx = redoTransition.from[0].offset
for idx := 0; idx < len(redoTransition.to); idx++ {
editor.pceTbl = append(editor.pceTbl, pieceTable{})
}
copy(editor.pceTbl[startIdx+len(redoTransition.to):], editor.pceTbl[startIdx:])
copy(editor.pceTbl[redoTransition.from[0].offset:redoTransition.from[0].offset+len(redoTransition.to)],
redoTransition.to[:])
}
editor.transitionsBackward = append(editor.transitionsBackward, redoTransition)
editor.transitionsForward = editor.transitionsForward[:forwTransitionsLastIndex]
}
return editor
}
func (editor editorImplementation) String() string {
resultText := ""
for idx := 0; idx < len(editor.pceTbl); idx++ {
if editor.pceTbl[idx].origin == true {
resultText += editor.origin[editor.pceTbl[idx].offset:(editor.pceTbl[idx].offset + editor.pceTbl[idx].length)]
} else {
resultText += editor.add[editor.pceTbl[idx].offset:(editor.pceTbl[idx].offset + editor.pceTbl[idx].length)]
}
}
return resultText
}
-func (editor editorImplementation) GetAdd() string {
- return editor.add
-}
-
-func (editor editorImplementation) GetOriginLen() int {
- return len(editor.origin)
-}
-
-func (editor editorImplementation) GetAddLen() int {
- return len(editor.add)
-}
-
func NewEditor(editorContent string) Editor {
var editor = editorImplementation{origin: editorContent, add: "",
pceTbl: []pieceTable{{
true, 0, len(editorContent)}},
textLenght: uint(len(editorContent))}
return editor
}