Wasteful, equidigital and frugal numbers

From Rosetta Code
Revision as of 16:29, 16 July 2022 by PureFox (talk | contribs) (Created new draft task and added a Wren solution.)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Wasteful, equidigital and frugal numbers 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.
Definitions

Let n be a positive integer and l(n) be the number of its digits in base b.

Express n as the product of its prime factors raised to the appropriate powers. Let D(n) be the total number of its base b digits in all its prime factors and in all their exponents that are greater than 1.

Then n is defined to be:

1. a wasteful (or extravagant) number if l(n) < D(n); or

2. an equidigital number if l(n) = D(n); or

3. a frugal (or economical) number if l(n) > D(n)

in base b.

By convention, the number 1 is considered to be an equidigital number in any base even though it has no prime factors.

An economical number is sometimes defined as being being one for which l(n) >= D(n) though this usage won't be followed here.


Examples

In base 10, the number 30 has a prime factorization of 2 x 3 x 5. The total number of digits is 3 (all exponents being 1) which is more than the 2 digits 30 has. So 30 is wasteful in base 10.

In base 10, the number 49 has a prime factorization of 7². The total number of digits, including those of the exponent, is 2 which is the same as the 2 digits 49 has. So 49 is equidigital in base 10.

In base 10, the number 125 has a prime factorization of 5³. The total number of digits, including those of the exponent, is 2 which is less than the 3 digits 125 has. So 125 is frugal in base 10.

In base 2, the number 100000 (32 decimal) has a prime factorization of 10^101 (2^5 decimal). The total number of binary digits, including those of the exponent, is 5 which is less than the 6 binary digits 100000 has. So 32 is frugal in base 2 (but equidigital in base 10).


Task

Compute and show here the first 50 and the 10,000th number in base 10 for each of the three categories of number defined above.

Also compute and show how many numbers less than 1,000,000 fall into each of the three categories.


Bonus

Do the same for base 11, but show the results in base 10.


References



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 analyze = Fn.new { |n, b|

   var factors = Int.primeFactors(n)
   var indivs = Lst.individuals(factors)
   var digits = 0
   for (indiv in indivs) {
       digits = digits + Int.digits(indiv[0], b).count
       if (indiv[1] > 1) digits = digits + Int.digits(indiv[1], b).count
   }
   return [Int.digits(n, b).count, digits]

}

for (b in [10, 11]) {

   var w = []
   var e = [1]
   var f = []
   var wc = 0
   var ec = 1
   var fc = 0
   var wc2 = 0
   var ec2 = 1
   var fc2 = 0
   var n = 2
   System.print("FOR BASE %(b):\n")
   while (fc < 10000 || ec < 10000 || wc < 10000) {
       var r = analyze.call(n, b)
       if (r[0] < r[1]) {
           if (w.count < 50 || wc == 9999) w.add(n)
           wc = wc + 1
           if (n < 1e6) wc2 = wc2 + 1
       } else if (r[0] == r[1]) {
           if (e.count < 50 || ec == 9999) e.add(n)
           ec = ec + 1
           if (n < 1e6) ec2 = ec2 + 1
       } else {
           if (f.count < 50 || fc == 9999) f.add(n)
           fc = fc + 1
           if (n < 1e6) fc2 = fc2 + 1
       }
       n = n + 1
   }
   System.print("First 50 Wasteful numbers:")
   Fmt.tprint("$4d", w[0..49], 10)
   System.print()
   System.print("First 50 Equidigital numbers:")
   Fmt.tprint("$4d", e[0..49], 10)
   System.print()
   System.print("First 50 Frugal numbers:")
   Fmt.tprint("$4d", f[0..49], 10)
   System.print()
   System.print("10,000th Wasteful number    : %(w[50])")
   System.print("10,000th Equidigital number : %(e[50])")
   System.print("10,000th Frugal number      : %(f[50])")
   System.print()
   System.print("For natural numbers < 1 million, the breakdown is as follows:")
   Fmt.print("  Wasteful numbers    : $6d", wc2)
   Fmt.print("  Equidigital numbers : $6d", ec2)
   Fmt.print("  Frugal numbers      : $6d", fc2)
   System.print()

}</lang>

Output: