You can use bufio.Scanner to read lines from input.
And since we always read numbers, we can create a highly optimized converter to get the number. We should avoid using Scanner.Text() , which creates a string , since we can only get the number from the raw bytes returned by Scanner.Bytes() . Scanner.Text() returns the same token as Scanner.Bytes() , but first converts to string , which is obviously slower and generates garbage and works for gc.
So, here is a converter function that gets int from raw bytes:
func toInt(buf []byte) (n int) { for _, v := range buf { n = n*10 + int(v-'0') } return }
This toInt() works because []byte contains an encoded sequence of UTF-8 bytes of a string representation of the decimal format of the number, which contains only digits in the range '0'..'9' , whose encoded bytes of UTF-8 are mapped one to one ( one byte is used for one digit). The mapping from a digit to a byte is just a shift: '0' -> 48 , '1' -> 49 , etc.
Using this is your complete application:
package main import ( "bufio" "fmt" "os" ) func main() { var n, k, c int scanner := bufio.NewScanner(os.Stdin) scanner.Scan() fmt.Sscanf(scanner.Text(), "%d %d", &n, &k) for ;n > 0; n-- { scanner.Scan() if toInt(scanner.Bytes())%k == 0 { c++ } } fmt.Println(c) } func toInt(buf []byte) (n int) { for _, v := range buf { n = n*10 + int(v-'0') } return }
This solution is about 4 times faster than calling strconv.Atoi() .
Notes:
In the above solution, I assumed that the input is valid, that is, it always contains valid numbers and contains at least n lines after the first (which gives us n and k ).
If the input is closed after n+1 lines, we can use a simplified for (and we donβt even need to reduce and rely on n ):
for scanner.Scan() { if toInt(scanner.Bytes())%k == 0 { c++ } }