' Puzzlet #199 ' A sequence is formed from integer n ' thus: if any of n's digits are zero, ' n = n + the sum of its digits; if n ' contains no zeroes, n = the product ' of its digits. All subsequent terms ' are formed in the same way. The ' sequence terminates when a term is ' reduced to a single digit. ' Example: 27, 41, 45, 65, 95, 140, 5. ' For initial values under 1,000, find ' all sequences greater than 30 terms. ' By Dave Ellis. ' Declarations declare SumDigits(s: int) declare ProductDigits(p: int) declare NoZeroes(n: int) declare GenerateSequence(n: int, p: int) def count, nr, n: int ' Screen SetUp color 11, 0: cls openconsole print "Searching ... " print color 15, 0 ' Initialisations nr = 1 ' Main routine do n = nr: 'save initial term 'get sequence length count = GenerateSequence(n, 0) if count > 30: 'length > 30? print "Count: ", count, chr$(8),". ", color 14, 0 GenerateSequence(n, -1): 'print it color 15, 0 print: print endif nr = nr + 1: 'get new initial term until nr > 1000 ' Finished color 11, 0 print "That's all, Folks!" print: print "Press any key ... ", do: until inkey$ <> "" closeconsole end ' +++ Subroutines and Functions +++ sub ProductDigits(p) ' Returns the product of the ' digits of integer p. Will ' give incorrect answer if p ' larger than defined limits ' for integers. def tot: int tot = 1 do ' separate out LSD and totalise tot = tot * (p % 10) ' chop off LSD p = p/10 until p = 0: ' all chopped off! return tot sub SumDigits(s) ' Returns the sum of the ' digits of integer s. Will ' give incorrect answer if s ' larger than defined limits ' for integers. def tot: int tot = 0 do ' separate out LSD and totalise tot = tot + (s % 10) ' chop off LSD s = s/10 until s = 0: 'all chopped off! return tot sub NoZeroes(n) ' If argument n is zero or it ' contains at least one zero ' after a non-zero digit, ' returns FALSE (0), otherwise ' returns TRUE (-1). ' Note: this method is 35% ' faster than string method. def flag: int flag = -1 do if n % 10 = 0: 'is LSD a zero? flag = 0 else n = n/10: 'chop off LSD endif until not flag | n < 1: 'done return flag sub GenerateSequence(n, p) ' Generates the Sequence term by ' term, and returns the lenght of ' the sequence as saved in cnt. ' If argument p is TRUE, will also ' print out sequence as each term ' is generated. ' By Dave Ellis. def cnt: int cnt = 1 if p: 'is it for printing? print n,: 'yes! endif do if NoZeroes(n): 'contain zeroes? n = n + ProductDigits(n): 'yes! else: 'no zeroes in it n = SumDigits(n) endif if p: 'print it? print n, endif cnt = cnt + 1 if p & (cnt % 8 = 0) print chr$(13) endif until (n < 10) return cnt