問題:https://www.spoj.pl/problems/INTEST/
Go言語の標準入力について.
Go言語で標準入力を受けとる方法はいくつかあるみたい.
・fmtのScanf等を使う
・scannerのScannerを使う
・bufioのReaderを使う
・io/ioutilのReadAllを使う
以下それぞれの方法における簡単な例.ちなみにos.Stdinはos.Fileで標準入力を表したものであり,bufio.Readerなどに用いる関数は実装されているのでそのまま使えるはず.os.Stdin.Readを使う手もあるけど面倒くさいので割愛.
・fmtのScanf等を使う
package main import ( "fmt" ) func main() { n:=0 fmt.Scan(&n) fmt.Println(n) }
・scannerのScannerを使う
package main import ( "scanner" "os" "fmt" ) func main() { s scanner.Scanner s.Init(os.Stdin) s.Scan() fmt.Println(s.TokenText()) }
・bufioのReaderを使う
pacage main import ( "bufio" "os" "fmt" ) func main() { in := bufio.NewReader(os.Stdin) str := in.ReadString('\n') fmt.Println(str) }
・io/ioutilのReadAllを使う
package main import ( "io/ioutil" "os" "fmt" ) func main() { str := ioutil.ReadAll(os.Stdin) fmt.Println(str) }
SPOJのINTESTでいろいろ試してみたけど最後ioutil.ReadAll以外の処理が遅すぎるらしく,TLEになる.
で,以下Acceptedのコード.ゴルーチンも使ってみたけどゴルーチンを使うとTLEするっぽいので使ってない.
package main import ( "os" "strconv" "bufio" "io/ioutil" ) func run() { n := next() k := next() c := 0 for i := 0; i < n; i++ { x := next() if x%k < 1 { c++ } } printIntln(c) } func main() { run() ioend() } var ( buf []byte p int out *bufio.Writer ) func init() { buf, _ = ioutil.ReadAll(os.Stdin) p = 0 out = bufio.NewWriter(os.Stdout) } func ioend() { out.Flush() } func next() int { r := 0 s := 1 for buf[p] == '\n' || buf[p] == ' ' { p++ } if buf[p] == '-' { s = -1 p++ } for '0' <= buf[p] && buf[p] <= '9' { r = 10*r + int(buf[p]-'0') p++ } return s * r } func printIntln(n int) { println(strconv.Itoa(n)) } func println(str string) { out.WriteString(str) out.WriteString("\n") }
ゴルーチン導入版.使い方が悪いのかもしれない.
package main import ( "os" "strconv" "bufio" "io/ioutil" ) func run() { n := <-in k := <-in c := 0 for i := 0; i < n; i++ { x := <-in if x%k < 1 { c++ } } printIntln(c) } func main() { run() ioend() } var ( in chan int buf []byte out *bufio.Writer ) func init() { in = make(chan int) buf, _ = ioutil.ReadAll(os.Stdin) go intInput() out = bufio.NewWriter(os.Stdout) } func ioend() { out.Flush() } func intInput() { p := 0 getBuf := make(chan byte) go func() { for p := 0; p < len(buf); p++ { getBuf <- buf[p] } getBuf <- 0 }() for p < len(buf) { r := 0 s := 1 b := <-getBuf for b == '\n' || b == ' ' { b = <-getBuf } if b == '-' { s = -1 b = <-getBuf } for ; '0' <= b && b <= '9'; b = <-getBuf { r = 10*r + int(b-'0') } in <- s*r } } func printIntln(n int) { println(strconv.Itoa(n)) } func println(str string) { out.WriteString(str) out.WriteString("\n") }