Skip to content

Instantly share code, notes, and snippets.

@vznvzn
Created November 19, 2020 03:59
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/7be5d3fa79634e7c241da640beae4403 to your computer and use it in GitHub Desktop.
Save vznvzn/7be5d3fa79634e7c241da640beae4403 to your computer and use it in GitHub Desktop.
def f2(n)
return n.odd? ? (n * 3 + 1) / 2 : n / 2
end
def seq(n)
l = [n]
while (n != 1)
n = f2(n)
l << n
end
return l
end
def d(s)
c = s.split('').select { |x| x == '1' }.size
d = c.to_f / s.length
return d
end
def outin(fn)
l = (f = File.open(fn)).readlines
f.close
raise if (l.shift.chop != '$dat << eof')
k = l.shift.split
i = l.index("eof\n")
raise if (i.nil?)
l[i..-1] = []
l2 = l.map { |x| Hash[[k, x.split.map { |x| Kernel.eval(x) }].transpose] }
l2.each { |x| x['ns'] = x['ns'].to_s }
$stderr.puts([fn, l2.size].inspect)
return l2
end
def load(l1 = [1])
l = []
l1.each \
{
|i|
l.concat(outin("tmp/gnuplot#{i}-1.cmd"))
}
return l
end
def fix(l, k)
l.each_with_index \
{
|x, i|
x[k] = l[i - 1][k] if (!x[k].finite?)
}
l.shift while (!l[0][k].finite?)
end
def lh(ns)
nw2 = ns.length / 2
return ns[nw2..-1], ns[0..nw2]
end
def dlh(ns)
nw1, nw2 = lh(ns)
d1 = d(nw1)
d2 = d(nw2)
return d1, d2, d1 - d2
end
def outd(f, l)
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')
return k
end
def outa(f, l, a = {}, t = '')
k = outd(f, l)
f.puts("set colors classic; set title '#{t}'; ")
f.puts("set ytics nomirror; set y2tics;")
f.puts("plot \\")
k, ct = [k - ['t'], "(column('t')):"] if (k.member?('t'))
k.each \
{
|x|
next if (a.member?(x) && a[x].nil?)
opt = a.fetch(x, '')
opt += ' lw 2 ' if (!opt.include?('lw'))
opt += ' with line ' if (!opt.include?('with') && !opt.include?('pt'))
f.puts("'$dat' using #{ct}(column('#{x}')) #{opt} title '#{x}',\\")
}
f.puts
# f.puts("reset; pause -1;")
end
def outafn(l, a = {}, fno = nil, t = '')
f = File.open(fn = "gnuplot#{fno}.cmd", 'w')
f.puts("set terminal png")
fn1 = "gnuplot#{fno}.png"
f.puts("set output '#{fn1}'")
outa(f, l, a)
f.puts("set output")
f.puts("print '#{fn1}'")
f.close
$stderr.puts([fn, t, l.size].inspect)
end
def sum(l)
return l.inject { |t, x| t + x }
end
def avg(l)
return l.empty? ? 0 : sum(l).to_f / l.size
end
def runavg(l, k, c)
l1 = l.map { |x| x[k] }
t = sum(l1[0...c])
l2 = (['-'] * (c - 1)) + [t.to_f / c]
while (l1.size > c)
t -= l1.shift
t += l1[c - 1]
l2 << (t.to_f / c)
end
ka = "#{k}a"
l.each_with_index { |x, i| x[ka] = l2[i] }
end
def smooth1(x)
$stderr.puts(x.inspect)
ns = x['ns']
n = ns.to_i(2)
l = seq(n)
l2 = []
l.each_with_index \
{
|x, i|
l2 << {'d' => d(x.to_s(2)), 'i' => l.size - i, 'nw' => x.to_s(2).length}
}
outafn(l2, {'i' => nil, 'd' => 'axes x1y2'}, 3)
outafn(l2.sort_by { |x| x['d'] }, {'i' => 'axes x1y2 pt 5', 'nw' => nil}, 4)
l1 = []
c = 50
l2.each { |x| j = (x['d'] * c).to_i; l1[j] = (l1[j].nil? ? [] : l1[j]) + [x['i']] }
l1 = l1.map { |x| x.nil? ? nil : avg(x) }
l1x = (0...l1.size).map { |x| l1[x].nil? ? nil : {'t' => x, 'ia' => l1[x]} }.compact
outafn(l1x, {'ia' => 'with linespoints pt 5'}, 5)
l3 = []
l2.each { |x| l3 << {'x' => (l1[(x['d'] * c).to_i])} }
runavg(l3, 'x', 200)
l4 = l2.map { |x| { 'da' => -(x['d'] - 0.5).abs } }
runavg(l4, 'da', 200)
outafn(l4, {}, 7)
l3.size.times { |x| l3[x]['daa'] = l4[x]['daa'] }
outafn(l3, {'xa' => 'lw 3', 'daa' => 'axes x1y2'}, 6)
end
def smooth2(x)
$stderr.puts(x.inspect)
ns = x['ns']
n = ns.to_i(2)
l = seq(n)
l2 = []
l.each_with_index \
{
|x, i|
l2 << {'d' => (d(x.to_s(2)) - 0.5).abs}
}
c = 750
runavg(l2, 'd', c)
a = {}
l2[c..-1].each_with_index { |x, j| a[x['da']] = l2.size - c - j }
l3 = a.to_a.shuffle.sort_by { |x| x[0] }.map \
{
|x, y|
{'daa' => x, 'y' => y}
}
outafn(l3, {'daa' => 'axes x1y2'}, 8)
outafn(l2, {'da' => 'axes x1y2 lw 3'}, 9)
outafn(l3, {'daa' => nil, 'y' => 'pt 5 ps 0.5'}, 10)
end
l = load()
x = l[-ARGV[0].to_i]
smooth1(x)
smooth2(x)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment