Skip to content

Instantly share code, notes, and snippets.

@WilliamHester
Created March 10, 2015 04:05
Show Gist options
  • Save WilliamHester/b818af4e0e4dbfde3812 to your computer and use it in GitHub Desktop.
Save WilliamHester/b818af4e0e4dbfde3812 to your computer and use it in GitHub Desktop.
judge.go
package main
import (
"fmt"
"os"
"os/exec"
"strings"
"time"
"bufio"
)
const (
timeout = 20 * time.Second
)
type error interface {
Error() string
}
func nameParts(filename string) (string, string) {
parts := strings.Split(filename, ".")
if len(parts) != 2 {
return "", ""
}
return parts[0], parts[1]
}
// Takes a filename scanned in from the
// main function and returns a command
// that is waiting to be started and read
// input from
func build(filename string) error {
command := exec.Command("javac", filename)
error := command.Run()
return error
}
// Runs the file
func getCommand(filename string) *exec.Cmd {
name, _ := nameParts(filename)
command := exec.Command("java", name)
return command
}
func main() {
var filename string
fmt.Scanln(&filename)
if err := build(filename); err != nil {
fmt.Println("Failed to compile")
fmt.Println(err)
return
}
cmd := getCommand(filename)
output, err := os.Create("./out.txt")
if err != nil {
fmt.Println(err)
return
}
errorOut, err := os.Create("./err.txt")
if err != nil {
fmt.Println(err)
return
}
input, err := os.Open("./in.txt")
if err != nil {
fmt.Println(err)
return
}
cmd.Stdin = input
cmd.Stderr = errorOut
cmd.Stdout = output
procErr := make(chan error)
go func() {
procErr <- cmd.Run()
}()
endTime := time.Now().Add(timeout)
completed := false
err = nil
for time.Now().Before(endTime) && !completed {
select {
default:
time.Sleep(time.Second)
case err = <-procErr:
completed = true
}
}
if !completed {
cmd.Process.Kill()
fmt.Println("Took too long")
return
}
if err != nil {
fmt.Println("Runtime error")
return
}
input.Close()
errorOut.Close()
output.Close()
correct, err := os.Open("./correct.txt")
if err != nil {
fmt.Println(err)
return
}
output, err = os.Open("./out.txt")
if err != nil {
fmt.Println(err)
return
}
equal := true
f1scanner := bufio.NewScanner(correct)
f2scanner := bufio.NewScanner(output)
f1scanner.Split(bufio.ScanLines)
f2scanner.Split(bufio.ScanLines)
f1 := f1scanner.Scan()
f2 := f2scanner.Scan()
for f1 && f2 {
if (f1scanner.Text() != f2scanner.Text()) {
equal = false
break
}
f1 = f1scanner.Scan()
f2 = f2scanner.Scan()
}
if equal && f1 == f2 {
fmt.Println("Correct solution!")
} else {
fmt.Println("Incorrect solution")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment