Skip to content

Instantly share code, notes, and snippets.

@vznvzn
Created March 18, 2017 02:51
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/29590f225838ca4d5e1a3618c4bc6c21 to your computer and use it in GitHub Desktop.
Save vznvzn/29590f225838ca4d5e1a3618c4bc6c21 to your computer and use it in GitHub Desktop.
def f2(n)
n = (n * 3 + 1) / 2 while (n.odd?)
n /= 2 while (n.even?)
return n
end
def adv(x)
n1 = n = x['n']
l = [n]
while (n >= n1 && n != 1)
n = f2(n)
l << n
end
x['g1'] = l.size
x['w1'] = x['n'].to_s(2).length
x['h1'] = (x['g1'].to_f / x['w1'] * 50).to_i
return x
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, sd, l.max.to_f, l.min.to_f
end
def range(l, s)
['g', 'w', 'h'].each \
{
|k|
l1 = l.map { |x| x["#{k}1"] }
a, sd, mx, mn = stat(l1)
h = hist(l1)
x = h.max_by { |k, v| v }
s.merge!({"#{k}_a" => a, "#{k}_sd" => sd,
"#{k}_mx" => mx, "#{k}_mn" => mn,
"#{k}_md" => x[0]})
}
end
def out(f, a)
f.puts(a.keys.join("\t")) if (f.size == 0)
f.puts(a.values.join("\t"))
f.flush
end
def next2(z)
l = [z]
p = z['p'] + 1
l << adv({'n'=>z['n'] + 2**p, 'p'=>p})
l << z.merge({'p'=>p})
return l
end
def sum(l)
t = 0
l.compact.each { |x| t += x }
return t == 0 ? nil : t
end
def next1(x, r, l2)
x = next2(x)
l2 << x[1]
return x if (r.empty?)
['g', 'w', 'h'].each \
{
|k|
sd = r["#{k}_sd"]
next if (sd == 0 || sd.nan?)
x[1][k] = (x[1]["#{k}1"] - r["#{k}_a"]) / sd
}
x[1]['gwh'] = sum([x[1]['g'], x[1]['w'], x[1]['h']])
x[1]['gw'] = sum([x[1]['g'], x[1]['w']])
x[1]['wh'] = sum([x[1]['w'], x[1]['h']])
x[1]['gh'] = sum([x[1]['g'], x[1]['h']])
return x
end
def hist(l)
h = {}
l.each \
{
|x|
h[x] = h.fetch(x, 0) + 1
}
return h.sort
end
def opt(c, w, fn, ns, o)
l1 = []
l2 = []
l1 << next2({'n'=>1, 'p'=>0})
r = {}
f = File.open('out.txt', 'w')
i = 0
w2 = ['g', 'w', 'h', 'gw', 'wh', 'gh', 'gwh', 'r']
c.times \
{
i += 1
if (i % 100 == 0) then
range(l1.map { |x| x[1] }, r)
$stderr.puts([w.join, i, r['w_mn']].inspect)
out(f, r)
break if (r['w_mn'] > ns)
end
w2.rotate!
if (w2.first == 'r') then
j = l1.size
else
l1 = l1.sort_by { |x| -x[1][x[1][w2.first].nil? ? 'g1' : w2.first] }
j = [20, l1.size].min
end
z = l1.delete_at(rand(j))
l1 << next1(z[1], r, l2)
l1 << next1(z[2], r, l2)
l1.delete_at((0...l1.size).min_by { |x| l1[x][1]['w1'] }) if (l1.size > 1000)
}
f.close
o << [fn, i] + (i == c ? ['x'] : [])
return l2
end
def plot(fn, c)
exe = "C:\\Program Files (x86)\\gnuplot\\bin\\wgnuplot"
system(exe, "-e", "set terminal png; set output 'data/#{fn}.png'; set colors classic; set title '#{fn}'; #{c}")
end
def plot1(fn, k, x = '')
c = "plot [0:100][0:150] 'out#{x}.txt' using (column('w_a')):(column('#{k}_a')):(column('#{k}_sd')) with errorbars title 'a',\
'' using (column('w_a')):(column('#{k}_md')) with line title 'md', \
'' using (column('w_a')):(column('#{k}_mn')) with line title 'mn', \
'' using (column('w_a')):(column('#{k}_mx')) with line title 'mx';"
plot(fn, c)
end
def hist2(l, fn)
h = {}
l.select { |x| x.member?('w1') }.each \
{
|x|
w = x['w1']
h[w] = [] if (!h.member?(w))
h[w] << x
}
f = File.open('out1.txt', 'w')
h.sort.each \
{
|k, v|
r = {}
range(v, r)
out(f, r)
}
f.close
['g', 'h'].each \
{
|k|
plot1("#{fn}_#{k}", k, '1')
}
end
def graph(c, w, ns, o)
l2 = opt(c, w, fn = 'gwhr', ns, o)
h = hist2(l2, fn)
end
def out2(k, l)
h = hist(l)
f = File.open("out_#{k}.txt", 'w')
h.each { |k, v| f.puts([k, v].join("\t")) }
f.close
end
File.delete(*Dir.glob('data/*'))
c = 100
o = []
graph(5e3.to_i, ['gwhr'], c, o)
o.each { |x| $stderr.puts(x.inspect) }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment