Commit 2633c47b authored by Trevor Cappallo's avatar Trevor Cappallo
Browse files

searching for sorter

parent 2a74a140
#!/usr/bin/env python
"""
Python port of Skynet.
Copyright (c) 2015 Trevor Cappallo
https://code.by.tc/
"""
import random
import time
EXPLORE = False
class Skython(object):
MAGIC_NUMBER = None #-12345
MAX_PROG_SIZE = 100
STEP_LIMIT = 250
STEP_LIMIT = 150
SHRINK = True
TRIM = 15
......@@ -16,6 +27,14 @@ class Skython(object):
'PEEK', 'SKIP', 'LAND', 'LOR', 'IFDO',
'IFF', 'NOT', 'EQ', 'LOCO_1', 'MOD',
]
INSTRUCTIONS2 = [
'LOCO_0', 'SWAB',
'SWAC', 'MULT', 'PUSH', 'POP', 'INC',
'ADD', 'JMP', 'JNE', 'DIV',
'NEG', 'XOR',
'SKIP', 'LAND', 'LOR', 'IFDO',
#'IFF',
]
ENABLED_FIB = [ 'SWAB', 'PUSH', 'INC', 'ADD', 'JNE', ]
ENABLED = [
'LOCO_0', 'INS', 'SWAB',
......@@ -25,8 +44,8 @@ class Skython(object):
'PEEK', 'SKIP', 'LAND', 'LOR', 'IFDO',
'IFF', 'NOT', 'EQ',
]
ENABLED = ENABLED_FIB
#ENABLED = INSTRUCTIONS
#ENABLED = ENABLED_FIB
ENABLED = INSTRUCTIONS #2
OP_CODE = {}
ENABLED_CODES = []
......@@ -35,6 +54,7 @@ class Skython(object):
self.OP_CODE[self.INSTRUCTIONS[i]] = i
for instruction in self.ENABLED:
self.ENABLED_CODES.append(self.OP_CODE[instruction])
self.unpretty = {}
def make_program(self, length):
prog = []
......@@ -100,8 +120,13 @@ class Skython(object):
a, c = c, a
elif op == 6: # MULT
a *= b
#a %= 10000000
if -(10**12) < a < 10**12:
a *= b
else:
return [], 666
#if a > 10**40:
# pc = self.MAX_PROG_SIZE
#a %= 10000000000000
elif op == 7: # PUSH
if sp < self.MAX_PROG_SIZE - 1:
......@@ -155,6 +180,8 @@ class Skython(object):
elif op == 20: # PEEK
if sp > 0 and output[sp - 1] != self.MAGIC_NUMBER:
b = output[sp - 1]
else:
pc = self.MAX_PROG_SIZE
elif op == 21: # SKIP
pc *= 2
......@@ -188,14 +215,14 @@ class Skython(object):
pc += 1
step += 1
# if step >= 10 and la == a and lb == b and lc == c and lsp == sp and lpc == pc:
# return [], 666
# else:
# la = a
# lb = b
# lc = c
# lsp = sp
# lpc = pc
if step >= 10 and la == a and lb == b and lc == c and lsp == sp and lpc == pc:
return [], 666
else:
la = a
lb = b
lc = c
lsp = sp
lpc = pc
if trace:
print "\t{}\t\t[{}\ta={}\tb={}\tc={}\tpc={}\tsp={}]\t\t(".format(self.INSTRUCTIONS[op], step, a, b, c, pc, sp),
......@@ -217,7 +244,7 @@ class Skython(object):
if len(model_out) > 0:
return output, sp
else:
return output[:min(self.TRIM, len(output))], sp
return output[:min(self.TRIM, len(output), sp)], sp
def explore(self, iterations=1000000, bound=MAX_PROG_SIZE // 2, max_steps=50):
timeout = total = redundant = degen = 0
......@@ -251,16 +278,18 @@ class Skython(object):
return results
def run(self, bound=50):
timeout = total = redundant = degen = exact = 0
def run(self, model_out, model_in=None, bound=50):
timeout = total = redundant = degen = 0
exact = 1
#lower_bound, upper_bound = 5, 15
model_in = []
if model_in is None:
model_in = []
#model_in = [1, 3, -5, 2, 20, 0, 6, 9, 7, -5]
#model_out = [4, -3, 20, 15, 2]
model_out = [1, 1, 2, 3, 5, 8, 13]
#model_out = [1, 1, 2, 3, 5, 8, 13]
#model_out = [0, 1, 2, 3, 4, 5]
......@@ -268,11 +297,11 @@ class Skython(object):
#model_out = [1, 3, 9, 27, 81]
wins = 0
wins_needed = 5
wins_needed = 1
solutions = set()
time_start = time.time()
while (True):
prog = self.make_program(random.randint(bound * 4 // 5, bound))
prog = self.make_program(random.randint(bound * 2 // 3, 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]
......@@ -310,8 +339,9 @@ class Skython(object):
if match == len(model_out):
wins += 1
print '|' + '#' * wins + '-' * (wins_needed - wins) + '|'
pretty_prog = "\t".join([self.INSTRUCTIONS[op] for op in prog])
self.unpretty[pretty_prog] = 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):
......@@ -325,7 +355,6 @@ class Skython(object):
if wins == wins_needed:
time_end = time.time()
time_elapsed = time_end - time_start
#run_program(prog, model_in, model_out, trace=True)
print "-=-VICTORY-=-"
print "total = {}k".format(total / 1000)
if wins > 1:
......@@ -333,22 +362,29 @@ class Skython(object):
print "mean solution time: {:.4f}s".format(time_elapsed / wins)
print "\n{} solutions:".format(len(solutions))
for prog in solutions:
print prog
print prog + '\n'
if len(solutions) < 10:
self.run_program(self.unpretty[prog], model_in, model_out, trace=True)
print '\n'
break
if __name__ == '__main__':
#Skython().run()
iterations = 10**6
skyt = Skython()
skyt.ENABLED_CODES = random.sample(range(30), random.randint(1, 30))
results = skyt.explore(iterations=iterations, max_steps=100, bound=20)
inverted = {}
for k, v in results.items():
if v not in inverted:
inverted[v] = []
inverted[v].append(k)
keys = sorted(inverted.keys(), reverse=False)
for k in keys:
print "{:.5%}\t{}\n\n".format(1.0 * k / iterations, '\t\t'.join(inverted[k]))
print len(keys), len(results), skyt.ENABLED_CODES
if EXPLORE:
iterations = 10**9
skyt.ENABLED_CODES = [skyt.OP_CODE[x] for x in skyt.INSTRUCTIONS2] # random.sample(range(30), random.randint(12, 26))
skyt.TRIM = 25
results = skyt.explore(iterations=iterations, max_steps=300, bound=50)
inverted = {}
for k, v in results.items():
if v not in inverted:
inverted[v] = []
inverted[v].append(k)
keys = sorted(inverted.keys(), reverse=False)
for k in keys:
print "{:.5%}\n\t{}\n\n".format(1.0 * k / iterations, '\n\t'.join(inverted[k]))
print len(keys), len(results), [skyt.INSTRUCTIONS[x] for x in sorted(skyt.ENABLED_CODES)]
else:
print [skyt.INSTRUCTIONS[x] for x in sorted(skyt.ENABLED_CODES)]
#skyt.run(model_out=[1,2,3,3,4,5], model_in=[4,3,1,3,5,2], bound=30)
skyt.run(model_out=[19,23,37,37,42], model_in=[23,37,42,37,19], bound=35)
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