Решение на Piece table от Слави Боянов

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

Към профила на Слави Боянов

Резултати

  • 10 точки от тестове
  • 0 бонус точки
  • 10 точки общо
  • 8 успешни тест(а)
  • 0 неуспешни тест(а)

Код

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 piece []byte
type table struct {
undo *table
redo *table
pieces []piece
}
func NewEditor(text string) Editor {
editor := new(table)
if text != "" {
editor.pieces = append(
editor.pieces,
createPiece(text),
)
}
return editor
}
func (self *table) String() (result string) {
for _, piece := range self.pieces {
result += string(piece[:])
}
return
}
func (self *table) Insert(
position uint,
text string,
) Editor {
result := self.setupNext(len(self.pieces) + 2)
index, point := shouldSplitAt(self.pieces, position)
result.pieces = append(
result.pieces,
self.pieces[0:index]...,
)
if index < len(self.pieces) {
firstPart, secondPart := splitAt(
self.pieces[index],
point,
)
if len(firstPart) > 0 {
result.pieces = append(result.pieces, firstPart)
}
defer func() {
result.pieces = append(result.pieces, secondPart)
result.pieces = append(
result.pieces,
self.pieces[index+1:len(self.pieces)]...,
)
}()
}
result.pieces = append(result.pieces, createPiece(text))
return result
}
func (self *table) Delete(offset uint, length uint) Editor {
result := self.setupNext(len(self.pieces) + 1)
secondOffset := offset + length
index, point := shouldSplitAt(self.pieces, offset)
result.pieces = append(
result.pieces,
self.pieces[0:index]...,
)
if index < len(self.pieces) {
firstPart, _ := splitAt(
self.pieces[index],
point,
)
if len(firstPart) > 0 {
result.pieces = append(result.pieces, firstPart)
}
index, point := shouldSplitAt(
self.pieces,
secondOffset,
)
if index < len(self.pieces) {
_, secondPart := splitAt(
self.pieces[index],
point,
)
result.pieces = append(
result.pieces,
secondPart,
)
result.pieces = append(
result.pieces,
self.pieces[index+1:]...,
)
}
}
return result
}
func (self *table) Undo() Editor {
if self.undo == nil {
return self
}
return self.undo
}
func (self *table) Redo() Editor {
if self.redo == nil {
return self
}
return self.redo
}
func (self *table) setupNext(size int) (result *table) {
result = &table{
undo: self,
redo: nil,
pieces: make([]piece, 0, size),
}
self.redo = result
result.undo = self
return
}
func shouldSplitAt(
pieces []piece,
position uint,
) (index int, point int) {
left := int(position)
for i, onePiece := range pieces {
if left < len(onePiece) {
return i, left
}
left -= len(onePiece)
}
return len(pieces), 0
}
func splitAt(toSplit piece, point int) (piece, piece) {
return toSplit[:point], toSplit[point:]
}
func createPiece(text string) piece {
return piece([]byte(text))
}

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

PASS
ok  	_/tmp/d20181107-53-192a3jb	0.002s
PASS
ok  	_/tmp/d20181107-53-192a3jb	0.002s
PASS
ok  	_/tmp/d20181107-53-192a3jb	0.002s
PASS
ok  	_/tmp/d20181107-53-192a3jb	0.002s
PASS
ok  	_/tmp/d20181107-53-192a3jb	0.002s
PASS
ok  	_/tmp/d20181107-53-192a3jb	0.002s
PASS
ok  	_/tmp/d20181107-53-192a3jb	0.002s
PASS
ok  	_/tmp/d20181107-53-192a3jb	0.002s

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

Слави обнови решението на 06.11.2018 03:38 (преди 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 table struct {
+ undo *table
+ redo *table
+ pieces []piece
+}
+
+func NewEditor(text string) Editor {
+ editor := new(table)
+ if text != "" {
+ editor.pieces = append(
+ editor.pieces,
+ createPiece(text),
+ )
+ }
+ return editor
+}
+
+func (self *table) String() (result string) {
+ for _, piece := range self.pieces {
+ result += string(piece[:])
+ }
+ return
+}
+
+func (self *table) Insert(
+ position uint,
+ text string,
+) Editor {
+ result := self.setupNext(len(self.pieces) + 2)
+ index, point := shouldSplitAt(self.pieces, position)
+ result.pieces = append(
+ result.pieces,
+ self.pieces[0:index]...,
+ )
+ if index < len(self.pieces) {
+ firstPart, secondPart := splitAt(
+ self.pieces[index],
+ point,
+ )
+ if len(firstPart) > 0 {
+ result.pieces = append(result.pieces, firstPart)
+ }
+ defer func() {
+ result.pieces = append(result.pieces, secondPart)
+ result.pieces = append(
+ result.pieces,
+ self.pieces[index+1:len(self.pieces)]...,
+ )
+ }()
+ }
+ result.pieces = append(result.pieces, createPiece(text))
+ return result
+}
+
+func (self *table) Delete(offset uint, length uint) Editor {
+ result := self.setupNext(len(self.pieces) + 1)
+ secondOffset := offset + length
+ index, point := shouldSplitAt(self.pieces, offset)
+ result.pieces = append(
+ result.pieces,
+ self.pieces[0:index]...,
+ )
+ if index < len(self.pieces) {
+ firstPart, _ := splitAt(
+ self.pieces[index],
+ point,
+ )
+ if len(firstPart) > 0 {
+ result.pieces = append(result.pieces, firstPart)
+ }
+ index, point := shouldSplitAt(
+ self.pieces,
+ secondOffset,
+ )
+ if index < len(self.pieces) {
+ _, secondPart := splitAt(
+ self.pieces[index],
+ point,
+ )
+ result.pieces = append(
+ result.pieces,
+ secondPart,
+ )
+ result.pieces = append(
+ result.pieces,
+ self.pieces[index+1:]...,
+ )
+ }
+ }
+ return result
+}
+
+func (self *table) Undo() Editor {
+ if self.undo == nil {
+ return self
+ }
+ return self.undo
+}
+
+func (self *table) Redo() Editor {
+ if self.redo == nil {
+ return self
+ }
+ return self.redo
+}
+
+func (self *table) setupNext(size int) (result *table) {
+ result = &table{
+ undo: self,
+ redo: nil,
+ pieces: make([]piece, 0, size),
+ }
+ self.redo = result
+ result.undo = self
+ return
+}
+
+func shouldSplitAt(
+ pieces []piece,
+ position uint,
+) (index int, point int) {
+ left := int(position)
+ for i, onePiece := range pieces {
+ if left < len(onePiece) {
+ return i, left
+ }
+ left -= len(onePiece)
+ }
+ return len(pieces), 0
+}
+
+func splitAt(toSplit piece, point int) (piece, piece) {
+ return toSplit[:point], toSplit[point:]
+}
+
+type piece []byte
+
+func createPiece(text string) piece {
+ return piece([]byte(text))
+}

Слави обнови решението на 06.11.2018 03:43 (преди 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 piece []byte
+
type table struct {
undo *table
redo *table
pieces []piece
}
func NewEditor(text string) Editor {
editor := new(table)
if text != "" {
editor.pieces = append(
editor.pieces,
createPiece(text),
)
}
return editor
}
func (self *table) String() (result string) {
for _, piece := range self.pieces {
result += string(piece[:])
}
return
}
func (self *table) Insert(
position uint,
text string,
) Editor {
result := self.setupNext(len(self.pieces) + 2)
index, point := shouldSplitAt(self.pieces, position)
result.pieces = append(
result.pieces,
self.pieces[0:index]...,
)
if index < len(self.pieces) {
firstPart, secondPart := splitAt(
self.pieces[index],
point,
)
if len(firstPart) > 0 {
result.pieces = append(result.pieces, firstPart)
}
defer func() {
result.pieces = append(result.pieces, secondPart)
result.pieces = append(
result.pieces,
self.pieces[index+1:len(self.pieces)]...,
)
}()
}
result.pieces = append(result.pieces, createPiece(text))
return result
}
func (self *table) Delete(offset uint, length uint) Editor {
result := self.setupNext(len(self.pieces) + 1)
secondOffset := offset + length
index, point := shouldSplitAt(self.pieces, offset)
result.pieces = append(
result.pieces,
self.pieces[0:index]...,
)
if index < len(self.pieces) {
firstPart, _ := splitAt(
self.pieces[index],
point,
)
if len(firstPart) > 0 {
result.pieces = append(result.pieces, firstPart)
}
index, point := shouldSplitAt(
self.pieces,
secondOffset,
)
if index < len(self.pieces) {
_, secondPart := splitAt(
self.pieces[index],
point,
)
result.pieces = append(
result.pieces,
secondPart,
)
result.pieces = append(
result.pieces,
self.pieces[index+1:]...,
)
}
}
return result
}
func (self *table) Undo() Editor {
if self.undo == nil {
return self
}
return self.undo
}
func (self *table) Redo() Editor {
if self.redo == nil {
return self
}
return self.redo
}
func (self *table) setupNext(size int) (result *table) {
result = &table{
undo: self,
redo: nil,
pieces: make([]piece, 0, size),
}
self.redo = result
result.undo = self
return
}
func shouldSplitAt(
pieces []piece,
position uint,
) (index int, point int) {
left := int(position)
for i, onePiece := range pieces {
if left < len(onePiece) {
return i, left
}
left -= len(onePiece)
}
return len(pieces), 0
}
func splitAt(toSplit piece, point int) (piece, piece) {
return toSplit[:point], toSplit[point:]
}
-
-type piece []byte
func createPiece(text string) piece {
return piece([]byte(text))
}