Skip to content

Instantly share code, notes, and snippets.

@vznvzn
Created May 29, 2018 02:12
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/406b28db65e85636740db82648d25c1c to your computer and use it in GitHub Desktop.
Save vznvzn/406b28db65e85636740db82648d25c1c to your computer and use it in GitHub Desktop.
def f1(n)
n = (n * 3 + 1) / 2 while (n.odd?)
n /= 2 while (n.even?)
return n
end
def f2(n)
return n.odd? ? (n * 3 + 1) / 2 : n / 2
end
def count(x, w)
n = n1 = x['n']
l = [n]
while (n >= n1 && n != 1)
n = {'packed' => true, 'unpacked' => false}[w] ? f1(n) : f2(n)
l << n
end
cm = (0...l.size).max_by { |x| l[x] }
return l[0..cm]
end
def d(s)
c = s.split('').select { |x| x == '1' }.size
d = c.to_f / s.length
return d
end
def data(n)
ns = n.to_s(2)
nl = ns.length
l = ns.split(/0+/)
l1 = l.map { |x| x.length }
d = d(ns)
x = stat(l1)
mxs = l.map { |x| x.length.to_f / nl }.max
return {'a' => x['a'],
'sd' => x['sd'],
'mx' => x['mx'],
'mxs' => mxs,
'd' => d,
'e' => l.size,
'es' => l.size.to_f / nl}
end
def uniq(l)
a = {}
l.each { |x| a[x['n']] = x }
# $stderr.puts({'ls1' => l.size, 'ls2' => a.size}.inspect)
return a.values
end
def stat(l)
l = [0] if (l.empty?)
t = t2 = 0
l.each \
{
|x|
t += x
t2 += x ** 2
}
c = l.size
a = t.to_f / c
z = t2.to_f / c - a ** 2
sd = Math.sqrt(z < 0 ? 0 : z)
return {'a' => a, 'sd' => sd, 'mx' => l.max, 'mn' => l.min}
end
def calc(l1)
l0 = []
l1.each_with_index \
{
|l2, i|
l = l2.reverse.map { |x| x.to_s(2).length }
(0...(l2.size - 1)).each \
{
|j|
mx, mxs = data(l2[j])
l0 << data(l2[j]).merge({'md' => j, 'w1' => l[j], 'w2' => l[j + 1]})
}
}
return l0
end
def out(fn, l, k)
f = File.open(fn, 'w')
f.puts("plot '-' using 1:2:3 with line linecolor palette lw 2 title '#{k}'")
l.sort_by { |x| x[k] }.each \
{
|x|
f.puts([x['md'], x['w1'], x[k]].join("\t"))
f.puts([x['md'] + 1, x['w2'], x[k]].join("\t"))
f.puts
}
f.puts('eof')
f.close
$stderr.puts(fn)
end
def read()
l = (f = File.open('tmp/mixdb.txt')).readlines.map { |x| Kernel.eval(x) }
f.close
return uniq(l)
end
def mid(l)
l = l.sort_by { |x| x.size }
mn = (l.size * 0.02).to_i
mx = (l.size * 0.90).to_i
return l[0...mn], l[mn..mx], l[mx..-1]
end
def cmd(x = nil)
f = File.open('gnuplot.cmd', x.nil? ? 'w' : 'a')
f.puts("#{x}; pause -1;") if (!x.nil?)
f.close
end
def resample(l)
la, l, lb = mid(l)
l0 = l.map { |x| x.size }
l = l.dup
mn = l[0].size
mx = l[-1].size
l1 = []
c = 115
a = {}
l2 = (0...l.size).to_a
(c + 1).times \
{
|x|
r = x.to_f / c
t = mn + r * (mx - mn)
i = (0...l.size).min_by { |x| (l[x].size - t).abs }
l1 << l.delete_at(i)
a[l2.delete_at(i)] = nil
}
f = File.open('out.txt', 'w')
la.each { |x| f.puts(x.size) }
l0.each_with_index { |x, i| f.puts([x, a.member?(i) ? x : nil].join("\t")) }
lb.each { |x| f.puts(x.size) }
f.close
f2 = File.open('out2.txt', 'w')
l1.each { |x| f2.puts(x.size) }
f2.close
cmd("plot 'out.txt' using 1 with line, '' using 2 pt 5 ps 0.5,'out2.txt' using 1 axes x2y2 pt 5 ps 0.5")
return l1
end
def run(l, z = '')
['a', 'sd', 'mx', 'mxs', 'd', 'e', 'es'].each \
{
|k|
out(fn = "gnuplot_#{z}#{k}.cmd", l, k)
cmd("load '#{fn}'")
}
end
cmd()
run(calc(l = read().map { |x| count(x, 'unpacked') }))
run(calc(resample(l)), 'n')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment