Colorful numbers

From Rosetta Code
Revision as of 18:35, 23 February 2022 by Rdm (talk | contribs) (J)
Colorful 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.

A colorful number is a non-negative base 10 integer where the product of every sub group of consecutive digits is unique.


E.G.

24753 is a colorful number. 2, 4, 7, 5, 3, (2×4)8, (4×7)28, (7×5)35, (5×3)15, (2×4×7)56, (4×7×5)140, (7×5×3)105, (2×4×7×5)280, (4×7×5×3)420, (2×4×7×5×3)840

Every product is unique.


2346 is not a colorful number. 2, 3, 4, 6, (2×3)6, (3×4)12, (4×6)24, (2×3×4)48, (3×4×6)72, (2×3×4×6)144

The product 6 is repeated.


Single digit numbers are considered to be colorful. A colorful number larger than 9 cannot contain a repeated digit, the digit 0 or the digit 1. As a consequence, there is a firm upper limit for colorful numbers; no colorful number can have more than 8 digits.


Task
  • Write a routine (subroutine, function, procedure, whatever it may be called in your language) to test if a number is a colorful number or not.
  • Use that routine to find all of the colorful numbers less than 100.
  • Use that routine to find the largest possible colorful number.


Stretch
  • Find and display the count of colorful numbers in each order of magnitude.
  • Find and show the total count of all colorful numbers.


Colorful numbers have no real number theory application. They are more a recreational math puzzle than a useful tool.


J

<lang J> colorful=: {{(-:~.);<@(*/\)\. 10 #.inv y}}"0

  I.colorful i.100

0 1 2 3 4 5 6 7 8 9 23 24 25 26 27 28 29 32 34 35 36 37 38 39 42 43 45 46 47 48 49 52 53 54 56 57 58 59 62 63 64 65 67 68 69 72 73 74 75 76 78 79 82 83 84 85 86 87 89 92 93 94 95 96 97 98

  C=: I.colorful <.i.1e8
  >./C

98746253

  (~.,. #/.~) 10 <.@^. C

__ 1

0     9
1    56
2   328
3  1540
4  5514
5 13956
6 21596
7 14256
  #C

57256</lang>

Phix

Library: Phix/online

You can run this online here.

with javascript_semantics
function colourful(integer n)
    if n<10 then return n>=0 end if
    sequence digits = sq_sub(sprintf("%d",n),'0'),
                 ud = unique(deep_copy(digits))
    integer ln = length(digits)
    if ud[1]<=1 or length(ud)!=ln then return false end if
    for i=1 to ln-1 do
        for j=i+1 to ln do
           atom prod = product(digits[i..j])
           if find(prod,ud) then return false end if
           ud &= prod
        end for
    end for
    return true
end function
 
atom t0 = time()
sequence cn = apply(true,sprintf,{{"%2d"},filter(tagset(100,0),colourful)})
printf(1,"The %d colourful numbers less than 100 are:\n%s\n",
         {length(cn),join_by(cn,1,10,"  ")})

sequence count = repeat(0,8),
         used = repeat(false,10)
integer largestcn = 0

procedure count_colourful(integer taken=0, string n="")
    if taken=0 then
        for digit='0' to '9' do
            integer dx = digit-'0'+1
            used[dx] = true
            count_colourful(iff(digit<'2'?9:1),""&digit)
            used[dx] = false
        end for
    else
        integer nn = to_integer(n)
        if colourful(nn) then
            integer ln = length(n)
            count[ln] += 1
            if nn>largestcn then largestcn = nn end if
        end if
        if taken<9 then
            for digit='2' to '9' do
                integer dx = digit-'0'+1
                if not used[dx] then
                    used[dx] = true
                    count_colourful(taken+1,n&digit)
                    used[dx] = false
                end if
            end for
        end if
    end if
end procedure
count_colourful()
printf(1,"The largest possible colourful number is: %,d\n\n",largestcn)
atom pow = 10
for dc=1 to length(count) do
    printf(1,"  %d digit colourful number count: %,6d - %7.3f%%\n",
               {dc, count[dc], 100*count[dc]/pow})
    pow = iff(pow=10?90:pow*10)
end for
printf(1,"\nTotal colourful numbers: %,d\n", sum(count))
?elapsed(time()-t0)
Output:
The 66 colourful numbers less than 100 are:
 0   1   2   3   4   5   6   7   8   9
23  24  25  26  27  28  29  32  34  35
36  37  38  39  42  43  45  46  47  48
49  52  53  54  56  57  58  59  62  63
64  65  67  68  69  72  73  74  75  76
78  79  82  83  84  85  86  87  89  92
93  94  95  96  97  98

The largest possible colourful number is: 98,746,253

  1 digit colourful number count:     10 - 100.000%
  2 digit colourful number count:     56 -  62.222%
  3 digit colourful number count:    328 -  36.444%
  4 digit colourful number count:  1,540 -  17.111%
  5 digit colourful number count:  5,514 -   6.127%
  6 digit colourful number count: 13,956 -   1.551%
  7 digit colourful number count: 21,596 -   0.240%
  8 digit colourful number count: 14,256 -   0.016%

Total colourful numbers: 57,256
"1.9s"

Raku

<lang perl6>sub is-colorful (Int $n) {

   return True if 0 <= $n <= 9;
   return False if $n.contains(0) || $n.contains(1) || $n < 0;
   my @digits = $n.comb;
   my %sums = @digits.Bag;
   return False if %sums.values.max > 1;
   for 2..@digits -> $group {
       @digits.rotor($group => 1 - $group).map: { %sums{ [×] $_ }++ }
       return False if %sums.values.max > 1;
   }
   True

}

put "Colorful numbers less than 100:\n" ~ (^100).race.grep( &is-colorful).batch(10)».fmt("%2d").join: "\n";

my ($start, $total) = 23456789, 10;

print "\nLargest magnitude colorful number: "; .put and last if .Int.&is-colorful for $start.flip … $start;


put "\nCount of colorful numbers for each order of magnitude:\n" ~

   "1 digit colorful number count: $total - 100%";

for 2..8 {

  put "$_ digit colorful number count: ",
  my $c = +(flat $start.comb.combinations($_).map: {.permutations».join».Int}).race.grep( &is-colorful ),
  " - {($c / (exp($_,10) - exp($_-1,10) ) * 100).round(.001)}%";
  $total += $c;

}

say "\nTotal colorful numbers: $total";</lang>

Output:
Colorful numbers less than 100:
 0  1  2  3  4  5  6  7  8  9
23 24 25 26 27 28 29 32 34 35
36 37 38 39 42 43 45 46 47 48
49 52 53 54 56 57 58 59 62 63
64 65 67 68 69 72 73 74 75 76
78 79 82 83 84 85 86 87 89 92
93 94 95 96 97 98

Largest magnitude colorful number: 98746253

Count of colorful numbers for each order of magnitude:
1 digit colorful number count: 10 - 100%
2 digit colorful number count: 56 - 62.222%
3 digit colorful number count: 328 - 36.444%
4 digit colorful number count: 1540 - 17.111%
5 digit colorful number count: 5514 - 6.127%
6 digit colorful number count: 13956 - 1.551%
7 digit colorful number count: 21596 - 0.24%
8 digit colorful number count: 14256 - 0.016%

Total colorful numbers: 57256

Wren

Library: Wren-math
Library: Wren-set
Library: Wren-seq
Library: wren-fmt

<lang ecmascript>import "./math" for Int, Nums import "./set" for Set import "./seq" for Lst import "./fmt" for Fmt

var isColorful = Fn.new { |n|

   if (n < 0) return false
   if (n < 10) return true
   var digits = Int.digits(n)
   if (digits.contains(0) || digits.contains(1)) return false
   var set = Set.new(digits)
   var dc = digits.count
   if (set.count < dc) return false
   for (k in 2..dc) {
       for (i in 0..dc-k) {
          var prod = 1
          for (j in i..i+k-1) prod = prod * digits[j]
          if (set.contains(prod)) return false
          set.add(prod)
       }
   }
   return true

}

System.print("The colorful numbers less than 100 are:") var colorful = (0..99).where { |i| isColorful.call(i) }.toList for (chunk in Lst.chunks(colorful, 10)) Fmt.print("$2d", chunk)

var largest = 0 System.print("\nThe largest possible colorful number is:") for (i in 1e8-1..0) {

   if (isColorful.call(i)) {
       Fmt.print("$,d", i)
       largest = i
       break
   }

}

var count = List.filled(9, 0) var dc = 1 var pow = 10 System.print("\nCount of colorful numbers for each order of magnitude:") var i = 0 while (true) {

   if (dc > 1) {
       var rem = i % 10
       if (rem == 0 || rem == 1) {
           i = i + 2 - rem
           continue
       }
   }
   if (isColorful.call(i)) count[dc] = count[dc] + 1
   if (i == pow - 1 || i == largest) {
       var total = (dc == 1) ? 10 : pow * 0.9
       var pc = 100 * count[dc] / total
       Fmt.print("  $d digit colorful number count: $,6d - $7.3f\%", dc, count[dc], pc)
       if (i == largest) break
       dc = dc + 1
       pow = pow * 10 
       i = pow * 0.2 + 2
   } else {
       i = i + 1
   }

}

Fmt.print("\nTotal colorful numbers: $,d", Nums.sum(count))</lang>

Output:
The colorful numbers less than 100 are:
 0  1  2  3  4  5  6  7  8  9
23 24 25 26 27 28 29 32 34 35
36 37 38 39 42 43 45 46 47 48
49 52 53 54 56 57 58 59 62 63
64 65 67 68 69 72 73 74 75 76
78 79 82 83 84 85 86 87 89 92
93 94 95 96 97 98

The largest possible colorful number is:
98,746,253

Count of colorful numbers for each order of magnitude:
  1 digit colorful number count:     10 - 100.000%
  2 digit colorful number count:     56 -  62.222%
  3 digit colorful number count:    328 -  36.444%
  4 digit colorful number count:  1,540 -  17.111%
  5 digit colorful number count:  5,514 -   6.127%
  6 digit colorful number count: 13,956 -   1.551%
  7 digit colorful number count: 21,596 -   0.240%
  8 digit colorful number count: 14,256 -   0.016%

Total colorful numbers: 57,256