Skip to content

Instantly share code, notes, and snippets.

@vznvzn
Created October 7, 2018 20:04
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/206cb99e9455bb79e3949491db512445 to your computer and use it in GitHub Desktop.
Save vznvzn/206cb99e9455bb79e3949491db512445 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 widthdiff(x, y)
x.to_s(2).length - y.to_s(2).length
end
def widthratio(x, y)
x.to_s(2).length.to_f / y.to_s(2).length
end
def d(s)
c = s.split('').select { |x| x == '1' }.size
d = c.to_f / s.length
return d
end
def mx1(ns)
return ns.split(/0+/).map { |x| x.length }.max
end
def count(x)
n = n1 = x['n']
l = [n]
cg = nil
i = nil
while (n >= n1 && n != 1)
n = f1(n)
cg = l.size if (cg.nil? && n < n1)
l << n
end
ns = n1.to_s(2)
cm = (0...l.size).max_by { |x| l[x] }
return x.merge({'cm' => cm,
'mx1' => l[0..cm].map { |x| mx1(x.to_s(2)) }.max,
'cg' => cg.nil? ? 0 : cg,
'w' => widthdiff(l[cm], n1),
'r' => widthratio(l[cm], n1),
'd' => (0.5 - d(ns)).abs,
'l' => l,
'nl' => ns.length})
end
def out(a, a2)
fn = "out#{$i}.txt"
k = a.keys.sort - a2.select { |k, v| v.nil? }.keys
if ($f.nil?) then
$f = File.open(fn, 'w')
$f.puts(k.join("\t"))
f2 = File.open('gnuplot.cmd', ($i == 0) ? 'w' : 'a')
f2.puts('set colors classic; set y2tics; set ytics nomirror; set key top left; ') if ($i == 0)
f2.puts("set title '#{$i}'; plot \\");
(a.keys - ['t']).each \
{
|x|
next if (!k.member?(x))
f2.puts("'#{fn}' using (column('t')):(column('#{x}')) with line title '#{x}' #{a2[x]}, \\")
}
f2.puts("; pause -1;")
f2.close
end
$f.puts(a.values_at(*k).join("\t"))
$f.flush
end
def next2(z, l, add = nil)
x = add.call(z, l) if (!add.nil?)
return true if (x)
out(z, {'cm' => 'lw 3', 'mx1' => 'lw 3',
'l' => nil, 'n' => nil, 'p' => nil, 'nl' => nil,
'd' => 'axes x1y2', 'r' => 'axes x1y2'}) if (z['t'] % 10 == 0)
p = z['p'] + 1
l << [z, count({'n'=>z['n'] + 2 ** p, 'p'=>p, 't' => z['t']}), z.merge({'p'=>p})]
return
end
def hard(k, w = nil)
$f = nil
l = []
l2 = []
next2(count({'n' => 1, 'p' => 0, 't' => 0}), l)
add = lambda { |x, l| l2 << x; return false; }
t = 0
a = nil
3000.times \
{
l1 = (0...l.size).sort_by { |x| [-l[x][1][k], l[x][1]['d']] }.select { |x| l[x][1]['mx1'] <= 10 }
return 'none', a, l2 if (l1.empty?)
a = {'t1' => t, 'l1' => l.size, 'l2' => l2.size}.merge(l[l1[0]][1].select { |k, | !['l', 'n'].member?(k)})
if ((t + 1) % 100 == 0) then
return 'abort', a, [] if (a['cm'] == 0)
# $stderr.puts(a) if ((t + 1) % 500 == 0)
end
i = l1[rand([l1.size, l1.size >= 50 ? 20 : 50].min)]
z = l.delete_at(i)
[z[1], z[2]].each { |x| return 'cutoff', a, l2 if (next2(x.merge({'t' => t}), l, add)) }
l.delete_at(l1[-1]) if (l.size > 2000)
t += 1
}
return 'end', a, l2
end
def sample(l, c)
r = l.size / c
l2 = *(0...l.size).select { |x| x % r == 0 }
l2[c..-1] = []
return l.values_at(*l2)
end
def review(fn)
l = File.open(fn).readlines.map { |x| Kernel.eval(x) }
$stderr.puts(l.size)
l = sample(l, 1000)
l.sort_by! { |x| x['nl'] }
l.each { |x| x.delete('n'); x.delete('p'); x['t'] = x['t'] / 10.0 }
f = File.open('gnuplot1.cmd', 'w')
f.puts("set y2tics; set ytics nomirror; set key center left;")
f.puts("$dat << eof")
ks = l[0].keys
f.puts(ks.join("\t"))
l.each { |x| f.puts(x.values.join("\t")) }
f.puts('eof')
f.puts('plot \\')
ks.each \
{
|x|
z = ''
z = 'axes x1y2 ' if (['d', 'r'].member?(x))
z += 'lw 4 ' if (['cm', 'cg', 'r'].member?(x))
z += 'dt 3' if (['t'].member?(x))
f.puts("'$dat' using (column('#{x}')) with line #{z},\\")
}
f.close
exit
end
fn = 'mixdb.txt'
review(fn) if (File.exists?(fn))
f = File.open(fn, 'w')
z = {}
seen = {}
n = 0
10.times \
{
|i|
$i = i
e, a, l2 = hard('cm', 100)
$f.close
$f = nil
z[e] = z.fetch(e, 0) + 1
n += l2.size
l2.each \
{
|x|
next if (seen.member?(x['n']))
seen[x['n']] = nil
x.delete('l')
f.puts(x.inspect)
f.flush
}
$stderr.puts("##{i} -- #{e} / #{n} count / #{seen.size} unique", a.inspect)
}
f.close
$stderr.puts(z.merge({'n' => n, 'n1' => seen.size}))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment