2023.02.03 Math 3600 3n+1

234 days ago by calkin

Let us investigate the 3n+1 problem.  We'll define f and g as described in the 2023-02-03 notes.

def f(n): if is_even(n): return(n/2) else: return(3*n+1) 
       
f(2) 
       
1
1
type(f(2)) 
       
<type 'sage.rings.rational.Rational'>
<type 'sage.rings.rational.Rational'>
type(Integer(f(2))) 
       
<type 'sage.rings.integer.Integer'>
<type 'sage.rings.integer.Integer'>
Integer(f(2)) 
       
1
1
Integer(3/4) 
       
Traceback (click to the left of this block for traceback)
...
TypeError: no conversion of this rational to integer
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "_sage_input_8.py", line 10, in <module>
    exec compile(u'open("___code___.py","w").write("# -*- coding: utf-8 -*-\\n" + _support_.preparse_worksheet_cell(base64.b64decode("SW50ZWdlcigzLzQp"),globals())+"\\n"); execfile(os.path.abspath("___code___.py"))
  File "", line 1, in <module>
    
  File "/tmp/tmpxmdAUC/___code___.py", line 3, in <module>
    exec compile(u'Integer(_sage_const_3 /_sage_const_4 )
  File "", line 1, in <module>
    
  File "sage/rings/integer.pyx", line 662, in sage.rings.integer.Integer.__init__ (/usr/local/sage-6.10/src/build/cythonized/sage/rings/integer.c:5806)
  File "sage/rings/rational.pyx", line 2670, in sage.rings.rational.Rational._integer_ (/usr/local/sage-6.10/src/build/cythonized/sage/rings/rational.c:23379)
TypeError: no conversion of this rational to integer

Let us improve the function f: we'll check that the input is an integer, and is positive.

def f(n): if n<1 or (type(n)==Integer)==False: return("Please input a positive integer") elif is_even(n): return(Integer(n/2)) else: return(3*n+1) 
       
f(3) 
       
10
10
type(f(3)) 
       
<type 'sage.rings.integer.Integer'>
<type 'sage.rings.integer.Integer'>
type(f(4)) 
       
<type 'sage.rings.integer.Integer'>
<type 'sage.rings.integer.Integer'>

Let us also define g, which computes (3n+1)/2 in one step.

def g(n): if n<1 or (type(n)==Integer)==False: return("Please input a positive integer") elif is_even(n): return(Integer(n/2)) else: return(Integer((3*n+1)/2)) 
       
g(3) 
       
5
5
type(g(3)) 
       
<type 'sage.rings.integer.Integer'>
<type 'sage.rings.integer.Integer'>
f(2) 
       
1
1
f(7) 
       
22
22
f(22) 
       
11
11
f(11) 
       
34
34
f(34) 
       
17
17
f(17) 
       
52
52
f(52) 
       
26
26
f(26) 
       
13
13
f(13) 
       
40
40
f(40) 
       
20
20
f(20) 
       
10
10
f(10) 
       
5
5
f(5) 
       
16
16
f(16) 
       
8
8

Since we believe we will always reach 1, let's create a while loop to compute how many steps for f to reach 1.

step_counter = 0 n=7 while n>1: step_counter+=1 n=f(n) print(step_counter) 
       
16
16
step_counter = 0 n=9 while n>1: step_counter+=1 n=f(n) print(step_counter) 
       
19
19

Let us think about creating a list of pairs [n,hs(n) ] where hs(n) is the number of steps needed to reach 1.

hailstone=[ [1,0] ] for m in srange(2,20): step_counter=0 n=m while n>1: step_counter+=1 n=f(n) hailstone.append([m,step_counter]) 
       
print(hailstone) 
       
[[1, 0], [2, 1], [3, 7], [4, 2], [5, 5], [6, 8], [7, 16], [8, 3], [9,
19], [10, 6], [11, 14], [12, 9], [13, 9], [14, 17], [15, 17], [16, 4],
[17, 12], [18, 20], [19, 20]]
[[1, 0], [2, 1], [3, 7], [4, 2], [5, 5], [6, 8], [7, 16], [8, 3], [9, 19], [10, 6], [11, 14], [12, 9], [13, 9], [14, 17], [15, 17], [16, 4], [17, 12], [18, 20], [19, 20]]
list_plot(hailstone) 
       
hailstone=[ [1,0] ] for m in srange(2,1000): step_counter=0 n=m while n>1: step_counter+=1 n=f(n) hailstone.append([m,step_counter]) list_plot(hailstone) 
       
hailstone=[ [1,0] ] for m in srange(2,10000): step_counter=0 n=m while n>1: step_counter+=1 n=f(n) hailstone.append([m,step_counter]) list_plot(hailstone) 
       
hailstone=[ [1,0] ] for m in srange(2,100000): step_counter=0 n=m while n>1: step_counter+=1 n=f(n) hailstone.append([m,step_counter]) list_plot(hailstone)