Task: Humble numbers





Java: import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class HumbleNumbers {

    public static void main(String[] args) {
        System.out.println("First 50 humble numbers:");
        System.out.println(Arrays.toString(humble(50)));
        Map<Integer,Integer> lengthCountMap = new HashMap<>();
        BigInteger[] seq = humble(1_000_000);
        for ( int i = 0 ; i < seq.length ; i++ ) {
            BigInteger humbleNumber = seq[i];
            int len = humbleNumber.toString().length();
            lengthCountMap.merge(len, 1, (v1, v2) -> v1 + v2);
        }
        List<Integer> sorted = new ArrayList<>(lengthCountMap.keySet());
        Collections.sort(sorted);
        System.out.printf("Length  Count%n");
        for ( Integer len : sorted ) {
            System.out.printf("    %2s  %5s%n", len, lengthCountMap.get(len));
        }
    }
    
    private static BigInteger[] humble(int n) {
        BigInteger two = BigInteger.valueOf(2);
        BigInteger twoTest = two;
        BigInteger three = BigInteger.valueOf(3);
        BigInteger threeTest = three;
        BigInteger five = BigInteger.valueOf(5);
        BigInteger fiveTest = five;
        BigInteger seven = BigInteger.valueOf(7);
        BigInteger sevenTest = seven;
        BigInteger[] results = new BigInteger[n];
        results[0] = BigInteger.ONE;
        int twoIndex = 0, threeIndex = 0, fiveIndex = 0, sevenIndex = 0;
        for ( int index = 1 ; index < n ; index++ ) {
            results[index] = twoTest.min(threeTest).min(fiveTest).min(sevenTest);
            if ( results[index].compareTo(twoTest) == 0 ) {
                twoIndex++;
                twoTest = two.multiply(results[twoIndex]);
            }
            if (results[index].compareTo(threeTest) == 0 ) {
                threeIndex++;
                threeTest = three.multiply(results[threeIndex]);
            }
            if (results[index].compareTo(fiveTest) == 0 ) {
                fiveIndex++;
                fiveTest = five.multiply(results[fiveIndex]);
            }
            if (results[index].compareTo(sevenTest) == 0 ) {
                sevenIndex++;
                sevenTest = seven.multiply(results[sevenIndex]);
            }
        }
        return results;
    }

}







Ada: with Ada.Text_IO;

procedure Show_Humble is

   type Positive is range 1 .. 2**63 - 1;
   First : constant Positive := Positive'First;
   Last  : constant Positive := 999_999_999;

   function Is_Humble (I : in Positive) return Boolean is
   begin
      if    I <= 1      then  return True;
      elsif I mod 2 = 0 then  return Is_Humble (I / 2);
      elsif I mod 3 = 0 then  return Is_Humble (I / 3);
      elsif I mod 5 = 0 then  return Is_Humble (I / 5);
      elsif I mod 7 = 0 then  return Is_Humble (I / 7);
      else                    return False;
      end if;
   end Is_Humble;

   subtype Digit_Range is Natural range First'Image'Length - 1 .. Last'Image'Length - 1;
   Digit_Count  : array (Digit_Range) of Natural := (others => 0);

   procedure Count_Humble_Digits is
      use Ada.Text_IO;
      Humble_Count : Natural := 0;
      Len : Natural;
   begin
      Put_Line ("The first 50 humble numbers:");
      for N in First .. Last loop
         if Is_Humble (N) then
            Len := N'Image'Length - 1;
            Digit_Count (Len) := Digit_Count (Len) + 1;

            if Humble_Count < 50 then
               Put (N'Image);
               Put (" ");
            end if;
            Humble_Count := Humble_Count + 1;
         end if;
      end loop;
      New_Line (2);
   end Count_Humble_Digits;

   procedure Show_Digit_Counts is
      package Natural_IO is
         new Ada.Text_IO.Integer_IO (Natural);
      use Ada.Text_IO;
      use Natural_IO;

      Placeholder : String := "Digits Count";
      Image_Digit : String renames Placeholder (1 .. 6);
      Image_Count : String renames Placeholder (8 .. Placeholder'Last);
   begin
      Put_Line ("The digit counts of humble numbers:");
      Put_Line (Placeholder);
      for Digit in Digit_Count'Range loop
         Put (Image_Digit, Digit);
         Put (Image_Count, Digit_Count (Digit));
         Put_Line (Placeholder);
      end loop;
   end Show_Digit_Counts;

begin
   Count_Humble_Digits;
   Show_Digit_Counts;
end Show_Humble;