Collatz_Sequence, modified_Collatz_Sequence, posiitve & negative logic test for integers
  By      aku
  For     Tcllib
  On      2021-09-18T08:30:12.893
Subject: Collatz_Sequence, modified_Collatz_Sequence, posiitve & negative logic test for integers
Add Attachment To Ticket e035b93f36
----
Request Collatz_Sequence, modified_Collatz_Sequence, posiitve & negative logic test for integers for math library. I have loaded the Collatz_Sequence code on the TCL WIKI. Refer to https://wiki.tcl-lang.org/_edit/Collatz_Sequences+%283%2AN%2B1%29+in+Console+Example+Demo+for+TCL+V3. Vesrsion 3 I have worked up a small test suite for the Collatz_Sequence. Solved problem. The proc collatz_sequence was substantially rewritten by HE and I replaced in the main deck and good feedback comments, which I will have to chew on. Many thanks to HE. I checked the proc collatz_sequence in small test suite and proc looks good, so I will pass ticket on to TCLLIB math. I have loaded the ticket e035b93f36 Title: Collatz_Sequence, modified_Collatz_Sequence, positive & negative logic test for integers.

 ----
Here are TCL calculations on  the Collatz Sequences. The Collatz Sequences were  named after German mathematician Lothar Collatz (1910–1990).  Collatz conjectured that the Collatz Sequence of any positive number would begin repeating and coalesce to 1. The proc collatz_sequence was substantially rewritten by [HE] and replaced in the  main deck and comments, which I will have to chew on. Primarily, I am interested in petitioning the code to the [TCLLIB]. Many thanks to HE for comments and feedback.

 ----
Here are TCL calculations on  the Collatz Sequences. The Collatz Sequences were  named after German mathematician Lothar Collatz (1910–1990).  Collatz conjectured that the Collatz Sequence of any positive number would begin repeating and coalesce to 1. The proc collatz_sequence was substantially rewritten by [HE] and replaced in the  main deck with good valuable comments, which I will have to chew on. Primarily, I am interested in petitioning the code to the [TCLLIB]. Many thanks to HE for comments and feedback.
---- 
The collatz_sequence proc returns the partial collatz_sequence from positive integers. This  collatz_sequence proc can easily generate an endless loop. In fact, the known collatz_sequences are an endless list or repetitive string of integers. The iteration number is a stop or limit to iteration. By custom, the end of the partial collatz_sequence is 1 or start of repetition. For example, the collatz_sequence for integer '''5''' would be ''' < 5 16 8 4 2 1 4 2 1 4 2 1 4 2 1 4 2 1 4 2 1 4 ...> ''' The proc with entry 5 is intended to report the partial collatz_sequence of ''' < 5 16 8 4 2 1 >'''. Many of the known collatz_sequences boil down to end in  ''' < ... 16 8 4 2 1 ... > ''', so its somewhat counter intuitive to me that various positive integers have the same terminus in their collatz_sequence.
----
if $N even, return { $N / 2 }.  If $N odd,  return (3*$N+1). Continue the collatz_sequence until returned item is 1 or start of repetition. The speed of the supporting procs IsOdd and IsEeven were undetermined. 
---- 
The modified_Collatz_Sequence is slightly different 2nd equation  ((3*$N+1)/2) used for faster and different numbers resolution as outlined in https://en.wikipedia.org/wiki/Collatz_conjecture.
----
proposed  Collatz_Sequences and  modified Collatz_Sequences functions in TCLLIB.
----
======
collatz_sequence_head (27, 4 ) evals  27 82 41 124
collatz_sequence_head (27, 3 ) evals  27 82 41  
collatz_sequence_head (27, 2 ) evals  27 82  
collatz_sequence_head (27, 1 ) evals  27    , initial entry 
collatz_sequence_head (10, 3 ) evals  5 16 8 
collatz_sequence_tail (27, 4 ) evals 8 4 2 1
collatz_sequence_tail (27, 3 ) evals 4 2 1
collatz_sequence_tail (27, 2 ) evals  2 1
collatz_sequence_tail (27 , 1 ) evals   1, final entry
collatz_sequence_tail (10 , 3 ) evals  4 2 1   
collatz_sequence_tail (27, 4 ) evals 8 4 2 1
collatz_sequence_max_sequence_value (27)  evals  9232?
collatz_sequence_max_sequence_value (10)  evals  6
collatz_sequence_length (10)  evals 6
collatz_sequence_length (27)  evals 111?
collatz_sequence_generate  (5) evals  5 16 8 4 2 1 
collatz_sequence_generate  (27) evals 27 82 41 124 62 31 94 47 142 71 214 107 322 161 484 242 121 364 182 91 274 137 412 206 103 310 155 466 233 700 350 175 526 263 790 395 1186 593 1780 890 445 1336 668 334 167 502 251 754 377 1132 566 283 850 425 1276 638 319 958 479 1438 719 2158 1079 3238 1619 4858 2429 7288 3644 1822 911 2734 1367 4102 2051 6154 3077 9232 4616 2308 1154 577 1732 866 433 1300 650 325 976 488 244 122 61 184 92 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
reverse_collatz_sequence_generate (5) 1 2 4 8 16 5
reverse_collatz_sequence_generate (7) 1 2 4 8 16 5 10 20 40 13 26 52 17 34 11 22 7
reverse_collatz_sequence_generate (10) 1 2 4 8 16 5 10 
reverse_collatz_sequence_generate (27) 1 2 4 8 16 5 10 20 40 80 160 53 106 35 70 23 46 92 184 61 122 244 488 976 325 650 1300 433 866 1732 577 1154 2308 4616 9232 3077 6154 2051 4102 1367 2734 911 1822 3644 7288 2429 4858 1619 3238 1079 2158 719 1438 479 958 319 638 1276 425 850 283 566 1132 377 754 251 502 167 334 668 1336 445 890 1780 593 1186 395 790 263 526 175 350 700 233 466 155 310 103 206 412 137 274 91 182 364 121 242 484 161 322 107 214 71 142 47 94 31 62 124 41 82 27
# using index number in second position
# Many known collatz_sequences coalesce to 1 to similiar tail, 16 8 4 2 1 
# so may have to  index to 8 or 9 to show any differences in reverse_collatz_sequence(N)
reverse_collatz_sequence_head (10 3) 1 2 4 
reverse_collatz_sequence_head (5 4) 1 2 4 8 
# reporting number of computation steps for collatz_sequence(N) , would also be useful
collatz_sequence_steps (27) returns 112?
collatz_sequence_steps (10) returns 6?
collatz_sequence_steps (50) returns 21?
# collatz_sequence sorted from maximum to minimum value
collatz_sequence_maximum_values (5)  returns 16 8 5 4 2 1
collatz_sequence_maximum_values_short_list (10 3) returns 16 8 10?
======
----
 Console wrapper for solution proc
  ***************************
  ***************************
%|table 1| || printed in tcl wiki format|% 
&| quantity| value  |value| comment, if any|& 
&| 1:|testcase_number || |&
&| 7.0 :|initial integer |   |   |&
&| 20.0 :|iteration limit , safety maybe cut short : | | |& 
&| 4.0 :|optional index_tails for heads, max values, and tails, usually 4 :  | | |& 
&| 17 :|optional constant , nominal 1, calc reverts to number of calc steps : |   |   |&
&| 17 :| steps_iteration_total: | | |& 
&| 52 :| collatz_sequence short list of maximum values : |  | |& 
&| 7 22 11 34 :|  collatz_sequence_head   : |  | |& 
&| 8 4 2 1 :|  collatz_sequence_tail :  |  | |&
&| 17 :|  collatz_sequence_length: |  | |&
&| 1 2 4 8 :| reverse_Collatz_Sequence head  : |   | |&
&| 1 2 4 8 16 5 10 20 40 13 26 52 17 34 11 22 7 :| reverse_Collatz_Sequence values  : |   | |&
&| 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1 :|  Collatz_Sequence values  : |   | |&


        # Collatz_Sequence calculator V4
        #  Collatz_Sequence test suite gui
        # gui graphical user interface on Windows10
        # written on Windows 10 PC
        # working under TCL version 8.6 
        # gold on TCL WIKI, 18sep2021
        package require Tk
        package require math::numtheory
        namespace path {::tcl::mathop ::tcl::mathfunc math::numtheory }
        set tcl_precision 17
        frame .frame -relief flat -bg aquamarine4
        pack .frame -side top -fill y -anchor center
        set names {{} {initial integer :} }
        lappend names {iteration limit, safety break  maybe cut short, usually 20: }
        lappend names {optional index for heads, tails, and max vals, usually 4 : }
        lappend names {optional constant , nominal 1, calc reverts to number of calc steps: }
        lappend names {answers, Collatz_Sequence short list of maximum values    : }
        lappend names { collatz_sequence_head  : }
        lappend names { collatz_sequence_tail  : }
        lappend names { Collatz_Sequence length  : }
        lappend names { Collatz_Sequence   : }        
        foreach i {1 2 3 4 5 6 7 8 9} {
            label .frame.label$i -text [lindex $names $i] -anchor e
            entry .frame.entry$i -width 35 -textvariable side$i
            grid .frame.label$i .frame.entry$i -sticky ew -pady 2 -padx 1 }
        proc about {} {
            set msg "Calculator for Collatz_Sequence  V2
            from TCL Club,
            written on TCL 8.6 "
            tk_messageBox -title "About" -message $msg } 
        proc self_help {} {
            set msg "Calculator for Collatz_Sequence V2
            from TCL ,
            # self help listing
            # 2 given  follow.
            1) initial integer  N1
            2) iteration limit $iteration
            3) optional index for heads and tails, usually 4
            4) number of calc steps or optional  constant, c. not used now
            # This calculator returns the partial Collatz_Sequence  
            # based on initial integer and iteration number of steps
            # optional constant mode, usually 1 for no decay, 
            # not used & open yet, optional constant 
            # iteration is safety break for brevity and counter endless loops
            # iteration  maybe cut short for brevity
            # The collatz_sequence proc returns the partial collatz_sequence
            # from positive integers. 
            # This collatz_sequence proc can easily generate an endless loop.
            # In fact, the known collatz_sequences are an endless list
            # or coalesce to 1 or a repetitive string of integers. 
            # The iteration number is a stop or limit steps of iteration.
            # By custom, the end of the partial collatz_sequence 
            # is 1 or start of repetition integers
            # max_values_list is short list of maximum values in list, 
            # number of maximum values controlled by an index number
            # collatz_sequence_head is initial values at start of sequence
            # collatz_sequence_tail is initial values at end of sequence
            # collatz_sequence_length is maximum length of partial collatz sequences
            # warning!!!  if index & iteration activated for brevity,
            # sequence list maybe cut short
            # collatz_sequence is list of collatz_sequence
            # warning!!! if index & iteration activated for brevity,
            # sequence list maybe cut short 
            # steps_iteration_total is total number of steps used in calc proc
            # For comparison, TCL code may include redundant paths & formulas.
            # The TCL calculator normally uses modern
            # units  for convenience to modern users and textbooks.
            # Any convenient and consistent in/output units might be used
            # like inches, feet, nindas, cubits, or dollars to donuts.
            # Recommended procedure is push testcase and fill frame,
            # change first three entries etc, push solve,
            # and then push report. Report allows copy and paste
            # from console to conventional texteditor. For testcases
            # testcase number is internal to the calculator and
            # will not be printed until the report button is pushed
            # for the current result numbers.
            # Use one line errorx proc to estimate percent errors. 
            # errorx proc is used in the report window (console).
            # Additional significant figures are used to check
            # the TCL program, not to infer the accuracy
            # of inputs and product reports.
            # Proc precisionx <AM> is loaded and may be used to
            # trim lengthy mantissas.
            # precisionx used on select numbers only, not used on every number.
            # Conventional text editor formulas or  grabbed from internet
            # Screens can be pasted into green report console.
            # Try copy and paste following into green screen console
            # set answer \[* 1. 2. 3. 4. 5. \]
            # returns  120
            # gold on  TCL Club, 30apr2021 "
            tk_messageBox -title "self_help" -message $msg }
        proc precisionx {precision float}  {
            #  tcl:wiki:Floating-point formatting, <AM>
            # select numbers only, not used on every number.
            set x [ expr {round( 10 ** $precision * $float) / (10.0 ** $precision)} ]
            #  rounded or clipped to nearest 7nd significant figure
            set x [ format "%#.7g" $x ]
            return $x
        }
        # Use one line errorx proc to estimate percent errors 
        # errorx proc is used in the report window (console)
        proc errorx  {aa bb} {expr { $aa > $bb ?   (($aa*1.)/$bb -1.)*100. : (($bb*1.)/$aa -1.)*100.}}
        # adapted from tcl-wiki Stats 2011-05-22, arithmetic mean  [RLE]
        #
        # ::collatz_sequence_special --
        #
        # Return the collatz_sequence
        #
        # Arguments:
        #    length  first value is length
        #    iteration second value is length
        #
        # Results: collatz_sequence
        #
        proc collatz_sequence_special { number iteration } {
        global steps_iteration_total
        set steps_iteration_total 1
        set count 1
        while 1 {
	lappend sequence $number
	if {$number == 1} {return $sequence}
	set number [expr {$number & 1 ? $number*3+1 : $number/2}]
        incr count 
        set steps_iteration_total $count
        if {  $count >  $iteration } {break }
         }
        return $sequence
         }
        # modified_collatz_sequence can be swapped in calculations proc
        proc modified_collatz_sequence_special { number iteration } {
        global steps_iteration_total
        # modified different formula from collatz_sequence_special
        set steps_iteration_total 1
        set count 1
        while 1 {
	lappend sequence $number
	if {$number == 1} {return $sequence}
	             if {$number % 2} {
                        # Odd
                        set number [expr {((3 * $number) + 1) / 2}]
                } else {
                        # Even
                        set number [expr {$number / 2}]
                }
        incr count 
        set steps_iteration_total $count
        if {  $count >  $iteration } {break }
         }
        return $sequence
         }
            # index is number of sequence values displayed from start of sequence
            # warning!!!  if index & iteration activated for brevity,
            # sequence list maybe cut short, including integers, 
            # maximum values, heads and tails reported
            # comments are placed outside these working routines 
            # because comments are deleted in final TCLLIB version, I think
            proc collatz_sequence_head_1 { sequence_list index }  {
            return  [lrange $sequence_list 0 $index] }
            # index is number of sequence values displayed from end of sequence
            proc collatz_sequence_tails_1 { sequence_list  index } {
            return   [lrange $sequence_list end-$index end]}
            # index may be used later here
            proc collatz_sequence_length_1 {sequence_list  index } { 
            return  [llength $sequence_list ]}
            # max_values_list is short list of maximum values in collatz_sequence           
            # ::tcl::mathfunc::max {*}$values ;# ==> 9
            proc max_values_list_1 {sequence_list index } {
            return   [ ::tcl::mathfunc::max {*}$sequence_list ]}
            proc reverse_sequence_list_1 { sequence_list } {
            return [ lreverse $sequence_list]   }
            proc reverse_sequence_head_1 { sequence_list  index } {
            set temp  [ lreverse $sequence_list]
            return [ lrange $temp 0 $index    ]   }
        proc calculate {     } {
            global side1 side2 side3 side4 side5
            global side6 side7 side8 side9 
            global side10 side11 side12
            global collatz_sequence_tail collatz_sequence_head
            global collatz_sequence_length collatz_sequence_max_sequence_value
            global max_values_list index_tails steps_iteration_total
            global testcase_number  
            global option_mode optional_constant  sequence_list
            incr testcase_number 
            set side1 [* $side1 1. ]
            set side2 [* $side2 1. ]
            set side3 [* $side3 1. ]
            set side4 [* $side4 1. ]
            set side9 1.
            set side10 1.
            set side11 1.
            set initial_integer  [int $side1 ]
            set iteration [ int $side2 ]
            set index_tails  [ int $side3 ]
            set index_tails [ expr { $index_tails - 1 } ]
            # index_tails should not be less than 0 or 1
            # index_tails is usually 4
            if { $index_tails < 1 } { set index_tails 4 }
            set sequence_list [ collatz_sequence_special $initial_integer $iteration ] 
            set collatz_sequence_head [ collatz_sequence_head_1 $sequence_list $index_tails ]
            set collatz_sequence_tail [ collatz_sequence_tails_1 $sequence_list $index_tails ]
            set collatz_sequence_length [ collatz_sequence_length_1  $sequence_list $index_tails ]
            set reverse_sequence_list_head [ reverse_sequence_head_1  $sequence_list $index_tails ]
            # set values {4 3 2 7 8 9}
            # ::tcl::mathfunc::max {*}$values ;# ==> 9
            set max_values_list [ max_values_list_1 $sequence_list $index_tails ]
            set side4 $steps_iteration_total 
            # maximum value in list
            set side5 $max_values_list
            # initial values at start of sequence
            set side6 $collatz_sequence_head
            # initial values at end of sequence
            set side7 $collatz_sequence_tail
            # maximum length of partial collatz sequences
            # warning!!!  if index & iteration activated for brevity,
            # sequence list maybe cut short
            set side8 $collatz_sequence_length 
            #  list of collatz_sequence
            # warning!!! if index & iteration activated for brevity,
            # sequence list maybe cut short
            set side9 $sequence_list
            set side10 $reverse_sequence_list_head 
            set side11  [ reverse_sequence_list_1  $sequence_list ]
            # we have computed the set 
             }
        proc fillup {aa bb cc dd ee ff gg hh ii} {
            .frame.entry1 insert 0 "$aa"
            .frame.entry2 insert 0 "$bb"
            .frame.entry3 insert 0 "$cc"
            .frame.entry4 insert 0 "$dd"
            .frame.entry5 insert 0 "$ee"
            .frame.entry6 insert 0 "$ff" 
            .frame.entry7 insert 0 "$gg"
            .frame.entry8 insert 0 "$hh" 
            .frame.entry9 insert 0 "$ii" 
             }
        proc clearx {} {
            foreach i {1 2 3 4 5 6 7 8 9 } {
                .frame.entry$i delete 0 end } }
        proc reportx {} {
            global side1 side2 side3 side4 side5
            global side6 side7 side8 side9 gr
            global side10 side11 side12  
            global testcase_number sequence_list
            global collatz_sequence_tail collatz_sequence_head
            global collatz_sequence_length collatz_sequence_max_sequence_value
            global max_values_list steps_iteration_total
            global option_mode optional_constant
            console show;
            puts "%|table $testcase_number| || printed in tcl wiki format|% "
            puts "&| quantity| value  |value| comment, if any|& "
            puts "&| $testcase_number:|testcase_number || |&"
            puts "&| $side1 :|initial integer |   |   |&"
            puts "&| $side2 :|iteration limit , safety maybe cut short : | | |& "  
            puts "&| $side3 :|optional index_tails for heads, max values, and tails, usually 4 :  | | |& "
            puts "&| $side4 :|optional constant , nominal 1, calc reverts to number of calc steps : |   |   |&"
            puts "&| $steps_iteration_total :| steps_iteration_total: | | |& "
            puts "&| $side5 :| collatz_sequence short list of maximum values : |  | |& "
            puts "&| $side6 :|  collatz_sequence_head   : |  | |& "
            puts "&| $side7 :|  collatz_sequence_tail :  |  | |&"
            puts "&| $side8 :|  collatz_sequence_length: |  | |&"
            puts "&| $side10 :| reverse_Collatz_Sequence head  : |   | |&"
            puts "&| $side11 :| reverse_Collatz_Sequence values  : |   | |&"
            puts "&| $side9 :|  Collatz_Sequence values  : |   | |&"
            } 
        frame .buttons -bg aquamarine4
        ::ttk::button .calculator -text "Solve" -command { calculate   }
        ::ttk::button .test2 -text "Testcase1" -command {clearx;fillup 7. 20. 4. 1.  1. 1. 1. 1. 1.   }
        ::ttk::button .test3 -text "Testcase2" -command {clearx;fillup 10. 20. 4. 1.  1. 1. 1. 1. 1.   }
        ::ttk::button .test4 -text "Testcase3" -command {clearx;fillup 27. 112. 4. 1.  1. 1. 1. 1. 1.  }
        ::ttk::button .clearallx -text clear -command {clearx }
        ::ttk::button .about -text about -command {about}
        ::ttk::button .self_help -text self_help -command {self_help }
        ::ttk::button .cons -text report -command { reportx }
        ::ttk::button .exit -text exit -command {exit}
        pack .calculator  -in .buttons -side top -padx 10 -pady 5
        pack  .clearallx .cons .self_help .about .exit .test4 .test3 .test2   -side bottom -in .buttons
        grid .frame .buttons -sticky ns -pady {0 10}
               . configure -background aquamarine4 -highlightcolor brown -relief raised -border 30
        wm title . "Collatz_Sequence  Calculator V2 " 
        # end of working deck
        # add cosmetics below to bottom of file 
        console eval {.console config -bg palegreen}
        console eval {.console config -font {fixed 20 bold}}
        console eval {wm geometry . 40x20}
        console eval {wm title . " Report for Collatz_Sequence Calculator V2  "}
        console eval {. configure -background orange -highlightcolor brown -relief raised -border 30}
        puts "  Console wrapper for solution proc"
        puts "  ***************************"
        puts "  ***************************"        
        
