Решение на Piece table от Павел Хаджиев

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

Към профила на Павел Хаджиев

Резултати

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

Код

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 struct {
origin bool
offset uint
length uint
}
type MyEditor struct {
pieceTable []Piece
origin []byte
add []byte
}
func NewEditor(originString string) Editor {
initialPiece := Piece{origin: true, offset: 0, length: uint(len(originString))}
pieceTable := make([]Piece, 1)
pieceTable[0] = initialPiece
origin := make([]byte, 0, len(originString))
origin = append(origin, []byte(originString)...)
add := make([]byte, 0, 10)
return &MyEditor{pieceTable: pieceTable, origin: origin, add: add}
}
func (ed *MyEditor) Insert(position uint, text string) Editor {
length := uint(0)
inserted := false
addPiece := Piece{origin: false, offset: uint(len(ed.add)), length: uint(len(text))}
for index, piece := range ed.pieceTable {
if (length + piece.length == position) {
temp := append([]Piece{addPiece}, ed.pieceTable[index + 1:]...)
ed.pieceTable = append(ed.pieceTable[:index + 1], temp...)
inserted = true
break
}
if (length + piece.length > position) {
firstHalfLength := position - length
secondHalfLength := piece.length - firstHalfLength
firstHalfOffset := piece.offset
secondHalfOffset := firstHalfOffset + firstHalfLength
firstHalf := Piece{origin: piece.origin, offset: firstHalfOffset, length: firstHalfLength}
secondHalf := Piece{origin: piece.origin, offset: secondHalfOffset, length: secondHalfLength}
ed.pieceTable[index] = firstHalf
temp := append([]Piece{addPiece, secondHalf}, ed.pieceTable[index + 1:]...)
ed.pieceTable = append(ed.pieceTable[:index + 1], temp...)
inserted = true
break
}
length += piece.length;
}
if !inserted {
ed.pieceTable = append(ed.pieceTable, []Piece{addPiece}...)
}
ed.add = append(ed.add, []byte(text)...)
return ed
}
func (ed *MyEditor) Delete(offset, lengthToDelete uint) Editor {
length := uint(0)
for index := 0; index < len(ed.pieceTable); index++ {
piece := ed.pieceTable[index]
if lengthToDelete == 0 {
break
}
if offset == length {
if lengthToDelete >= piece.length {
if index + 1 < len(ed.pieceTable) {
lengthToDelete -= piece.length
ed.pieceTable = append(ed.pieceTable[:index], ed.pieceTable[index + 1:]...)
index--
continue
} else {
ed.pieceTable = ed.pieceTable[:index]
break
}
} else {
ed.pieceTable[index].offset += lengthToDelete
ed.pieceTable[index].length -= lengthToDelete
break;
}
}
// if offset < length + piece.length {
// if lengthToDelete >= piece.length {
// if index + 1 < len(ed.pieceTable) {
// lengthToDelete -= piece.length
// ed.pieceTable = append(ed.pieceTable[:index], ed.pieceTable[index + 1:]...)
// index--
// continue
// } else {
// ed.pieceTable = ed.pieceTable[:index]
// break
// }
// } else {
// ed.pieceTable[index].length -= lengthToDelete
// break;
// }
// }
length += piece.length
}
return ed
}
func (ed *MyEditor) Undo() Editor {
return ed
}
func (ed *MyEditor) Redo() Editor {
return ed
}
func (ed MyEditor) String() string {
result := ""
for _, piece := range ed.pieceTable {
var toAppend string
if (piece.origin) {
toAppend = string(ed.origin[piece.offset:piece.offset + piece.length])
} else {
toAppend = string(ed.add[piece.offset:piece.offset + piece.length])
}
result += toAppend
}
return result
}

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

--- FAIL: TestExampleFromReadme (0.00s)
    solution_test.go:75: Expect: "A span of English text"; got "A large span of English text"
    solution_test.go:75: Expect: "A span of text"; got "A large span of English text"
FAIL
exit status 1
FAIL	_/tmp/d20181107-53-1qlwn94	0.003s
--- FAIL: TestOutOfBound (0.00s)
    solution_test.go:75: Expect: "A span of"; got "A span of text!"
FAIL
exit status 1
FAIL	_/tmp/d20181107-53-1qlwn94	0.002s
PASS
ok  	_/tmp/d20181107-53-1qlwn94	0.003s
--- FAIL: TestSeveralUndos (0.00s)
    solution_test.go:75: Expect: "A span of text"; got "A large span of English text"
    solution_test.go:75: Expect: "A large span of text"; got "A large span of English text"
FAIL
exit status 1
FAIL	_/tmp/d20181107-53-1qlwn94	0.002s
PASS
ok  	_/tmp/d20181107-53-1qlwn94	0.002s
--- FAIL: TestSeveralRedos (0.00s)
    solution_test.go:75: Expect: "A large span of text"; got "A large span of English text"
    solution_test.go:75: Expect: "A span of text"; got "A large span of English text"
FAIL
exit status 1
FAIL	_/tmp/d20181107-53-1qlwn94	0.002s
PASS
ok  	_/tmp/d20181107-53-1qlwn94	0.003s
--- FAIL: TestUnicode (0.00s)
    solution_test.go:75: Expect: "Жълтата дюля беше щастлива, че пухът, който цъфна, замръзна като гьон."; got "Жълтата дюля беше щастлива, че пухът, който цъфна, и замръзна като гьон."
FAIL
exit status 1
FAIL	_/tmp/d20181107-53-1qlwn94	0.002s

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

Павел обнови решението на 07.11.2018 16:59 (преди 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 struct {
+ origin bool
+ offset uint
+ length uint
+}
+
+type MyEditor struct {
+ pieceTable []Piece
+
+ origin []byte
+ add []byte
+}
+
+func NewEditor(originString string) Editor {
+ initialPiece := Piece{origin: true, offset: 0, length: uint(len(originString))}
+ pieceTable := make([]Piece, 1)
+ pieceTable[0] = initialPiece
+
+ origin := make([]byte, 0, len(originString))
+ origin = append(origin, []byte(originString)...)
+
+ add := make([]byte, 0, 10)
+
+ return &MyEditor{pieceTable: pieceTable, origin: origin, add: add}
+}
+
+func (ed *MyEditor) Insert(position uint, text string) Editor {
+ length := uint(0)
+ inserted := false
+ addPiece := Piece{origin: false, offset: uint(len(ed.add)), length: uint(len(text))}
+ for index, piece := range ed.pieceTable {
+ if (length + piece.length == position) {
+ temp := append([]Piece{addPiece}, ed.pieceTable[index + 1:]...)
+ ed.pieceTable = append(ed.pieceTable[:index + 1], temp...)
+
+ inserted = true
+ break
+ }
+
+ if (length + piece.length > position) {
+ firstHalfLength := position - length
+ secondHalfLength := piece.length - firstHalfLength
+
+ firstHalfOffset := piece.offset
+ secondHalfOffset := firstHalfOffset + firstHalfLength
+
+ firstHalf := Piece{origin: piece.origin, offset: firstHalfOffset, length: firstHalfLength}
+ secondHalf := Piece{origin: piece.origin, offset: secondHalfOffset, length: secondHalfLength}
+
+ ed.pieceTable[index] = firstHalf
+
+ temp := append([]Piece{addPiece, secondHalf}, ed.pieceTable[index + 1:]...)
+ ed.pieceTable = append(ed.pieceTable[:index + 1], temp...)
+
+ inserted = true
+ break
+ }
+
+ length += piece.length;
+ }
+
+ if !inserted {
+ ed.pieceTable = append(ed.pieceTable, []Piece{addPiece}...)
+ }
+
+ ed.add = append(ed.add, []byte(text)...)
+
+ return ed
+}
+
+func (ed *MyEditor) Delete(offset, lengthToDelete uint) Editor {
+ length := uint(0)
+ for index := 0; index < len(ed.pieceTable); index++ {
+ piece := ed.pieceTable[index]
+ if lengthToDelete == 0 {
+ break
+ }
+
+ if offset == length {
+ if lengthToDelete >= piece.length {
+ if index + 1 < len(ed.pieceTable) {
+ lengthToDelete -= piece.length
+ ed.pieceTable = append(ed.pieceTable[:index], ed.pieceTable[index + 1:]...)
+ index--
+ continue
+ } else {
+ ed.pieceTable = ed.pieceTable[:index]
+ break
+ }
+ } else {
+ ed.pieceTable[index].offset += lengthToDelete
+ ed.pieceTable[index].length -= lengthToDelete
+ break;
+ }
+
+ }
+
+ // if offset < length + piece.length {
+ // if lengthToDelete >= piece.length {
+ // if index + 1 < len(ed.pieceTable) {
+ // lengthToDelete -= piece.length
+ // ed.pieceTable = append(ed.pieceTable[:index], ed.pieceTable[index + 1:]...)
+ // index--
+ // continue
+ // } else {
+ // ed.pieceTable = ed.pieceTable[:index]
+ // break
+ // }
+ // } else {
+ // ed.pieceTable[index].length -= lengthToDelete
+ // break;
+ // }
+
+ // }
+
+ length += piece.length
+ }
+
+ return ed
+}
+
+func (ed *MyEditor) Undo() Editor {
+ return ed
+}
+
+func (ed *MyEditor) Redo() Editor {
+ return ed
+}
+
+func (ed MyEditor) String() string {
+ result := ""
+ for _, piece := range ed.pieceTable {
+ var toAppend string
+ if (piece.origin) {
+ toAppend = string(ed.origin[piece.offset:piece.offset + piece.length])
+ } else {
+ toAppend = string(ed.add[piece.offset:piece.offset + piece.length])
+ }
+ result += toAppend
+ }
+
+ return result
+}

П.С. - завършения Delete, който не ми стигна времето да напиша:

func (ed *MyEditor) Delete(offset, lengthToDelete uint) Editor {
length := uint(0)
for index := 0; index < len(ed.pieceTable); index++ {
    piece := ed.pieceTable[index]
    if lengthToDelete == 0 || offset < length {
        break
    }

    if offset == length {
        if lengthToDelete >= piece.length {
            if index + 1 < len(ed.pieceTable) {
                lengthToDelete -= piece.length
                ed.pieceTable = append(ed.pieceTable[:index], ed.pieceTable[index + 1:]...)
                index--
                continue
            } else {
                ed.pieceTable = ed.pieceTable[:index]
                break
            }
        } else {
            ed.pieceTable[index].offset += lengthToDelete
            ed.pieceTable[index].length -= lengthToDelete
            break;
        }

    }

    if offset < length + piece.length {
        if lengthToDelete >= piece.length - (offset - length) {
            deleted := piece.length - (offset - length)
            lengthToDelete -= deleted

            ed.pieceTable[index].length = offset - length
            length = offset
            continue
        } else {
            ed.pieceTable[index].length = offset - length
            newPieceOffset := piece.offset + ed.pieceTable[index].length + lengthToDelete
            newPiece := Piece{origin: piece.origin, offset: newPieceOffset, length: piece.length - newPieceOffset}

            if index + 1 < len(ed.pieceTable) {
                temp := append([]Piece{newPiece}, ed.pieceTable[index + 1:]...)
                ed.pieceTable = append(ed.pieceTable[:index + 1], temp...)
            } else {
                ed.pieceTable = append(ed.pieceTable, newPiece)
            }
            break
        }

    }

    length += piece.length
}

return ed

}

Next time :)