Skip to content

Instantly share code, notes, and snippets.

@vznvzn
Created December 17, 2018 00:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vznvzn/11802d584ae1f3bf76067c3e316d0a9f to your computer and use it in GitHub Desktop.
Save vznvzn/11802d584ae1f3bf76067c3e316d0a9f to your computer and use it in GitHub Desktop.
def f2(n)
return n.odd? ? (n * 3 + 1) / 2 : n / 2
end
def dense(w, d)
w2 = w - 1
a = (0...w2).to_a
s = '0' * w2
(1..(d * w - 1)).map { a.delete_at(rand(a.size)) }.each { |x| s[x, 1] = '1' }
return ('1' + s)
end
def d(s)
c = s.split('').select { |x| x == '1' }.size
d = c.to_f / s.length
return d
end
def len01(ns)
nl = ns.length
return 0, 0 if (nl < 50)
l1 = ns.split(/0+/).map { |x| x.length }
l2 = ns.split(/1+/)[1..-1]
l2 = [''] if (l2.nil?)
l0 = l2.map { |x| x.length }
return l0, l1
end
def mx01(ns)
return len01(ns).flatten.max
end
def initr(w, m)
l = []
b = 1
while (w > 0)
t = [w, m].min
r = (t <= 1) ? 1 : rand(t) + 1
l << [b] * r
b ^= 1
w -= r
end
s = l.flatten.join
return s
end
def initd(w, m)
d = m.to_f / w
w2 = w - 1
a = (0...w2).to_a
s = '0' * w2
(1..(d * w - 1)).map { a.delete_at(rand(a.size)) }.each { |x| s[x, 1] = '1' }
return ('1' + s)
end
def initb(w, m)
r = m.to_f / w
return '1' + (1...w).map { rand < r ? '0' : '1' }.join
end
def initr2(w, m, b)
l = []
while (w > 0)
t = [w, m].min
r = (t <= 1) ? 1 : rand(t) + 1
l << [b] * r
b ^= 1
w -= r
end
s = l.flatten.join
return s
end
def initw(w, m)
w -= 2
m = [w, m].min
i = rand([w - m, 1].max)
j = w - i - m
b = rand(2)
ns = initr2(i, rand([i - 1, 1].max) + 1, b ^ 1).reverse + ([b] * m).join + initr2(j, rand([j - 1, 1].max) + 1, b ^ 1)
s = '1' + (ns[0].to_i ^ 1).to_s + ns
return s
end
def mut(ns)
ns = ns.dup
i = rand(ns.length - 1) + 1
ns[i, 1] = (ns[i, 1].to_i ^ 1).to_s
return ns
end
def inner(ns1, ns2)
a, b = [ns1, ns2].sort_by { |x| x.length }
d = b.length - a.length
i = rand(d + 1)
c = b.dup
c[i, a.length] = a
ns1.replace(b)
ns2.replace(c)
end
def mix(ns1, ns2)
ns1 = ns1.dup
ns2 = ns2.dup
inner(ns1, ns2)
return (0...ns1.length).map { |x| [ns1, ns2][rand(2)][x, 1] }.join
end
def cut(ns1, ns2)
ns1 = ns1.dup
ns2 = ns2.dup
inner(ns1, ns2)
i = rand(ns1.length)
return ns1[0...i] + ns2[i..-1]
end
def ext(ns)
return (0..rand(3)).map { rand(2) }.join + ns
end
def count(ns)
n1 = n = ns.to_i(2)
l = [n]
while (n >= n1)
n = f2(n)
l << n
end
cm = (0...l.size).max_by { |x| l[x] }
return {'z' => cm,
'c' => l.size
}
end
def fmt(msg, x)
t = msg.member?(x) ? Time.now.to_i - msg[x] : 0
m = t / 60
s = t % 60
msg[x] = "#{m}m #{s}s"
end
def add(h, ns, seen, msg)
return if (seen.member?(ns))
seen[ns] = nil
x = {'ns' => ns}.merge(count(ns))
return if (!x.member?('z'))
j = ns.length
h[j] = [] if (!h.member?(j))
a, b = [h[j][0], h[j][-1]]
h[j] = h.fetch(j, []) + [x]
h[j] = h[j].sort_by { |x| -x['z'] }
h[j][50..-1] = [] if (h[j].size > 50)
t = msg['t']
msg['t0'] = Time.now.to_s
msg['s'] = seen.size
msg['hc1'] = h.size
msg['hc2'] = h.map { |k, v| v.size }.inject(0){ |t, x| t + x }
if (msg['a1'].nil? || x['z'] > msg['a1']['z']) then
msg['a1'] = x
msg2 = msg.dup
['t', 't1', 't2'].each { |x| fmt(msg2, x) }
p(msg2)
end
msg['t1'], msg['a'] = [Time.now.to_i, h[j][0]['z']] if (a.nil? || h[j][0]['z'] != a['z'])
if (b.nil? || h[j][-1]['z'] != b['z']) then
msg['t2'], msg['b'] = [Time.now.to_i, h[j][-1]['z']]
seen[ns] = x
end
end
def top(h1)
return h1[rand([h1.size / 4, h1.size].max)]
end
def opt(w1)
h = {}
ops = ['initr0', 'initd0', 'initb0', 'initw0', 'mut1', 'mix2', 'cut2'] # ext1
seen = {}
msg = {'t' => Time.now.to_i}
loop \
{
opc = ops[rand(ops.size)]
c = opc[-1..-1].to_i
op = opc[0..-2]
case (c)
when 0
ns = send(op, w1, rand(w1))
add(h, ns, seen, msg)
when 1, 2
redo if (h.empty?)
ks = h.keys.sort_by { |x| -h[x][0]['z'] }
h.delete(ks.pop) if (ks.size > 50)
msg['hmn'], msg['hmx'] = [ks.min, ks.max]
ks = ks[0...[ks.size, ks.size / 4].max]
arg = (0...c).map { ks[rand(ks.size)] }
l = arg.map { |x| top(h[x])['ns'] }
ns = send(op, *l)
ns[0, 1] = '1'
add(h, ns, seen, msg)
end
break if (msg['t2'] - msg['t'] > 180)
}
f = File.open('mixdb.txt', 'w')
l = seen.select { |k, v| v != nil }.map { |x| x[1] }.sort_by { |x| x['z'] }
l.each { |x| f.puts(x.inspect) }
f.close
$stderr.puts(l.size)
end
def seqmx(n)
n1 = n
l = [n]
l2 = []
while (n >= n1)
n = f2(n)
l << n
l2 << mx01(n.to_s(2))
end
cm = (0...l.size).max_by { |x| l[x] }
return l2[0..cm]
end
def sample(l, c)
r = l.size / c
l2 = *(0...l.size).select { |x| x % r == 0 }
l2[c..-1] = []
return l.values_at(*l2)
end
def review(fn)
l1 = sample(l = File.open(fn).readlines.map { |x| Kernel.eval(x) }, 50)
f2 = File.open('out2.txt', 'w')
l.each { |x| f2.puts(d(x['ns'])) }
f2.close
f = File.open('out.txt', 'w')
j = 0
l1.each \
{
|x|
ns = x['ns']
l1 = seqmx(ns.to_i(2))
d = d(ns)
ns = dense(ns.length, d)
l2 = seqmx(ns.to_i(2))
[l1, l2].each_with_index \
{
|l, c|
l.each_with_index { |x, i| f.puts([j + i, x * [1, -1][c], c + 1].join("\t")) }
f.puts
}
j += [l1.size, l2.size].max + 20
}
f.close
exit
end
fn = 'mixdb.txt'
review(fn) if (File.exist?(fn))
opt(100)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment