Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@vznvzn
Created September 21, 2019 05:13
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/f41f1ad431343c8301127c59aecf98f1 to your computer and use it in GitHub Desktop.
Save vznvzn/f41f1ad431343c8301127c59aecf98f1 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
a = {'n' => n,
'cg' => cg,
'cg1' => cg1,
'c' => c,
'cm1' => cm1,
'cm' => cm,
'mx01' => mx01,
'mx01s' => mx01s,
'd' => d(ns),
'e' => e(ns)}
$i = 0 if ($i.nil?)
$i += 1
$l << a.merge({'n' => Math.log(n)}) if ($i % 100 == 0)
return a
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.select { |x, x1| x1['f'] == 'b' }.map { |x| x[1][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
}
return s
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
def outa(f, l, a = {}, t = '')
f.puts('$dat << eof')
k = l[0].keys
f.puts(k.join("\t"))
l.each { |x| f.puts(x.values.join("\t")) }
f.puts('eof')
f.puts("set colors classic; set ytics nomirror; set y2tics; set title '#{t}'; plot \\")
k.each \
{
|x|
next if (a.member?(x) && a[x].nil?)
f.puts("'$dat' using (column('#{x}')) with line #{a.fetch(x, '')},\\")
}
f.puts
# f.puts("reset; pause -1;")
end
a = {}
n = 1
c = 100
$l = []
c.times { node(a, n += 1) }
f = File.open('gnuplot.cmd', 'w')
f.puts('$dat << eof')
f.puts(['s', 'n', 'x_z'].join("\t"))
l1 = []
150.times \
{
|i|
s = stats(a)
l1 << s
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;")
outa(f = File.open('gnuplot1.cmd', 'w'), l1,
{'n_a' => nil, 'n_sd' => nil, 'd_a' => 'axes x1y2', 'd_sd' => 'axes x1y2',
'e_a' => 'axes x1y2', 'e_sd' => 'axes x1y2'
})
f.close
outa(f = File.open('gnuplot2.cmd', 'w'), $l,
{'d' => 'axes x1y2', 'e' => 'axes x1y2'})
f.close
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment