Решение на Piece table от Иван Ангелов

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

Към профила на Иван Ангелов

Резултати

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

Код

package main
type Editor interface {
// String returns complete representation of what a file looks
// like after all manipulations.
String() string
// Insert text starting from given position.
Insert(position uint, text string) Editor
// Delete length items from offset.
Delete(offset, length uint) Editor
}
type CustomEditor struct {
Origin []byte
Add []byte
CurrOffsetAdd uint
Table []Piece
CurrLengthFile uint
}
type Piece struct {
Origin bool
Offset uint
Length uint
}
func (f CustomEditor) String() (result string) {
for _, piece := range f.Table {
if piece.Origin == true {
result += string(f.Origin[piece.Offset:piece.Length])
} else {
result += string(f.Add[piece.Offset : piece.Offset+piece.Length])
}
}
return
}
func NewEditor(s string) (e Editor) {
origin := []byte(s)
add := make([]byte, 0)
table := make([]Piece, 0)
table = append(table, Piece{Origin: true, Offset: 0, Length: uint(len(s))})
e = &CustomEditor{Origin: origin, CurrOffsetAdd: 0, Add: add, Table: table, CurrLengthFile: uint(len(s))}
return
}
func (f CustomEditor) Delete(offset uint, length uint) Editor {
if offset >= f.CurrLengthFile {
//do nothing
} else if offset+length >= f.CurrLengthFile {
if offset == 0 {
f.Table = f.Table[:0]
} else {
var currLength uint
var idxDelete int
var lastLength uint
for i, piece := range f.Table {
currLength += piece.Length
if offset < currLength {
idxDelete = i
lastLength = piece.Length
break
}
}
f.Table = f.Table[0 : idxDelete+1]
del := offset - currLength + lastLength
f.Table[idxDelete].Length = del
}
} else {
var currLength uint
var idxFirstDelete int
var idxSecondDelete int
var firstDelete uint
var secondDelete uint
var gone bool
var isSameBuf bool
var secondDeleteStart uint
for i, piece := range f.Table {
currLength += piece.Length
if !isSameBuf && offset < currLength && offset+length < currLength {
isSameBuf = true
idxFirstDelete = i
idxSecondDelete = i
firstDelete = offset - currLength + piece.Length
secondDelete = firstDelete + length
break
}
if !gone && offset < currLength {
idxFirstDelete = i
firstDelete = offset - currLength + piece.Length
gone = true
}
if gone && offset+length < currLength {
idxSecondDelete = i
secondDeleteStart = offset + length - currLength + piece.Length
secondDelete = currLength - length - offset
break
}
}
if isSameBuf {
cLength := f.Table[idxFirstDelete].Length
f.Table[idxFirstDelete].Length = firstDelete
newPieceInAdd := Piece{Origin: f.Table[idxFirstDelete].Origin, Offset: secondDelete, Length: cLength - secondDelete}
f.Table = append(f.Table, Piece{})
copy(f.Table[idxFirstDelete+1:], f.Table[idxFirstDelete:])
f.Table[idxFirstDelete+1] = newPieceInAdd
} else {
//handle first
f.Table[idxFirstDelete].Length = firstDelete
//handle second
f.Table[idxSecondDelete].Offset += secondDeleteStart
f.Table[idxSecondDelete].Length = secondDelete
f.Table = append(f.Table[0:idxFirstDelete+1], f.Table[idxSecondDelete:]...)
}
}
return f
}
func (f CustomEditor) Insert(position uint, text string) Editor {
//append new string to add slice
f.Add = append(f.Add, text...)
//create new piece for add,
//offset is calcualted by add buffer
newPieceInAdd := Piece{Origin: false, Offset: f.CurrOffsetAdd, Length: uint(len(text))}
f.CurrOffsetAdd += uint(len(text)) //+ 1
if position > f.CurrLengthFile {
if f.Table[len(f.Table)-1].Origin == false {
position = f.CurrLengthFile
//append to curr file
f.Table[len(f.Table)-1].Length += uint(len(text))
//f.Table = append(f.Table, newPieceInAdd)
} else {
position = f.CurrLengthFile
//append to curr file
f.Table = append(f.Table, newPieceInAdd)
}
} else {
//find before piece
var idx int
for i, piece := range f.Table {
if piece.Offset <= position && position <= piece.Length {
idx = i
break
}
}
f.CurrLengthFile += uint(len(text))
//modify before piece
oldLength := f.Table[idx].Length
f.Table[idx].Length = position
//create afterPiece
newPieceAfterAdded := Piece{Origin: f.Table[idx].Origin, Offset: f.Table[idx].Length, Length: oldLength}
//add new piece
//add after added piece
if len(f.Table) == 1 {
f.Table = append(f.Table, newPieceInAdd, newPieceAfterAdded)
} else {
f.Table = append(f.Table, Piece{}, Piece{})
copy(f.Table[idx+3:], f.Table[idx+1:])
f.Table[idx+1] = newPieceInAdd
f.Table[idx+2] = newPieceAfterAdded
}
}
return f
}

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

# _/tmp/d20181107-53-ux5vqm [_/tmp/d20181107-53-ux5vqm.test]
./solution_test.go:28:26: f.Undo undefined (type Editor has no field or method Undo)
./solution_test.go:31:39: f.Delete(2, 6).Undo undefined (type Editor has no field or method Undo)
./solution_test.go:40:38: f.Undo undefined (type Editor has no field or method Undo)
./solution_test.go:47:26: f.Undo undefined (type Editor has no field or method Undo)
./solution_test.go:52:52: NewEditor("A large span of text").Insert(16, "English ").Delete(2, 6).Delete(10, 8).Undo undefined (type Editor has no field or method Undo)
./solution_test.go:61:25: NewEditor("A large span of text").Insert(16, "English ").Undo undefined (type Editor has no field or method Undo)
FAIL	_/tmp/d20181107-53-ux5vqm [build failed]
# _/tmp/d20181107-53-ux5vqm [_/tmp/d20181107-53-ux5vqm.test]
./solution_test.go:28:26: f.Undo undefined (type Editor has no field or method Undo)
./solution_test.go:31:39: f.Delete(2, 6).Undo undefined (type Editor has no field or method Undo)
./solution_test.go:40:38: f.Undo undefined (type Editor has no field or method Undo)
./solution_test.go:47:26: f.Undo undefined (type Editor has no field or method Undo)
./solution_test.go:52:52: NewEditor("A large span of text").Insert(16, "English ").Delete(2, 6).Delete(10, 8).Undo undefined (type Editor has no field or method Undo)
./solution_test.go:61:25: NewEditor("A large span of text").Insert(16, "English ").Undo undefined (type Editor has no field or method Undo)
FAIL	_/tmp/d20181107-53-ux5vqm [build failed]
# _/tmp/d20181107-53-ux5vqm [_/tmp/d20181107-53-ux5vqm.test]
./solution_test.go:28:26: f.Undo undefined (type Editor has no field or method Undo)
./solution_test.go:31:39: f.Delete(2, 6).Undo undefined (type Editor has no field or method Undo)
./solution_test.go:40:38: f.Undo undefined (type Editor has no field or method Undo)
./solution_test.go:47:26: f.Undo undefined (type Editor has no field or method Undo)
./solution_test.go:52:52: NewEditor("A large span of text").Insert(16, "English ").Delete(2, 6).Delete(10, 8).Undo undefined (type Editor has no field or method Undo)
./solution_test.go:61:25: NewEditor("A large span of text").Insert(16, "English ").Undo undefined (type Editor has no field or method Undo)
FAIL	_/tmp/d20181107-53-ux5vqm [build failed]
# _/tmp/d20181107-53-ux5vqm [_/tmp/d20181107-53-ux5vqm.test]
./solution_test.go:28:26: f.Undo undefined (type Editor has no field or method Undo)
./solution_test.go:31:39: f.Delete(2, 6).Undo undefined (type Editor has no field or method Undo)
./solution_test.go:40:38: f.Undo undefined (type Editor has no field or method Undo)
./solution_test.go:47:26: f.Undo undefined (type Editor has no field or method Undo)
./solution_test.go:52:52: NewEditor("A large span of text").Insert(16, "English ").Delete(2, 6).Delete(10, 8).Undo undefined (type Editor has no field or method Undo)
./solution_test.go:61:25: NewEditor("A large span of text").Insert(16, "English ").Undo undefined (type Editor has no field or method Undo)
FAIL	_/tmp/d20181107-53-ux5vqm [build failed]
# _/tmp/d20181107-53-ux5vqm [_/tmp/d20181107-53-ux5vqm.test]
./solution_test.go:28:26: f.Undo undefined (type Editor has no field or method Undo)
./solution_test.go:31:39: f.Delete(2, 6).Undo undefined (type Editor has no field or method Undo)
./solution_test.go:40:38: f.Undo undefined (type Editor has no field or method Undo)
./solution_test.go:47:26: f.Undo undefined (type Editor has no field or method Undo)
./solution_test.go:52:52: NewEditor("A large span of text").Insert(16, "English ").Delete(2, 6).Delete(10, 8).Undo undefined (type Editor has no field or method Undo)
./solution_test.go:61:25: NewEditor("A large span of text").Insert(16, "English ").Undo undefined (type Editor has no field or method Undo)
FAIL	_/tmp/d20181107-53-ux5vqm [build failed]
# _/tmp/d20181107-53-ux5vqm [_/tmp/d20181107-53-ux5vqm.test]
./solution_test.go:28:26: f.Undo undefined (type Editor has no field or method Undo)
./solution_test.go:31:39: f.Delete(2, 6).Undo undefined (type Editor has no field or method Undo)
./solution_test.go:40:38: f.Undo undefined (type Editor has no field or method Undo)
./solution_test.go:47:26: f.Undo undefined (type Editor has no field or method Undo)
./solution_test.go:52:52: NewEditor("A large span of text").Insert(16, "English ").Delete(2, 6).Delete(10, 8).Undo undefined (type Editor has no field or method Undo)
./solution_test.go:61:25: NewEditor("A large span of text").Insert(16, "English ").Undo undefined (type Editor has no field or method Undo)
FAIL	_/tmp/d20181107-53-ux5vqm [build failed]
# _/tmp/d20181107-53-ux5vqm [_/tmp/d20181107-53-ux5vqm.test]
./solution_test.go:28:26: f.Undo undefined (type Editor has no field or method Undo)
./solution_test.go:31:39: f.Delete(2, 6).Undo undefined (type Editor has no field or method Undo)
./solution_test.go:40:38: f.Undo undefined (type Editor has no field or method Undo)
./solution_test.go:47:26: f.Undo undefined (type Editor has no field or method Undo)
./solution_test.go:52:52: NewEditor("A large span of text").Insert(16, "English ").Delete(2, 6).Delete(10, 8).Undo undefined (type Editor has no field or method Undo)
./solution_test.go:61:25: NewEditor("A large span of text").Insert(16, "English ").Undo undefined (type Editor has no field or method Undo)
FAIL	_/tmp/d20181107-53-ux5vqm [build failed]
# _/tmp/d20181107-53-ux5vqm [_/tmp/d20181107-53-ux5vqm.test]
./solution_test.go:28:26: f.Undo undefined (type Editor has no field or method Undo)
./solution_test.go:31:39: f.Delete(2, 6).Undo undefined (type Editor has no field or method Undo)
./solution_test.go:40:38: f.Undo undefined (type Editor has no field or method Undo)
./solution_test.go:47:26: f.Undo undefined (type Editor has no field or method Undo)
./solution_test.go:52:52: NewEditor("A large span of text").Insert(16, "English ").Delete(2, 6).Delete(10, 8).Undo undefined (type Editor has no field or method Undo)
./solution_test.go:61:25: NewEditor("A large span of text").Insert(16, "English ").Undo undefined (type Editor has no field or method Undo)
FAIL	_/tmp/d20181107-53-ux5vqm [build failed]

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

Иван обнови решението на 06.11.2018 23:49 (преди 9 месеца)

+package main
+
+type Editor interface {
+ // String returns complete representation of what a file looks
+ // like after all manipulations.
+ String() string
+
+ // Insert text starting from given position.
+ Insert(position uint, text string) Editor
+
+ // Delete length items from offset.
+ Delete(offset, length uint) Editor
+}
+
+type CustomEditor struct {
+ Origin []byte
+ Add []byte
+ CurrOffsetAdd uint
+ Table []Piece
+ CurrLengthFile uint
+}
+
+type Piece struct {
+ Origin bool
+ Offset uint
+ Length uint
+}
+
+func (f CustomEditor) String() (result string) {
+ for _, piece := range f.Table {
+ if piece.Origin == true {
+ result += string(f.Origin[piece.Offset:piece.Length])
+ } else {
+ result += string(f.Add[piece.Offset : piece.Offset+piece.Length])
+ }
+ }
+
+ return
+}
+
+func NewEditor(s string) (e Editor) {
+ origin := []byte(s)
+ add := make([]byte, 0)
+ table := make([]Piece, 0)
+ table = append(table, Piece{Origin: true, Offset: 0, Length: uint(len(s))})
+ e = &CustomEditor{Origin: origin, CurrOffsetAdd: 0, Add: add, Table: table, CurrLengthFile: uint(len(s))}
+
+ return
+}
+
+func (f CustomEditor) Delete(offset uint, length uint) Editor {
+ if offset >= f.CurrLengthFile {
+ //do nothing
+ } else if offset+length >= f.CurrLengthFile {
+ if offset == 0 {
+ f.Table = f.Table[:0]
+ } else {
+ var currLength uint
+ var idxDelete int
+ var lastLength uint
+ for i, piece := range f.Table {
+ currLength += piece.Length
+ if offset < currLength {
+ idxDelete = i
+ lastLength = piece.Length
+ break
+ }
+
+ }
+
+ f.Table = f.Table[0 : idxDelete+1]
+ del := offset - currLength + lastLength
+ f.Table[idxDelete].Length = del
+ }
+ } else {
+ var currLength uint
+ var idxFirstDelete int
+ var idxSecondDelete int
+ var firstDelete uint
+ var secondDelete uint
+ var gone bool
+ var isSameBuf bool
+
+ var secondDeleteStart uint
+
+ for i, piece := range f.Table {
+ currLength += piece.Length
+ if !isSameBuf && offset < currLength && offset+length < currLength {
+ isSameBuf = true
+ idxFirstDelete = i
+ idxSecondDelete = i
+ firstDelete = offset - currLength + piece.Length
+ secondDelete = firstDelete + length
+ break
+ }
+ if !gone && offset < currLength {
+ idxFirstDelete = i
+ firstDelete = offset - currLength + piece.Length
+ gone = true
+ }
+
+ if gone && offset+length < currLength {
+ idxSecondDelete = i
+ secondDeleteStart = offset + length - currLength + piece.Length
+ secondDelete = currLength - length - offset
+ break
+ }
+
+ }
+
+ if isSameBuf {
+ cLength := f.Table[idxFirstDelete].Length
+ f.Table[idxFirstDelete].Length = firstDelete
+ newPieceInAdd := Piece{Origin: f.Table[idxFirstDelete].Origin, Offset: secondDelete, Length: cLength - secondDelete}
+ f.Table = append(f.Table, Piece{})
+
+ copy(f.Table[idxFirstDelete+1:], f.Table[idxFirstDelete:])
+
+ f.Table[idxFirstDelete+1] = newPieceInAdd
+
+ } else {
+ //handle first
+ f.Table[idxFirstDelete].Length = firstDelete
+
+ //handle second
+ f.Table[idxSecondDelete].Offset += secondDeleteStart
+ f.Table[idxSecondDelete].Length = secondDelete
+ f.Table = append(f.Table[0:idxFirstDelete+1], f.Table[idxSecondDelete:]...)
+ }
+
+ }
+
+ return f
+}
+
+func (f CustomEditor) Insert(position uint, text string) Editor {
+ //append new string to add slice
+ f.Add = append(f.Add, text...)
+ //create new piece for add,
+ //offset is calcualted by add buffer
+ newPieceInAdd := Piece{Origin: false, Offset: f.CurrOffsetAdd, Length: uint(len(text))}
+ f.CurrOffsetAdd += uint(len(text)) //+ 1
+
+ if position > f.CurrLengthFile {
+ if f.Table[len(f.Table)-1].Origin == false {
+ position = f.CurrLengthFile
+ //append to curr file
+ f.Table[len(f.Table)-1].Length += uint(len(text))
+ //f.Table = append(f.Table, newPieceInAdd)
+ } else {
+ position = f.CurrLengthFile
+ //append to curr file
+ f.Table = append(f.Table, newPieceInAdd)
+ }
+
+ } else {
+ //find before piece
+ var idx int
+ for i, piece := range f.Table {
+ if piece.Offset <= position && position <= piece.Length {
+ idx = i
+ break
+ }
+ }
+
+ f.CurrLengthFile += uint(len(text))
+
+ //modify before piece
+ oldLength := f.Table[idx].Length
+ f.Table[idx].Length = position
+
+ //create afterPiece
+ newPieceAfterAdded := Piece{Origin: f.Table[idx].Origin, Offset: f.Table[idx].Length, Length: oldLength}
+
+ //add new piece
+ //add after added piece
+
+ if len(f.Table) == 1 {
+ f.Table = append(f.Table, newPieceInAdd, newPieceAfterAdded)
+ } else {
+ f.Table = append(f.Table, Piece{}, Piece{})
+ copy(f.Table[idx+3:], f.Table[idx+1:])
+ f.Table[idx+1] = newPieceInAdd
+ f.Table[idx+2] = newPieceAfterAdded
+ }
+ }
+
+ return f
+}