Skip to content

Instantly share code, notes, and snippets.

@vznvzn
Created September 21, 2019 05: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/df62fd3f49fba828c1e5e64d09c1d7cc to your computer and use it in GitHub Desktop.
Save vznvzn/df62fd3f49fba828c1e5e64d09c1d7cc to your computer and use it in GitHub Desktop.
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 lenx(ns, p)
l = ns.split(p)
l = [] if (l.nil?)
l.shift if (l[0] == '')
return l.map { |x| x.length }
end
def len01x(ns)
return lenx(ns, /0+/), lenx(ns, /1+/)
end
def e(ns)
return len01x(ns).flatten.size.to_f / ns.length
end
def seq(n)
n1 = n
l = []
begin
l << n
n = f2(n)
end while (n != 1)
return l
end
def mx01x(ns)
l1, l0 = len01x(ns)
return (l1 + l0).max.to_f
end
def measure(l)
cm1 = (0...l.size).max_by { |x| l[x] }
cg = l.index { |x| x < l[0] }
cg = l.size - 1 if (cg.nil?)
cg1 = l.rindex { |x| x >= l[0] }
cm = (0..cg).max_by { |x| l[x] }
c = l.size
n = l[0]
ns = n.to_s(2)
mx01 = mx01x(ns)
mx01s = mx01.to_f / ns.length
{'n' => n,
'cg' => cg,
'cg1' => cg1,
'c' => c,
'cm1' => cm1,
'cm' => cm,
'mx01' => mx01,
'mx01s' => mx01s,
'd' => d(ns),
'e' => e(ns)}
end
def stat(l)
return 0, 0, 0 if (l.empty?)
t = l.inject { |a, x| a + x }
t2 = l.inject { |a, x| a + x ** 2 }
c = l.size
a = t.to_f / c
z = t2.to_f / c - a ** 2
sd = Math.sqrt(z < 0 ? 0 : z)
raise if (sd.nan?)
return a, sd, l.max
end
def stats(a)
s = {}
ks = a.first[1].keys - ['z', 'f']
ks.each \
{
|k|
av, sd = stat(a.values.map { |x| x[k] })
s["#{k}_a"] = av
s["#{k}_sd"] = sd
}
a.each \
{
|k, x|
z = 0
ks.each { |k| z += ((x[k] - s["#{k}_a"]) / s["#{k}_sd"]) ** 2 }
x['z'] = z
}
end
def count(a, n, x = 'a')
m = a.member?(n)
a[n] = measure(seq(n)) if (!m)
a[n]['f'] = x
end
def node(a, n)
count(a, n)
count(a, n * 2, 'b')
count(a, (n - 1) / 3, 'b') if (n % 3 == 1 && ((n - 1) / 3).odd?)
end
def adv(a, x, s, f)
n = x['n']
f.puts([s, n, x['z']].join("\t"))
node(a, n)
end
a = {}
n = 1
c = 100
c.times { node(a, n += 1) }
f = File.open('gnuplot.cmd', 'w')
f.puts('$dat << eof')
f.puts(['s', 'n', 'x_z'].join("\t"))
200.times \
{
|i|
stats(a)
l2 = a.values.select { |x| x['f'] == 'b' }
l = l2.sort_by { |x| x['z'] }.reverse
x1 = l2.min_by { |x| x['n'] }
adv(a, x1, 1, f)
(c / 2).times \
{
raise if (l.empty?)
x = l.shift
adv(a, x, 2, f)
}
}
f.puts('eof')
f.puts("plot $dat using x:(log(column('n'))):(column('s')) with point linecolor variable pt 5 ps 0.5; pause -1;")
f.puts("plot $dat using x:(log(column('x_z'))):(column('s')) with point linecolor variable pt 5 ps 0.5; pause -1;")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment