Решение на Piece table от Кристиан Желязков

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

Към профила на Кристиан Желязков

Резултати

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

Код

package main
import (
"bytes"
)
type Editor interface {
Insert(position uint, text string) Editor
Delete(offset, length uint) Editor
Undo() Editor
Redo() Editor
String() string
}
type PieceTable struct {
origin []byte
add []byte
pStack piecesStack
lastAddedOffset int
}
type piecesStack struct {
currentPieces []Piece
previousPieces []Piece
nextPieces []Piece
}
type Piece struct {
origin bool
offset int
length int
}
func (pieceTable *PieceTable) Insert(position uint, text string) Editor {
if position > pieceTable.pStack.countCurrentPiecesSize() {
position = pieceTable.pStack.countCurrentPiecesSize()
}
pieceTable.add = append(pieceTable.add, text...)
newPieces := make([]Piece, 128)
counter := 0
isAdded := false
for _, piece := range pieceTable.pStack.currentPieces {
if piece.length > 0 {
if uint(counter+piece.length) >= position && !isAdded {
diff := int(position) - counter
firstPiece := Piece{origin: piece.origin, offset: piece.offset, length: diff}
secondPiece := Piece{origin: false, offset: pieceTable.lastAddedOffset, length: len(text)}
thirdPiece := Piece{origin: piece.origin, offset: piece.offset + diff, length: piece.length - diff}
newPieces = append(newPieces, firstPiece)
newPieces = append(newPieces, secondPiece)
newPieces = append(newPieces, thirdPiece)
pieceTable.lastAddedOffset += len(text)
isAdded = true
} else {
newPieces = append(newPieces, piece)
}
counter += piece.length
}
}
pieceTable.pStack.previousPieces = pieceTable.pStack.currentPieces
pieceTable.pStack.currentPieces = newPieces
pieceTable.pStack.nextPieces = nil
return pieceTable
}
func (pieceTable *PieceTable) Delete(offset, length uint) Editor {
if offset > pieceTable.pStack.countCurrentPiecesSize() {
return pieceTable
}
if offset+length > pieceTable.pStack.countCurrentPiecesSize() {
length = pieceTable.pStack.countCurrentPiecesSize() - offset
}
newPieces := make([]Piece, 128)
counter := uint(0)
isDeletionStarted := false
for _, piece := range pieceTable.pStack.currentPieces {
if piece.length > 0 {
if counter+uint(piece.length) >= offset && length > 0 {
diff := int(offset - counter)
if !isDeletionStarted {
firstPiece := Piece{origin: piece.origin, offset: piece.offset, length: piece.offset + diff}
newPieces = append(newPieces, firstPiece)
isDeletionStarted = true
}
if uint(piece.length-diff) >= length {
secondPiece := Piece{origin: piece.origin, offset: piece.offset + int(length) + diff, length: piece.length - int(length) - diff}
newPieces = append(newPieces, secondPiece)
length = 0
} else {
length -= uint(piece.length - diff)
}
} else {
newPieces = append(newPieces, piece)
}
counter += uint(piece.length)
if length > 0 && isDeletionStarted {
offset = counter
}
}
}
pieceTable.pStack.previousPieces = pieceTable.pStack.currentPieces
pieceTable.pStack.currentPieces = newPieces
pieceTable.pStack.nextPieces = nil
return pieceTable
}
func (pieceTable *PieceTable) Redo() Editor {
if pieceTable.pStack.currentPieces != nil && pieceTable.pStack.nextPieces != nil {
pieceTable.pStack.currentPieces = pieceTable.pStack.nextPieces
}
return pieceTable
}
func (pieceTable *PieceTable) Undo() Editor {
if pieceTable.pStack.currentPieces != nil && pieceTable.pStack.previousPieces != nil {
pieceTable.pStack.nextPieces = pieceTable.pStack.currentPieces
pieceTable.pStack.currentPieces = pieceTable.pStack.previousPieces
}
return pieceTable
}
func (pieceTable *PieceTable) String() string {
var buffer bytes.Buffer
for _, piece := range pieceTable.pStack.currentPieces {
if piece.length > 0 {
if piece.origin {
buffer.WriteString(string(pieceTable.origin[piece.offset : piece.offset+piece.length]))
} else {
buffer.WriteString(string(pieceTable.add[piece.offset : piece.offset+piece.length]))
}
}
}
return buffer.String()
}
func NewEditor(text string) Editor {
initPieces := make([]Piece, 34)
piece := Piece{origin: true, offset: 0, length: len(text)}
initPieces[0] = piece
initStack := piecesStack{currentPieces: initPieces, previousPieces: nil, nextPieces: nil}
pieceTable := new(PieceTable)
pieceTable.origin = []byte(text)
pieceTable.pStack = initStack
return pieceTable
}
func (pStack *piecesStack) countCurrentPiecesSize() uint {
counter := uint(0)
for _, piece := range pStack.currentPieces {
counter += uint(piece.length)
}
return counter
}
func main() {
}

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

--- FAIL: TestExampleFromReadme (0.00s)
    solution_test.go:75: Expect: "A span of text"; got "A span of text\x00\x00\x00\x00text"
FAIL
exit status 1
FAIL	_/tmp/d20181107-53-aquc9a	0.002s
PASS
ok  	_/tmp/d20181107-53-aquc9a	0.003s
PASS
ok  	_/tmp/d20181107-53-aquc9a	0.002s
--- FAIL: TestSeveralUndos (0.00s)
    solution_test.go:75: Expect: "A span of text"; got "A span of text\x00\x00\x00\x00text"
    solution_test.go:75: Expect: "A large span of text"; got "A span of English text"
FAIL
exit status 1
FAIL	_/tmp/d20181107-53-aquc9a	0.002s
PASS
ok  	_/tmp/d20181107-53-aquc9a	0.002s
--- FAIL: TestSeveralRedos (0.00s)
    solution_test.go:75: Expect: "A large span of text"; got "A span of English text"
    solution_test.go:75: Expect: "A span of text"; got "A span of English text"
FAIL
exit status 1
FAIL	_/tmp/d20181107-53-aquc9a	0.002s
PASS
ok  	_/tmp/d20181107-53-aquc9a	0.002s
PASS
ok  	_/tmp/d20181107-53-aquc9a	0.002s

История (4 версии и 2 коментара)

Кристиан обнови решението на 04.11.2018 13:28 (преди 9 месеца)

+package main
+
+import (
+ "bytes"
+ "fmt"
+)
+
+type Editor interface {
+ Insert(position uint, text string) Editor
+
+ Delete(offset, length uint) Editor
+
+ Undo() Editor
+
+ Redo() Editor
+
+ String() string
+}
+
+type PieceTable struct {
+ origin []byte
+ add []byte
+ pStack piecesStack
+ lastAddedOffset int
+}
+
+type piecesStack struct {
+ currentPieces []Piece
+ previousPieces []Piece
+ nextPieces []Piece
+}
+
+type Piece struct {
+ origin bool
+ offset int
+ length int
+}
+
+func (pieceTable *PieceTable) Insert(position uint, text string) Editor {
+ if position > uint(len(pieceTable.origin)+len(pieceTable.add)) {
+ position = uint(len(pieceTable.origin) + len(pieceTable.add))
+ }
+
+ pieceTable.add = append(pieceTable.add, text...)
+
+ newPieces := make([]Piece, 128)
+ counter := 0
+ isAdded := false
+
+ for _, piece := range pieceTable.pStack.currentPieces {
+ if piece.length > 0 {
+ if uint(counter+piece.length) >= position && !isAdded {
+ diff := int(position) - counter
+ firstPiece := Piece{origin: piece.origin, offset: piece.offset, length: diff}
+ secondPiece := Piece{origin: false, offset: pieceTable.lastAddedOffset, length: len(text)}
+ thirdPiece := Piece{origin: piece.origin, offset: piece.offset + diff, length: piece.length - diff}
+
+ newPieces = append(newPieces, firstPiece)
+ newPieces = append(newPieces, secondPiece)
+ newPieces = append(newPieces, thirdPiece)
+
+ pieceTable.lastAddedOffset += len(text)
+ isAdded = true
+ } else {
+ newPieces = append(newPieces, piece)
+ }
+ counter += piece.length
+ }
+ }
+ pieceTable.pStack.previousPieces = pieceTable.pStack.currentPieces
+ pieceTable.pStack.currentPieces = newPieces
+ pieceTable.pStack.nextPieces = nil
+
+ return pieceTable
+}
+
+func (pieceTable *PieceTable) Delete(offset, length uint) Editor {
+ if offset > uint(len(pieceTable.origin)+len(pieceTable.add)) {
+ return pieceTable
+ }
+ if offset+length > uint(len(pieceTable.origin)+len(pieceTable.add)) {
+ length = length + offset - uint(len(pieceTable.origin)+len(pieceTable.add))
+ }
+
+ newPieces := make([]Piece, 128)
+ counter := uint(0)
+ isDeletionStarted := false
+
+ for _, piece := range pieceTable.pStack.currentPieces {
+ if piece.length > 0 {
+ if counter+uint(piece.length) >= offset && length > 0 {
+ diff := int(offset - counter)
+ if !isDeletionStarted {
+ firstPiece := Piece{origin: piece.origin, offset: piece.offset, length: piece.offset + diff}
+ newPieces = append(newPieces, firstPiece)
+ isDeletionStarted = true
+ }
+ if uint(piece.length-diff) > length {
+ secondPiece := Piece{origin: piece.origin, offset: piece.offset + int(length) + 1, length: piece.length - int(length) - 1}
+ newPieces = append(newPieces, secondPiece)
+ length = 0
+ } else {
+ length -= uint(piece.length - diff)
+ }
+
+ } else {
+ newPieces = append(newPieces, piece)
+ }
+ counter += uint(piece.length)
+
+ if length > 0 {
+ offset = counter
+ }
+ }
+ }
+
+ pieceTable.pStack.previousPieces = pieceTable.pStack.currentPieces
+ pieceTable.pStack.currentPieces = newPieces
+ pieceTable.pStack.nextPieces = nil
+ return pieceTable
+}
+
+func (pieceTable *PieceTable) Redo() Editor {
+ if pieceTable.pStack.currentPieces != nil && pieceTable.pStack.nextPieces != nil {
+ pieceTable.pStack.currentPieces = pieceTable.pStack.nextPieces
+ }
+ return pieceTable
+}
+
+func (pieceTable *PieceTable) Undo() Editor {
+ if pieceTable.pStack.currentPieces != nil && pieceTable.pStack.previousPieces != nil {
+ pieceTable.pStack.nextPieces = pieceTable.pStack.currentPieces
+ pieceTable.pStack.currentPieces = pieceTable.pStack.previousPieces
+ }
+ return pieceTable
+}
+
+func (pieceTable *PieceTable) String() string {
+ var buffer bytes.Buffer
+
+ for _, piece := range pieceTable.pStack.currentPieces {
+ if piece.length > 0 {
+ if piece.origin {
+ buffer.WriteString(string(pieceTable.origin[piece.offset : piece.offset+piece.length]))
+ } else {
+ buffer.WriteString(string(pieceTable.add[piece.offset : piece.offset+piece.length]))
+ }
+ }
+ }
+
+ return buffer.String()
+}
+
+func NewEditor(text string) Editor {
+ initPieces := make([]Piece, 34)
+ piece := Piece{origin: true, offset: 0, length: len(text)}
+ initPieces[0] = piece
+ initStack := piecesStack{currentPieces: initPieces, previousPieces: nil, nextPieces: nil}
+ pieceTable := new(PieceTable)
+ pieceTable.origin = []byte(text)
+ pieceTable.pStack = initStack
+ return pieceTable
+}
+
+func main() {
+ var f = NewEditor("A large span of text")
+ f = f.Insert(16, "English ").Delete(2, 6)
+ fmt.Println(f.String())
+}

Кристиан обнови решението на 04.11.2018 15:14 (преди 9 месеца)

package main
import (
"bytes"
- "fmt"
)
type Editor interface {
Insert(position uint, text string) Editor
Delete(offset, length uint) Editor
Undo() Editor
Redo() Editor
String() string
}
type PieceTable struct {
origin []byte
add []byte
pStack piecesStack
lastAddedOffset int
}
type piecesStack struct {
currentPieces []Piece
previousPieces []Piece
nextPieces []Piece
}
type Piece struct {
origin bool
offset int
length int
}
func (pieceTable *PieceTable) Insert(position uint, text string) Editor {
if position > uint(len(pieceTable.origin)+len(pieceTable.add)) {
position = uint(len(pieceTable.origin) + len(pieceTable.add))
}
pieceTable.add = append(pieceTable.add, text...)
newPieces := make([]Piece, 128)
counter := 0
isAdded := false
for _, piece := range pieceTable.pStack.currentPieces {
if piece.length > 0 {
if uint(counter+piece.length) >= position && !isAdded {
diff := int(position) - counter
firstPiece := Piece{origin: piece.origin, offset: piece.offset, length: diff}
secondPiece := Piece{origin: false, offset: pieceTable.lastAddedOffset, length: len(text)}
thirdPiece := Piece{origin: piece.origin, offset: piece.offset + diff, length: piece.length - diff}
newPieces = append(newPieces, firstPiece)
newPieces = append(newPieces, secondPiece)
newPieces = append(newPieces, thirdPiece)
pieceTable.lastAddedOffset += len(text)
isAdded = true
} else {
newPieces = append(newPieces, piece)
}
counter += piece.length
}
}
pieceTable.pStack.previousPieces = pieceTable.pStack.currentPieces
pieceTable.pStack.currentPieces = newPieces
pieceTable.pStack.nextPieces = nil
return pieceTable
}
func (pieceTable *PieceTable) Delete(offset, length uint) Editor {
if offset > uint(len(pieceTable.origin)+len(pieceTable.add)) {
return pieceTable
}
if offset+length > uint(len(pieceTable.origin)+len(pieceTable.add)) {
length = length + offset - uint(len(pieceTable.origin)+len(pieceTable.add))
}
newPieces := make([]Piece, 128)
counter := uint(0)
isDeletionStarted := false
for _, piece := range pieceTable.pStack.currentPieces {
if piece.length > 0 {
if counter+uint(piece.length) >= offset && length > 0 {
diff := int(offset - counter)
if !isDeletionStarted {
firstPiece := Piece{origin: piece.origin, offset: piece.offset, length: piece.offset + diff}
newPieces = append(newPieces, firstPiece)
isDeletionStarted = true
}
- if uint(piece.length-diff) > length {
- secondPiece := Piece{origin: piece.origin, offset: piece.offset + int(length) + 1, length: piece.length - int(length) - 1}
+ if uint(piece.length-diff) >= length {
+ secondPiece := Piece{origin: piece.origin, offset: piece.offset + int(length) + diff, length: piece.length - int(length) - diff}
newPieces = append(newPieces, secondPiece)
length = 0
} else {
length -= uint(piece.length - diff)
}
} else {
newPieces = append(newPieces, piece)
}
counter += uint(piece.length)
-
if length > 0 {
offset = counter
}
}
}
pieceTable.pStack.previousPieces = pieceTable.pStack.currentPieces
pieceTable.pStack.currentPieces = newPieces
pieceTable.pStack.nextPieces = nil
return pieceTable
}
func (pieceTable *PieceTable) Redo() Editor {
if pieceTable.pStack.currentPieces != nil && pieceTable.pStack.nextPieces != nil {
pieceTable.pStack.currentPieces = pieceTable.pStack.nextPieces
}
return pieceTable
}
func (pieceTable *PieceTable) Undo() Editor {
if pieceTable.pStack.currentPieces != nil && pieceTable.pStack.previousPieces != nil {
pieceTable.pStack.nextPieces = pieceTable.pStack.currentPieces
pieceTable.pStack.currentPieces = pieceTable.pStack.previousPieces
}
return pieceTable
}
func (pieceTable *PieceTable) String() string {
var buffer bytes.Buffer
for _, piece := range pieceTable.pStack.currentPieces {
if piece.length > 0 {
if piece.origin {
buffer.WriteString(string(pieceTable.origin[piece.offset : piece.offset+piece.length]))
} else {
buffer.WriteString(string(pieceTable.add[piece.offset : piece.offset+piece.length]))
}
}
}
return buffer.String()
}
func NewEditor(text string) Editor {
initPieces := make([]Piece, 34)
piece := Piece{origin: true, offset: 0, length: len(text)}
initPieces[0] = piece
initStack := piecesStack{currentPieces: initPieces, previousPieces: nil, nextPieces: nil}
pieceTable := new(PieceTable)
pieceTable.origin = []byte(text)
pieceTable.pStack = initStack
return pieceTable
}
func main() {
- var f = NewEditor("A large span of text")
- f = f.Insert(16, "English ").Delete(2, 6)
- fmt.Println(f.String())
+
}

Кристиан обнови решението на 04.11.2018 16:18 (преди 9 месеца)

package main
import (
"bytes"
)
type Editor interface {
Insert(position uint, text string) Editor
Delete(offset, length uint) Editor
Undo() Editor
Redo() Editor
String() string
}
type PieceTable struct {
origin []byte
add []byte
pStack piecesStack
lastAddedOffset int
}
type piecesStack struct {
currentPieces []Piece
previousPieces []Piece
nextPieces []Piece
}
type Piece struct {
origin bool
offset int
length int
}
func (pieceTable *PieceTable) Insert(position uint, text string) Editor {
- if position > uint(len(pieceTable.origin)+len(pieceTable.add)) {
- position = uint(len(pieceTable.origin) + len(pieceTable.add))
+ if position > pieceTable.pStack.countCurrentPiecesSize() {
+ position = pieceTable.pStack.countCurrentPiecesSize()
}
pieceTable.add = append(pieceTable.add, text...)
newPieces := make([]Piece, 128)
counter := 0
isAdded := false
for _, piece := range pieceTable.pStack.currentPieces {
if piece.length > 0 {
if uint(counter+piece.length) >= position && !isAdded {
diff := int(position) - counter
firstPiece := Piece{origin: piece.origin, offset: piece.offset, length: diff}
secondPiece := Piece{origin: false, offset: pieceTable.lastAddedOffset, length: len(text)}
thirdPiece := Piece{origin: piece.origin, offset: piece.offset + diff, length: piece.length - diff}
newPieces = append(newPieces, firstPiece)
newPieces = append(newPieces, secondPiece)
newPieces = append(newPieces, thirdPiece)
pieceTable.lastAddedOffset += len(text)
isAdded = true
} else {
newPieces = append(newPieces, piece)
}
counter += piece.length
}
}
pieceTable.pStack.previousPieces = pieceTable.pStack.currentPieces
pieceTable.pStack.currentPieces = newPieces
pieceTable.pStack.nextPieces = nil
return pieceTable
}
func (pieceTable *PieceTable) Delete(offset, length uint) Editor {
- if offset > uint(len(pieceTable.origin)+len(pieceTable.add)) {
+ if offset > pieceTable.pStack.countCurrentPiecesSize() {
return pieceTable
}
- if offset+length > uint(len(pieceTable.origin)+len(pieceTable.add)) {
- length = length + offset - uint(len(pieceTable.origin)+len(pieceTable.add))
+ if offset+length > pieceTable.pStack.countCurrentPiecesSize() {
+ length = pieceTable.pStack.countCurrentPiecesSize() - offset
}
newPieces := make([]Piece, 128)
counter := uint(0)
isDeletionStarted := false
for _, piece := range pieceTable.pStack.currentPieces {
if piece.length > 0 {
- if counter+uint(piece.length) >= offset && length > 0 {
+ if counter+uint(piece.length) > offset && length > 0 {
diff := int(offset - counter)
if !isDeletionStarted {
firstPiece := Piece{origin: piece.origin, offset: piece.offset, length: piece.offset + diff}
newPieces = append(newPieces, firstPiece)
isDeletionStarted = true
}
if uint(piece.length-diff) >= length {
secondPiece := Piece{origin: piece.origin, offset: piece.offset + int(length) + diff, length: piece.length - int(length) - diff}
newPieces = append(newPieces, secondPiece)
length = 0
} else {
length -= uint(piece.length - diff)
}
-
} else {
newPieces = append(newPieces, piece)
}
counter += uint(piece.length)
- if length > 0 {
+ if length > 0 && isDeletionStarted {
offset = counter
}
}
}
pieceTable.pStack.previousPieces = pieceTable.pStack.currentPieces
pieceTable.pStack.currentPieces = newPieces
pieceTable.pStack.nextPieces = nil
return pieceTable
}
func (pieceTable *PieceTable) Redo() Editor {
if pieceTable.pStack.currentPieces != nil && pieceTable.pStack.nextPieces != nil {
pieceTable.pStack.currentPieces = pieceTable.pStack.nextPieces
}
return pieceTable
}
func (pieceTable *PieceTable) Undo() Editor {
if pieceTable.pStack.currentPieces != nil && pieceTable.pStack.previousPieces != nil {
pieceTable.pStack.nextPieces = pieceTable.pStack.currentPieces
pieceTable.pStack.currentPieces = pieceTable.pStack.previousPieces
}
return pieceTable
}
func (pieceTable *PieceTable) String() string {
var buffer bytes.Buffer
for _, piece := range pieceTable.pStack.currentPieces {
if piece.length > 0 {
if piece.origin {
buffer.WriteString(string(pieceTable.origin[piece.offset : piece.offset+piece.length]))
} else {
buffer.WriteString(string(pieceTable.add[piece.offset : piece.offset+piece.length]))
}
}
}
return buffer.String()
}
func NewEditor(text string) Editor {
initPieces := make([]Piece, 34)
piece := Piece{origin: true, offset: 0, length: len(text)}
initPieces[0] = piece
initStack := piecesStack{currentPieces: initPieces, previousPieces: nil, nextPieces: nil}
pieceTable := new(PieceTable)
pieceTable.origin = []byte(text)
pieceTable.pStack = initStack
return pieceTable
}
+func (pStack *piecesStack) countCurrentPiecesSize() uint {
+ counter := uint(0)
+ for _, piece := range pStack.currentPieces {
+ counter += uint(piece.length)
+ }
+ return counter
+}
+
func main() {
-
}

Кристиан обнови решението на 07.11.2018 13:43 (преди 9 месеца)

package main
-
import (
- "bytes"
+ "bytes"
)
-
type Editor interface {
- Insert(position uint, text string) Editor
-
- Delete(offset, length uint) Editor
-
- Undo() Editor
-
- Redo() Editor
-
- String() string
+ Insert(position uint, text string) Editor
+ Delete(offset, length uint) Editor
+ Undo() Editor
+ Redo() Editor
+ String() string
}
-
type PieceTable struct {
- origin []byte
- add []byte
- pStack piecesStack
- lastAddedOffset int
+ origin []byte
+ add []byte
+ pStack piecesStack
+ lastAddedOffset int
}
-
type piecesStack struct {
- currentPieces []Piece
- previousPieces []Piece
- nextPieces []Piece
+ currentPieces []Piece
+ previousPieces []Piece
+ nextPieces []Piece
}
-
type Piece struct {
- origin bool
- offset int
- length int
+ origin bool
+ offset int
+ length int
}
-
func (pieceTable *PieceTable) Insert(position uint, text string) Editor {
- if position > pieceTable.pStack.countCurrentPiecesSize() {
- position = pieceTable.pStack.countCurrentPiecesSize()
- }
-
- pieceTable.add = append(pieceTable.add, text...)
-
- newPieces := make([]Piece, 128)
- counter := 0
- isAdded := false
-
- for _, piece := range pieceTable.pStack.currentPieces {
- if piece.length > 0 {
- if uint(counter+piece.length) >= position && !isAdded {
- diff := int(position) - counter
- firstPiece := Piece{origin: piece.origin, offset: piece.offset, length: diff}
- secondPiece := Piece{origin: false, offset: pieceTable.lastAddedOffset, length: len(text)}
- thirdPiece := Piece{origin: piece.origin, offset: piece.offset + diff, length: piece.length - diff}
-
- newPieces = append(newPieces, firstPiece)
- newPieces = append(newPieces, secondPiece)
- newPieces = append(newPieces, thirdPiece)
-
- pieceTable.lastAddedOffset += len(text)
- isAdded = true
- } else {
- newPieces = append(newPieces, piece)
- }
- counter += piece.length
- }
- }
- pieceTable.pStack.previousPieces = pieceTable.pStack.currentPieces
- pieceTable.pStack.currentPieces = newPieces
- pieceTable.pStack.nextPieces = nil
-
- return pieceTable
+ if position > pieceTable.pStack.countCurrentPiecesSize() {
+ position = pieceTable.pStack.countCurrentPiecesSize()
+ }
+ pieceTable.add = append(pieceTable.add, text...)
+ newPieces := make([]Piece, 128)
+ counter := 0
+ isAdded := false
+ for _, piece := range pieceTable.pStack.currentPieces {
+ if piece.length > 0 {
+ if uint(counter+piece.length) >= position && !isAdded {
+ diff := int(position) - counter
+ firstPiece := Piece{origin: piece.origin, offset: piece.offset, length: diff}
+ secondPiece := Piece{origin: false, offset: pieceTable.lastAddedOffset, length: len(text)}
+ thirdPiece := Piece{origin: piece.origin, offset: piece.offset + diff, length: piece.length - diff}
+ newPieces = append(newPieces, firstPiece)
+ newPieces = append(newPieces, secondPiece)
+ newPieces = append(newPieces, thirdPiece)
+ pieceTable.lastAddedOffset += len(text)
+ isAdded = true
+ } else {
+ newPieces = append(newPieces, piece)
+ }
+ counter += piece.length
+ }
+ }
+ pieceTable.pStack.previousPieces = pieceTable.pStack.currentPieces
+ pieceTable.pStack.currentPieces = newPieces
+ pieceTable.pStack.nextPieces = nil
+ return pieceTable
}
-
func (pieceTable *PieceTable) Delete(offset, length uint) Editor {
- if offset > pieceTable.pStack.countCurrentPiecesSize() {
- return pieceTable
- }
- if offset+length > pieceTable.pStack.countCurrentPiecesSize() {
- length = pieceTable.pStack.countCurrentPiecesSize() - offset
- }
-
- newPieces := make([]Piece, 128)
- counter := uint(0)
- isDeletionStarted := false
-
- for _, piece := range pieceTable.pStack.currentPieces {
- if piece.length > 0 {
- if counter+uint(piece.length) > offset && length > 0 {
- diff := int(offset - counter)
- if !isDeletionStarted {
- firstPiece := Piece{origin: piece.origin, offset: piece.offset, length: piece.offset + diff}
- newPieces = append(newPieces, firstPiece)
- isDeletionStarted = true
- }
- if uint(piece.length-diff) >= length {
- secondPiece := Piece{origin: piece.origin, offset: piece.offset + int(length) + diff, length: piece.length - int(length) - diff}
- newPieces = append(newPieces, secondPiece)
- length = 0
- } else {
- length -= uint(piece.length - diff)
- }
- } else {
- newPieces = append(newPieces, piece)
- }
- counter += uint(piece.length)
- if length > 0 && isDeletionStarted {
- offset = counter
- }
- }
- }
-
- pieceTable.pStack.previousPieces = pieceTable.pStack.currentPieces
- pieceTable.pStack.currentPieces = newPieces
- pieceTable.pStack.nextPieces = nil
- return pieceTable
+ if offset > pieceTable.pStack.countCurrentPiecesSize() {
+ return pieceTable
+ }
+ if offset+length > pieceTable.pStack.countCurrentPiecesSize() {
+ length = pieceTable.pStack.countCurrentPiecesSize() - offset
+ }
+ newPieces := make([]Piece, 128)
+ counter := uint(0)
+ isDeletionStarted := false
+ for _, piece := range pieceTable.pStack.currentPieces {
+ if piece.length > 0 {
+ if counter+uint(piece.length) >= offset && length > 0 {
+ diff := int(offset - counter)
+ if !isDeletionStarted {
+ firstPiece := Piece{origin: piece.origin, offset: piece.offset, length: piece.offset + diff}
+ newPieces = append(newPieces, firstPiece)
+ isDeletionStarted = true
+ }
+ if uint(piece.length-diff) >= length {
+ secondPiece := Piece{origin: piece.origin, offset: piece.offset + int(length) + diff, length: piece.length - int(length) - diff}
+ newPieces = append(newPieces, secondPiece)
+ length = 0
+ } else {
+ length -= uint(piece.length - diff)
+ }
+ } else {
+ newPieces = append(newPieces, piece)
+ }
+ counter += uint(piece.length)
+ if length > 0 && isDeletionStarted {
+ offset = counter
+ }
+ }
+ }
+ pieceTable.pStack.previousPieces = pieceTable.pStack.currentPieces
+ pieceTable.pStack.currentPieces = newPieces
+ pieceTable.pStack.nextPieces = nil
+ return pieceTable
}
-
func (pieceTable *PieceTable) Redo() Editor {
- if pieceTable.pStack.currentPieces != nil && pieceTable.pStack.nextPieces != nil {
- pieceTable.pStack.currentPieces = pieceTable.pStack.nextPieces
- }
- return pieceTable
+ if pieceTable.pStack.currentPieces != nil && pieceTable.pStack.nextPieces != nil {
+ pieceTable.pStack.currentPieces = pieceTable.pStack.nextPieces
+ }
+ return pieceTable
}
-
func (pieceTable *PieceTable) Undo() Editor {
- if pieceTable.pStack.currentPieces != nil && pieceTable.pStack.previousPieces != nil {
- pieceTable.pStack.nextPieces = pieceTable.pStack.currentPieces
- pieceTable.pStack.currentPieces = pieceTable.pStack.previousPieces
- }
- return pieceTable
+ if pieceTable.pStack.currentPieces != nil && pieceTable.pStack.previousPieces != nil {
+ pieceTable.pStack.nextPieces = pieceTable.pStack.currentPieces
+ pieceTable.pStack.currentPieces = pieceTable.pStack.previousPieces
+ }
+ return pieceTable
}
-
func (pieceTable *PieceTable) String() string {
- var buffer bytes.Buffer
-
- for _, piece := range pieceTable.pStack.currentPieces {
- if piece.length > 0 {
- if piece.origin {
- buffer.WriteString(string(pieceTable.origin[piece.offset : piece.offset+piece.length]))
- } else {
- buffer.WriteString(string(pieceTable.add[piece.offset : piece.offset+piece.length]))
- }
- }
- }
-
- return buffer.String()
+ var buffer bytes.Buffer
+ for _, piece := range pieceTable.pStack.currentPieces {
+ if piece.length > 0 {
+ if piece.origin {
+ buffer.WriteString(string(pieceTable.origin[piece.offset : piece.offset+piece.length]))
+ } else {
+ buffer.WriteString(string(pieceTable.add[piece.offset : piece.offset+piece.length]))
+ }
+ }
+ }
+ return buffer.String()
}
-
func NewEditor(text string) Editor {
- initPieces := make([]Piece, 34)
- piece := Piece{origin: true, offset: 0, length: len(text)}
- initPieces[0] = piece
- initStack := piecesStack{currentPieces: initPieces, previousPieces: nil, nextPieces: nil}
- pieceTable := new(PieceTable)
- pieceTable.origin = []byte(text)
- pieceTable.pStack = initStack
- return pieceTable
+ initPieces := make([]Piece, 34)
+ piece := Piece{origin: true, offset: 0, length: len(text)}
+ initPieces[0] = piece
+ initStack := piecesStack{currentPieces: initPieces, previousPieces: nil, nextPieces: nil}
+ pieceTable := new(PieceTable)
+ pieceTable.origin = []byte(text)
+ pieceTable.pStack = initStack
+ return pieceTable
}
func (pStack *piecesStack) countCurrentPiecesSize() uint {
- counter := uint(0)
- for _, piece := range pStack.currentPieces {
- counter += uint(piece.length)
- }
-
- return counter
+ counter := uint(0)
+ for _, piece := range pStack.currentPieces {
+ counter += uint(piece.length)
+ }
+ return counter
}
-
func main() {
-}
+}