For problem statement at 0-999/0-99/30-39/39/problemG.txt this is a correct solution, but verifier at 0-999/0-99/30-39/39/verifierG.go ends with build reference: REFERENCE_SOURCE_PATH not set
exit status 1 can you fix the verifier? package main
import (
"fmt"
"io"
"os"
)
const (
nodeNum = iota
nodeVar
nodeCall
nodeAdd
nodeSub
nodeMul
nodeDiv
)
const (
cmpLt = iota
cmpGt
cmpEq
)
type Expr struct {
kind int
val int
left, right *Expr
}
type Cond struct {
op int
left, right *Expr
}
type Stmt struct {
hasCond bool
cond *Cond
expr *Expr
}
type Parser struct {
s string
pos int
}
func isSpace(c byte) bool {
return c == ' ' || c == '\n' || c == '\r' || c == '\t'
}
func isDigit(c byte) bool {
return c >= '0' && c <= '9'
}
func (p *Parser) skip() {
for p.pos < len(p.s) && isSpace(p.s[p.pos]) {
p.pos++
}
}
func (p *Parser) peek() byte {
p.skip()
if p.pos >= len(p.s) {
return 0
}
return p.s[p.pos]
}
func (p *Parser) accept(t string) bool {
p.skip()
if p.pos+len(t) > len(p.s) {
return false
}
if p.s[p.pos:p.pos+len(t)] == t {
p.pos += len(t)
return true
}
return false
}
func (p *Parser) expect(t string) {
if !p.accept(t) {
panic("parse error")
}
}
func (p *Parser) parseNumber() *Expr {
p.skip()
val := 0
for p.pos < len(p.s) && isDigit(p.s[p.pos]) {
val = val*10 + int(p.s[p.pos]-'0')
p.pos++
}
return &Expr{kind: nodeNum, val: val}
}
func (p *Parser) parseMultiplier() *Expr {
p.skip()
c := p.peek()
if isDigit(c) {
return p.parseNumber()
}
if c == 'n' {
p.pos++
return &Expr{kind: nodeVar}
}
if c == 'f' {
p.pos++
p.expect("(")
arg := p.parseExpr()
p.expect(")")
return &Expr{kind: nodeCall, left: arg}
}
panic("parse error")
}
func (p *Parser) parseProduct() *Expr {
node := p.parseMultiplier()
for {
p.skip()
if p.accept("*") {
right := p.parseMultiplier()
node = &Expr{kind: nodeMul, left: node, right: right}
} else if p.accept("/") {
right := p.parseMultiplier()
node = &Expr{kind: nodeDiv, left: node, right: right}
} else {
break
}
}
return node
}
func (p *Parser) parseExpr() *Expr {
node := p.parseProduct()
for {
p.skip()
if p.accept("+") {
right := p.parseProduct()
node = &Expr{kind: nodeAdd, left: node, right: right}
} else if p.accept("-") {
right := p.parseProduct()
node = &Expr{kind: nodeSub, left: node, right: right}
} else {
break
}
}
return node
}
func (p *Parser) parseCond() *Cond {
left := p.parseExpr()
var op int
if p.accept("==") {
op = cmpEq
} else if p.accept(">") {
op = cmpGt
} else if p.accept("<") {
op = cmpLt
} else {
panic("parse error")
}
right := p.parseExpr()
return &Cond{op: op, left: left, right: right}
}
func (p *Parser) parseStmt() Stmt {
if p.accept("if") {
p.expect("(")
cond := p.parseCond()
p.expect(")")
p.expect("return")
expr := p.parseExpr()
p.expect(";")
return Stmt{hasCond: true, cond: cond, expr: expr}
}
p.expect("return")
expr := p.parseExpr()
p.expect(";")
return Stmt{expr: expr}
}
func (p *Parser) parseFunction() []Stmt {
p.expect("int")
p.expect("f")
p.expect("(")
p.expect("int")
p.expect("n")
p.expect(")")
p.expect("{")
var stmts []Stmt
for {
p.skip()
if p.peek() == '}' {
break
}
stmts = append(stmts, p.parseStmt())
}
p.expect("}")
return stmts
}
func evalExpr(e *Expr, n int, fvals []int) int {
switch e.kind {
case nodeNum:
return e.val
case nodeVar:
return n
case nodeCall:
arg := evalExpr(e.left, n, fvals)
return fvals[arg]
case nodeAdd:
return (evalExpr(e.left, n, fvals) + evalExpr(e.right, n, fvals)) & 32767
case nodeSub:
return (evalExpr(e.left, n, fvals) - evalExpr(e.right, n, fvals)) & 32767
case nodeMul:
return (evalExpr(e.left, n, fvals) * evalExpr(e.right, n, fvals)) & 32767
case nodeDiv:
return evalExpr(e.left, n, fvals) / evalExpr(e.right, n, fvals)
}
return 0
}
func evalCond(c *Cond, n int, fvals []int) bool {
a := evalExpr(c.left, n, fvals)
b := evalExpr(c.right, n, fvals)
switch c.op {
case cmpLt:
return a < b
case cmpGt:
return a > b
case cmpEq:
return a == b
}
return false
}
func evalFunction(stmts []Stmt, n int, fvals []int) int {
for _, st := range stmts {
if !st.hasCond || evalCond(st.cond, n, fvals) {
return evalExpr(st.expr, n, fvals)
}
}
return 0
}
func main() {
data, _ := io.ReadAll(os.Stdin)
s := string(data)
i := 0
for i < len(s) && isSpace(s[i]) {
i++
}
target := 0
for i < len(s) && isDigit(s[i]) {
target = target*10 + int(s[i]-'0')
i++
}
p := Parser{s: s[i:]}
stmts := p.parseFunction()
fvals := make([]int, 32768)
for n := 0; n < 32768; n++ {
fvals[n] = evalFunction(stmts, n, fvals)
}
ans := -1
for n := 32767; n >= 0; n-- {
if fvals[n] == target {
ans = n
break
}
}
fmt.Print(ans)
}