Minify program after hitting score
This commit is contained in:
@@ -65,6 +65,19 @@ func (def *Definition) Grow(statusChan chan<- Status) (*vm.Program, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if status.BestScore == status.TargetScore {
|
if status.BestScore == status.TargetScore {
|
||||||
|
err = def.minifyProgram(prog)
|
||||||
|
if err != nil {
|
||||||
|
if statusChan != nil {
|
||||||
|
close(statusChan)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if statusChan != nil {
|
||||||
|
statusChan <- status
|
||||||
|
}
|
||||||
|
|
||||||
if statusChan != nil {
|
if statusChan != nil {
|
||||||
close(statusChan)
|
close(statusChan)
|
||||||
}
|
}
|
||||||
@@ -106,3 +119,42 @@ func (def *Definition) sumOuts() uint64 {
|
|||||||
|
|
||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (def *Definition) minifyProgram(prog *vm.Program) error {
|
||||||
|
for f := 0; f < len(prog.Functions); f++ {
|
||||||
|
err := def.minifyFunction(prog, f)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (def *Definition) minifyFunction(prog *vm.Program, f int) error {
|
||||||
|
baseScore, err := def.score(prog)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for loop := true; loop; {
|
||||||
|
loop = false
|
||||||
|
|
||||||
|
for i := 0; i < len(prog.Functions[f].Instructions); i++ {
|
||||||
|
origInstructions := prog.Functions[f].Instructions
|
||||||
|
tmp := make([]*vm.Instruction, len(prog.Functions[f].Instructions))
|
||||||
|
copy(tmp, prog.Functions[f].Instructions)
|
||||||
|
prog.Functions[f].Instructions = append(tmp[:i], tmp[i+1:]...)
|
||||||
|
|
||||||
|
newScore, err := def.score(prog)
|
||||||
|
if err == nil && newScore >= baseScore {
|
||||||
|
loop = true
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
prog.Functions[f].Instructions = origInstructions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package grow
|
package grow
|
||||||
|
|
||||||
import "math"
|
|
||||||
import "math/rand"
|
import "math/rand"
|
||||||
|
|
||||||
import "github.com/firestuff/subcoding/gen"
|
import "github.com/firestuff/subcoding/gen"
|
||||||
@@ -10,7 +9,7 @@ const instructionsPerFunctionMean = 15
|
|||||||
const instrucitonsPerFunctionStdDev = 10
|
const instrucitonsPerFunctionStdDev = 10
|
||||||
|
|
||||||
func Mutate(prog *vm.Program) {
|
func Mutate(prog *vm.Program) {
|
||||||
target := int(math.Max(2, rand.NormFloat64()*instrucitonsPerFunctionStdDev+instructionsPerFunctionMean))
|
target := int(rand.NormFloat64()*instrucitonsPerFunctionStdDev+instructionsPerFunctionMean)
|
||||||
|
|
||||||
if len(prog.Functions[0].Instructions) < target {
|
if len(prog.Functions[0].Instructions) < target {
|
||||||
addInstruction(prog, prog.Functions[0])
|
addInstruction(prog, prog.Functions[0])
|
||||||
|
|||||||
17
vm/state.go
17
vm/state.go
@@ -68,6 +68,15 @@ func (state *State) setHandlers() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) processInstruction() {
|
func (state *State) processInstruction() {
|
||||||
|
for state.functionIndex < 0 ||
|
||||||
|
state.functionIndex >= int64(len(state.program.Functions)) ||
|
||||||
|
state.instructionIndex < 0 ||
|
||||||
|
state.instructionIndex >= int64(len(state.function().Instructions)) {
|
||||||
|
|
||||||
|
state.ret()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
fnc := state.function()
|
fnc := state.function()
|
||||||
instr := fnc.Instructions[state.instructionIndex]
|
instr := fnc.Instructions[state.instructionIndex]
|
||||||
state.instructionIndex += 1
|
state.instructionIndex += 1
|
||||||
@@ -77,14 +86,6 @@ func (state *State) processInstruction() {
|
|||||||
if state.program.InstructionLimit > 0 && state.instructionCount > state.program.InstructionLimit {
|
if state.program.InstructionLimit > 0 && state.instructionCount > state.program.InstructionLimit {
|
||||||
state.setError(fmt.Errorf("Instruction limit (%d) exceeded", state.program.InstructionLimit))
|
state.setError(fmt.Errorf("Instruction limit (%d) exceeded", state.program.InstructionLimit))
|
||||||
}
|
}
|
||||||
|
|
||||||
for state.functionIndex < 0 ||
|
|
||||||
state.functionIndex >= int64(len(state.program.Functions)) ||
|
|
||||||
state.instructionIndex < 0 ||
|
|
||||||
state.instructionIndex >= int64(len(state.function().Instructions)) {
|
|
||||||
|
|
||||||
state.ret()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) readUnsigned(op *Operand) uint64 {
|
func (state *State) readUnsigned(op *Operand) uint64 {
|
||||||
|
|||||||
Reference in New Issue
Block a user