Colorful numbers

From Rosetta Code
Task
Colorful numbers
You are encouraged to solve this task according to the task description, using any language you may know.

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.

11l

Translation of: Python
V largest = [0]

F iscolorful(n)
   I n C 0.<10
      R 1B
   V dig = String(n).map(c -> Int(c))
   I 1 C dig | 0 C dig | dig.len > Set(dig).len
      R 0B
   V products = Array(Set(dig))
   L(i) 0 .< dig.len
      L(j) i + 2 .. dig.len
         V p = product(dig[i .< j])
         I p C products
            R 0B
         products.append(p)

   :largest[0] = max(n, :largest[0])
   R 1B

print(‘Colorful numbers for 1:25, 26:50, 51:75, and 76:100:’)
L(i) (1.<101).step(25)
   L(j) 25
      I iscolorful(i + j)
         print(f:‘{commatize(i + j): 5}’, end' ‘’)
   print()

V csum = 0
L(i) 8
   V j = I i == 0 {0} E 10 ^ i
   V k = 10 ^ (i + 1) - 1
   V n = sum((j .. k).map(x -> Int(iscolorful(x))))
   csum += n
   print(‘The count of colorful numbers between ’j‘ and ’k‘ is ’n‘.’)

print(‘The largest possible colorful number is ’largest[0]‘.’)
print(‘The total number of colorful numbers is ’csum‘.’)
Output:
Colorful numbers for 1:25, 26:50, 51:75, and 76:100:
    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 count of colorful numbers between 0 and 9 is 10.
The count of colorful numbers between 10 and 99 is 56.
The count of colorful numbers between 100 and 999 is 328.
The count of colorful numbers between 1000 and 9999 is 1540.
The count of colorful numbers between 10000 and 99999 is 5514.
The count of colorful numbers between 100000 and 999999 is 13956.
The count of colorful numbers between 1000000 and 9999999 is 21596.
The count of colorful numbers between 10000000 and 99999999 is 14256.
The largest possible colorful number is 98746253.
The total number of colorful numbers is 57256.

ALGOL 68

Using brute force for the stretch.

BEGIN # find colourful numbers: numbers where the product of every sub-group #
      # of digits is uniue ( non-negative numbers only )                     #
      # note that (as stated in the task) for multi-digit numbers, the       #
      # digits 0 and 1 cannot appear                                         #

      # returns TRUE if n is colourful, FALSE otherswise                     #
      PROC is colourful = ( INT n )BOOL:
           IF   n <  0 THEN FALSE
           ELIF n < 10 THEN TRUE
           ELSE
               # more than 1 digit - must teat the digits and digit groups   #
               INT v     := n;
               # table to hold the digits and groups, as 0 and 1 can't       #
               # appear, there will be at most 8 digits so at most 36 groups #
               [ 1 : 46 ]INT dg;
               # split and count the digits                                  #
               [ 0 :  9 ]INT d count;
               INT s end := 0; # position of the last single digit in dg     #
               FOR i FROM LWB d count TO UPB d count DO d count[ i ] := 0 OD;
               BOOL unique := TRUE;
               WHILE v > 0 AND unique DO
                   INT d              = v MOD 10;
                   dg[ s end +:= 1 ] := d;
                   unique            := 1 = ( d count[ d ] +:= 1 );
                   v OVERAB 10
               OD;
               IF unique THEN unique := d count[ 0 ] + d count[ 1 ] = 0 FI;
               # form the group products, stopping if one is non-unique      #
               INT dg pos := s end;
               FOR group width FROM 2 TO s end WHILE unique DO
                   FOR group start TO ( s end + 1 ) - group width WHILE unique DO
                       INT product := 1;
                       INT g pos   := group start - 1;
                       FOR i TO group width DO product *:= dg[ g pos +:= 1 ] OD;
                       dg[ dg pos +:= 1 ] := product;
                       FOR i TO dg pos - 1 WHILE unique DO
                           unique := dg[ i ] /= dg[ dg pos ]
                       OD
                   OD
               OD;
               unique
           FI # is colourful # ;

    # show the colourful numbers under 100                                   #
    print( ( "Colourful numbers less than 100:", newline ) );
    INT c count := 0;
    FOR i FROM 0 TO 99 DO
        IF is colourful( i ) THEN
            print( ( whole( i, -3 ) ) );
            IF ( c count +:= 1 ) MOD 11 = 0 THEN print( ( newline ) ) FI
        FI
    OD;
    print( ( newline ) );
    # find the largest colourful number                                      #
    INT max colourful := 0;
    FOR i FROM 98765432 BY -1 WHILE max colourful = 0 DO
        IF is colourful( i ) THEN
            max colourful := i
        FI
    OD;
    print( ( "The largest colourful number is: ", whole( max colourful, 0 ), newline ) );
    # show the number of colourful numbers by order of magnitude             #
    INT p10     := 10;
    c count     :=  0;
    INT t count :=  0;
    FOR i FROM 0 TO max colourful DO
        IF i = p10 THEN
            print( ( "Colourful numbers below ", whole( p10, -10 ), ": ", whole( c count, 0 ), newline ) );
            t count +:= c count;
            c count  := 0;
            p10     *:= 10
        FI;
        IF is colourful( i ) THEN
            c count +:= 1
        FI
    OD;
    print( ( "Colourful numbers below ", whole( p10, -10 ), ": ", whole( c count, 0 ), newline ) );
    print( ( "Total number of colourful numbers : ", whole( t count + c count, 0 ), newline ) )
END
Output:
Colourful 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

The largest colourful number is: 98746253
Colourful numbers below         10: 10
Colourful numbers below        100: 56
Colourful numbers below       1000: 328
Colourful numbers below      10000: 1540
Colourful numbers below     100000: 5514
Colourful numbers below    1000000: 13956
Colourful numbers below   10000000: 21596
Colourful numbers below  100000000: 14256
Total number of colourful numbers : 57256

AppleScript

(*
    This observes the task requirement that colorful numbers be identified using a test handler,
    but uses the information regarding 1s and 0s and some logic to skip obvious non-starters
    and save a few minutes' running time. Since multiplication is commutative, every number's
    "colorful" status is the same as its reverse's. Working up from 0, the lower number of each
    mirrored colorful pair is met first and its reverse derived. If the largest reversed number
    obtained so far is actually reached, it's the last colorful number at that magnitude. The
    search either end there or jumps to the lowest number worth trying at the next level.
*)
on isColorful(n)
    if ((n > 98765432) or (n < 0) or (n mod 1 > 0)) then return false
    set products to {n mod 10}
    repeat while (n > 9)
        set n to n div 10
        set digit to n mod 10
        if ((digit < 2) or (digit is in products)) then return false
        set end of products to digit
    end repeat
    set nDigits to (count products)
    repeat with i from 1 to (nDigits - 1)
        set prod to products's item i
        repeat with j from (i + 1) to nDigits
            set prod to prod * (products's item j)
            if (prod is in products) then return false
            set end of products to prod
        end repeat
    end repeat
    
    return true
end isColorful

on join(lst, delim)
    set astid to AppleScript's text item delimiters
    set AppleScript's text item delimiters to delim
    set txt to lst as text
    set AppleScript's text item delimiters to astid
    return txt
end join

on task()
    set colorfuls to {}
    set counter to 0
    set counts to {}
    set magnitude to 1 -- 10 ^ (number of digits - 1).
    set largestReverse to 9 -- Largest reverse of a single-digit number!
    set n to 0
    repeat
        if (isColorful(n)) then
            if (n < 100) then set end of colorfuls to text -3 thru -1 of ("   " & n)
            set counter to counter + 1
            if (n = largestReverse) then
                set end of counts to counter
                set counter to 0
                set magnitude to magnitude * 10
                if (magnitude > 98765432) then exit repeat
                set n to 2.3456789 * magnitude div 1 - 1
            else
                set temp to n
                set |reverse| to temp mod 10
                repeat while (temp > 9)
                    set temp to temp div 10
                    set |reverse| to |reverse| * 10 + temp mod 10
                end repeat
                if (|reverse| > largestReverse) then set largestReverse to |reverse|
            end if
        end if
        if (n mod 10 = 9) then
            set n to n + 3
        else
            set n to n + 1
        end if
    end repeat
    
    set output to {"The colorful numbers below 100:"}
    repeat with i from 1 to 66 by 11
        set end of output to join(colorfuls's items i thru (i + 10), "")
    end repeat
    set end of output to linefeed & "The largest colorful number is " & largestReverse
    set counter to counts's beginning
    set end of output to linefeed & "The number of them with 1 digit is " & counter
    repeat with i from 2 to (count counts)
        set end of output to "The number with " & i & " digits is " & (counts's item i)
        set counter to counter + (counts's item i)
    end repeat
    set end of output to "The total number overall is " & counter
    return join(output, linefeed)
end task

task()
Output:
"The colorful numbers below 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

The largest colorful number is 98746253

The number of them with 1 digit is 10
The number with 2 digits is 56
The number with 3 digits is 328
The number with 4 digits is 1540
The number with 5 digits is 5514
The number with 6 digits is 13956
The number with 7 digits is 21596
The number with 8 digits is 14256
The total number overall is 57256"

Or here's an alternative using the same isColorful handler but with a translation of the Phix solution's count_colourful function feeding in the numbers. Multi-digit numbers containing 0, 1, or duplicated digits are studiously not produced, so the execution time is very much shorter. (Just over nine seconds on the test machine as opposed to just over six minutes.) Same output as above.

on isColorful(n)
    if ((n > 98765432) or (n < 0) or (n mod 1 > 0)) then return false
    set products to {n mod 10}
    repeat while (n > 9)
        set n to n div 10
        set digit to n mod 10
        if ((digit < 2) or (digit is in products)) then return false
        set end of products to digit
    end repeat
    set nDigits to (count products)
    repeat with i from 1 to (nDigits - 1)
        set prod to products's item i
        repeat with j from (i + 1) to nDigits
            set prod to prod * (products's item j)
            if (prod is in products) then return false
            set end of products to prod
        end repeat
    end repeat
    
    return true
end isColorful

on join(lst, delim)
    set astid to AppleScript's text item delimiters
    set AppleScript's text item delimiters to delim
    set txt to lst as text
    set AppleScript's text item delimiters to astid
    return txt
end join

on task()
    set colorfuls to {}
    repeat with n from 0 to 100
        if (isColorful(n)) then set end of colorfuls to ("   " & n)'s text -3 thru -1
    end repeat
    
    script cc
        property used : {false, false, false, false, false, false, false, false, false, false}
        property counts : {0, 0, 0, 0, 0, 0, 0, 0}
        property largest : 0
        
        on count_colourful(taken, x, n)
            set used's item x to true
            if (isColorful(n)) then
                set ln to 1
                repeat until ((10 ^ ln) > n)
                    set ln to ln + 1
                end repeat
                set counts's item ln to (counts's item ln) + 1
                if (n > largest) then set largest to n
            end if
            if (taken < 9) then
                repeat with digit from 2 to 9
                    set dx to digit + 1
                    if (not used's item dx) then
                        count_colourful(taken + 1, dx, n * 10 + digit)
                    end if
                end repeat
            end if
            set used's item x to false
        end count_colourful
    end script
    repeat with digit from 0 to 9
        cc's count_colourful(((digit < 2) as integer) * 8 + 1, digit + 1, digit)
    end repeat
    
    set output to {"The colorful numbers below 100:"}
    repeat with i from 1 to 66 by 11
        set end of output to join(colorfuls's items i thru (i + 10), "")
    end repeat
    set end of output to linefeed & "The largest colorful number is " & cc's largest
    set counter to cc's counts's beginning
    set end of output to linefeed & "The number of them with 1 digit is " & counter
    repeat with i from 2 to (count cc's counts)
        set end of output to "The number with " & i & " digits is " & (cc's counts's item i)
        set counter to counter + (cc's counts's item i)
    end repeat
    set end of output to "The total number overall is " & counter
    return join(output, linefeed)
end task

task()

C

The count_colorful function is based on Phix.

#include <locale.h>
#include <stdbool.h>
#include <stdio.h>
#include <time.h>

bool colorful(int n) {
    // A colorful number cannot be greater than 98765432.
    if (n < 0 || n > 98765432)
        return false;
    int digit_count[10] = {};
    int digits[8] = {};
    int num_digits = 0;
    for (int m = n; m > 0; m /= 10) {
        int d = m % 10;
        if (n > 9 && (d == 0 || d == 1))
            return false;
        if (++digit_count[d] > 1)
            return false;
        digits[num_digits++] = d;
    }
    // Maximum number of products is (8 x 9) / 2.
    int products[36] = {};
    for (int i = 0, product_count = 0; i < num_digits; ++i) {
        for (int j = i, p = 1; j < num_digits; ++j) {
            p *= digits[j];
            for (int k = 0; k < product_count; ++k) {
                if (products[k] == p)
                    return false;
            }
            products[product_count++] = p;
        }
    }
    return true;
}

static int count[8];
static bool used[10];
static int largest = 0;

void count_colorful(int taken, int n, int digits) {
    if (taken == 0) {
        for (int d = 0; d < 10; ++d) {
            used[d] = true;
            count_colorful(d < 2 ? 9 : 1, d, 1);
            used[d] = false;
        }
    } else {
        if (colorful(n)) {
            ++count[digits - 1];
            if (n > largest)
                largest = n;
        }
        if (taken < 9) {
            for (int d = 2; d < 10; ++d) {
                if (!used[d]) {
                    used[d] = true;
                    count_colorful(taken + 1, n * 10 + d, digits + 1);
                    used[d] = false;
                }
            }
        }
    }
}

int main() {
    setlocale(LC_ALL, "");

    clock_t start = clock();

    printf("Colorful numbers less than 100:\n");
    for (int n = 0, count = 0; n < 100; ++n) {
        if (colorful(n))
            printf("%2d%c", n, ++count % 10 == 0 ? '\n' : ' ');
    }

    count_colorful(0, 0, 0);
    printf("\n\nLargest colorful number: %'d\n", largest);

    printf("\nCount of colorful numbers by number of digits:\n");
    int total = 0;
    for (int d = 0; d < 8; ++d) {
        printf("%d   %'d\n", d + 1, count[d]);
        total += count[d];
    }
    printf("\nTotal: %'d\n", total);

    clock_t end = clock();
    printf("\nElapsed time: %f seconds\n",
           (end - start + 0.0) / CLOCKS_PER_SEC);
    return 0;
}

{{out>@TIO.RUN}}

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 colorful number: 98,746,253

Count of colorful numbers by number of digits:
1   10
2   56
3   328
4   1,540
5   5,514
6   13,956
7   21,596
8   14,256

Total: 57,256

Elapsed time: 0.031256 seconds

C++

#include <cstdint>
#include <iomanip>
#include <iostream>
#include <vector>

std::vector<uint32_t> count(8, 0);
std::vector<bool> used(10, false);
uint32_t largest = 0;

bool is_colorful(const uint32_t& number) {
	if ( number > 98'765'432 ) {
		return false;
	}

	std::vector<uint32_t> digit_count(10, 0);
	std::vector<uint32_t> digits(8, 0);
	uint32_t number_digits = 0;

	for ( uint32_t i = number; i > 0; i /= 10 ) {
		uint32_t digit = i % 10;
		if ( number > 9 && ( digit == 0 || digit == 1 ) ) {
			return false;
		}
		if ( ++digit_count[digit] > 1 ) {
			return false;
		}
		digits[number_digits++] = digit;
	}

	std::vector<uint32_t> products(36, 0);
	for ( uint32_t i = 0, product_count = 0; i < number_digits; ++i ) {
		for ( uint32_t j = i, product = 1; j < number_digits; ++j ) {
			product *= digits[j];
			for ( uint32_t k = 0; k < product_count; ++k ) {
				if ( products[k] == product ) {
					return false;
				}
			}
			products[product_count++] = product;
		}
	}
	return true;
}

void count_colorful(const uint32_t& taken, const uint32_t& number, const uint32_t& digits) {
	if ( taken == 0 ) {
		for ( uint32_t digit = 0; digit < 10; ++digit ) {
			used[digit] = true;
			count_colorful(digit < 2 ? 9 : 1, digit, 1);
			used[digit] = false;
		}
	} else {
		if ( is_colorful(number) ) {
			++count[digits - 1];
			if ( number > largest ) {
				largest = number;
			}
		}
		if ( taken < 9 ) {
			for ( uint32_t digit = 2; digit < 10; ++digit ) {
				if ( ! used[digit] ) {
					used[digit] = true;
					count_colorful(taken + 1, number * 10 + digit, digits + 1);
					used[digit] = false;
				}
			}
		}
	}
}

int main() {
	std::cout << "Colorful numbers less than 100:" << std::endl;
	for ( uint32_t number = 0, count = 0; number < 100; ++number ) {
		if ( is_colorful(number) ) {
			std::cout << std::setw(2) << number << ( ++count % 10 == 0 ? "\n" : " ");
		}
	}
	std::cout << "\n" << std::endl;

	count_colorful(0, 0, 0);
	std::cout << "Count of colorful numbers by number of digits:" << std::endl;
	uint32_t total = 0;
	for ( uint32_t digit = 0; digit < 8; ++digit ) {
		std::cout << digit + 1 << ": " << count[digit] << std::endl;
		total += count[digit];
	}
	std::cout << std::endl;

	std::cout << "The largest possible colorful number is: " << largest << "\n" << std::endl;
	std::cout << "The total number of colorful numbers is: " << total << std::endl;
}
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 

Count of colorful numbers by number of digits:
1: 10
2: 56
3: 328
4: 1540
5: 5514
6: 13956
7: 21596
8: 14256

The largest possible colorful number is: 98746253

The total number of colorful numbers is: 57256

Delphi

Works with: Delphi version 6.0


procedure ShowColorfulNumbers(Memo: TMemo);
var I,P,Cnt,OldCnt,Start,Stop: integer;
var S: string;
var Largest: integer;


	function IsColorful(N: integer): boolean;
	var IA: TIntegerDynArray;
	var PList: TList;
	var I,J,D,P: integer;
	begin
	PList:=TList.Create;
	try
	Result:=False;
	GetDigits(N,IA);
	{Number of digits at a time}
	for D:=1 to Length(IA) do
	 {For all digits in number}
	 for I:=High(IA) downto D-1 do
		begin
		P:=1;
		{Product of digits in a group}
		for J:=0 to D-1 do P:=P * IA[I-J];
		{Has it already been used}
		if PList.IndexOf(Pointer(P))>=0 then exit;
		{Store in list}
		PList.Add(Pointer(P));
		end;
	Result:=True;
	finally PList.Free; end;
	end;


begin
Cnt:=0; S:='';
Memo.Line.Add('Colorful Number less than 100');
for I:=0 to 100-1 do
 if IsColorful(I) then
 	begin
	Inc(Cnt);
	S:=S+Format('%7D',[I]);
	If (Cnt mod 5)=0 then S:=S+CRLF;
	end;
Memo.Lines.Add(S);
Memo.Lines.Add('Count = '+IntToStr(Cnt));
for Largest:=98765432 downto 1 do
 if IsColorful(Largest) then break;
Memo.Lines.Add('Largest Colorful Number = '+IntToStr(Largest));

Start:=0; Stop:=9;
Cnt:=0; OldCnt:=0;
for P:=1 to 8 do
	begin
	for I:=Start to Stop do
	 if IsColorful(I) then Inc(Cnt);
	Memo.Lines.Add(Format('Colorful Numbers from %10.0n to %10.0n: %5D', [Start+0.0,Stop+0.0,Cnt-OldCnt]));
	Start:=Stop+1;
	Stop:=(Start*10)-1;
	OldCnt:=Cnt;
	end;
for I:=Stop+1 to Largest do
 if IsColorful(I) then Inc(Cnt);
Memo.Lines.Add('Total All Colorful = '+IntToStr(Cnt));
end;
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
Count = 66

Largest Colorful Number = 98746253

Colorful Numbers from          0 to          9:    10
Colorful Numbers from         10 to         99:    56
Colorful Numbers from        100 to        999:   328
Colorful Numbers from      1,000 to      9,999:  1540
Colorful Numbers from     10,000 to     99,999:  5514
Colorful Numbers from    100,000 to    999,999: 13956
Colorful Numbers from  1,000,000 to  9,999,999: 21596
Colorful Numbers from 10,000,000 to 99,999,999: 14256
Total All Colorful = 57256
Elapsed Time: 01:36.252 min


EasyLang

Translation of: C
func colorful n .
   len digcnt[] 10
   arrbase digcnt[] 0
   len digits[] 8
   m = n
   while m > 0
      d = m mod 10
      if n > 9 and d <= 1
         return 0
      .
      digcnt[d] += 1
      if digcnt[d] > 1
         return 0
      .
      ndigs += 1
      digits[ndigs] = d
      m = m div 10
   .
   len products[] 36
   for i to ndigs
      p = 1
      for j = i to ndigs
         p *= digits[j]
         for k to prodcnt
            if products[k] = p
               return 0
            .
         .
         prodcnt += 1
         products[prodcnt] = p
      .
   .
   return 1
.
len cnt[] 8
len used[] 10
arrbase used[] 0
largest = 0
proc cnt_colorful taken n digits . .
   if taken = 0
      for d = 0 to 9
         used[d] = 1
         h = 1
         if d < 2
            h = 9
         .
         cnt_colorful h d 1
         used[d] = 0
      .
      return
   .
   if colorful n = 1
      cnt[digits] += 1
      largest = higher largest n
   .
   if taken < 9
      for d = 2 to 9
         if used[d] = 0
            used[d] = 1
            cnt_colorful (taken + 1) (n * 10 + d) (digits + 1)
            used[d] = 0
         .
      .
   .
.
print "Colorful numbers less than 100:"
for n = 0 to 99
   if colorful n = 1
      write n & " "
   .
.
cnt_colorful 0 0 0
print "\n\nLargest colorful number:" & largest
# 
print "\nCount of colorful numbers by number of digits:\n"
for d to 8
   print d & "   " & cnt[d]
   total += cnt[d]
.
print "\nTotal: " & total
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 colorful number:98746253

Count of colorful numbers by number of digits:

1   10
2   56
3   328
4   1540
5   5514
6   13956
7   21596
8   14256

Total: 57256

Factor

Works with: Factor version 0.99 2021-06-02
USING: assocs grouping grouping.extras io kernel literals math
math.combinatorics math.ranges prettyprint project-euler.common
sequences sequences.extras sets ;

CONSTANT: digits $[ 2 9 [a..b] ]

: (colorful?) ( seq -- ? )
    all-subseqs [ product ] map all-unique? ;

: colorful? ( n -- ? )
    [ t ] [ number>digits (colorful?) ] if-zero ;

: table. ( seq cols -- )
    [ "" pad-groups ] keep group simple-table. ;

: (oom-count) ( n -- count )
    digits swap <k-permutations> [ (colorful?) ] count ;

: oom-count ( n -- count )
    dup 1 = [ drop 10 ] [ (oom-count) ] if ;

"Colorful numbers under 100:" print
100 <iota> [ colorful? ] filter 10 table. nl

"Largest colorful number:" print
digits <permutations> [ (colorful?) ] find-last nip digits>number . nl

"Count of colorful numbers by number of digits:" print
8 [1..b] [ oom-count ] zip-with dup .
"Total: " write values sum .
Output:
Colorful numbers under 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 colorful number:
98746253

Count of colorful numbers by number of digits:
{
    { 1 10 }
    { 2 56 }
    { 3 328 }
    { 4 1540 }
    { 5 5514 }
    { 6 13956 }
    { 7 21596 }
    { 8 14256 }
}
Total: 57256

FreeBASIC

Dim Shared As Uinteger largest = 0

Function isColorful(n As Uinteger) As Uinteger   
    ' A colorful number cannot be greater than 98765432
    If n < 0 Or n > 98765432 Then Return 0
    If n >= 0 And n < 10 Then Return 1    ' Single digit number is colorful
    
    Dim As Uinteger i, j, k, tmp = n
    Dim As String s = Str(n)
    Dim As Uinteger digits(Len(s))
    For i = 1 To Len(s)
        digits(i) = Val(Mid(s, i, 1))
        If digits(i) = 0 Or digits(i) = 1 Then Return 0
    Next i
    
    Dim As Uinteger uniqueDigits(9)
    For i = 1 To Len(s)
        uniqueDigits(digits(i)) += 1
    Next i
    For i = 0 To 9
        If uniqueDigits(i) > 1 Then Return 0
    Next i
    
    Dim As Uinteger products(Len(s) * (Len(s) + 1) / 2)
    Dim As Uinteger pIndex = 0
    For i = 1 To Len(s)
        products(pIndex) = digits(i)
        pIndex += 1
    Next i
    For i = 2 To Len(s)
        For j = 0 To Len(s) - i
            Dim As Uinteger product = 1
            For k = j To (j + i) - 1
                product *= digits(k + 1)
            Next k
            For k = 0 To pIndex - 1
                If products(k) = product Then Return 0
            Next k
            products(pIndex) = product
            pIndex += 1
        Next j
    Next i
    
    If tmp > largest Then largest = tmp
    Return 1
End Function

Sub TestColorfuls()
    Dim As Uinteger i, j, k, cnt, x, csum, pow
    
    Print "Colorful numbers less than 100:"
    cnt = 0
    For i = 0 To 99
        If isColorful(i) Then 
            cnt +=1 
            Print Using "###"; i;
            If cnt Mod 10 = 0 Then Print
        End If
    Next i
    
    Print !"\n\nCount of colorful numbers for each order of magnitude:"
    csum = 0
    pow = 10
    For i = 0 To 7
        j = Iif(i = 0, 0, 10 ^ i)
        k = 10 ^ (i + 1) - 1
        cnt = 0
        For x = j To k
            cnt += isColorful(x)
        Next x
        
        csum += cnt
        Print Using " # digit colourful number count: ####,# - ###.###%"; i+1; cnt; 100 * cnt/pow
        pow = Iif(pow = 10, 90, pow * 10)
    Next i
    
    Print !"\nLargest magnitude colorful number: "; largest
    Print "Total colorful numbers :"; csum
End Sub

Dim As Double t0 = Timer
TestColorfuls()
Print Using !"\nTook ###.### seconds on i5 @ 3.20 GHz"; Timer - t0

Sleep
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  

Count of colorful numbers for each order of magnitude:
 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%

Largest magnitude colorful number: 98746253
Total colorful numbers: 57256

Took 171.906 seconds on i5 @ 3.20 GHz

FutureBasic

begin globals
NSInteger gLargest
end globals

gLargest = 0

local fn IsColorful( n as NSInteger, base as NSInteger  ) as BOOL
  NSUInteger i, j, k, temp = n
  
  // A colorful number cannot be greater than 98765432.
  if ( n < 0 || n > 98765432 ) then return NO
  if ( n >= 0 && n < 10 ) then return YES
  
  CFMutableArrayRef digits = fn MutableArrayNew
  
  while ( n > 0 )
    MutableArrayAddObject( digits, @(n % base) )
    n /= base
  wend
  
  CFSetRef uniqueDigits = fn SetWithArray( digits )
  
  if ( len(uniqueDigits) < len(digits) || fn SetContainsObject( uniqueDigits, @(0) ) || fn SetContainsObject( uniqueDigits, @(1) ) )
    return NO
  end if
  
  CFMutableSetRef products = fn MutableSetWithArray( digits )
  NSUInteger        length = len(digits)
  
  for i = 2 to length
    for j = 0 to length - i
      NSInteger product = 1
      for k = j to ( j + i ) -1
        product *= fn NumberIntegerValue( digits[k] )
      next
      if ( fn SetContainsObject( products, @(product) ) )
        return NO
      end if
      MutableSetAddObject( products, @(product) )
    next
  next
  
  if ( temp > gLargest ) then gLargest = temp
end fn = YES


void local fn TestColorfuls
  NSInteger i, j, k, n, x
  
  printf @"Colorful numbers for 1:25, 26:50, 51:75, and 76:100:"
  
  for i = 1 to 100
    if ( fn IsColorful( i, 10 ) )
      printf @"%5ld \b", (long)i
    end if
    if ( i % 25 == 0 )
      print
    end if
  next
  print
  
  NSInteger csum = 0
  for i = 0 to 7
    j = ( i == 0 ) ? 0 : fn pow( 10, i )
    k = fn pow( 10, i + 1 ) - 1
    n = 0
    for x = j to k
      if ( fn IsColorful( x, 10 ) )
        n++
      end if
    next
    csum += n
    if i < 7 then printf @"The count of colorful numbers between %ld and %ld is %ld.", (long)j, (long)k, (long)n
  next
  
  printf @"\nThe largest possible colorful number is %ld.", (long)gLargest
  printf @"The total number of colorful numbers is %ld.", (long)csum
end fn

window 1, @"Colorful Numbers", ( 0, 0, 800, 300 )

CFTimeInterval t : t = fn CACurrentMediaTime
fn TestColorfuls
print : printf @"Compute time: %.3f seconds",(fn CACurrentMediaTime-t)

HandleEvents
Output:
Colorful numbers for 1:25, 26:50, 51:75, and 76:100:
    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 count of colorful numbers between 0 and 9 is 10.
The count of colorful numbers between 10 and 99 is 56.
The count of colorful numbers between 100 and 999 is 328.
The count of colorful numbers between 1000 and 9999 is 1540.
The count of colorful numbers between 10000 and 99999 is 5514.
The count of colorful numbers between 100000 and 999999 is 13956.
The count of colorful numbers between 1000000 and 9999999 is 21596.

The largest possible colorful number is 98746253.
The total number of colorful numbers is 57256.

Compute time: 59.100 seconds


Go

Translation of: Phix
Library: Go-rcu
package main

import (
    "fmt"
    "rcu"
    "strconv"
)

func isColorful(n int) bool {
    if n < 0 {
        return false
    }
    if n < 10 {
        return true
    }
    digits := rcu.Digits(n, 10)
    for _, d := range digits {
        if d == 0 || d == 1 {
            return false
        }
    }
    set := make(map[int]bool)
    for _, d := range digits {
        set[d] = true
    }
    dc := len(digits)
    if len(set) < dc {
        return false
    }
    for k := 2; k <= dc; k++ {
        for i := 0; i <= dc-k; i++ {
            prod := 1
            for j := i; j <= i+k-1; j++ {
                prod *= digits[j]
            }
            if ok := set[prod]; ok {
                return false
            }
            set[prod] = true
        }
    }
    return true
}

var count = make([]int, 9)
var used = make([]bool, 11)
var largest = 0

func countColorful(taken int, n string) {
    if taken == 0 {
        for digit := 0; digit < 10; digit++ {
            dx := digit + 1
            used[dx] = true
            t := 1
            if digit < 2 {
                t = 9
            }
            countColorful(t, string(digit+48))
            used[dx] = false
        }
    } else {
        nn, _ := strconv.Atoi(n)
        if isColorful(nn) {
            ln := len(n)
            count[ln]++
            if nn > largest {
                largest = nn
            }
        }
        if taken < 9 {
            for digit := 2; digit < 10; digit++ {
                dx := digit + 1
                if !used[dx] {
                    used[dx] = true
                    countColorful(taken+1, n+string(digit+48))
                    used[dx] = false
                }
            }
        }
    }
}

func main() {
    var cn []int
    for i := 0; i < 100; i++ {
        if isColorful(i) {
            cn = append(cn, i)
        }
    }
    fmt.Println("The", len(cn), "colorful numbers less than 100 are:")
    for i := 0; i < len(cn); i++ {
        fmt.Printf("%2d ", cn[i])
        if (i+1)%10 == 0 {
            fmt.Println()
        }
    }

    countColorful(0, "")
    fmt.Println("\n\nThe largest possible colorful number is:")
    fmt.Println(rcu.Commatize(largest))

    fmt.Println("\nCount of colorful numbers for each order of magnitude:")
    pow := 10
    for dc := 1; dc < len(count); dc++ {
        cdc := rcu.Commatize(count[dc])
        pc := 100 * float64(count[dc]) / float64(pow)
        fmt.Printf("  %d digit colorful number count: %6s - %7.3f%%\n", dc, cdc, pc)
        if pow == 10 {
            pow = 90
        } else {
            pow *= 10
        }
    }

    sum := 0
    for _, c := range count {
        sum += c
    }
    fmt.Printf("\nTotal colorful numbers: %s\n", rcu.Commatize(sum))
}
Output:
The 66 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

Haskell

This example is incorrect. Please fix the code and remove this message.

Details: 10 is not a Colorful number; nor is 98765432: 6×5×4 == 5×4×3×2 == 120

import Data.List ( nub ) 
import Data.List.Split ( divvy ) 
import Data.Char ( digitToInt ) 

isColourful :: Integer -> Bool
isColourful n 
   |n >= 0 && n <= 10 = True
   |n > 10 && n < 100 = ((length s) == (length $ nub s)) &&
    (not $ any (\c -> elem c "01") s)
   |n >= 100 = ((length s) == (length $ nub s)) && (not $ any (\c -> elem c "01") s)
     && ((length products) == (length $ nub products))
    where
     s :: String
     s = show n
     products :: [Int]
     products = map (\p -> (digitToInt $ head p) * (digitToInt $ last p))
      $ divvy 2 1 s

solution1 :: [Integer]
solution1 = filter isColourful [0 .. 100]

solution2 :: Integer
solution2 = head $ filter isColourful [98765432, 98765431 ..]
Output:
[0,1,2,3,4,5,6,7,8,9,10,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](solution1)
98765432(solution2)

Haskell (alternate version)

An alternate Haskell version, which some may consider to be in a more idiomatic style. No attempt at optimization has been made, so we don't attempt the stretch goals.

import Data.List (inits, nub, tails, unfoldr)

-- Non-empty subsequences containing only consecutive elements from the
-- argument.  For example:
--
--   consecs [1,2,3]  =>  [[1],[1,2],[1,2,3],[2],[2,3],[3]]
consecs :: [a] -> [[a]]
consecs = drop 1 . ([] :) . concatMap (drop 1 . inits) . tails

-- The list of digits in the argument, from least to most significant.  The
-- number 0 is represented by the empty list.
toDigits :: Int -> [Int]
toDigits = unfoldr step
  where step 0 = Nothing
        step n = let (q, r) = n `quotRem` 10 in Just (r, q)

-- True if and only if all the argument's elements are distinct.
allDistinct :: [Int] -> Bool
allDistinct ns = length ns == length (nub ns)

-- True if and only if the argument is a colorful number.
isColorful :: Int -> Bool
isColorful = allDistinct . map product . consecs . toDigits

main :: IO ()
main = do
  let smalls = filter isColorful [0..99]
  putStrLn $ "Small colorful numbers: " ++ show smalls

  let start = 98765432
      largest = head $ dropWhile (not . isColorful) [start, start-1 ..]
  putStrLn $ "Largest colorful number: " ++ show largest
Output:
$ colorful
Small colorful numbers: [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 colorful number: 98746253

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

(Note that 0, here is a different order of magnitude than 1.)

Java

Translation of: C
public class ColorfulNumbers {
    private int count[] = new int[8];
    private boolean used[] = new boolean[10];
    private int largest = 0;

    public static void main(String[] args) {
        System.out.printf("Colorful numbers less than 100:\n");
        for (int n = 0, count = 0; n < 100; ++n) {
            if (isColorful(n))
                System.out.printf("%2d%c", n, ++count % 10 == 0 ? '\n' : ' ');
        }

        ColorfulNumbers c = new ColorfulNumbers();

        System.out.printf("\n\nLargest colorful number: %,d\n", c.largest);

        System.out.printf("\nCount of colorful numbers by number of digits:\n");
        int total = 0;
        for (int d = 0; d < 8; ++d) {
            System.out.printf("%d   %,d\n", d + 1, c.count[d]);
            total += c.count[d];
        }
        System.out.printf("\nTotal: %,d\n", total);
    }

    private ColorfulNumbers() {
        countColorful(0, 0, 0);
    }

    public static boolean isColorful(int n) {
        // A colorful number cannot be greater than 98765432.
        if (n < 0 || n > 98765432)
            return false;
        int digit_count[] = new int[10];
        int digits[] = new int[8];
        int num_digits = 0;
        for (int m = n; m > 0; m /= 10) {
            int d = m % 10;
            if (n > 9 && (d == 0 || d == 1))
                return false;
            if (++digit_count[d] > 1)
                return false;
            digits[num_digits++] = d;
        }
        // Maximum number of products is (8 x 9) / 2.
        int products[] = new int[36];
        for (int i = 0, product_count = 0; i < num_digits; ++i) {
            for (int j = i, p = 1; j < num_digits; ++j) {
                p *= digits[j];
                for (int k = 0; k < product_count; ++k) {
                    if (products[k] == p)
                        return false;
                }
                products[product_count++] = p;
            }
        }
        return true;
    }

    private void countColorful(int taken, int n, int digits) {
        if (taken == 0) {
            for (int d = 0; d < 10; ++d) {
                used[d] = true;
                countColorful(d < 2 ? 9 : 1, d, 1);
                used[d] = false;
            }
        } else {
            if (isColorful(n)) {
                ++count[digits - 1];
                if (n > largest)
                    largest = n;
            }
            if (taken < 9) {
                for (int d = 2; d < 10; ++d) {
                    if (!used[d]) {
                        used[d] = true;
                        countColorful(taken + 1, n * 10 + d, digits + 1);
                        used[d] = false;
                    }
                }
            }
        }
    }
}
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 colorful number: 98,746,253

Count of colorful numbers by number of digits:
1   10
2   56
3   328
4   1,540
5   5,514
6   13,956
7   21,596
8   14,256

Total: 57,256

jq

Generic Utility Functions

# Uncomment for gojq
# def _nwise($n):
#   def n: if length <= $n then . else .[0:$n] , (.[$n:] | n) end;
#   n;

def lpad($len): tostring | ($len - length) as $l | (" " * $l)[:$l] + .;

# Generate a stream of the permutations of the input array.
def permutations:
  if length == 0 then []
  else
    range(0;length) as $i
    | [.[$i]] + (del(.[$i])|permutations) 
  end ;

Colorful Numbers

def isColorful:
  def digits: [tostring | explode[] | [.] | implode | tonumber];

  if . < 0 then false
  elif . < 10 then true
  else . as $n
  | digits as $digits
  | if any($digits[]; . == 0 or . == 1) then false
    else ($digits|unique) as $set
    | ($digits|length) as $dc
    | if ($set|length) < $dc then false
      else label $out
      | foreach range(2; $dc) as $k ({$set}; 
          foreach range(0; $dc-$k+1) as $i (.;
            (reduce range($i; $i+$k) as $j (1; . *  $digits[$j])) as $prod
            | if .set|index($prod) then .return = 0, break $out   
              else .set += [$prod]
	      end ;
	    . );
	  select(.return) ) // null
      | if .return == 0 then false else true end
      end
    end
  end;

# Emit a stream of colorfuls in range(a;b)
def colorfuls(a;b):
  range(a;b) | select(isColorful);

The Tasks

def task($n):
  [colorfuls(0; $n)]
  | "The \(length) colorful numbers less than \($n) are:",
    (_nwise($10) | map(lpad(4)) | join(" ")) ;

def largestColorful:
  [[range(2;10)] | permutations | join("") | tonumber | select(isColorful)] | max;

# Emit a JSON object giving the counts by number of digits
def classifyColorful:
  def nonTrivialCandidates:
    [range(2; 10)]
    | range(1; 9) as $length
    | combinations($length) 
    | join("")
    | tonumber;
  reduce (0,1,nonTrivialCandidates) as $i ({};
     if $i|isColorful
     then .[$i|tostring|length|tostring] += 1
     else .
     end);
     
task(100),
"",
"The largest possible colorful number is \(largestColorful)."
"",
"The counts of colorful numbers by number of digits are:",
(classifyColorful
 | (., "\nTotal: \([.[]]|add)"))

Invocation: jq -ncr -f colorful.jq

Output:
The 66 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 98746253.

The counts of colorful numbers by number of digits are:
{"1":10,"2":56,"3":328,"4":1540,"5":5514,"6":13956,"7":21596,"8":14256}

Total: 57256

Julia

largest = 0

function iscolorful(n, base=10)
    0 <= n < 10 && return true
    dig = digits(n, base=base)
    (1 in dig || 0 in dig || !allunique(dig)) && return false
    products = Set(dig)
    for i in 2:length(dig), j in 1:length(dig)-i+1
        p = prod(dig[j:j+i-1])
        p in products && return false
        push!(products, p)
    end
    if n > largest
        global largest = n
    end
    return true
end
 
function testcolorfuls()
    println("Colorful numbers for 1:25, 26:50, 51:75, and 76:100:")
    for i in 1:100
        iscolorful(i) && print(rpad(i, 5))
        i % 25 == 0 && println()
    end
    csum = 0
    for i in 0:7
        j, k = i == 0 ? 0 : 10^i, 10^(i+1) - 1
        n = count(i -> iscolorful(i), j:k)
        csum += n
        println("The count of colorful numbers between $j and $k is $n.")
    end
    println("The largest possible colorful number is $largest.")
    println("The total number of colorful numbers is $csum.")
end
 
testcolorfuls()
Output:
Colorful numbers for 1:25, 26:50, 51:75, and 76:100:
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 count of colorful numbers between 0 and 9 is 10.
The count of colorful numbers between 10 and 99 is 56.
The count of colorful numbers between 100 and 999 is 328.
The count of colorful numbers between 1000 and 9999 is 1540.
The count of colorful numbers between 10000 and 99999 is 5514.
The count of colorful numbers between 100000 and 999999 is 13956.
The count of colorful numbers between 1000000 and 9999999 is 21596.
The count of colorful numbers between 10000000 and 99999999 is 14256.
The largest possible colorful number is 98746253.
The total number of colorful numbers is 57256.

Mathematica /Wolfram Language

ClearAll[ColorfulNumberQ]
ColorfulNumberQ[n_Integer?NonNegative] := Module[{digs, parts},
  If[n > 98765432,
   False
   ,
   digs = IntegerDigits[n];
   parts = Partition[digs, #, 1] & /@ Range[1, Length[digs]];
   parts //= Catenate;
   parts = Times @@@ parts;
   DuplicateFreeQ[parts]
   ]
  ]
Multicolumn[Select[Range[99], ColorfulNumberQ], Appearance -> "Horizontal"]

sel = Union[FromDigits /@ Catenate[Permutations /@ Subsets[Range[2, 9], {1, \[Infinity]}]]];
sel = Join[sel, {0, 1}];
cns = Select[sel, ColorfulNumberQ];

Max[cns]

Tally[IntegerDigits/*Length /@ cns] // Grid

Length[cns]
Output:
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							

98746253

1	10
2	56
3	328
4	1540
5	5514
6	13956
7	21596
8	14256

57256

Nim

Translation of: Python
import std/[math, intsets, strformat]

func digits(n: Natural): seq[int] =
  ## Return the digits of "n" in reverse order.
  var n = n
  while true:
    result.add n mod 10
    n = n div 10
    if n == 0: break

var largest = 0

proc isColorful(n: Natural): bool =
  ## Return true if "n" is colorful.
  if n in 0..9: return true
  let digSeq = n.digits
  var digSet: set[0..9]
  for d in digSeq:
    if d <= 1 or d in digSet:
      return false
    digSet.incl d
  var products = digSeq.toIntSet()
  for i in 0..<digSeq.high:
    for j in (i + 1)..digSeq.high:
      let p = prod(digSeq.toOpenArray(i, j))
      if p in products:
        return false
      products.incl p
  if n > largest: largest = n
  result = true

echo "Colorful numbers for 1:25, 26:50, 51:75, and 76:100:"
for i in countup(1, 100, 25):
  for j in 0..24:
    if isColorful(i + j):
      stdout.write &"{i + j: 5}"
  echo()

echo()
var csum = 0
for i in 0..7:
  let j = if i == 0: 0 else: 10^i
  let k = 10^(i+1) - 1
  var n = 0
  for x in j..k:
    if x.isColorful: inc n
  inc csum, n
  echo &"The count of colorful numbers between {j} and {k} is {n}."

echo()
echo &"The largest possible colorful number is {largest}."
echo &"The total number of colorful numbers is {csum}."
Output:
Colorful numbers for 1:25, 26:50, 51:75, and 76:100:
    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 count of colorful numbers between 0 and 9 is 10.
The count of colorful numbers between 10 and 99 is 56.
The count of colorful numbers between 100 and 999 is 328.
The count of colorful numbers between 1000 and 9999 is 1540.
The count of colorful numbers between 10000 and 99999 is 5514.
The count of colorful numbers between 100000 and 999999 is 13956.
The count of colorful numbers between 1000000 and 9999999 is 21596.
The count of colorful numbers between 10000000 and 99999999 is 14256.

The largest possible colorful number is 98746253.
The total number of colorful numbers is 57256.

Pascal

Free Pascal

I've created a lexical permutation of [2,3,4,5,6,7,8,9] which results in 40320 arrangements.
So 0,1 are missing. The test of 3 digits is simple a test of the first three digits of these arrangments every delta = (8-3)! = 120 (for one digit = (8-1)! = 5040 ).
At home, the C-Version compiled with -Ofast is still faster with best 15.03 ms vs 18ms of my version
But such short timings differ extrem from run to run.

{$IFDEF FPC}
  {$mode Delphi}
  {$Optimization ON,All}
  {$Coperators ON}
{$ENDIF}
{$IFDEF WINDOWS}
  {$APPTYPE CONSOLE}
{$ENDIF}
uses
  sysutils;
const
  EightFak = 1*2*3*4*5*6*7*8;  
type
  tDgt  = Int8;
  tpDgt = pInt8;  
  tDgtfield = array[0..7] of tdgt;
  tpDgtfield = ^tDgtfield;
  
  tPermfield  =  tDgtfield;
  tAllPermDigits = array[0..EightFak] of tDgtfield;
  tMarkNotColorful = array[0..EightFak-1] of byte;

  tDat = Uint32;
  tusedMultiples = array[0..8*9 DIV 2-2] of tDat;
  
var
  AllPermDigits :tAllPermDigits;
  MarkNotColorful:tMarkNotColorful;
  permcnt,
  totalCntColorFul,CntColorFul : Int32;

procedure PermLex(n: Int32;StartVal:Int8);
var
  Perm : tPermField;
  k,j : Int32;
  temp: tDgt;
  pDat :tpDgt;
begin
  For j := 0 to n-1 do
    Perm[j]:= j+StartVal; 
    
  permcnt := 0;
  dec(n);
  repeat
    AllPermDigits[permcnt] := Perm;  
    inc(permcnt);
    k :=  N-1;
    pDat := @Perm[k];
    while (pDat[0]> pDat[1])  And (k >=Low(Perm) ) do
    begin
      dec(pDat);
      dec(k);
    end;

    if k >= Low(Perm)  then
    begin
      j := N;
      pDat := @Perm[j];
      temp := Perm[k];
      while (temp > pDat[0]) And (J >K) do
      begin
        dec(j);
        dec(pDat);
      end;

      Perm[k] := pDat[0];
      pDat[0] := temp;
      j := N; 
      pDat := @Perm[j];
      Inc(k); 

      while j>k do
      begin
        temp := pDat[0];
        pDat[0] := Perm[k];
        Perm[k] := temp;

        dec(j);
        dec(pDat);
        inc(k);
      end;
    end
    else
      break;
  until false;
end;

procedure OutNum(const num:tPermfield;dgtCnt: Int32);
var
  i : integer;
Begin
  For i := 0 to dgtcnt-1 do
    write(num[i]);
  writeln;
end;

function isAlreadyExisting(var uM :tusedMultiples; maxIdx : Int32;dat :tDat):boolean;
var
  I : Int32;
begin
  if maxIdx >= 0 then
  begin
    i := maxIdx;  
    repeat
      if dat = uM[i] then
        EXIT(true);
      Dec(i);
    until i <0;
  end;  
  uM[maxIdx+1]:= dat;
  result := false;
end;

function CalcValue(pDgtfield : tpDgtfield;TestDgtCnt:Int32):int32;
begin
  result :=  1;
  repeat
     result *=pDgtfield[TestDgtCnt];
     dec(TestDgtCnt);
   until TestDgtCnt <0;
end;    
 
function isCheckColorful(dgtCnt: NativeInt;idx:Int32):boolean;
var
  usedMultiples : tusedMultiples;
  pDgtfield : ^tDgtfield;
  TestDgtCnt,StartIdx,value,maxIdx : Int32;
begin
  //needn't to test product of all digits.It's a singular max value
  dec(dgtCnt);        
  pDgtfield := @AllPermDigits[idx];
  maxIdx := -1;

 //multiples of TestDgtCnt digits next to one another
  For TestDgtCnt := 0 to dgtCnt do
  begin
    For StartIdx := 0 to dgtCnt-TestDgtCnt do
    begin
      value := CalcValue(@pDgtfield[StartIdx],TestDgtCnt);
//      value := 1;      For l := 0 to TestDgtCnt do        value *=pDgtfield[StartIdx+l];
      if isAlreadyExisting(usedMultiples,maxIdx,value) then
        EXIT(false);
      inc(MaxIdx);
    end;
  end;
  inc(totalCntColorFul);
  inc(CntColorFul);
  result := true;
end;

procedure CheckDgtCnt(dgtCnt,delta:Int32);
var
  i,j : int32;
begin
  i := 0;
  CntColorFul := 0;
  if dgtCnt = 1 then
     CntColorFul := 2;//0,1

  if delta = 1 then 
  begin
    For i := i to EightFak-1  do
      IF (MarkNotColorful[i]=0) AND not isCheckColorful(dgtCnt,i)then
        MarkNotColorful[i] := dgtcnt;
  end
  else
  Begin 
    if dgtcnt<3 then    
    //always colorful
    begin
      repeat
        isCheckColorful(dgtCnt,i);
        inc(i,delta);      
      until i>EightFak-1;
    end
    else
    begin      
      repeat
        IF (MarkNotColorful[i]=0) AND not isCheckColorful(dgtCnt,i) then
        begin
          //mark a range as not colorful 
          j := i+delta-1;
          repeat
            MarkNotColorful[j] := dgtcnt;
            dec(j);
          until j < i;  
        end;  
        inc(i,delta);      
      until i>EightFak-1;
    end;
  end;
end;

var
  T0 : Int64;
  i,j,delta: INteger;
Begin
  T0 := GetTickCount64;
  PermLex(8,2);
  //takes ~1 ms til here
  delta := 15;
  writeln('First colorful numbers less than 100'); 
  For i := 0 to 9 do
  Begin
    write(i:4);
    dec(delta);
  end;  
  For i := 2 to 9 do
    For j := 2 to 9 do 
      if j<> i then
      begin
        //write(i:3,j);
        dec(delta);
        if delta = 0 then
        begin
          delta:= 15;
          Writeln;
        end;   
      end;   
  writeln;
  writeln;  
  Writeln('    digits     count of colorful numbers');  
  totalCntColorFul := 2;//0,1,
  delta := EightFak-1;  
  delta := (delta+1) DIV 8;
  j := 7;
  repeat
    CheckDgtCnt(8-j,delta);
    writeln(8-j:10,CntColorFul:10);
    if j = 0 then
      BREAK;
    delta := delta DIV j;
    dec(j);
  until false;
  Writeln;
  Writeln('Total number of colorful numbers: ',totalCntColorFul);
  Write('Highest Value :');
  For i := High(AllPermDigits) downto low(AllPermDigits) do
    if MarkNotColorful[i] = 0 then
    Begin
      OutNum(AllPermDigits[i],8); 
      BREAK;
    end;  

  Writeln('Runtime in ms ',GetTickCount64-T0);
end.
@TIO.RUN:
First 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

    digits     count of colorful numbers
         1        10
         2        56
         3       328
         4      1540
         5      5514
         6     13956
         7     21596
         8     14256

Total number of colorful numbers: 57256
Highest Value :98746253

Runtime in ms 38 (= best TIO.Run up to 51 ms )
Runtime in ms 18 (= best up to 27 ms @home )

Perl

Translation of: Raku
use strict;
use warnings;
use feature 'say';
use enum qw(False True);
use List::Util <max uniqint product>;
use Algorithm::Combinatorics qw(combinations permutations);

sub table { my $t = shift() * (my $c = 1 + length max @_); ( sprintf( ('%'.$c.'d')x@_, @_) ) =~ s/.{1,$t}\K/\n/gr }

sub is_colorful {
    my($n) = @_;
    return True if 0 <= $n and $n <= 9;
    return False if $n =~ /0|1/ or $n < 0;
    my @digits = split '', $n;
    return False unless @digits == uniqint @digits;
    my @p;
    for my $w (0 .. @digits) {
        push @p, map { product @digits[$_ .. $_+$w] } 0 .. @digits-$w-1;
        return False unless @p == uniqint @p
    }
    True
}

say "Colorful numbers less than 100:\n" . table 10, grep { is_colorful $_ } 0..100;

my $largest = 98765432;
1 while not is_colorful --$largest;
say "Largest magnitude colorful number: $largest\n";

my $total= 10;
map { is_colorful(join '', @$_) and $total++ } map { permutations $_ } combinations [2..9], $_ for 2..8;
say "Total colorful numbers: $total";
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

Total colorful numbers: 57256

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"

Picat

colorful_number(N) =>
  N < 10 ;
  (X = N.to_string,
   X.len <= 8,
   not membchk('0',X),
   not membchk('1',X),
   distinct(X),
   [prod(S.map(to_int)) : S in  findall(S,(append(_,S,_,X),S != [])) ].distinct).

distinct(L) =>
  L.len == L.remove_dups.len.

All colorful numbers <= 100.

main =>
  Colorful = [N : N in 0..100, colorful_number(N)],
  Len = Colorful.len,
  foreach({C,I} in zip(Colorful,1..Len))
    printf("%2d%s",C, cond(I mod 10 == 0, "\n"," "))
  end,
  nl,
  println(len=Len)
Output:
 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 
len = 66

Largest colorful number.

main =>
  N = 98765431,
  Found = false,
  while (Found == false)
    if colorful_number(N) then
      println(N),
      Found := true
    end,
    N := N - 1
  end.
Output:
98746253

Count of colorful numbers in each magnitude and of total colorful numbers.

main =>
  TotalC = 0,
  foreach(I in 1..8)
    C = 0,
    printf("Digits %d: ", I),
    foreach(N in lb(I)..ub(I))
      if colorful_number(N) then
        C := C + 1
      end
    end,
    println(C),
    TotalC := TotalC + C
  end,
  println(total=TotalC),
  nl.

% Lower and upper bounds.
% For N=3: lb=123 and ub=987
lb(N) = cond(N < 2, 0, [I.to_string : I in 1..N].join('').to_int).
ub(N) = [I.to_string : I in 9..-1..9-N+1].join('').to_int.
Output:
Digits 1: 10
Digits 2: 56
Digits 3: 328
Digits 4: 1540
Digits 5: 5514
Digits 6: 13956
Digits 7: 21596
Digits 8: 14256
total = 57256

Python

from math import prod

largest = [0]

def iscolorful(n):
    if 0 <= n < 10:
        return True
    dig = [int(c) for c in str(n)]
    if 1 in dig or 0 in dig or len(dig) > len(set(dig)):
        return False
    products = list(set(dig))
    for i in range(len(dig)):
        for j in range(i+2, len(dig)+1):
            p = prod(dig[i:j])
            if p in products:
                return False
            products.append(p)

    largest[0] = max(n, largest[0])
    return True

print('Colorful numbers for 1:25, 26:50, 51:75, and 76:100:')
for i in range(1, 101, 25):
    for j in range(25):
        if iscolorful(i + j):
            print(f'{i + j: 5,}', end='')
    print()

csum = 0
for i in range(8):
    j = 0 if i == 0 else 10**i
    k = 10**(i+1) - 1
    n = sum(iscolorful(x) for x in range(j, k+1))
    csum += n
    print(f'The count of colorful numbers between {j} and {k} is {n}.')

print(f'The largest possible colorful number is {largest[0]}.')
print(f'The total number of colorful numbers is {csum}.')
Output:
Colorful numbers for 1:25, 26:50, 51:75, and 76:100:
    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 count of colorful numbers between 0 and 9 is 10.
The count of colorful numbers between 10 and 99 is 56.
The count of colorful numbers between 100 and 999 is 328.
The count of colorful numbers between 1000 and 9999 is 1540.
The count of colorful numbers between 10000 and 99999 is 5514.
The count of colorful numbers between 100000 and 999999 is 13956.
The count of colorful numbers between 1000000 and 9999999 is 21596.
The count of colorful numbers between 10000000 and 99999999 is 14256.
The largest possible colorful number is 98746253.
The total number of colorful numbers is 57256.

Raku

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).hyper.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}).hyper.grep( &is-colorful ),
   " - {($c / (exp($_,10) - exp($_-1,10) ) * 100).round(.001)}%";
   $total += $c;
}

say "\nTotal colorful numbers: $total";
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

RPL

We have assumed that the largest colored number has 8 digits. This means we only need to check the permutations of 98765432. Brute force is here used, generating these permutations - and many other numbers - through decrementation by 9. Before testing the colorfulness, the sum of the digits of the generated number is compared to that of 98765432. This improves execution time a little bit.

If the search had been unsuccessful, we would have tested the different possibilities of 7-digit pandigital numbers - but luckily it was not necessary.

Works with: HP version 48G
RPL code Comment
 ≪ →STR DUP SIZE → num dig
 ≪ CASE
       dig 1 == THEN 1 END
       num "0" POS num "1" POS OR THEN 0 END
       1 SF 
       { } 1 dig FOR j num j DUP SUB STR→ + NEXT 
       DUP SORT ΔLIST 1 + ΠLIST NOT THEN DROP 0 END
       DUP 
       1 dig 1 - FOR k
          1 dig k - FOR c
             OVER c DUP k + SUB ΠLIST
             IF DUP2 POS 
             THEN DROP 1 CF dig DUP 'c' STO 'k' STO
             ELSE + END
       NEXT NEXT  
       DROP2 1 FS? END
≫ ≫ 'COLOR?' STO
COLOR? ( num  → boolean ) 

if num has only 1 digit then return true
if num contains 0 or 1 then return false
color = true
convert n into a list of digits
if 2 digits are identical then return false
list of products = list of digits
  for k = 1 to ndig-1
    for c = 1 to ndig-k
      p = digit[c]*..*digit[c+k]
      if p in list of products
      then color = false, exit loops
      else append p to list of products
  end loops
  clean stack, return color

≪ →STR 0 
  1 3 PICK SIZE FOR j 
     OVER j DUP SUB NUM + 
  NEXT SWAP DROP
≫ 'DSTAMP' STO

≪ { }
   1 100 FOR j IF j COLOR? THEN + END NEXT
   98765432 DUP DSTAMP SWAP
   WHILE DUP COLOR? NOT REPEAT
      DO 9 - UNTIL DUP2 DSTAMP == END
   END SWAP DROP
≫ 'TASK' STO
Output:
2: { 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 }
1: 98746253

Largest colorful number found in 10 minutes 22 seconds on a HP-48G.


Ruby

All colorful candidates larger than 1 digit must be a permutation of digits [2,3,4,5,6,7,8,9], so test only those:

def colorful?(ar)
  products = []
  (1..ar.size).all? do |chunk_size|
    ar.each_cons(chunk_size) do |chunk|
      product = chunk.inject(&:*)
      return false if products.include?(product)
      products << product
    end
  end
end

below100 = (0..100).select{|n| colorful?(n.digits)}
puts "The colorful numbers less than 100 are:", below100.join(" "), ""
puts "Largest colorful number: #{(98765432.downto(1).detect{|n| colorful?(n.digits) })}", ""

total = 0
(1..8).each do |numdigs|
   digits = (numdigs == 1 ? (0..9).to_a : (2..9).to_a)
   count  = digits.permutation(numdigs).count{|perm| colorful?(perm)}
   puts "#{numdigs} digit colorful numbers count: #{count}"
   total += count
end

puts "\nTotal colorful numbers: #{total}"
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

Largest colorful number: 98746253

1 digit colorful numbers count: 10
2 digit colorful numbers count: 56
3 digit colorful numbers count: 328
4 digit colorful numbers count: 1540
5 digit colorful numbers count: 5514
6 digit colorful numbers count: 13956
7 digit colorful numbers count: 21596
8 digit colorful numbers count: 14256

Total colorful numbers: 57256

Rust

use core::cmp::max;
use std::collections::HashSet;

fn to_digits(mut n: u64, base: u64) -> Vec<u64> {
    if n == 0 {
        return [0].to_vec();
    }
    let mut v: Vec<u64> = Vec::new();
    while n > 0 {
        let d = n % base;
        n /= base;
        v.push(d);
    }
    return v;
}

fn is_colorful(n: u64) -> bool {
    if &n > &9 {
        let dig: Vec<u64> = to_digits(n, 10);
        if dig.contains(&1) || dig.contains(&0) {
            return false;
        }
        let mut products: HashSet<u64> = HashSet::new();
        for i in 0..dig.len() {
            if products.contains(&dig[i]) {
                return false;
            }
            products.insert(dig[i]);
        }
        for i in 0..dig.len() {
            for j in i+2..dig.len()+1 {
                let p: u64 = (dig[i..j]).iter().product();
                if products.contains(&p) {
                    return false;
                }
                products.insert(p);
            }
        }
    }
    return true;
}

fn main() {
    println!("Colorful numbers for 1:25, 26:50, 51:75, and 76:100:");
    for i in (1..101).step_by(25) {
        for j in 0..25 {
            if is_colorful(i + j) {
                print!("{:5}", i + j);
            }
        }
        println!();
    }
    println!();

    let mut csum: u64 = 0;
    let mut largest: u64 = 0;
    let mut n: u64;
    for i in 0..8 {
        let j: u64 = { if i == 0 { 0 } else { 10_u64.pow(i) } }; 
        let k: u64 = 10_u64.pow(i + 1) - 1;
        n = 0;
        for x in j..k+1 {
            if is_colorful(x) {
                largest = max(largest, x);
                n += 1;
            }
        }
        println!("The count of colorful numbers within the interval [{j}, {k}] is {n}.");
        csum += n;
    }
    println!("The largest possible colorful number is {largest}.");
    println!("The total number of colorful numbers is {csum}.")
}
Output:
Colorful numbers for 1:25, 26:50, 51:75, and 76:100:
    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 count of colorful numbers within the interval [0, 9] is 10.
The count of colorful numbers within the interval [10, 99] is 56.
The count of colorful numbers within the interval [100, 999] is 328.
The count of colorful numbers within the interval [1000, 9999] is 1540.
The count of colorful numbers within the interval [10000, 99999] is 5514.
The count of colorful numbers within the interval [100000, 999999] is 13956.
The count of colorful numbers within the interval [1000000, 9999999] is 21596.
The largest possible colorful number is 98746253.
The total number of colorful numbers is 57256.

Uiua

# A colourful number has unique products for all subsequences.

IsC₀ ← (
  ≡(□↙)+1⇡⧻⟜¤      # Stringify and find all starts.
  ≡⍚(≡(/×≡⋕↘)⇡⧻⟜¤) # Find all subsequences and /× them.
  =∩⧻⟜◴/◇⊂         # Flatten list, check for dups.
)
IsCand ← ¬/↥[⊃(∊@0|∊@1|≠∩⧻⟜◴)] # Exclude obvious fails.
IsC ← ⨬(0|IsC₀)IsCand.°⋕
&p$"Colourful numbers below 100:\n_"▽⊸≡IsC+1⇡100
&p$"Highest possible colourful number: _"⍢(-1|¬IsC)/(+×10)↙8⇌⇡10
Output:
Colourful numbers below 100:
[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]
Highest colourful number: 98746253

Wren

Translation of: Phix
Library: Wren-math
Library: Wren-set
Library: Wren-fmt
import "./math" for Int, Nums
import "./set" for Set
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
}

var count = List.filled(9, 0)
var used  = List.filled(11, false)
var largest = 0

var countColorful // recursive
countColorful = Fn.new { |taken, n|
    if (taken == 0) {
        for (digit in 0..9) {
            var dx = digit + 1
            used[dx] = true
            countColorful.call((digit < 2) ? 9 : 1, String.fromByte(digit + 48))
            used[dx] = false
        }
    } else {
        var nn = Num.fromString(n)
        if (isColorful.call(nn)) {
            var ln = n.count
            count[ln] = count[ln] + 1
            if (nn > largest) largest = nn
        }
        if (taken < 9) {
            for (digit in 2..9) {
                var dx = digit + 1
                if (!used[dx]) {
                    used[dx] = true
                    countColorful.call(taken + 1, n + String.fromByte(digit + 48))
                    used[dx] = false
                }
            }
        }
    }
}

var cn = (0..99).where { |i| isColorful.call(i) }.toList
System.print("The %(cn.count) colorful numbers less than 100 are:")
Fmt.tprint("$2d", cn, 10)

countColorful.call(0, "")
System.print("\nThe largest possible colorful number is:")
Fmt.print("$,d\n", largest)

System.print("Count of colorful numbers for each order of magnitude:")
var pow = 10
for (dc in 1...count.count) {
    Fmt.print("  $d digit colorful number count: $,6d - $7.3f\%", dc, count[dc], 100 * count[dc] / pow)
    pow = (pow == 10) ? 90 : pow * 10
}

Fmt.print("\nTotal colorful numbers: $,d", Nums.sum(count))
Output:
The 66 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

XPL0

func IPow(A, B);        \A^B
int  A, B, T, I;
[T:= 1;
for I:= 1 to B do T:= T*A;
return T;
];

func Colorful(N);       \Return 'true' if N is a colorful number
int  N, Digits, R, I, J, Prod;
def  Size = 9*8*7*6*5*4*3*2 + 1;
char Used(Size), Num(10);
[if N < 10 then return true;    \single digit number is colorful
FillMem(Used, false, 10);       \digits must be unique
Digits:= 0;
repeat  N:= N/10;               \slice digits off N
        R:= rem(0);
        if N=1 or R=0 or R=1 then return false;
        if Used(R) then return false;
        Used(R):= true;         \digits must be unique
        Num(Digits):= R;
        Digits:= Digits+1;
until   N = 0;
FillMem(Used+10, false, Size-10); \products must be unique
for I:= 0 to Digits-2 do
    [Prod:= Num(I);
    for J:= I+1 to Digits-1 do
        [Prod:= Prod * Num(J);
        if Used(Prod) then return false;
        Used(Prod):= true;
        ];
    ];
return true;
];

int Count, N, Power, Total;
[Text(0, "Colorful numbers less than 100:
");
Count:= 0;
for N:= 0 to 99 do
    if Colorful(N) then
        [IntOut(0, N);
        Count:= Count+1;
        if rem(Count/10) then ChOut(0, 9\tab\) else CrLf(0);
        ];
Text(0, "

Largest magnitude colorful number: ");
N:= 98_765_432;
loop    [if Colorful(N) then quit;
        N:= N-1;
        ];
IntOut(0, N);
Text(0, "

Count of colorful numbers for each order of magnitude:
");
Total:= 0;
for Power:= 1 to 8 do
    [Count:= if Power=1 then 1 else 0;
    for N:= IPow(10, Power-1) to IPow(10, Power)-1 do
        if Colorful(N) then Count:= Count+1;
    IntOut(0, Power);
    Text(0, " digit colorful number count: ");
    IntOut(0, Count);
    CrLf(0);
    Total:= Total + Count;
    ];
Text(0, "
Total colorful numbers: ");
IntOut(0, Total);
CrLf(0);
]
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
2 digit colorful number count: 56
3 digit colorful number count: 328
4 digit colorful number count: 1540
5 digit colorful number count: 5514
6 digit colorful number count: 13956
7 digit colorful number count: 21596
8 digit colorful number count: 14256

Total colorful numbers: 57256