PDA

View Full Version : Project Lovecraft Problem 6



danbaron
05-04-2010, 05:55
Problem 6:

Make a thinBasic script that multiplies and finds the product of the following two integers.

1)
4225678345671239269412376809064563457830987094214727890460503258124429509352125309123467889090967803

2)
9034098905607687535809534264324877930963452357175890408065643678402109067842097453251206046098340056

DTB

zak
05-04-2010, 08:44
Hi danbaron
you said a thinbasic code, ie pure thinbasic code, but for a variation until someone present his code, here is a lazy solution using gmp library as documented here:
http://community.thinbasic.com/index.php?topic=1410.0
the answer:
38175196118078646234796018047078508876075927016257021775208337789644882612626336290568135391711676360295755214293161291134825045621348587392814424177752560047244220841334894056033458232344500841216968

Charles Pegge
05-04-2010, 19:37
The same result using Assembler:

This is not optimised but it gets the job done with Binary Coded Decimal. It could be accelerated using base 10^8 arithmetic or anything in between.

Charles

danbaron
05-04-2010, 20:52
Okay, guys.

In that case, here is the same result again.

Dan


'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'file = Lovecraft6.tbasicc
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Uses "console"
Uses "file"
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

%neg = -1
%pos = +1

%intsize = 1000

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Type genint
digit(%intsize) As Byte
sign As Integer
error As Byte
End Type

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Global filestring As String = "Lovecraft6.txt"
Global outfile As DWord

'##########################################################################################

Function TBMain()
Local s As String
Local num1, num2, num3 As genint

outfile = FILE_Open(filestring, "output")

s = "4225678345671239269412376809064563457830987094214727890460503258124429509352125309123467889090967803"

genintsetvalue(num1, s)
genintstringrep(num1, s)
writeoutputline("num1:")
writeoutputline("")
writeoutputline(s)
writeoutputline("")

If geninterror(num1) Then
geninterrormessage("bad num1: --> script termination.")
Exit Function
End If

s = "9034098905607687535809534264324877930963452357175890408065643678402109067842097453251206046098340056"

genintsetvalue(num2, s)
genintstringrep(num2, s)
writeoutputline("num2:")
writeoutputline("")
writeoutputline(s)
writeoutputline("")

If geninterror(num2) Then
geninterrormessage("bad num2: --> script termination.")
Exit Function
End If

genintmult(num1, num2, num3)
genintstringrep(num3, s)
writeoutputline("num3:")
writeoutputline("")
writeoutputline(s)

If geninterror(num3) Then
geninterrormessage("bad num3: --> script termination.")
Exit Function
End If

FILE_Close(outfile)

WaitKey
End Function

'##########################################################################################

Function genintsetvalue(ByRef gn As genint, ByRef vs As String)
Static i, ln As DWord
Static v As Byte

ln = Len(vs)

v = Asc(Mid$(vs, 1, 1))

Select Case v
Case 43
genintsetsign(gn, %pos)
Case 45
genintsetsign(gn, %neg)
Case 48 To 57
genintsetsign(gn, %pos)
gn.digit(ln) = v - 48
Case Else
genintseterror(gn)
Return
End Select

For i = 2 To ln
v = Asc(Mid$(vs, i, 1))

If v < 48 Then
genintseterror(gn)
Return
EndIf

If v > 57 Then
genintseterror(gn)
Return
EndIf

gn.digit(ln - i + 1) = v - 48
Next
End Function

'--------------------------------------------------------------

Function genintstringrep(ByRef gn As genint, ByRef vs As String)
Static i, j As DWord

If genintnegsign(gn) Then
vs = "-"
Else
vs = "+"
End If

i = 0

Do
If %intsize - i = 0 Then
vs = "0"
Return
End If

If gn.digit(%intsize - i) > 0 Then Exit Do
i += 1
Loop

For j = i + 1 To %intsize
vs = vs & Chr$(48 + gn.digit(%intsize - j + 1))
Next

End Function

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Function genintgetsize(ByRef gn As genint) As DWord
Static i As DWord

i = 0

Do
If %intsize - i = 0 Then Return 0
If gn.digit(%intsize - i) > 0 Then Exit Do
i += 1
Loop

Return %intsize - i
End Function

'--------------------------------------------------------------

Function genintzero(ByRef gn As genint)
Static i As DWord
For i = 1 To %intsize
gn.digit(i) = 0
Next
End Function

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Function genintsetsign(ByRef gn As genint, s As Integer)
gn.sign = s
End Function

'--------------------------------------------------------------

Function genintgetsign(ByRef gn As genint) As Integer
If gn.sign < 0 Then
Return -1
Else
Return 1
EndIf
End Function

'--------------------------------------------------------------

Function genintnegsign(ByRef gn As genint) As Byte
If gn.sign > -1 Then
Return FALSE
Else
Return TRUE
End If
End Function

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Function genintseterror(ByRef gn As genint)
gn.error = TRUE
End Function

'--------------------------------------------------------------

Function geninterror(ByRef gn As genint) As Byte
If gn.error Then
Return TRUE
Else
Return FALSE
End If
End Function

'--------------------------------------------------------------

Function geninterrormessage(es As String)
writeoutputline(es)
FILE_Close(outfile)
WaitKey
End Function

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Function genintshiftleft(ByRef gn As genint, nplaces As DWord)
Static sz, i, j As DWord

sz = genintgetsize(gn)

For i = 1 To sz
j = sz - i + 1
gn.digit(j + nplaces) = gn.digit(j)
Next

For i = 1 To nplaces
gn.digit(i) = 0
Next

End Function

'--------------------------------------------------------------

Function genintadd(ByRef a As genint, ByRef b As genint, ByRef c As genint)
Static i As DWord
Static s, v, k As Byte
Static asize, bsize, maxsize As DWord
Static temp As genint

asize = genintgetsize(a)
bsize = genintgetsize(b)
maxsize = asize
If bsize > maxsize Then maxsize = bsize

genintzero(temp)

k = 0
For i = 1 To maxsize + 1
s = a.digit(i) + b.digit(i) + k
v = Mod(s, 10)
k = s \ 10
temp.digit(i) = v
Next

For i = 1 To %intsize
c.digit(i) = temp.digit(i)
Next

End Function

'--------------------------------------------------------------

Function genintmult(ByRef a As genint, ByRef b As genint, ByRef c As genint)
Static i, j As DWord
Static p, v, k As Byte
Static asize, bsize, tsize As DWord
Static temp As genint

genintzero(c)
genintzero(temp)

asize = genintgetsize(a)
bsize = genintgetsize(b)
tsize = asize + bsize
If tsize > %intsize Then
genintseterror(c)
Return
EndIf

If ((genintgetsign(a) * genintgetsign(b)) < 0) Then genintsetsign(c, %neg)

For i = 1 To asize
k = 0
For j = 1 To bsize + 1
p = a.digit(i) * b.digit(j) + k
v = Mod(p, 10)
k = p \ 10
temp.digit(j) = v
Next

genintshiftleft(temp, i - 1)
genintadd(c, temp, c)
genintzero(temp)
Next

End Function

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Function writeoutputline(s As String)
Console_WriteLine(s)
FILE_LinePrint(outfile, s)
End Function

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~