-1

Here I am trying to write a function FindMajorDifference(words) where it returns words that are 10-, 11- and 12-string from the file "words.txt". A k-string is a string B where the distance between any pair of distinct letters (within a circular arrangement of the alphabet) is larger than k. For example,

  • "silk" is a 1-string
  • "oaks" is a 3-string, 2-string and 1-string.

In my code below, I tried to put all 10-, 11- and 12-string into an array but I think there's something wrong with it. I've been trying to figure out if I processed the file line by line correctly or not.

package main

import (
    "fmt"
    "io/ioutil"
)

func findMajorDifference(words []byte) []string 
{
    alpha := "abcdefghijklmnopqrstuvwxyz"
    major := []string{}

    B := string(words)

    distance := 0 // current distance between 2 distinct letters (pos1 - pos2)
    min := 26     // smallest distance between 2 distinct letters
    pos1 := 0     // position of first letter in the alpha array
    pos2 := 0     // position of second letter in the alpha array

    for i := 0; i < len(B); i++ {
        current := B[i] // current letter
        for x := 1; x < len(B); x++ {
            next := B[x] // next distinct letter
            if current != next {
                // find position of letters
                for j := 0; j < len(alpha); j++ {
                    if current == alpha[j] {
                        pos1 = j
                    }
                }
                for k := 0; k < len(alpha); k++ {
                    if next == alpha[k] {
                        pos2 = k
                    }
                }
                // find distance
                if pos1 > pos2 {
                    distance = pos1 - pos2
                } else {
                    distance = pos2 - pos1
                }
                if distance < min {
                    min = distance
                }
            }
        }
        if min == 11 || min == 12 || min == 13 {
            major = append(major, string(B[i]))
        }
    }
    return major
} // end of findMajorBinjai

func main() 
{
    words, err := ioutil.ReadFile("words.txt")

    if err != nil {
        fmt.Println("File reading error", err)
        return
    }

    fmt.Println("test")                           // This line is printed
    fmt.Println("%s", findMajorDifference(words)) // Gives no output

}

My code didn't give out any errors but it didn't print the output I wanted either.

Ayush Gupta
  • 8,716
  • 8
  • 59
  • 92
  • 1
    Possible duplicate of [reading file line by line in go](https://stackoverflow.com/questions/8757389/reading-file-line-by-line-in-go) – nicolasassi Oct 19 '19 at 16:53

2 Answers2

2

Use bufio.NewReader and Reader.ReadString

func GetFileReader(filePath string) *os.File {
    path, err := filepath.Abs(filePath)
    if err != nil {
        panic(err)
    }
    inFile, err := os.Open(path)
    if err != nil {
        panic(errors.New(err.Error() + `: ` + path))
    }
    return inFile
}

func Read(r io.Reader) {
    reader := bufio.NewReader(r)
    for {
        text, err := reader.ReadString('\n')
        if err != nil {
            if err == io.EOF {
                return
            }
            panic(err)
        }
        //your logic using text
    }
}

func main() {
   inFile := GetFileReader(filePath)
   defer inFile.Close()
   Read(inFile)
}
Ayush Gupta
  • 8,716
  • 8
  • 59
  • 92
1

Based on your explanation, there are multiple words in the file. The way it is done in the current code snippet is, the complete content of file is passed as the bite array. This would work fine if there is just one word in the file. If there are multiple words the letter of different words are also considered in computing the distance. You are not getting any output as blank slice is returned.

You may overcome this by reading each word individually and passing it to the function. I have modified your main to achieve expected result without changing function

func main() {
// words, err := ioutil.ReadFile("words.txt")
filehandle, err := os.Open("words.txt")
if err != nil {
    panic(err)
}
defer filehandle.Close()
scanner := bufio.NewScanner(filehandle)
for scanner.Scan() {
    words := scanner.Text()
    fmt.Println("%s", findMajorDifference([]byte(words))) // Gives no output
}

}

Devendra Mukharaiya
  • 480
  • 1
  • 5
  • 19
  • as for "silk", we need to find the distance between any pair of distinct letters, hence: SI = 10, SL = 7, SK = 8, IL = 3, IK = 2, KL = 2. Since the minimum distance calculated is 2, meaning that "silk" is a 1-string. Hope this helps! – N Amilah Oct 19 '19 at 15:14
  • as for "oaks": OA = 12, OK = 4, OS = 4, AK = 10, AS = 8, KS = 8. The minimum distance calculated is 4 hence it is true for 3-string, 2-string and 1-string. Here are more examples: “gggaaaacccccacacacaceeeggg” is a 1-string; “gggaaaaddddggggwwwwaaaaaaaaagggggggg” is a 2-string, as well as a 1-string. The binary operator ⊖ denotes the distance between 2 letters within a circular arrangement of the alphabet3. For instance, ‘c’ ⊖ ‘y’ = ‘y’ ⊖ ‘c’ = 4. Since there are 26 letters in the alphabet, for any letter pair a and b, 0 ≤ a ⊖ b ≤ 13. – N Amilah Oct 19 '19 at 15:22
  • @NAmilah : Seems that the issue is, function is written to compute logic for word while the entire content of file is passed as the argument from main. I have modified my answer to include main that might address your issue – Devendra Mukharaiya Oct 19 '19 at 17:09
  • @NAmilah : Did the answer helped in what you wanted to achieve? – Devendra Mukharaiya Oct 20 '19 at 12:46