diff --git a/grow/cli/main.go b/grow/cli/main.go index bd9c39b..fb66a89 100644 --- a/grow/cli/main.go +++ b/grow/cli/main.go @@ -6,6 +6,7 @@ import "math/rand" import "os" import "time" +import "github.com/firestuff/subcoding/asm" import "github.com/firestuff/subcoding/grow" func main() { @@ -28,8 +29,31 @@ func main() { log.Fatal(err) } - _, err = def.Grow() - if err != nil { - log.Fatal(err) + statusChan := make(chan grow.Status) + + go func() { + _, err = def.Grow(statusChan) + if err != nil { + log.Fatal(err) + } + }() + + for { + status, ok := <-statusChan + + if !ok { + break + } + + if status.BestProgram == nil { + continue + } + + src, err := asm.Disassemble(status.BestProgram) + if err != nil { + log.Fatal(err) + } + + log.Printf("New best score %d / %d (after %d attempts):\n%s", status.BestScore, status.TargetScore, status.Attempts, src) } } diff --git a/grow/grow.go b/grow/grow.go index 90de4c0..1d93bdd 100644 --- a/grow/grow.go +++ b/grow/grow.go @@ -1,44 +1,47 @@ package grow -import "log" - -import "github.com/firestuff/subcoding/asm" import "github.com/firestuff/subcoding/gen" import "github.com/firestuff/subcoding/vm" -func (def *Definition) Grow() (*vm.Program, error) { - high_score := 0 +func (def *Definition) Grow(statusChan chan<- Status) (*vm.Program, error) { + status := Status{ + TargetScore: uint64(len(def.Samples)), + } - log.Print("Starting grow run...") + if statusChan != nil { + statusChan <- status + } // TODO: Score should be number of output criteria, not number of Samples - for progs := 0; ; progs++ { + for { + status.Attempts++ + prog := gen.RandProgram(def.GlobalMemorySize, def.FunctionMemorySize, def.InstructionLimit) score, err := def.Score(prog) if err != nil { + close(statusChan) return nil, err } - if score > high_score { - high_score = score + if score > status.BestScore { + status.BestScore = score + status.BestProgram = prog - src, err := asm.Disassemble(prog) - if err != nil { - return nil, err + if statusChan != nil { + statusChan <- status } - log.Printf("New high score %d / %d (after %d attempts):\n%s", high_score, len(def.Samples), progs, src) - - if score == len(def.Samples) { + if status.BestScore == status.TargetScore { + close(statusChan) return prog, nil } } } } -func (def *Definition) Score(prog *vm.Program) (int, error) { - score := 0 +func (def *Definition) Score(prog *vm.Program) (uint64, error) { + score := uint64(0) for _, sample := range def.Samples { state, err := vm.NewState(prog) diff --git a/grow/status.go b/grow/status.go new file mode 100644 index 0000000..641b847 --- /dev/null +++ b/grow/status.go @@ -0,0 +1,12 @@ +package grow + +import "github.com/firestuff/subcoding/vm" + +type Status struct { + TargetScore uint64 + + Attempts uint64 + + BestScore uint64 + BestProgram *vm.Program +}