Another update from ingydotnet^djgoku

This commit is contained in:
Ingy döt Net 2015-11-18 06:14:39 +00:00
parent 91df62d461
commit 948b86eafa
7604 changed files with 108452 additions and 22726 deletions

View file

@ -0,0 +1,103 @@
* Hailstone sequence 16/08/2015
HAILSTON CSECT
USING HAILSTON,R12
LR R12,R15
ST R14,SAVER14
BEGIN L R11,=F'100000' nmax
LA R8,27 n=27
LR R1,R8
MVI FTAB,X'01' ftab=true
BAL R14,COLLATZ
LR R10,R1 p
XDECO R8,XDEC n
MVC BUF1+10(6),XDEC+6
XDECO R10,XDEC p
MVC BUF1+18(5),XDEC+7
LA R5,6
LA R3,0 i
LA R4,BUF1+25
LOOPED L R2,TAB(R3) tab(i)
XDECO R2,XDEC
MVC 0(7,R4),XDEC+5
LA R3,4(R3) i=i+1
LA R4,7(R4)
C R5,=F'4'
BNE BCT
LA R4,7(R4)
BCT BCT R5,LOOPED
XPRNT BUF1,80 print hailstone(n)=p,tab(*)
MVC LONGEST,=F'0' longest=0
MVI FTAB,X'00' ftab=true
LA R8,1 i
LOOPI CR R8,R11 do i=1 to nmax
BH ELOOPI
LR R1,R8 n
BAL R14,COLLATZ
LR R10,R1 p
L R4,LONGEST
CR R4,R10 if longest<p
BNL NOTSUP
ST R8,IVAL ival=i
ST R10,LONGEST longest=p
NOTSUP LA R8,1(R8) i=i+1
B LOOPI
ELOOPI EQU * end i
XDECO R11,XDEC maxn
MVC BUF2+9(6),XDEC+6
L R1,IVAL ival
XDECO R1,XDEC
MVC BUF2+28(6),XDEC+6
L R1,LONGEST longest
XDECO R1,XDEC
MVC BUF2+36(5),XDEC+7
XPRNT BUF2,80 print maxn,hailstone(ival)=longest
B RETURN
* * * r1=collatz(r1)
COLLATZ LR R7,R1 m=n (R7)
LA R6,1 p=1 (R6)
LOOPP C R7,=F'1' do p=1 by 1 while(m>1)
BNH ELOOPP
CLI FTAB,X'01' if ftab
BNE NONOK
C R6,=F'1' if p>=1
BL NONOK
C R6,=F'3' & p<=3
BH NONOK
LR R1,R6 then
BCTR R1,0
SLA R1,2
ST R7,TAB(R1) tab(p)=m
NONOK LR R4,R7 m
N R4,=F'1' m&1
LTR R4,R4 if m//2=0 (if not(m&1))
BNZ ODD
EVEN SRA R7,1 m=m/2
B EIFM
ODD LA R3,3
MR R2,R7 *m
LA R7,1(R3) m=m*3+1
EIFM CLI FTAB,X'01' if ftab
BNE NEXTP
MVC TAB+12,TAB+16 tab(4)=tab(5)
MVC TAB+16,TAB+20 tab(5)=tab(6)
ST R7,TAB+20 tab(6)=m
NEXTP LA R6,1(R6) p=p+1
B LOOPP
ELOOPP LR R1,R6 end p; return(p)
BR R14 end collatz
*
RETURN L R14,SAVER14 restore caller address
XR R15,R15 set return code
BR R14 return to caller
SAVER14 DS F
IVAL DS F
LONGEST DS F
N DS F
TAB DS 6F
FTAB DS X
BUF1 DC CL80'hailstone(nnnnnn)=nnnnn : nnnnnn nnnnnn nnnnnn ...*
... nnnnnn nnnnnn nnnnnn'
BUF2 DC CL80'longest <nnnnnn : hailstone(nnnnnn)=nnnnn'
XDEC DS CL12
YREGS
END HAILSTON

View file

@ -0,0 +1,89 @@
CLASS lcl_hailstone DEFINITION.
PUBLIC SECTION.
TYPES: tty_sequence TYPE STANDARD TABLE OF i
WITH NON-UNIQUE EMPTY KEY,
BEGIN OF ty_seq_len,
start TYPE i,
len TYPE i,
END OF ty_seq_len,
tty_seq_len TYPE HASHED TABLE OF ty_seq_len
WITH UNIQUE KEY start.
CLASS-METHODS:
get_next
IMPORTING
n TYPE i
RETURNING
VALUE(r_next_hailstone_num) TYPE i,
get_sequence
IMPORTING
start TYPE i
RETURNING
VALUE(r_sequence) TYPE tty_sequence,
get_longest_sequence_upto
IMPORTING
limit TYPE i
RETURNING
VALUE(r_longest_sequence) TYPE ty_seq_len.
PRIVATE SECTION.
TYPES: BEGIN OF ty_seq,
start TYPE i,
seq TYPE tty_sequence,
END OF ty_seq.
CLASS-DATA: sequence_buffer TYPE HASHED TABLE OF ty_seq
WITH UNIQUE KEY start.
ENDCLASS.
CLASS lcl_hailstone IMPLEMENTATION.
METHOD get_next.
r_next_hailstone_num = COND #( WHEN n MOD 2 = 0 THEN n / 2
ELSE ( 3 * n ) + 1 ).
ENDMETHOD.
METHOD get_sequence.
INSERT start INTO TABLE r_sequence.
IF start = 1.
RETURN.
ENDIF.
READ TABLE sequence_buffer ASSIGNING FIELD-SYMBOL(<buff>)
WITH TABLE KEY start = start.
IF sy-subrc = 0.
INSERT LINES OF <buff>-seq INTO TABLE r_sequence.
ELSE.
DATA(seq) = get_sequence( get_next( start ) ).
INSERT LINES OF seq INTO TABLE r_sequence.
INSERT VALUE ty_seq( start = start
seq = seq ) INTO TABLE sequence_buffer.
ENDIF.
ENDMETHOD.
METHOD get_longest_sequence_upto.
DATA: max_seq TYPE ty_seq_len,
act_seq TYPE ty_seq_len.
DO limit TIMES.
act_seq-len = lines( get_sequence( sy-index ) ).
IF act_seq-len > max_seq-len.
max_seq-len = act_seq-len.
max_seq-start = sy-index.
ENDIF.
ENDDO.
r_longest_sequence = max_seq.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
cl_demo_output=>begin_section( |Hailstone sequence of 27 is: | ).
cl_demo_output=>write( REDUCE string( INIT result = ``
FOR item IN lcl_hailstone=>get_sequence( 27 )
NEXT result = |{ result } { item }| ) ).
cl_demo_output=>write( |With length: { lines( lcl_hailstone=>get_sequence( 27 ) ) }| ).
cl_demo_output=>begin_section( |Longest hailstone sequence upto 100k| ).
cl_demo_output=>write( lcl_hailstone=>get_longest_sequence_upto( 100000 ) ).
cl_demo_output=>display( ).

View file

@ -1,52 +1,91 @@
print "Part 1: Create a routine to generate the hailstone sequence for a number."
print ""
while hailstone < 1 or hailstone <> int(hailstone)
input "Please enter a positive integer: "; hailstone
wend
print ""
print "The following is the 'Hailstone Sequence' for your number..."
print ""
print hailstone
while hailstone <> 1
if hailstone / 2 = int(hailstone / 2) then hailstone = hailstone / 2 else hailstone = (3 * hailstone) + 1
print hailstone
wend
print ""
input "Hit 'Enter' to continue to part 2...";dummy$
cls
print "Part 2: Use the routine to show that the hailstone sequence for the number 27 has 112 elements starting with 27, 82, 41, 124 and ending with 8, 4, 2, 1."
print ""
print "No. in Seq.","Hailstone Sequence Number for 27"
print ""
c = 1: hailstone = 27
print c, hailstone
while hailstone <> 1
c = c + 1
if hailstone / 2 = int(hailstone / 2) then hailstone = hailstone / 2 else hailstone = (3 * hailstone) + 1
print c, hailstone
wend
print ""
input "Hit 'Enter' to continue to part 3...";dummy$
cls
print "Part 3: Show the number less than 100,000 which has the longest hailstone sequence together with that sequence's length.(But don't show the actual sequence)!"
print ""
print "Calculating result... Please wait... This could take a little while..."
print ""
print "Percent Done", "Start Number", "Seq. Length", "Maximum Sequence So Far"
print ""
for cc = 1 to 99999
hailstone = cc: c = 1
while hailstone <> 1
c = c + 1
if hailstone / 2 = int(hailstone / 2) then hailstone = hailstone / 2 else hailstone = (3 * hailstone) + 1
wend
if c > max then max = c: largesthailstone = cc
locate 1, 7
print " "
locate 1, 7
print using("###.###", cc / 99999 * 100);"%", cc, c, max
scan
next cc
print ""
print "The number less than 100,000 with the longest 'Hailstone Sequence' is "; largesthailstone;". It's sequence length is "; max;"."
end
' version 17-06-2015
' compile with: fbc -s console
Function hailstone_fast(number As ULongInt) As ULongInt
' faster version
' only counts the sequence
Dim As ULongInt count = 1
While number <> 1
If (number And 1) = 1 Then
number += number Shr 1 + 1 ' 3*n+1 and n/2 in one
count += 2
Else
number Shr= 1 ' divide number by 2
count += 1
End If
Wend
Return count
End Function
Sub hailstone_print(number As ULongInt)
' print the number and sequence
Dim As ULongInt count = 1
Print "sequence for number "; number
Print Using "########"; number; 'starting number
While number <> 1
If (number And 1) = 1 Then
number = number * 3 + 1 ' n * 3 + 1
count += 1
Else
number = number \ 2 ' n \ 2
count += 1
End If
Print Using "########"; number;
Wend
Print : Print
Print "sequence length = "; count
Print
Print String(79,"-")
End Sub
Function hailstone(number As ULongInt) As ULongInt
' normal version
' only counts the sequence
Dim As ULongInt count = 1
While number <> 1
If (number And 1) = 1 Then
number = number * 3 + 1 ' n * 3 + 1
count += 1
End If
number = number \ 2 ' divide number by 2
count += 1
Wend
Return count
End Function
' ------=< MAIN >=------
Dim As ULongInt number
Dim As UInteger x, max_x, max_seq
hailstone_print(27)
Print
For x As UInteger = 1 To 100000
number = hailstone(x)
If number > max_seq Then
max_x = x
max_seq = number
End If
Next
Print "The longest sequence is for "; max_x; ", it has a sequence length of "; max_seq
' empty keyboard buffer
While Inkey <> "" : Var _key_ = Inkey : Wend
Print : Print : Print "hit any key to end program"
Sleep
End

View file

@ -1,37 +1,52 @@
function Hailstone(sys *n)
'=========================
if n and 1
n=n*3+1
else
n=n>>1
end if
end function
function HailstoneSequence(sys n) as sys
'=======================================
count=1
do
Hailstone n
Count++
if n=1 then exit do
end do
return count
end function
'MAIN
'====
maxc=0
maxn=0
e=100000
for n=1 to e
c=HailstoneSequence n
if c>maxc
maxc=c
maxn=n
end if
next
print e ", " maxn ", " maxc
'result 100000, 77031, 351
print "Part 1: Create a routine to generate the hailstone sequence for a number."
print ""
while hailstone < 1 or hailstone <> int(hailstone)
input "Please enter a positive integer: "; hailstone
wend
print ""
print "The following is the 'Hailstone Sequence' for your number..."
print ""
print hailstone
while hailstone <> 1
if hailstone / 2 = int(hailstone / 2) then hailstone = hailstone / 2 else hailstone = (3 * hailstone) + 1
print hailstone
wend
print ""
input "Hit 'Enter' to continue to part 2...";dummy$
cls
print "Part 2: Use the routine to show that the hailstone sequence for the number 27 has 112 elements starting with 27, 82, 41, 124 and ending with 8, 4, 2, 1."
print ""
print "No. in Seq.","Hailstone Sequence Number for 27"
print ""
c = 1: hailstone = 27
print c, hailstone
while hailstone <> 1
c = c + 1
if hailstone / 2 = int(hailstone / 2) then hailstone = hailstone / 2 else hailstone = (3 * hailstone) + 1
print c, hailstone
wend
print ""
input "Hit 'Enter' to continue to part 3...";dummy$
cls
print "Part 3: Show the number less than 100,000 which has the longest hailstone sequence together with that sequence's length.(But don't show the actual sequence)!"
print ""
print "Calculating result... Please wait... This could take a little while..."
print ""
print "Percent Done", "Start Number", "Seq. Length", "Maximum Sequence So Far"
print ""
for cc = 1 to 99999
hailstone = cc: c = 1
while hailstone <> 1
c = c + 1
if hailstone / 2 = int(hailstone / 2) then hailstone = hailstone / 2 else hailstone = (3 * hailstone) + 1
wend
if c > max then max = c: largesthailstone = cc
locate 1, 7
print " "
locate 1, 7
print using("###.###", cc / 99999 * 100);"%", cc, c, max
scan
next cc
print ""
print "The number less than 100,000 with the longest 'Hailstone Sequence' is "; largesthailstone;". It's sequence length is "; max;"."
end

View file

@ -1,48 +1,37 @@
NewList Hailstones.i() ; Make a linked list to use as we do not know the numbers of elements needed for an Array
function Hailstone(sys *n)
'=========================
if n and 1
n=n*3+1
else
n=n>>1
end if
end function
Procedure.i FillHailstones(n) ; Fills the list & returns the amount of elements in the list
Shared Hailstones() ; Get access to the Hailstones-List
ClearList(Hailstones()) ; Remove old data
Repeat
AddElement(Hailstones()) ; Add an element to the list
Hailstones()=n ; Fill current value in the new list element
If n=1
ProcedureReturn ListSize(Hailstones())
ElseIf n%2=0
n/2
Else
n=(3*n)+1
EndIf
ForEver
EndProcedure
function HailstoneSequence(sys n) as sys
'=======================================
count=1
do
Hailstone n
Count++
if n=1 then exit do
end do
return count
end function
If OpenConsole()
Define i, l, maxl, maxi
l=FillHailstones(27)
Print("#27 has "+Str(l)+" elements and the sequence is: "+#CRLF$)
ForEach Hailstones()
If i=6
Print(#CRLF$)
i=0
EndIf
i+1
Print(RSet(Str(Hailstones()),5))
If Hailstones()<>1
Print(", ")
EndIf
Next
'MAIN
'====
i=1
Repeat
l=FillHailstones(i)
If l>maxl
maxl=l
maxi=i
EndIf
i+1
Until i>=100000
Print(#CRLF$+#CRLF$+"The longest sequence below 100000 is #"+Str(maxi)+", and it has "+Str(maxl)+" elements.")
maxc=0
maxn=0
e=100000
for n=1 to e
c=HailstoneSequence n
if c>maxc
maxc=c
maxn=n
end if
next
Print(#CRLF$+#CRLF$+"Press ENTER to exit."): Input()
CloseConsole()
EndIf
print e ", " maxn ", " maxc
'result 100000, 77031, 351

View file

@ -1,40 +1,48 @@
print "Part 1: Create a routine to generate the hailstone sequence for a number."
print ""
NewList Hailstones.i() ; Make a linked list to use as we do not know the numbers of elements needed for an Array
while hailstone < 1 or hailstone <> int(hailstone)
input "Please enter a positive integer: "; hailstone
wend
count = doHailstone(hailstone,"Y")
Procedure.i FillHailstones(n) ; Fills the list & returns the amount of elements in the list
Shared Hailstones() ; Get access to the Hailstones-List
ClearList(Hailstones()) ; Remove old data
Repeat
AddElement(Hailstones()) ; Add an element to the list
Hailstones()=n ; Fill current value in the new list element
If n=1
ProcedureReturn ListSize(Hailstones())
ElseIf n%2=0
n/2
Else
n=(3*n)+1
EndIf
ForEver
EndProcedure
print: print "Part 2: Use the routine to show that the hailstone sequence for the number 27 has 112 elements starting with 27, 82, 41, 124 and ending with 8, 4, 2, 1."
count = doHailstone(27,"Y")
If OpenConsole()
Define i, l, maxl, maxi
l=FillHailstones(27)
Print("#27 has "+Str(l)+" elements and the sequence is: "+#CRLF$)
ForEach Hailstones()
If i=6
Print(#CRLF$)
i=0
EndIf
i+1
Print(RSet(Str(Hailstones()),5))
If Hailstones()<>1
Print(", ")
EndIf
Next
print: print "Part 3: Show the number less than 100,000 which has the longest hailstone sequence together with that sequence's length.(But don't show the actual sequence)!"
print "Calculating result... Please wait... This could take a little while..."
print "Stone Percent Count"
for i = 1 to 99999
count = doHailstone(i,"N")
if count > maxCount then
theBigStone = i
maxCount = count
print using("#####",i);" ";using("###.#", i / 99999 * 100);"% ";using("####",count)
end if
next i
end
i=1
Repeat
l=FillHailstones(i)
If l>maxl
maxl=l
maxi=i
EndIf
i+1
Until i>=100000
Print(#CRLF$+#CRLF$+"The longest sequence below 100000 is #"+Str(maxi)+", and it has "+Str(maxl)+" elements.")
'---------------------------------------------
' pass number and print (Y/N)
FUNCTION doHailstone(hailstone,prnt$)
if prnt$ = "Y" then
print
print "The following is the 'Hailstone Sequence' for number:";hailstone
end if
while hailstone <> 1
if (hailstone and 1) then hailstone = (hailstone * 3) + 1 else hailstone = hailstone / 2
doHailstone = doHailstone + 1
if prnt$ = "Y" then
print hailstone;chr$(9);
if (doHailstone mod 10) = 0 then print
end if
wend
END FUNCTION
Print(#CRLF$+#CRLF$+"Press ENTER to exit."): Input()
CloseConsole()
EndIf

View file

@ -1,42 +1,40 @@
Module HailstoneSequence
Sub Main()
' Checking sequence of 27.
print "Part 1: Create a routine to generate the hailstone sequence for a number."
print ""
Dim l As List(Of Long) = HailstoneSequence(27)
Console.WriteLine("27 has {0} elements in sequence:", l.Count())
while hailstone < 1 or hailstone <> int(hailstone)
input "Please enter a positive integer: "; hailstone
wend
count = doHailstone(hailstone,"Y")
For i As Integer = 0 To 3 : Console.Write("{0}, ", l(i)) : Next
Console.Write("... ")
For i As Integer = l.Count - 4 To l.Count - 1 : Console.Write(", {0}", l(i)) : Next
print: print "Part 2: Use the routine to show that the hailstone sequence for the number 27 has 112 elements starting with 27, 82, 41, 124 and ending with 8, 4, 2, 1."
count = doHailstone(27,"Y")
Console.WriteLine()
print: print "Part 3: Show the number less than 100,000 which has the longest hailstone sequence together with that sequence's length.(But don't show the actual sequence)!"
print "Calculating result... Please wait... This could take a little while..."
print "Stone Percent Count"
for i = 1 to 99999
count = doHailstone(i,"N")
if count > maxCount then
theBigStone = i
maxCount = count
print using("#####",i);" ";using("###.#", i / 99999 * 100);"% ";using("####",count)
end if
next i
end
' Finding longest sequence for numbers below 100000.
Dim max As Integer = 0
Dim maxCount As Integer = 0
For i = 1 To 99999
l = HailstoneSequence(i)
If l.Count > maxCount Then
max = i
maxCount = l.Count
End If
Next
Console.WriteLine("Max elements in sequence for number below 100k: {0} with {1} elements.", max, maxCount)
Console.ReadLine()
End Sub
Private Function HailstoneSequence(ByVal n As Long) As List(Of Long)
Dim valList As New List(Of Long)()
valList.Add(n)
Do Until n = 1
n = IIf(n Mod 2 = 0, n / 2, (3 * n) + 1)
valList.Add(n)
Loop
Return valList
End Function
End Module
'---------------------------------------------
' pass number and print (Y/N)
FUNCTION doHailstone(hailstone,prnt$)
if prnt$ = "Y" then
print
print "The following is the 'Hailstone Sequence' for number:";hailstone
end if
while hailstone <> 1
if (hailstone and 1) then hailstone = (hailstone * 3) + 1 else hailstone = hailstone / 2
doHailstone = doHailstone + 1
if prnt$ = "Y" then
print hailstone;chr$(9);
if (doHailstone mod 10) = 0 then print
end if
wend
END FUNCTION

View file

@ -1,31 +1,41 @@
@echo off
setlocal enabledelayedexpansion
if "%1" equ "" goto :eof
call :hailstone %1 seq cnt
echo %seq%
goto :eof
echo.
::Task #1
call :hailstone 111
echo Task #1: (Start:!sav!)
echo !seq!
echo.
echo Sequence has !cnt! elements.
echo.
::Task #2
call :hailstone 27
echo Task #2: (Start:!sav!)
echo !seq!
echo.
echo Sequence has !cnt! elements.
echo.
pause>nul
exit /b 0
::The Function
:hailstone
set num=%1
set %2=%1
set seq=%1
set sav=%1
set cnt=0
:loop
if %num% equ 1 goto :eof
call :iseven %num% res
if %res% equ T goto divideby2
set /a num = (3 * num) + 1
set %2=!%2! %num%
goto loop
:divideby2
set /a num = num / 2
set %2=!%2! %num%
set /a cnt+=1
if !num! equ 1 goto :eof
set /a isodd=%num%%%2
if !isodd! equ 0 goto divideby2
set /a num=(3*%num%)+1
set seq=!seq! %num%
goto loop
:iseven
set /a tmp = %1 %% 2
if %tmp% equ 1 (
set %2=F
) else (
set %2=T
)
goto :eof
:divideby2
set /a num/=2
set seq=!seq! %num%
goto loop

View file

@ -1,2 +1,23 @@
>hailstone.cmd 20
20 10 5 16 8 4 2 1
@echo off
setlocal enableDelayedExpansion
if "%~1"=="test" (
for /l %%. in () do (
set /a "test1=num %% 2, cnt=cnt+1"
if !test1! equ 0 (set /a num/=2 & if !num! equ 1 exit !cnt!) else (set /a num=3*num+1)
)
)
set max=0
set record=0
for /l %%X in (2,1,100000) do (
set num=%%X & cmd /c "%~f0" test
if !errorlevel! gtr !max! (set /a "max=!errorlevel!,record=%%X")
)
set /a max+=1
echo.Number less than 100000 with longest sequence: %record%
echo.With length %max%.
pause>nul
exit /b 0

View file

@ -0,0 +1,23 @@
$ n = f$integer( p1 )
$ i = 1
$ loop:
$ if p2 .nes. "QUIET" then $ s'i = n
$ if n .eq. 1 then $ goto done
$ i = i + 1
$ if .not. n
$ then
$ n = n / 2
$ else
$ if n .gt. 715827882 then $ exit ! avoid overflowing
$ n = 3 * n + 1
$ endif
$ goto loop
$ done:
$ if p2 .nes. "QUIET"
$ then
$ penultimate_i = i - 1
$ antepenultimate_i = i - 2
$ preantepenultimate_i = i - 3
$ write sys$output "sequence has ", i, " elements starting with ", s1, ", ", s2, ", ", s3, ", ", s4, " and ending with ", s'preantepenultimate_i, ", ", s'antepenultimate_i, ", ", s'penultimate_i, ", ", s'i
$ endif
$ sequence_length == i

View file

@ -0,0 +1,41 @@
$ limit = f$integer( p1 )
$ i = 1
$ max_so_far = 0
$ loop:
$ call hailstone 'i quiet
$ if sequence_length .gt. max_so_far
$ then
$ max_so_far = sequence_length
$ current_record_holder = i
$ endif
$ i = i + 1
$ if i .lt. limit then $ goto loop
$ write sys$output current_record_holder, " is the number less than ", limit, " which has the longest hailstone sequence which is ", max_so_far, " in length"
$ exit
$
$ hailstone: subroutine
$ n = f$integer( p1 )
$ i = 1
$ loop:
$ if p2 .nes. "QUIET" then $ s'i = n
$ if n .eq. 1 then $ goto done
$ i = i + 1
$ if .not. n
$ then
$ n = n / 2
$ else
$ if n .gt. 715827882 then $ exit ! avoid overflowing
$ n = 3 * n + 1
$ endif
$ goto loop
$ done:
$ if p2 .nes. "QUIET"
$ then
$ penultimate_i = i - 1
$ antepenultimate_i = i - 2
$ preantepenultimate_i = i - 3
$ write sys$output "sequence has ", i, " elements starting with ", s1, ", ", s2, ", ", s3, ", ", s4, " and ending with ", s'preantepenultimate_i, ", ", s'antepenultimate_i, ", ", s'penultimate_i, ", ", s'i
$ endif
$ sequence_length == I
$ exit
$ endsubroutine

View file

@ -0,0 +1,67 @@
class
APPLICATION
create
make
feature
make
local
test: LINKED_LIST [INTEGER]
count, number, te: INTEGER
do
create test.make
test := hailstone_sequence (27)
io.put_string ("There are " + test.count.out + " elements in the sequence for the number 27.")
io.put_string ("%NThe first 4 elements are: ")
across
1 |..| 4 as t
loop
io.put_string (test [t.item].out + "%T")
end
io.put_string ("%NThe last 4 elements are: ")
across
(test.count - 3) |..| test.count as t
loop
io.put_string (test [t.item].out + "%T")
end
across
1 |..| 99999 as c
loop
test := hailstone_sequence (c.item)
te := test.count
if te > count then
count := te
number := c.item
end
end
io.put_string ("%NThe longest sequence for numbers below 100000 is " + count.out + " for the number " + number.out + ".")
end
hailstone_sequence (n: INTEGER): LINKED_LIST [INTEGER]
-- Members of the Hailstone Sequence starting from 'n'.
require
n_is_positive: n > 0
local
seq: INTEGER
do
create Result.make
from
seq := n
until
seq = 1
loop
Result.extend (seq)
if seq \\ 2 = 0 then
seq := seq // 2
else
seq := ((3 * seq) + 1)
end
end
Result.extend (seq)
ensure
sequence_terminated: Result.last = 1
end
end

View file

@ -1,21 +1,22 @@
defmodule Hailstone do
def step(1), do: 0
def step(n) when Integer.even?(n), do: div(n,2)
def step(n) when Integer.odd?(n), do: n*3 + 1
require Integer
def step(1) , do: 0
def step(n) when Integer.is_even(n), do: div(n,2)
def step(n) , do: n*3 + 1
def sequence(n) do
Enum.to_list(Stream.take_while(Stream.iterate(n, &step/1), &(&1 > 0)))
Stream.iterate(n, &step/1) |> Stream.take_while(&(&1 > 0)) |> Enum.to_list
end
def run do
seq27 = Hailstone.sequence(27)
seq27 = sequence(27)
len27 = length(seq27)
repr = String.replace(inspect(seq27, limit: 4), "]",
String.replace(inspect(Enum.drop(seq27,len27-4)), "[", ", "))
IO.puts("Hailstone(27) has #{len27} elements: #{repr}")
repr = String.replace(inspect(seq27, limit: 4) <> inspect(Enum.drop(seq27,len27-4)), "][", ", ")
IO.puts "Hailstone(27) has #{len27} elements: #{repr}"
{start, len} = Enum.max_by( Enum.map(1..100_000, fn(n) -> {n, length(Hailstone.sequence(n))} end),
fn({_,len}) -> len end )
IO.puts("Longest sequence starting under 100000 begins with #{start} and has #{len} elements.")
{len, start} = Enum.map(1..100_000, fn(n) -> {length(sequence(n)), n} end) |> Enum.max
IO.puts "Longest sequence starting under 100000 begins with #{start} and has #{len} elements."
end
end

View file

@ -0,0 +1,28 @@
-module(collatz).
-export([main/0,collatz/1,coll/1,max_atz_under/1]).
collatz(1) -> 1;
collatz(N) when N rem 2 == 0 -> 1 + collatz(N div 2);
collatz(N) when N rem 2 > 0 -> 1 + collatz(3 * N +1).
max_atz_under(N) ->
F = fun (X) -> {collatz(X), X} end,
{_, Index} = lists:max(lists:map(F, lists:seq(1, N))),
Index.
coll(1) -> [1];
coll(N) when N rem 2 == 0 -> [N|coll(N div 2)];
coll(N) -> [N|coll(3 * N + 1)].
main() ->
io:format("collatz(4) non-list total: ~w~n", [collatz(4)]),
io:format("coll(4) with lists ~w~n", [coll(4)] ),
Seq27 = coll(27),
Seq1000 = coll(max_atz_under(100000)),
io:format("coll(27) length: ~B~n", [length(Seq27)]),
io:format("coll(27) first 4: ~w~n", [lists:sublist(Seq27, 4)]),
io:format("collatz(27) last 4: ~w~n",
[lists:nthtail(length(Seq27) - 4, Seq27)]),
io:format("maximum N <= 100000..."),
io:format("Max: ~w~n", [max_atz_under(100000)]),
io:format("Total: ~w~n", [ length( Seq1000 ) ] ).

View file

@ -0,0 +1,18 @@
import Data.List (maximumBy)
import Data.Ord (comparing)
main = do putStrLn $ "Collatz sequence for 27: "
++ ((show.hailstone) 27)
++ "\n"
++ "The number "
++ (show longestChain)
++" has the longest hailstone sequence"
++" for any number less then 100000. "
++"The sequence has length "
++ (show.length.hailstone $ longestChain)
hailstone = takeWhile (/=1) . (iterate collatz)
where collatz n = if even n then n `div` 2 else 3*n+1
longestChain = fst $ maximumBy (comparing snd) $
map ((\x -> (x,(length.hailstone) x))) [1..100000]

View file

@ -0,0 +1,20 @@
(function () {
// Hailstone Sequence
// n -> [n]
function hailstone(n) {
return n === 1 ? [1] : (
[n].concat(
hailstone(n % 2 ? n * 3 + 1 : n / 2)
)
)
}
var lstCollatz27 = hailstone(27);
return {
length: lstCollatz27.length,
sequence: lstCollatz27
};
})();

View file

@ -0,0 +1,7 @@
{"length":112,"sequence":[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]}

View file

@ -0,0 +1,58 @@
(function () {
function memoized(fn) {
var dctMemo = {};
return function (x) {
var varValue = dctMemo[x];
if ('u' === (typeof varValue)[0])
dctMemo[x] = varValue = fn(x);
return varValue;
};
}
// Hailstone Sequence
// n -> [n]
function hailstone(n) {
return n === 1 ? [1] : (
[n].concat(
hailstone(n % 2 ? n * 3 + 1 : n / 2)
)
)
}
// Derived a memoized version of the function,
// which can reuse previously calculated paths
var fnCollatz = memoized(hailstone);
// Iterative version of range
// [m..n]
function range(m, n) {
var a = Array(n - m + 1),
i = n + 1;
while (i--) a[i - 1] = i;
return a;
}
// Fold/reduce over an array to find the maximum length
function longestBelow(n) {
return range(1, n).reduce(
function (a, x, i) {
var lng = fnCollatz(x).length;
return lng > a.l ? {
n: i + 1,
l: lng
} : a
}, {
n: 0,
l: 0
}
)
}
return longestBelow(100000);
})();

View file

@ -0,0 +1,2 @@
// Number, length of sequence
{"n":77031, "l":351}

View file

@ -0,0 +1,53 @@
(function (n) {
var dctMemo = {};
// Length only of hailstone sequence
// n -> n
function collatzLength(n) {
var i = 1,
a = n,
lng;
while (a !== 1) {
lng = dctMemo[a];
if ('u' === (typeof lng)[0]) {
a = (a % 2 ? 3 * a + 1 : a / 2);
i++;
} else return lng + i - 1;
}
return i;
}
// Iterative version of range
// [m..n]
function range(m, n) {
var a = Array(n - m + 1),
i = n + 1;
while (i--) a[i - 1] = i;
return a;
}
// Fold/reduce over an array to find the maximum length
function longestBelow(n) {
return range(1, n).reduce(
function (a, x) {
var lng = dctMemo[x] || (dctMemo[x] = collatzLength(x));
return lng > a.l ? {
n: x,
l: lng
} : a
}, {
n: 0,
l: 0
}
)
}
return [100000, 1000000, 10000000].map(longestBelow);
})();

View file

@ -0,0 +1,5 @@
[
{"n":77031, "l":351}, // 100,000
{"n":837799, "l":525}, // 1,000,000
{"n":8400511, "l":686} // 10,000,000
]

View file

@ -0,0 +1,2 @@
longestBelow(100000000)
-> {"n":63728127, "l":950}

View file

@ -0,0 +1 @@
With[{seq = HailstoneFP[27]}, { Length[seq], Take[seq, 4], Take[seq, -4]}]

View file

@ -0,0 +1 @@
Short[HailstoneFP[27],0.45]

View file

@ -0,0 +1 @@
MaximalBy[Table[{i, Length[HailstoneFP[i]]}, {i, 100000}], Last]

View file

@ -1,5 +1,3 @@
# Author M. McNabb
function Get-HailStone {
param($n)
@ -13,15 +11,10 @@ function Get-HailStone {
function Get-HailStoneBelowLimit {
param($UpperLimit)
$Counts = @()
for ($i = 1; $i -lt $UpperLimit; $i++) {
$Object = [pscustomobject]@{
[pscustomobject]@{
'Number' = $i
'Count' = (Get-HailStone $i).count
}
$Counts += $Object
}
$Counts
}

View file

@ -1,27 +1,28 @@
/*REXX pgm tests a number and a range for hailstone (Collatz) sequences.*/
parse arg x y . /*get optional arguments from CL.*/
if x=='' | x==',' then x=27 /*Any 1st argument? Use default.*/
if y=='' | y==',' then y=100000-1 /*Any 2nd argument? Use default.*/
numeric digits 20; @.=0 /*handle big #s; initialize array*/
$=hailstone(x) /*═══════════════════task 1═════════════════════════*/
/*REXX pgm tests a number and also a range for hailstone (Collatz) sequences. */
numeric digits 20 /*be able to handle gihugeic numbers. */
parse arg x y . /*get optional arguments from the C.L. */
if x=='' | x==',' then x=27 /*No 1st argument? Then use default.*/
if y=='' | y==',' then y=100000-1 /* " 2nd " " " " */
$=hailstone(x) /*▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒task 1▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒*/
say x ' has a hailstone sequence of ' words($)
say ' and starts with: ' subword($, 1, 4) " ∙∙∙"
say ' and ends with: ' subword($, max(1, words($)-3))
say ' and starts with: ' subword($, 1, 4) " ∙∙∙"
say ' and ends with: ' subword($, max(5, words($)-3))
if y==0 then exit /*▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒task 2▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒*/
say
if y==0 then exit /*═══════════════════task 2═════════════════════════*/
w=0; do j=1 for y /*traipse through the numbers. */
call hailstone j /*compute the hailstone sequence.*/
if #hs<=w then iterate /*Not big 'nuff? Then keep going.*/
bigJ=j; w=#hs /*remember what # has biggest HS.*/
w=0; do j=1 for y /*traipse through the range of numbers.*/
call hailstone j /*compute the hailstone sequence for J.*/
if #hs<=w then iterate /*Not big 'nuff? Then keep traipsing.*/
bigJ=j; w=#hs /*remember what # has biggest hailstone*/
end /*j*/
say '(between 1'y") " bigJ ' has the longest hailstone sequence:' w
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────HAILSTONE subroutine────────────────*/
hailstone: procedure expose #hs; parse arg n 1 s /*N & S set to 1st arg*/
say '(between 1'y") " bigJ ' has the longest hailstone sequence:' w
say 'and took'
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────HAILSTONE subroutine──────────────────────*/
hailstone: procedure expose #hs; parse arg n 1 s /*N & S are set to 1st arg.*/
do #hs=1 while n\==1 /*loop while N isn't unity. */
if n//2 then n=n*3+1 /*if N is odd, calc: 3*n +1 */
else n=n%2 /* " " " even, perform fast ÷ */
s=s n /*build a sequence list (append).*/
end /*#hs*/
return s
do #hs=1 while n\==1 /*keep loop while N isn't unity. */
if n//2 then n=n*3 + 1 /*N is odd ? Then calculate 3*n + 1 */
else n=n%2 /*" " even? Then calculate fast ÷ */
s=s n /* [↑] % is REXX integer division. */
end /*#hs*/ /* [↑] append N to the sequence list*/
return s /*return the S string to the invoker.*/

View file

@ -1,30 +1,38 @@
/*REXX pgm tests a number and a range for hailstone (Collatz) sequences.*/
parse arg x y . /*get optional arguments from CL.*/
if x=='' | x==',' then x=27 /*Any 1st argument? Use default.*/
if y=='' | y==',' then y=99999 /*Any 2nd argument? Use default.*/
numeric digits 20; @.=0 /*handle big #s; initialize array*/
$=hailstone(x) /*═══════════════════task 1═════════════════════════*/
/*REXX pgm tests a number and also a range for hailstone (Collatz) sequences. */
!.=0; !.0=1; !.2=1; !.4=1; !.6=1; !.8=1 /*assign even digits to be "true". */
numeric digits 20; @.=0 /*handle big numbers; initialize array.*/
parse arg x y z .; !.h=y /*get optional arguments from the C,L. */
if x=='' | x==',' then x=27 /*No 1st argument? Then use default.*/
if y=='' | y==',' then y=100000-1 /* " 2nd " " " " */
if z=='' | z==',' then z=12 /*head/tail number? " " " */
$=hailstone(x) /*▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒task 1▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒*/
say x ' has a hailstone sequence of ' words($)
say ' and starts with: ' subword($, 1, 4) " ∙∙∙"
say ' and ends with: ' subword($, max(1, words($)-3))
say
if y==0 then exit /*═══════════════════task 2═════════════════════════*/
w=0; do j=1 for y /*loop through all numbers <100k.*/
$=hailstone(j) /*compute the hailstone sequence.*/
#hs=words($) /*find the length of the sequence*/
if #hs<=w then iterate /*Not big 'nuff? Then keep going.*/
bigJ=j; w=#hs /*remember what # has biggest HS.*/
say ' and starts with: ' subword($, 1, z) " ∙∙∙"
say ' and ends with: ' subword($, max(z+1, words($)-z+1))
say /*Z: show first & last Z numbers*/
if y==0 then exit /*▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒task 2▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒*/
w=0; do j=1 for y /*traipse through the range of numbers.*/
$=hailstone(j) /*compute the hailstone sequence for J.*/
#hs=words($) /*find the length of the hailstone seq.*/
if #hs<=w then iterate /*Not big 'nuff? Then keep traipsing.*/
bigJ=j; w=#hs /*remember what # has biggest hailstone*/
end /*j*/
say '(between 1'y") " bigJ ' has the longest hailstone sequence:' w
say '(between 1'y") " bigJ ' has the longest hailstone sequence:' w
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────HAILSTONE subroutine────────────────*/
hailstone: procedure expose @.; parse arg n 1 s 1 o /*N,S,O = 1st arg.*/
@.1= /*special case for unity. */
do while @.n==0 /*loop while residual is unknown.*/
if n//2 then n=n*3+1 /*if N is odd, calc: 3*n +1 */
else n=n%2 /* " " " even, perform fast ÷ */
s=s n /*build a sequence list (append).*/
/*──────────────────────────────────HAILSTONE subroutine──────────────────────*/
hailstone: procedure expose @. !.; parse arg n 1 s 1 o /*N,S,O are 1st arg.*/
@.1= /*handle the special case for unity (1)*/
do while @.n==0 /*loop while the residual is unknown. */
parse var n '' -1 L /*extract the last decimal digit of N.*/
if !.L then n=n%2 /*N is even? Then calculate fast ÷ */
else n=n*3 + 1 /*? ? odd ? Then calculate 3*n + 1 */
s=s n /* [↑] %: is the REXX integer division*/
end /*#hs*/ /* [↑] append N to the sequence list*/
s=s @.n /*append the number to a sequence list.*/
@.o=subword(s,2) /*use memoization for this hailstone #.*/
r=s; h=!.h
do while r\==''; parse var r _ r /*get next the subsequence. */
if @._\==0 then return s /*Already found? Return S. */
if _>! then return s /*Out of range? Return S. */
@._=r /*assign the subsequence #. */
end /*while*/
s=s @.n /*append to a sequence list. */
@.o=subword(s,2) /*memoization for this hailstone.*/
return s

View file

@ -1,27 +1,40 @@
use std::vec::Vec;
fn hailstone(start : u32) -> Vec<u32> {
let mut res = Vec::new();
let mut next = start;
fn hailstone(mut n : int) -> Vec<int>{
let mut v = vec!(n);
while n > 1{
n = if n % 2 == 0 { n / 2 }
else { 3 * n + 1 };
v.push(n);
res.push(start);
while next != 1 {
next = if next % 2 == 0 { next/2 } else { 3*next+1 };
res.push(next);
}
return v;
res
}
fn main() {
let mut max_sequence = 0i;
let mut number_max_sequence = 0i;
let hs27 = hailstone(27);
println!("hailstone(27) has {} elements, starting from {} and ending to {}.", hs27.len(), hs27[0..4], hs27[hs27.len()-4..hs27.len()]);
let test_num = 27;
let test_hailseq = hailstone(test_num);
for i in range(1i, 100000) {
let hs_i = hailstone(i);
if hs_i.len() as int > max_sequence {
max_sequence = hs_i.len() as int;
number_max_sequence = i;
println!("For {} number of elements is {} ", test_num, test_hailseq.len());
let fst_slice = test_hailseq[0..4].iter()
.fold("".to_owned(), |acc, i| { acc + &*(i.to_string()).to_owned() + ", " });
let last_slice = test_hailseq[test_hailseq.len()-4..].iter()
.fold("".to_owned(), |acc, i| { acc + &*(i.to_string()).to_owned() + ", " });
println!(" hailstone starting with {} ending with {} ", fst_slice, last_slice);
let max_range = 100000;
let mut max_len = 0;
let mut max_seed = 0;
for i_seed in 1..max_range {
let i_len = hailstone(i_seed).len();
if i_len > max_len {
max_len = i_len;
max_seed = i_seed;
}
}
println!("Maximum : {} elements with number {}.", max_sequence, number_max_sequence);
println!("Longest sequence is {} element long for seed {}", max_len, max_seed);
}

View file

@ -0,0 +1,42 @@
'function arguments: "num" is the number to sequence and "return" is the value to return - "s" for the sequence or
'"e" for the number elements.
Function hailstone_sequence(num,return)
n = num
sequence = num
elements = 1
Do Until n = 1
If n Mod 2 = 0 Then
n = n / 2
Else
n = (3 * n) + 1
End If
sequence = sequence & " " & n
elements = elements + 1
Loop
Select Case return
Case "s"
hailstone_sequence = sequence
Case "e"
hailstone_sequence = elements
End Select
End Function
'test driving.
'show sequence for 27
WScript.StdOut.WriteLine "Sequence for 27: " & hailstone_sequence(27,"s")
WScript.StdOut.WriteLine "Number of Elements: " & hailstone_sequence(27,"e")
WScript.StdOut.WriteBlankLines(1)
'show the number less than 100k with the longest sequence
count = 1
n_elements = 0
n_longest = ""
Do While count < 100000
current_n_elements = hailstone_sequence(count,"e")
If current_n_elements > n_elements Then
n_elements = current_n_elements
n_longest = "Number: " & count & " Length: " & n_elements
End If
count = count + 1
Loop
WScript.StdOut.WriteLine "Number less than 100k with the longest sequence: "
WScript.StdOut.WriteLine n_longest