SR
Jump to navigation
Jump to search
SR (Seeded Random) is an esolang invented by User:None1 and inspired by Seed.
Every program in SR consists of 5 numbers separated by spaces. Let's say that these numbers are A B C D and E.
When executing an SR program, first output A as character using the charset !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\n (\n is the line feed). Then let A be (A*B+C)%D. This process is repeated E times.
Examples
Print hello
72 48588 120650 484115 5
Nope. interpreter
46 63241 17783 257074 5
Print hi
72 40 127 258 2
Print fuck
70 28842 30961 68260 4
Implementations
This is a Python implementation, along with a genetic algorithm to generate programs (the examples are all generated using this program), you may need to change the argument when using the algorithm.
import json,gc
from secrets import randbelow
from json import *
def sri(a,b,c,d,e):
res=''
strtbl=''.join(map(chr,range(32,127)))+'\n'
for i in range(e):
res+=strtbl[a%len(strtbl)]
a=(a*b+c)%d
return res
def sr(x):
return sri(*map(int,x.split()))
def srscore(a,b,c,d,e,s):
cc=sri(a,b,c,d,e)
res=1
for i,j in enumerate(cc):
res+=256-abs(ord(j)-ord(s[i]))
return res
def gen(s,m):
strtbl = ''.join(map(chr, range(32, 127))) + '\n'
d=randbelow(m-1)+1
return strtbl.index(s[0]),randbelow(min(m,d)),randbelow(min(m,d)),d,len(s)
GENERATIONS=100000 # Maximum number of generations
CANDIDATES=1000 # Number of genomes
MUTATE_NUM=60 # Bits to XOR when mutating
SHOW=50 # Show every SHOW generations
genomes=[]
scores=[]
pref_sum=[]
new_genomes=[]
temp_genomes=[]
result=None
max_score=-1
def save(s):
with open('temp.json','w') as f:
json.dump({'string':s,'genome':genomes,'maxscore':max_score,'result':result},f)
def read(s):
global genomes,max_score,result
try:
with open('temp.json','r') as f:
t=json.load(f)
if t['string']!=s:
return False
genomes=t['genome']
max_score=t['maxscore']
result=t['result']
except:
return False
return True
def select(pref_sum):
pos=randbelow(pref_sum[-1]+1)
l,r,ans=0,len(pref_sum)-1,0
while l<=r:
mid=(l+r)>>1
if pref_sum[mid]>=pos:
ans=mid
r=mid-1
else:
l=mid+1
return ans
def init(s,m):
global genomes,new_genomes,pref_sum
for i in range(CANDIDATES):
genomes.append(gen(s,m))
def merge_(x,y):
k=randbelow(4)
a,b,c,d,e=x
A,B,C,D,E=y
return ((a,)+(b,c,d)[:k]+(B,C,D)[k:]+(e,),(a,)+(B,C,D)[:k]+(b,c,d)[k:]+(e,))
def mutate_num(x):
# return randbelow(MUTATE_NUM*2+1)-MUTATE_NUM+x
return (x^(1<<randbelow(MUTATE_NUM)) if randbelow(2) else x)
def mutate_(x,m):
a,b,c,d,e=x
return a,mutate_num(b)%m,mutate_num(c)%m,mutate_num(d)%m+1,e
def merge():
global new_genomes
new_genomes=[]
fittest = None
maxscore = -1
for i, j in enumerate(scores):
a, b, c, d, e = genomes[i]
if fittest:
A, B, C, D, E = fittest
if (maxscore < j) or (not fittest) or (
maxscore == j and len(str(a)) + len(str(b)) + len(str(c)) + len(str(d)) + len(str(e)) < len(
str(A)) + len(str(B)) + len(str(C)) + len(str(D)) + len(str(E))):
fittest = (a, b, c, d, e)
maxscore=j
new_genomes.append(fittest)
for i in range(CANDIDATES):
x,y=select(pref_sum),select(pref_sum)
a,b=merge_(genomes[x],genomes[y])
new_genomes.append(a),new_genomes.append(b)
def mutate(m):
global temp_genomes,new_genomes
temp_genomes=[]
for i in new_genomes:
temp_genomes.append(mutate_(i,m))
new_genomes=temp_genomes[:]
def get_pref_sum(s):
global scores,genomes,pref_sum
scores=[]
pref_sum=[]
for i in genomes:
scores.append(srscore(*i,s))
k=0
for i in scores:
k+=i
pref_sum.append(k)
def record():
global max_score,result
sc=max(scores)
if (not result) or max_score<sc:
result=genomes[scores.index(sc)]
max_score=sc
def one_generation(s,m):
global genomes
get_pref_sum(s)
record()
merge()
mutate(m)
genomes=new_genomes[:]
def generate(s,m): # s: target string m: maximum value used
if not read(s):
init(s,m)
for i in range(GENERATIONS):
one_generation(s, m)
if (i+1)%50==0:
print(f'Generation: {i+1}\tMaximum score: {max_score}\tCode: {result}')
save(s)
gc.collect()
if max_score==256*len(s)+1:
break
print(f'Generation: {i + 1}\tMaximum score: {max_score}\tCode: {result}')
print(f'Code: {result}\tScore: {max_score}')
Note
It is guessed but not proved that this esolang can produce any output in the charset.