Решение на Нормализация на пътища от Живко Чобанов

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

Към профила на Живко Чобанов

Резултати

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

Код

package main
import "strings"
func lastInPathIsDir(pathSplitBySlash []string) bool {
lastInPath := pathSplitBySlash[len(pathSplitBySlash)-1]
return lastInPath == ".." || lastInPath == ""
}
func repairRoot(clearPath *string) {
if *clearPath == "." {
*clearPath = "/"
} else {
*clearPath = "/" + *clearPath
}
}
func parsePath(weirdPath string) (clearPath string) {
pathSplitBySlash := strings.Split(weirdPath, "/")
numberOfDirsToSkip := 0
for i := len(pathSplitBySlash) - 1; i >= 0; i-- {
if pathSplitBySlash[i] == "" {
continue
}
if pathSplitBySlash[i] == ".." {
numberOfDirsToSkip++
} else if numberOfDirsToSkip > 0 {
numberOfDirsToSkip--
} else {
if clearPath == "" {
clearPath = pathSplitBySlash[i]
} else {
clearPath = pathSplitBySlash[i] + "/" + clearPath
}
}
}
repairRoot(&clearPath)
if lastInPathIsDir(pathSplitBySlash) && clearPath != "/" {
clearPath += "/"
}
return
}

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

PASS
ok  	_/tmp/d20131015-29033-1jn4mkw	0.011s
PASS
ok  	_/tmp/d20131015-29033-1jn4mkw	0.011s
PASS
ok  	_/tmp/d20131015-29033-1jn4mkw	0.011s
PASS
ok  	_/tmp/d20131015-29033-1jn4mkw	0.011s
PASS
ok  	_/tmp/d20131015-29033-1jn4mkw	0.011s
PASS
ok  	_/tmp/d20131015-29033-1jn4mkw	0.011s
PASS
ok  	_/tmp/d20131015-29033-1jn4mkw	0.011s
PASS
ok  	_/tmp/d20131015-29033-1jn4mkw	0.011s

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

Живко обнови решението на 13.10.2013 14:17 (преди над 4 години)

+package main
+
+var clearPath string
+
+const (
+ unknownDir = iota
+ normalDir
+ oneDot
+ twoDots
+)
+
+var (
+ numberOfDirsToSkip int8
+ directoryDotsUpToNow int8 = unknownDir
+)
+
+func reverseString(str string) (reversedStr string) {
+ for _, character := range str {
+ reversedStr = string(character) + reversedStr
+ }
+ return
+}
+
+func addToClearPath(character rune) {
+ clearPath = string(character) + clearPath
+}
+
+func goBackInClearPath() {
+ numberOfDirsToSkip++
+}
+
+func finalizeDirectory() {
+ addDots()
+ if numberOfDirsToSkip > 0 {
+ numberOfDirsToSkip--
+ } else {
+ addToClearPath('/')
+ }
+ directoryDotsUpToNow = unknownDir
+}
+
+func addDots() {
+ if directoryDotsUpToNow == twoDots {
+ addToClearPath('.')
+ addToClearPath('.')
+ } else if directoryDotsUpToNow == oneDot {
+ addToClearPath('.')
+ }
+}
+
+func getAndRemoveContent(variable *string) string {
+ var_content := *variable
+ *variable = ""
+ return var_content
+}
+
+func newDot(character rune) {
+ switch {
+ case directoryDotsUpToNow == unknownDir:
+ directoryDotsUpToNow = oneDot
+ case directoryDotsUpToNow == normalDir:
+ if numberOfDirsToSkip == 0 {
+ addToClearPath(character)
+ }
+ case directoryDotsUpToNow == oneDot:
+ directoryDotsUpToNow = twoDots
+ case directoryDotsUpToNow == twoDots:
+ addDots()
+ directoryDotsUpToNow = normalDir
+ }
+}
+
+func parsePath(weirdPath string) string {
+ var character rune
+ reversedWeirdPath := reverseString(weirdPath)
+ for _, character = range reversedWeirdPath {
+ if character == '/' {
+ if directoryDotsUpToNow == twoDots {
+ goBackInClearPath()
+ directoryDotsUpToNow = unknownDir
+ } else {
+ finalizeDirectory()
+ }
+ } else if character == '.' {
+ newDot(character)
+ } else {
+ if numberOfDirsToSkip == 0 {
+ if directoryDotsUpToNow != normalDir {
+ addDots()
+ }
+ addToClearPath(character)
+ }
+ directoryDotsUpToNow = normalDir
+ }
+ }
+ if character != '/' && character != '.' {
+ clearPath = "/" + clearPath
+ }
+ if clearPath == "" {
+ clearPath = "/"
+ }
+ numberOfDirsToSkip = 0
+ directoryDotsUpToNow = unknownDir
+ return getAndRemoveContent(&clearPath)
+}

Живко обнови решението на 14.10.2013 12:28 (преди над 4 години)

package main
-var clearPath string
+import "strings"
-const (
- unknownDir = iota
- normalDir
- oneDot
- twoDots
-)
-
-var (
- numberOfDirsToSkip int8
- directoryDotsUpToNow int8 = unknownDir
-)
-
-func reverseString(str string) (reversedStr string) {
- for _, character := range str {
- reversedStr = string(character) + reversedStr
- }
- return
+func lastInPathIsDir(pathSplitBySlash []string) bool {
+ lastInPath := pathSplitBySlash[len(pathSplitBySlash)-1]
+ return lastInPath == ".." || lastInPath == ""
}
-func addToClearPath(character rune) {
- clearPath = string(character) + clearPath
-}
-
-func goBackInClearPath() {
- numberOfDirsToSkip++
-}
-
-func finalizeDirectory() {
- addDots()
- if numberOfDirsToSkip > 0 {
- numberOfDirsToSkip--
+func repairRoot(clearPath *string) {
+ if *clearPath == "." {
+ *clearPath = "/"
} else {
- addToClearPath('/')
+ *clearPath = "/" + *clearPath
}
- directoryDotsUpToNow = unknownDir
}
-func addDots() {
- if directoryDotsUpToNow == twoDots {
- addToClearPath('.')
- addToClearPath('.')
- } else if directoryDotsUpToNow == oneDot {
- addToClearPath('.')
- }
-}
-
-func getAndRemoveContent(variable *string) string {
- var_content := *variable
- *variable = ""
- return var_content
-}
-
-func newDot(character rune) {
- switch {
- case directoryDotsUpToNow == unknownDir:
- directoryDotsUpToNow = oneDot
- case directoryDotsUpToNow == normalDir:
- if numberOfDirsToSkip == 0 {
- addToClearPath(character)
+func parsePath(weirdPath string) (clearPath string) {
+ pathSplitBySlash := strings.Split(weirdPath, "/")
+ numberOfDirsToSkip := 0
+ for i := len(pathSplitBySlash) - 1; i >= 0; i-- {
+ if pathSplitBySlash[i] == "" {
+ continue
}
- case directoryDotsUpToNow == oneDot:
- directoryDotsUpToNow = twoDots
- case directoryDotsUpToNow == twoDots:
- addDots()
- directoryDotsUpToNow = normalDir
- }
-}
-
-func parsePath(weirdPath string) string {
- var character rune
- reversedWeirdPath := reverseString(weirdPath)
- for _, character = range reversedWeirdPath {
- if character == '/' {
- if directoryDotsUpToNow == twoDots {
- goBackInClearPath()
- directoryDotsUpToNow = unknownDir
+ if pathSplitBySlash[i] == ".." {
+ numberOfDirsToSkip++
+ } else if numberOfDirsToSkip > 0 {
+ numberOfDirsToSkip--
+ } else {
+ if clearPath == "" {
+ clearPath = pathSplitBySlash[i]
} else {
- finalizeDirectory()
+ clearPath = pathSplitBySlash[i] + "/" + clearPath
}
- } else if character == '.' {
- newDot(character)
- } else {
- if numberOfDirsToSkip == 0 {
- if directoryDotsUpToNow != normalDir {
- addDots()
- }
- addToClearPath(character)
- }
- directoryDotsUpToNow = normalDir
}
}
- if character != '/' && character != '.' {
- clearPath = "/" + clearPath
+ repairRoot(&clearPath)
+ if lastInPathIsDir(pathSplitBySlash) && clearPath != "/" {
+ clearPath += "/"
}
- if clearPath == "" {
- clearPath = "/"
- }
- numberOfDirsToSkip = 0
- directoryDotsUpToNow = unknownDir
- return getAndRemoveContent(&clearPath)
+ return
}

Благодаря за съвета :). Предния път пробвах да реша задачата без използване на "strings" и масиви и затова стана толкова дълго. Сега я реших с минимално навлизане в масивите и низовете. И реших да не ползвам глобални променливи, защото изолацията на тестовете се разваля.