begin % show some Hailstone Sequence related information % % calculates the length of the sequence generated by n, % % if showFirstAndLast is true, the first and last 4 elements of the % % sequence are stored in first and last % % hs holds a cache of the upbHs previously calculated sequence lengths % % if showFirstAndLast is false, the cache will be used % procedure hailstone ( integer value n ; integer array first, last ( * ) ; integer result length ; integer array hs ( * ) ; integer value upbHs ; logical value showFirstAndLast ) ; if not showFirstAndLast and n <= upbHs and hs( n ) not = 0 then begin % no need to store the start and end of the sequence and we already % % know the length of the sequence for n % length := hs( n ) end else begin % must calculate the sequence length % integer sv; for i := 1 until 4 do first( i ) := last( i ) := 0; length := 0; sv := n; if sv > 0 then begin while begin length := length + 1; if showFirstAndLast then begin if length <= 4 then first( length ) := sv; for lPos := 1 until 3 do last( lPos ) := last( lPos + 1 ); last( 4 ) := sv end else if sv <= upbHs and hs( sv ) not = 0 then begin % have a known value % length := ( length + hs( sv ) ) - 1; sv := 1 end ; sv not = 1 end do begin sv := if odd( sv ) then ( 3 * sv ) + 1 else sv div 2 end while_sv_ne_1 ; if n < upbHs then hs( n ) := length end if_sv_gt_0 end hailstone ; begin % test the hailstone procedure % integer HS_CACHE_SIZE; HS_CACHE_SIZE := 100000; begin integer array first, last ( 1 :: 4 ); integer length, maxLength, maxNumber; integer array hs ( 1 :: HS_CACHE_SIZE ); for i := 1 until HS_CACHE_SIZE do hs( i ) := 0; hailstone( 27, first, last, length, hs, HS_CACHE_SIZE, true ); write( i_w := 1, s_w := 0 , "27: length ", length, ", first: [" , first( 1 ), " ", first( 2 ), " ", first( 3 ), " ", first( 4 ) , "] last: [" , last( 1 ), " ", last( 2 ), " ", last( 3 ), " ", last( 4 ) , "]" ); maxNumber := 0; maxLength := 0; for n := 1 until 100000 do begin hailstone( n, first, last, length, hs, HS_CACHE_SIZE, false ); if length > maxLength then begin maxNumber := n; maxLength := length end if_length_gt_maxLength end for_n ; write( i_w := 1, s_w := 1, "Maximum sequence length: ", maxLength, " for: ", maxNumber ) end end end.