From 9a8cf96e08ab929dcadf7bfcb76545f9b271a171 Mon Sep 17 00:00:00 2001 From: Evan Burkey Date: Mon, 7 Nov 2022 11:01:00 -0800 Subject: [PATCH 1/3] refactor simple TCP server into pkg --- cmd/primetime/main.go | 23 +++++++++++++++++++++++ cmd/smoketest/main.go | 26 ++++---------------------- pkg/conn/conn.go | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 22 deletions(-) create mode 100644 cmd/primetime/main.go create mode 100644 pkg/conn/conn.go diff --git a/cmd/primetime/main.go b/cmd/primetime/main.go new file mode 100644 index 0000000..f2ecded --- /dev/null +++ b/cmd/primetime/main.go @@ -0,0 +1,23 @@ +package main + +import ( + "log" + "net" + + "protohackers/pkg/conn" +) + +type data struct { + Method string `json:"method"` + Number int `json:"number"` +} + +func main() { + err := conn.StartSimple(primetime) + if err != nil { + log.Fatalln(err) + } +} + +func primetime(c net.Conn) { +} diff --git a/cmd/smoketest/main.go b/cmd/smoketest/main.go index 10f924b..f90bcf8 100644 --- a/cmd/smoketest/main.go +++ b/cmd/smoketest/main.go @@ -1,40 +1,22 @@ package main import ( - "fmt" "io" "log" "net" - "os" -) -const ( - connPort = "3030" - connType = "tcp4" + "protohackers/pkg/conn" ) func main() { - l, err := net.Listen(connType, ":"+connPort) + err := conn.StartSimple(smoketest) if err != nil { log.Fatalln(err) - os.Exit(1) - } - defer l.Close() - - fmt.Println(fmt.Sprintf("Listening on port %s", connPort)) - - for { - conn, err := l.Accept() - if err != nil { - log.Fatalln(err) - } - go handleRequest(conn) } } -func handleRequest(conn net.Conn) { - defer conn.Close() - if _, err := io.Copy(conn, conn); err != nil { +func smoketest(c net.Conn) { + if _, err := io.Copy(c, c); err != nil { log.Fatalln(err) } } diff --git a/pkg/conn/conn.go b/pkg/conn/conn.go new file mode 100644 index 0000000..3d928ba --- /dev/null +++ b/pkg/conn/conn.go @@ -0,0 +1,33 @@ +package conn + +import ( + "fmt" + "net" +) + +const ( + Port = ":3030" + Type = "tcp4" +) + +func StartSimple(handler func(conn net.Conn)) error { + l, err := net.Listen(Type, Port) + if err != nil { + return err + } + defer l.Close() + + fmt.Println(fmt.Sprintf("Listening on port %s", Port)) + + for { + c, err := l.Accept() + if err != nil { + return err + } + go handler(c) + err = c.Close() + if err != nil { + return err + } + } +} From 71179f50992d95b93d60fa65c227ed73f80b1ce7 Mon Sep 17 00:00:00 2001 From: Evan Burkey Date: Mon, 7 Nov 2022 11:06:30 -0800 Subject: [PATCH 2/3] fix close bug --- cmd/primetime/main.go | 1 + cmd/smoketest/main.go | 1 + pkg/conn/conn.go | 1 - 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/primetime/main.go b/cmd/primetime/main.go index f2ecded..7ad3841 100644 --- a/cmd/primetime/main.go +++ b/cmd/primetime/main.go @@ -20,4 +20,5 @@ func main() { } func primetime(c net.Conn) { + defer c.Close() } diff --git a/cmd/smoketest/main.go b/cmd/smoketest/main.go index f90bcf8..717bb7b 100644 --- a/cmd/smoketest/main.go +++ b/cmd/smoketest/main.go @@ -16,6 +16,7 @@ func main() { } func smoketest(c net.Conn) { + defer c.Close() if _, err := io.Copy(c, c); err != nil { log.Fatalln(err) } diff --git a/pkg/conn/conn.go b/pkg/conn/conn.go index 3d928ba..9d266e9 100644 --- a/pkg/conn/conn.go +++ b/pkg/conn/conn.go @@ -25,7 +25,6 @@ func StartSimple(handler func(conn net.Conn)) error { return err } go handler(c) - err = c.Close() if err != nil { return err } From 594f17547277c575663f807c73af882d2d9306e6 Mon Sep 17 00:00:00 2001 From: Evan Burkey Date: Mon, 7 Nov 2022 11:24:46 -0800 Subject: [PATCH 3/3] implement primetime --- cmd/primetime/main.go | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/cmd/primetime/main.go b/cmd/primetime/main.go index 7ad3841..5921b0e 100644 --- a/cmd/primetime/main.go +++ b/cmd/primetime/main.go @@ -1,15 +1,24 @@ package main import ( + "bufio" + "encoding/json" "log" + "math/big" "net" "protohackers/pkg/conn" ) +var ( + malformedResponse = []byte("malformed\n") + trueResponse = []byte(`{"method":"isPrime","prime":true}` + "\n") + falseResponse = []byte(`{"method":"isPrime","prime":false}` + "\n") +) + type data struct { - Method string `json:"method"` - Number int `json:"number"` + Method string `json:"method"` + Number *float64 `json:"number"` } func main() { @@ -21,4 +30,23 @@ func main() { func primetime(c net.Conn) { defer c.Close() + sc := bufio.NewScanner(c) + for sc.Scan() { + response := process(sc.Bytes()) + c.Write(response) + } + if err := sc.Err(); err != nil { + log.Fatalln(err) + } +} + +func process(buf []byte) []byte { + var in data + err := json.Unmarshal(buf, &in) + if err != nil || in.Method != "isPrime" || in.Number == nil { + return malformedResponse + } else if big.NewInt(int64(*in.Number)).ProbablyPrime(0) { + return trueResponse + } + return falseResponse }