Skip to content

Instantly share code, notes, and snippets.

@vznvzn vznvzn/bitwise36.rb
Created Jun 29, 2019

Embed
What would you like to do?
def f2(n)
return n.odd? ? (n * 3 + 1) / 2 : n / 2
end
def d(s)
c = s.split('').select { |x| x == '1' }.size
d = c.to_f / s.length
return d
end
def keys(ks2)
ksmn = ks2.select { |x| x.end_with?('-') }
ksmx = ks2 - ksmn
ksmn.each { |x| x.replace(x.chop) }
return {'ks' => ksmn + ksmx, 'ksmx' => ksmx}
end
def order(l, ks2)
l2 = (0...l.size).map { {} }
$k = keys(ks2) if ($k.nil?)
$k['ks'].each \
{
|k|
l1 = (0...l.size).map { |x| {k => l[x][k], 'i' => x} }
s = $k['ksmx'].member?(k) ? -1 : 1
l1.sort_by! { |x| s * x[k] }
(0...l1.size).each { |x| l2[l1[x]['i']][k] = x }
}
l2.each { |x| x['z'] = x.values.inject(0) { |t, x| t + x } }
return (0...l2.size).sort_by { |x| l2[x]['z'] }
end
def out(a, a2 = {}, t = nil)
fn = 'out.txt'
k = a.keys
if ($f1.nil?) then
$f1 = File.open(fn, 'w')
$f1.puts(k.join("\t"))
f2 = File.open('gnuplot.cmd', 'w')
st = t.nil? ? 'unset title; ' : "set title '#{t}'; "
f2.puts("set ytics nomirror; set y2tics; set colors classic; set key top left box opaque; #{st}; plot \\")
(a.keys - ['t']).each \
{
|x|
f2.puts("'#{fn}' using (column('t')):(column('#{x}')) with line title '#{x}' #{a2[x]}, \\")
}
f2.puts
f2.close
end
$f1.puts(a.values_at(*k).join("\t"))
$f1.flush
end
def remove(a, ks)
a = a.dup
ks.each { |x| a.delete(x) }
return a
end
def seq(n)
n1 = n
l = []
begin
l << n
n = f2(n)
end while (n != 1)
return l
end
def fwd(l)
l1 = []
l.each_with_index \
{
|x, i|
j = x.to_s(2).length
x1 = l[i + j]
l1 << (x1.nil? ? 0 : x1)
}
return l1
end
def mono(l, l2 = [])
return {'mx' => 0} if (l.nil? || l.empty?)
mn = {'i' => 0, 'mn' => l[0]}
mx = {'i' => 0, 'j' => 0, 'mx' => 0}
(1...l.size).each \
{
|j|
mn = [mn, {'i' => j, 'mn' => l[j]}].min_by { |x| x['mn'] }
mx = [mx, {'i' => mn['i'], 'j' => j, 'mx' => j - mn['i']}].max_by { |x| x['mx'] }
}
# l2.replace(l.map { |x| {'x' => Math.log(x)} })
return mx
end
def count(ns)
l = seq(ns.to_i(2))
cm1 = (0...l.size).max_by { |x| l[x] }
cg = l.index { |x| x < l[0] }
cg = l.size if (cg.nil?)
cm = (0...cg).max_by { |x| l[x] }
l1 = fwd(l)
mx = mono(l1)
return {
'ns' => ns,
'c' => l.size,
'cm' => cm,
'cm1' => cm1,
'cg' => cg,
'nw' => ns.length,
'l' => l,
'l1' => l1,
'mx' => mx['mx'],
'mxnw' => mx['mx'].to_f / ns.length
}
end
def fmt(x)
return remove(x, ['l', 'l1'])
end
def axes2()
return ['mxnw'].inject({}) { |h, x| h.merge({x => 'axes x1y2' }) }
end
def add(l, ns)
$t = 0 if ($t.nil?)
$t += 1
x = count(ns).merge({'t' => $t})
l << x
x = fmt(x)
out(remove(x, ['ns']), axes2()) if ($t % $d == 0)
$stderr.puts(x.inspect) if ($t % 200 == 0)
end
def adj(ns)
ns1 = ns.dup
ns1[0, 1] = '10'
ns2 = ns.dup
ns2[0, 1] = '11'
return ns1, ns2
end
def opt(ks)
c = 5e3.to_i
$d = c * 2 / 2000
add(l = [], '1')
c.times \
{
l1 = order(l, ks)
i = l1[rand([l1.size, 50].min)]
x = l.delete_at(i)
ns1, ns2 = adj(x['ns'])
add(l, ns1)
add(l, ns2)
}
return l[order(l, ks)[0]]
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
ks = ['nw', 'cm', 'cg', 'c', 'mx', 'mxnw']
x = opt(ks)
$stderr.puts(fmt(x).inspect)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.