Search code examples
arraysgoiostdoutstdin

Best practices to take input


I have written a mergeSort function, which sorted 1 million integers in 750ms, but it takes 9 seconds to take input.

This is how I have taken input to my slice, which is to be sorted.

code snippet:

array := make([]int,n)
for i := 0; i < n; i++ {
    fmt.Scanf("%d",&array[i])
}

What I need is, an efficient way to take integers as input into a slice. Input contains only integers, seperated by space or each integer in new-line.

Sample Input 1:

3
9
1
13

Sample Input 2:

3 9 1 13

If efficient solution is available for any one type of Input, it would suffice


Solution

  • package main
    
    import (
        "io/ioutil"
        "os"
    )
    // inp is a variable in which we store our whole input
    var inp []byte
    // loc is used as index and remember till where we have seen our input
    var loc int
    
    func main() {
        // we read whole input and store it in inp and then append '\n', so
        // that we don't get any type index out of bound error, while 
        // scanning the last digit.
        inp, _ = ioutil.ReadAll(os.Stdin)
        inp = append(inp, '\n')
        // when ever scanInt is called, it will return single value of type int
        // usage:
        // n := scanInt()
    
    }
    
    func scanInt() (res int) {
        // skip if byte value doesn't belong to integer and break when it is
        // an integer
        for ; inp[loc] < 48 || inp[loc] > 57; loc++ {
        }
        // If it is an integer parse it completely else break return the result
    
        for ; inp[loc] > 47 && inp[loc] < 58 ; loc++ {
            res = (res << 1  ) + (res << 3) + int(inp[loc]-48)
        }
        return
    }