Skip to content

Instantly share code, notes, and snippets.

@vznvzn
Created October 16, 2015 20:47
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/0aba0b347d01dc1ac003 to your computer and use it in GitHub Desktop.
Save vznvzn/0aba0b347d01dc1ac003 to your computer and use it in GitHub Desktop.
#!/usr/bin/ruby1.8
def f1(n)
n = (n * 3 + 1) / 2 while (n % 2 == 1)
n /= 2 while (n % 2 == 0)
return n
end
def dense(n)
s = n.to_s(2)
c = 0
s.length.times \
{
|i|
c += s[i, 1].to_i
}
return c.to_f / s.length
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 f(n, w)
n1 = n
c = 0
l = [n]
cg = nil
while (n != 1)
n = f1(n)
l << n
c += 1
cg = c if (cg.nil? && n < n1)
break if (!cg.nil? && w != 'c')
end
cm = (0...l.size).max_by { |x| l[x] }
return {'cm' => cm,
'cg' => cg.nil? ? 0 : cg,
'm' => l[cm].to_s(2).length,
'w' => widthdiff(l[cm], n1),
'r' => widthratio(l[cm], n1),
'c' => l.size,
'd' => (0.5 - dense(n1)).abs}
end
def long(m, w)
return {'n' => rand(2**m) | 1 } if (w == 'z')
l = [{'n' => 1, 'p' => 0}.merge(f(1, w))]
t = 0
e = 2000
loop \
{
l = l.sort_by { |x| [x[w], -x['d']] }.reverse
x = l.delete_at(rand([l.size, 20].min))
p2 = x['p'] + 1
n2 = x['n'] + 2 ** p2
x1 = x.dup
x1['p'] = p2
l << x1
x2 = {'n' => n2, 'p' => p2}.merge(f(n2, w))
l << x2
t += 1
w2 = w
if (w == 'r') then
z = l.sort_by { |x| x['n'] }.reverse[0...100].max_by { |x| x['r'] }
w2 = 's'
else
z = l.max_by { |x| x[w] }
end
z.merge!({ 't' => t, 's' => t.to_f / e })
return z if (z[w2] >= m)
return if (t >= e)
}
end
def mono(l)
y = nil;
c = m = a = 0
b = nil
l.each_with_index \
{
|x, i|
c += 1
if (c > m) then
m = c
b = a
end
next if (!(y.nil? || x <= y))
y = x
c = 0
a = i
}
return m, b, l.size, b.to_f / l.size
end
def smooth2(n, w, w1, w2)
l = []
w.times { l << n; n += 2 }
l2 = l.dup
seen = {}
l1 = []
begin
j = (0...l2.size).max_by { |x| l2[x] }
z = l[j]
f = w2 ? seen.member?(z) : z == 1
if (f) then
l.delete_at(j)
l2.delete_at(j)
next
end
seen[z] = nil
l[j] = f1(z)
l2[j] += z
t = 0
if (w1) then
l.each { |x| t += x.to_s(2).length }
l1 << t
else
l.each { |x| t += x }
l1 << t.to_s(2).length
end
end while (!l.empty?)
return l1
end
def run(p, k)
r = p[k]
c = 100
a, b = r
d = (b - a).to_f / c
b1 = [false, true]
(c + 1).times \
{
z = long(a, k)
next if (z.nil?)
l = []
b1.each { |w1| b1.each { |w2| l << mono(smooth2(z['n'], 100, w1, w2)) } }
puts([l, k, a, z['n'].to_s(2).length].join("\t"))
$stdout.flush
a += d
}
end
def run1()
z = long(10, 'z')
l2 = []
b = [false, true]
b.each { |w1| b.each { |w2| l2 << smooth2(z['n'], 100, w1, w2) } }
c = l2.map { |x| x.length }.max
l2.each { |l| l[l.size...c] = [0] * (c - l.size) }
l2 = l2.transpose
l2.each { |x| puts(x.join("\t")) }
exit
end
run1() if (ARGV[0] == '1')
p = {'cm' => [0, 50],
'cg' => [0, 100],
'm' => [0, 300],
'w' => [0, 75],
'r' => [0.0, 1.0],
'c' => [0, 250],
'z' => [0, 1000],
'p' => [0, 300]
}
run(p, ARGV[0])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment