# collatz binary mapping patterns similar to codes!

re collatz this surprising new finding jumped out at me recently. seems promising, still analyzing it. 💡 ❗ ❓

again consider the collatz function as two possible operations, and one can determine a kind of “collatz hash ID” associated with each integer, where the operations are binary digits ‘0’ and ‘1’ in a string. one can define a set of numbers/strings $C(x, y)$ where $x$ is the total number of operations and $y$ is the number of a specific operation, in this case the $3n+1$ “op”. this functions somewhat similar to the combinatorial “Choose(x, y)” operation.

here is a remarkable finding, graphically depicted below for (eg) $C(30,7)$. the set $C(x,y)$ “tends” (but not always) to refer to integers of exactly the same “size” as expressed in binary! it tends to refer to two different consecutive sizes for $C(x,5)$ and $C(x,10)$. (is it for $y$ multiples of five?) there are presumably other basic patterns; havent delved too much into this yet, and need to create a basic 3-d plot of $C(x,y)$ at some pt.

some of the rationale/inspiration for this is that $C(x,y)$ seemed to be more “orderly” for low $y$. in other words the division/multiplication by two operation is conceptually simpler esp wrt binary (its just a “shift”) and the $3n+1$ op seems to be the “scrambling” operation. this also revisits the similarity of Collatz to PRNGs and shows it similar to LCGs.

this suggests there is some relationship between the collatz conjecture and coding theory! the idea is that for some $C(x,y)$ it is “converting”/1-1 mapping codes of length $s_1$ into codes of length $s_2$.

there are 4 associated graphs below that look at symmetries of this, where one can sort by either $x, f(x)$ where $x,f(x)$ are in binary, or the “reverse” of the two binary strings. the left sides of each graph are the “collatz Hash IDs” and the right sides are the integers, both expressed in binary.

some other news. many of the reverse tree algorithms previous on this site have a funky, humbling glitch. they are not really generating the tree correctly/uniquely! this was found & fixed with the help of a bit of test/verification code embedded in this following code to look for duplicate integers. (a new @#\$& swear acryonym? TEIHTFID: Too Err Is Human….) 😡

in short where the condition (y % 3 == 1) is used, what is needed is (y % 3 == 1 && ((y - 1) / 3).odd?)

def out(a, b, x, f)

c = a + '   ' + b
c.split('').each_with_index \
{
|c, y|
next if (c == ' ')
f.puts([y, x].join("\t"))
}

end

l = [[[8], '', 0]]

c, n = ARGV.map { |x| x.to_i }

c.times \
{
|x|
l2 = []
l.each \
{
|t, p, c|
y = t[-1]
next if ([1, 4].member?(y))
l2 << [t + [y * 2], p + ' ', c]
l2 << [t + [(y - 1) / 3], p + '.', c + 1] if (y % 3 == 1 && ((y - 1) / 3).odd?)
}

l = l2.select { |x| x[2] <= n }
a = {}
l.each \
{
|t, p, c|
x = t[-1]
a[x] = [] if (!a.member?(x))
a[x] += [t]
if (a[x].size > 1) then
p([c, a[x]])
exit
end
}
}

l = l.select { |x| x[2] == n}

l.each \
{
|l2|
t = l2[0]
z = t[-1]
l2 << z.to_s(2).gsub('0', ' ').gsub('1', '.')
}

(0..3).each \
{
|s|
case s
when 0
l.sort_by! { |x| x[1] }
when 1
l.sort_by! { |x| x[1].reverse }
when 2
l.sort_by! { |x| x[3] }
when 3
l.sort_by! { |x| x[3].reverse }
end

f = File.open("fork8d#{s}.txt", 'w')

l.each_with_index \
{
|l2, x|
t, p, c, z = l2

out(p, z, x, f)
x += 1
}
f.close
}

## 3d plot of 2 op counts randomly sampled

(8/7) this is another visualization that took quite awhile to develop iteratively. its in 3d. it turns out to be a roughly 2-d surface but gnuplot “surface plot” functionality does not seem to have an option to work with such an object other than as a point cloud. so the code comes up with a specified method of drawing some lines between nearby points, but only for lines of less than a certain threshold, to aid in human perception of the results. here the breakdown of $(x,y,z)$ pairs is graphed where $z$ is the binary width of the starting integer, and $x,y$ are the counts of the 2 resulting $3n+1$ and ½ “ops”. it uses random sampling with increased density as $z$ increases. the result is DAG-like plot.

disconnected/ “spaced out” lines on far fringe are rare cases of very long trajectories. the graphs are 2 slightly different angles. the random sampling has the advantage of being able to look at very large starting integers. there seems some kind of common probability distribution at each $z$ that presumably is parameterized somehow by $z$. for low values of $z$ its apparently bimodal. as mentioned earlier this sorts points into 2d equivalence classes where some bins contain many trajectories. the lower $z$ values oversample all the 2d equivalence classes but the higher ones undersample them all. from some other experiments the total number of equivalence classes grows according to some low-degree polynomial but with added noise around it— like everything else about the collatz behavior. (sometimes it seems that if any quantity of collatz would be measurable by any nonrandom/ noisy function, it could lead to a proof….)

def count(n)

x = 0
y = 0
while (n > 1)

n.even? ? x += 1 : y += 1
n = n.even? ? n / 2 : n * 3 + 1
end
return [x, y]

end

def count2(n)

x = 0
y = 0
while (n > 1)

n.even? ? x += 1 : y += 1
n = n.even? ? n / 2 : (n * 3 + 1) / 2
end
return [x, y]

end

def out(p1, p2)

d = Math.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2 + (p1[2] - p2[2]) ** 2)
return if (d > 10)

puts(p1.join("\t"))
puts(p2.join("\t"))
puts("\n\n")

end

l2 = []

30.times \
{
|i|

a = {}
(50 + i).times\
{
n = ('1' + (1..i).map { rand(2).to_s }.join).to_i(2)
x, y = count2(n)
a[[x, y, i]] = nil
}
l = a.keys
l.sort_by { |x, y, i| x }

(0...(l.size - 1)).each \
{
|j|
x, y, i = l[j]
x2, y2, i2 = l[j + 1]

out([x, y, i], [x2, y2, i2])
}

l.each \
{
|x, y, i|
x2, y2, i2 = l2.min_by {  |x2, y2, i2| (x - x2) ** 2 + (y - y2) ** 2 + (i - i2) ** 2 }

out([x, y, i], [x2, y2, i2])
} if (!l2.empty?)

l2 = l
}