Commit f11eb986 authored by Trevor Cappallo's avatar Trevor Cappallo
Browse files

enumerate integers finding minimum length program

parent 721885dd
thing=0
#!/usr/bin/env python
"""
......@@ -24,6 +25,7 @@ class Skython(object):
'NEG', 'XOR', 'LOCO_2', 'DEC', 'SWBC',
'PEEK', 'SKIP', 'LAND', 'LOR', 'IFDO',
'IFF', 'NOT', 'EQ', 'LOCO_1', 'MOD',
'POW', 'LEFT', 'RIGHT',
]
INSTRUCTIONS2 = [
'LOCO_0', 'SWAB',
......@@ -126,7 +128,7 @@ class Skython(object):
a, c = c, a
elif op == 6: # MULT
if -(10**12) < a < 10**12:
if -(10**6) < a < 10**6:
a *= b
else:
return [], 666
......@@ -185,7 +187,7 @@ class Skython(object):
elif op == 20: # PEEK
if sp > 0 and output[sp - 1] != self.MAGIC_NUMBER:
b = output[sp - 1]
c = output[sp - 1]
#else:
# pc = self.MAX_PROG_SIZE
......@@ -218,6 +220,22 @@ class Skython(object):
if b:
a %= b
elif op == 30: # POW
if -100 < a < 100 and b < 5:
try:
a = int(a ** b)
except ZeroDivisionError:
pass
else:
return [], 666
elif op == 31: # LEFT
if sp > 0:
sp -= 1
elif op == 32: # RIGHT
sp += 1
if sp == len(output):
output.append(0)
pc += 1
step += 1
......@@ -240,7 +258,8 @@ class Skython(object):
print ")"
if step >= step_limit:
break
#break
return [], 666
# cool = False
# if sp >= 15 and output[0] != output[2] and output[3] != output[7] and output[8] != output[13]:
......@@ -252,7 +271,7 @@ class Skython(object):
else:
return output[:min(self.TRIM, len(output), sp)], sp
def explore(self, iterations=1000000, bound=MAX_PROG_SIZE // 2, max_steps=50):
def explore(self, iterations=1000000, bound=MAX_PROG_SIZE // 2, max_steps=64):
timeout = total = redundant = degen = 0
results = {}
progs = {}
......@@ -278,37 +297,39 @@ class Skython(object):
degen += 1
continue
output = [o if o >= 0 else -o for o in output]
s = ','.join([str(x) for x in output])
if s not in results:
results[s] = 0
progs[s] = [0] * 30
progs[s] = [0] * len(self.INSTRUCTIONS)
results[s] += 1
for op in prog:
progs[s][op] += 1
return results, progs
def run(self, model_out, model_in=None, bound=50):
def run(self, model_out, model_in=None, bound=50, total_bound=10**7):
timeout = total = redundant = degen = 0
exact = 1
exact = 0
last_prog = None
#lower_bound, upper_bound = 5, 15
if model_in is None:
model_in = []
wins = 0
wins_needed = 5
wins_needed = 15
solutions = set()
time_start = time.time()
while True:
prog = self.make_program(random.randint(bound * 2 // 3, bound))
prog = self.make_program(random.randint(max(min(bound * 4 // 5, bound - 1), 1), bound))
output = [self.MAGIC_NUMBER] + [0] * (self.MAX_PROG_SIZE - 1)
for i in range(1, len(model_in) + 1):
output[i] = model_in[i - 1]
total += 1
if total % 10**6 == 0:
print total / 10**6
#if total % 10**6 == 0:
# print total / 10**6
(output, r) = self.run_program(prog, model_in, model_out)
......@@ -330,6 +351,9 @@ class Skython(object):
#elif not exact and r < len(model_out):
# continue
if exact and len(output) != len(model_out):
continue
match = 0
for i in range(len(model_out)):
if output[i] == model_out[i]:
......@@ -339,14 +363,15 @@ class Skython(object):
if match == len(model_out):
wins += 1
last_prog = prog
pretty_prog = "\t".join([self.INSTRUCTIONS[op] for op in prog])
self.unpretty[pretty_prog] = prog
print '|' + '#' * wins + '-' * (wins_needed - wins) + '| ' + pretty_prog
#print '|' + '#' * wins + '-' * (wins_needed - wins) + '| ' + pretty_prog
solutions.add(pretty_prog)
lengths = [s.count('\t') + 1 for s in solutions]
if self.SHRINK and max(lengths) > min(lengths):
bound = min(lengths)
print "Resetting with new upper bound: {}".format(bound)
#print "Resetting with new upper bound: {}".format(bound)
wins = 0
solutions = set()
time_start = time.time()
......@@ -355,49 +380,86 @@ class Skython(object):
if wins == wins_needed:
time_end = time.time()
time_elapsed = time_end - time_start
print "-=-VICTORY-=-"
#print "-=-VICTORY-=-"
print "total = {}k".format(total / 1000)
if wins > 1:
print "average = {}k".format(total / wins / 1000)
print "mean solution time: {:.4f}s".format(time_elapsed / wins)
print "\n{} solutions:".format(len(solutions))
for prog in solutions:
print prog + '\n'
if len(solutions) < 10:
self.run_program(self.unpretty[prog], model_in, model_out, trace=True)
print '\n'
#if wins > 1:
# print "average = {}k".format(total / wins / 1000)
#print "mean solution time: {:.4f}s".format(time_elapsed / wins)
print "solution time: {:.4f}s".format(time_elapsed)
print "{} solutions:".format(len(solutions))
#for prog in solutions:
# print prog + '\n'
# if len(solutions) < 10:
# self.run_program(self.unpretty[prog], model_in, model_out, trace=True)
# print '\n'
pretty_prog = "\t".join([self.INSTRUCTIONS[op] for op in prog])
print pretty_prog
print "%d ==> %d" % (thing, len(prog))
break
if False and total >= total_bound:
time_end = time.time()
time_elapsed = time_end - time_start
# print "-=-VICTORY-=-"
print "total = {}k".format(total / 1000)
if last_prog is None:
print "None?!"
total = 0
continue
# if wins > 1:
# print "average = {}k".format(total / wins / 1000)
# print "mean solution time: {:.4f}s".format(time_elapsed / wins)
print "solution time: {:.4f}s".format(time_elapsed)
print "{} solutions:".format(len(solutions))
# for prog in solutions:
# print prog + '\n'
# if len(solutions) < 10:
# self.run_program(self.unpretty[prog], model_in, model_out, trace=True)
# print '\n'
pretty_prog = "\t".join([self.INSTRUCTIONS[op] for op in last_prog])
print pretty_prog
print "%d ==> %d" % (thing, len(last_prog))
break
def main(self):
# EXPLORE = True
EXPLORE = False
# EXPLORE = True
global thing
thing += 1
#thing = random.randint(1,100)
#print "thing =", thing
self.INSTRUCTIONS3 = [
'SWAB', 'MULT', #'IFF', 'JGTE',
'PUSH', 'INC', 'INS',
'ADD',
'NEG', #'XOR', #'LOCO_2', #'SWBC',
'POP', #'PEEK',
'PUSH', 'INC', 'NEG', #'INS', #'DEC',
'ADD', 'DIV', 'SWAC', #'SWBC',
#'NEG', #'XOR', #'LOCO_2', #'SWBC',
'POP', 'PEEK', #'POW', #'PEEK',
#'IFF', #'LOCO_0',
'JNE', #'JGTE',
'JNE', #'LEFT', 'RIGHT',
]
self.ENABLED_CODES = [self.OP_CODE[x] for x in self.INSTRUCTIONS3] # random.sample(range(30), random.randint(12, 26))
model_in = [1, 3, -5, 2, 20, 0, 6, 9, 7, -5]
model_out = [4, -3, 20, 15, 2]
self.ENABLED_CODES = [self.OP_CODE[x] for x in self.INSTRUCTIONS3] # random.sample(range(len(self.INSTRUCTIONS)), random.randint(12, 26))
#self.ENABLED_CODES += random.sample(range(len(self.INSTRUCTIONS)), random.randint(15, 20))
self.ENABLED_CODES = list(set(self.ENABLED_CODES))
model_in = []
model_out = [thing]
#model_in = [1, 3, -5, 2, 20, 0, 6, 9, 7, -5]
#model_out = [4, -3, 20, 15, 2]
#model_out = [2, 15, 20, -3, 4]
#model_in = []
#model_in = [-4, 78, 604, 4, 12, -4]
#model_out = [1, 1, 2, 3, 5, 8, 13]
#model_out = [0, 1, 2, 3, 4, 5]
#model_out = [1, 2, 4, 8, 16, 32]
#model_out = [1, 3, 9, 27, 81]
#model_out = [115]
if EXPLORE:
iterations = 10**6
self.TRIM = 10
results, progs = self.explore(iterations=iterations, max_steps=256, bound=32)
iterations = 10**8
self.TRIM = 5
results, progs = self.explore(iterations=iterations, max_steps=100, bound=36)
inverted = {}
for k, v in results.items():
if v not in inverted:
......@@ -409,11 +471,11 @@ class Skython(object):
print len(keys), len(results), [self.INSTRUCTIONS[x] for x in sorted(self.ENABLED_CODES)]
print "-" * 50
q = []
for i in range(30):
for i in range(len(self.INSTRUCTIONS)):
n = 0
sum_percent = 0.0
for k in keys:
if k < 100:
if k < 10:
for pat in inverted[k]:
n += progs[pat][i] #progs[inverted[k]][i]
#sum_percent += progs[inverted[k]][i] * (1.0 * k / iterations)
......@@ -425,7 +487,7 @@ class Skython(object):
print r
print "-" * 50
q2 = []
for i in range(30):
for i in range(len(self.INSTRUCTIONS)):
n = 0
sum_percent = 0.0
for k in keys:
......@@ -440,11 +502,11 @@ class Skython(object):
print r
print "-" * 50
q3 = []
for i in range(30):
for i in range(len(self.INSTRUCTIONS)):
n = 0
sum_percent = 0.0
for k in keys:
if k > 10000:
if k > 500000:
for pat in inverted[k]:
n += progs[pat][i] #progs[inverted[k]][i]
#sum_percent += progs[inverted[k]][i] * (1.0 * k / iterations)
......@@ -455,11 +517,12 @@ class Skython(object):
for p, r in sorted(q3):
print r
else:
print [self.INSTRUCTIONS[x] for x in sorted(self.ENABLED_CODES)]
#self.run(model_out=[1,2,3,3,4,5], model_in=[4,3,1,3,5,2], bound=30)
#print [self.INSTRUCTIONS[x] for x in sorted(self.ENABLED_CODES)]
#self.run(model_out=[1,2,3,3,4,5], model_in=[4,3,1,3,5,2], bound=len(self.INSTRUCTIONS))
#self.run(model_out=[19,23,37,37,42], model_in=[23,37,42,37,19], bound=35)
self.run(model_out=model_out, model_in=model_in, bound=15)
self.run(model_out=model_out, model_in=model_in, bound=50)
if __name__ == '__main__':
Skython().main()
while True:
Skython().main()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment