Minimum multiple of m where digital sum equals m

From Rosetta Code
Revision as of 11:52, 25 January 2022 by Rdm (talk | contribs) (J)
Minimum multiple of m where digital sum equals m is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Generate the sequence a(n) when each element is the minimum integer multiple m such that the digit sum of n times m is equal to n.


Task
  • Find the first 40 elements of the sequence.


Stretch
  • Find the next 30 elements of the sequence.


See also



ALGOL 68

<lang algol68>BEGIN # find the smallest m where mn = digit sum of n, n in 1 .. 70 #

   # returns the digit sum of n, n must be >= 0 #
   OP   DIGITSUM = ( INT n )INT:
        IF  n < 10 THEN n
        ELSE
           INT result := n MOD  10;
           INT v      := n OVER 10;
           WHILE v > 0 DO
               result +:= v MOD  10;
               v       := v OVER 10
           OD;
           result
        FI # DIGITSUM # ;
   # show the minimum multiples of n where the digit sum of the multiple is n #
   FOR n TO 70 DO
       BOOL found multiple := FALSE;
       FOR m WHILE NOT found multiple DO
           IF DIGITSUM ( m * n ) = n THEN
               found multiple := TRUE;
               print( ( " ", whole( m, -8 ) ) );
               IF n MOD 10 = 0 THEN print( ( newline ) ) FI
           FI
       OD
   OD

END</lang>

Output:
        1        1        1        1        1        1        1        1        1       19
       19        4       19       19       13       28       28       11       46      199
       19      109       73       37      199       73       37      271      172     1333
      289      559     1303      847     1657      833     1027     1576     1282    17497
     4339     2119     2323    10909    11111    12826    14617    14581    16102   199999
    17449    38269    56413    37037  1108909   142498   103507   154981   150661  1333333
   163918   322579   315873   937342  1076923  1030303   880597  1469116  1157971 12842857

Haskell

<lang haskell>import Data.Bifunctor (first) import Data.List (elemIndex, intercalate, transpose) import Data.List.Split (chunksOf) import Data.Maybe (fromJust) import Text.Printf (printf)


A131382 ------------------------

a131382 :: [Int] a131382 =

 fromJust . (elemIndex <*> productDigitSums)
   <$> [1 ..]

productDigitSums :: Int -> [Int] productDigitSums n = digitSum . (n *) <$> [0 ..]


TEST -------------------------

main :: IO () main =

 (putStrLn . table " ") $
   chunksOf 10 $ show <$> take 40 a131382

GENERIC ------------------------

digitSum :: Int -> Int digitSum 0 = 0 digitSum n = uncurry (+) (first digitSum $ quotRem n 10)

table :: String -> String -> String table gap rows =

 let ws = maximum . fmap length <$> transpose rows
     pw = printf . flip intercalate ["%", "s"] . show
  in unlines $ intercalate gap . zipWith pw ws <$> rows</lang>
Output:
  1   1    1   1    1   1    1    1    1    19
 19   4   19  19   13  28   28   11   46   199
 19 109   73  37  199  73   37  271  172  1333
289 559 1303 847 1657 833 1027 1576 1282 17497


J

Implementation:

<lang J> findfirst=: Template:($:@((+1+i.@+:)@

A131382=: {{y&Template:X = sumdigits x*y findfirst}}"0

sumdigits=: +/@|:@(10&#.inv)</lang>

Task example: <lang J> A131382 1+i.4 10

 1   1    1   1    1   1    1    1    1    19
19   4   19  19   13  28   28   11   46   199
19 109   73  37  199  73   37  271  172  1333

289 559 1303 847 1657 833 1027 1576 1282 17497</lang>


Julia

<lang julia>minproddigsum(n) = findfirst(i -> sum(digits(n * i)) == n, 1:typemax(Int32))

for j in 1:70

   print(lpad(minproddigsum(j), 10), j % 7 == 0 ? "\n" : "")

end

</lang>

Output:
         1         1         1         1         1         1         1
         1         1        19        19         4        19        19
        13        28        28        11        46       199        19
       109        73        37       199        73        37       271
       172      1333       289       559      1303       847      1657
       833      1027      1576      1282     17497      4339      2119
      2323     10909     11111     12826     14617     14581     16102
    199999     17449     38269     56413     37037   1108909    142498
    103507    154981    150661   1333333    163918    322579    315873
    937342   1076923   1030303    880597   1469116   1157971  12842857

Perl

<lang perl>#!/usr/bin/perl

use strict; # https://rosettacode.org/wiki/Minimum_multiple_of_m_where_digital_sum_equals_m use warnings; use ntheory qw( sumdigits );

my @answers = map

 {
 my $m = 1;
 $m++ until sumdigits($m*$_) == $_;
 $m;
 } 1 .. 70;

print "@answers\n\n" =~ s/.{65}\K /\n/gr;</lang>

Output:
1 1 1 1 1 1 1 1 1 19 19 4 19 19 13 28 28 11 46 199 19 109 73 37 199
73 37 271 172 1333 289 559 1303 847 1657 833 1027 1576 1282 17497
4339 2119 2323 10909 11111 12826 14617 14581 16102 199999 17449 38269
56413 37037 1108909 142498 103507 154981 150661 1333333 163918 322579
315873 937342 1076923 1030303 880597 1469116 1157971 12842857

Phix

Translation of: XPL0
with javascript_semantics
integer c = 0, n = 1
while c<70 do
    integer m = 1
    while true do
        integer nm = n*m, t = 0
        while nm do
            t += remainder(nm,10)
            nm = floor(nm/10)
        end while
        if t=n then exit end if
        m += 1
    end while
    c += 1
    printf(1,"%-8d%s",{m,iff(remainder(c,10)=0?"\n":"")})
    n += 1
end while
Output:
1       1       1       1       1       1       1       1       1       19
19      4       19      19      13      28      28      11      46      199
19      109     73      37      199     73      37      271     172     1333
289     559     1303    847     1657    833     1027    1576    1282    17497
4339    2119    2323    10909   11111   12826   14617   14581   16102   199999
17449   38269   56413   37037   1108909 142498  103507  154981  150661  1333333
163918  322579  315873  937342  1076923 1030303 880597  1469116 1157971 12842857

Python

<lang python>A131382

from itertools import count, islice


  1. a131382 :: [Int]

def a131382():

   An infinite series of the terms of A131382
   return (
       elemIndex(x)(
           productDigitSums(x)
       ) for x in count(1)
   )


  1. productDigitSums :: Int -> [Int]

def productDigitSums(n):

   The sum of the decimal digits of n
   return (digitSum(n * x) for x in count(0))


  1. ------------------------- TEST -------------------------
  2. main :: IO ()

def main():

   First 40 terms of A131382
   print(
       table(10)([
           str(x) for x in islice(
               a131382(),
               40
           )
       ])
   )


  1. ----------------------- GENERIC ------------------------
  1. chunksOf :: Int -> [a] -> a

def chunksOf(n):

   A series of lists of length n, subdividing the
      contents of xs. Where the length of xs is not evenly
      divisible, the final list will be shorter than n.
   
   def go(xs):
       return (
           xs[i:n + i] for i in range(0, len(xs), n)
       ) if 0 < n else None
   return go


  1. digitSum :: Int -> Int

def digitSum(n):

   The sum of the digital digits of n.
   
   return sum(int(x) for x in list(str(n)))


  1. elemIndex :: a -> [a] -> (None | Int)

def elemIndex(x):

   Just the first index of x in xs,
      or None if no elements match.
   
   def go(xs):
       try:
           return next(
               i for i, v in enumerate(xs) if x == v
           )
       except StopIteration:
           return None
   return go


  1. table :: Int -> [String] -> String

def table(n):

   A list of strings formatted as
      right-justified rows of n columns.
   
   def go(xs):
       w = len(xs[-1])
       return '\n'.join(
           ' '.join(row) for row in chunksOf(n)([
               s.rjust(w, ' ') for s in xs
           ])
       )
   return go


  1. MAIN ---

if __name__ == '__main__':

   main()</lang>
Output:
    1     1     1     1     1     1     1     1     1    19
   19     4    19    19    13    28    28    11    46   199
   19   109    73    37   199    73    37   271   172  1333
  289   559  1303   847  1657   833  1027  1576  1282 17497

Raku

<lang perl6>sub min-mult-dsum ($n) { (1..∞).first: (* × $n).comb.sum == $n }

say .fmt("%2d: ") ~ .&min-mult-dsum for flat 1..40, 41..70;</lang>

Output:
 1: 1
 2: 1
 3: 1
 4: 1
 5: 1
 6: 1
 7: 1
 8: 1
 9: 1
10: 19
11: 19
12: 4
13: 19
14: 19
15: 13
16: 28
17: 28
18: 11
19: 46
20: 199
21: 19
22: 109
23: 73
24: 37
25: 199
26: 73
27: 37
28: 271
29: 172
30: 1333
31: 289
32: 559
33: 1303
34: 847
35: 1657
36: 833
37: 1027
38: 1576
39: 1282
40: 17497
41: 4339
42: 2119
43: 2323
44: 10909
45: 11111
46: 12826
47: 14617
48: 14581
49: 16102
50: 199999
51: 17449
52: 38269
53: 56413
54: 37037
55: 1108909
56: 142498
57: 103507
58: 154981
59: 150661
60: 1333333
61: 163918
62: 322579
63: 315873
64: 937342
65: 1076923
66: 1030303
67: 880597
68: 1469116
69: 1157971
70: 12842857

Wren

Library: Wren-math
Library: Wren-seq
Library: Wren-fmt

<lang ecmascript>import "./math" for Int import "./seq" for Lst import "./fmt" for Fmt

var res = [] for (n in 1..70) {

   var m = 1
   while (Int.digitSum(m * n) != n) m = m + 1
   res.add(m)

} for (chunk in Lst.chunks(res, 10)) Fmt.print("$,10d", chunk)</lang>

Output:
         1          1          1          1          1          1          1          1          1         19
        19          4         19         19         13         28         28         11         46        199
        19        109         73         37        199         73         37        271        172      1,333
       289        559      1,303        847      1,657        833      1,027      1,576      1,282     17,497
     4,339      2,119      2,323     10,909     11,111     12,826     14,617     14,581     16,102    199,999
    17,449     38,269     56,413     37,037  1,108,909    142,498    103,507    154,981    150,661  1,333,333
   163,918    322,579    315,873    937,342  1,076,923  1,030,303    880,597  1,469,116  1,157,971 12,842,857

XPL0

<lang XPL0>func SumDigits(N); \Return sum of digits in N int N, S; [S:= 0; while N do

   [N:= N/10;
   S:= S + rem(0);
   ];

return S; ];

int C, N, M; [C:= 0; N:= 1; repeat M:= 1;

       while SumDigits(N*M) # N do M:= M+1;
       IntOut(0, M);
       C:= C+1;
       if rem (C/10) then ChOut(0, 9\tab\) else CrLf(0);
       N:= N+1;

until C >= 40+30; ]</lang>

Output:
1       1       1       1       1       1       1       1       1       19
19      4       19      19      13      28      28      11      46      199
19      109     73      37      199     73      37      271     172     1333
289     559     1303    847     1657    833     1027    1576    1282    17497
4339    2119    2323    10909   11111   12826   14617   14581   16102   199999
17449   38269   56413   37037   1108909 142498  103507  154981  150661  1333333
163918  322579  315873  937342  1076923 1030303 880597  1469116 1157971 12842857