Sequence: smallest number with exactly n divisors

From Rosetta Code
Revision as of 19:20, 11 April 2019 by rosettacode>Craigd (→‎{{header|zkl}}: added code)
Sequence: smallest number with exactly n divisors 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.

Calculate the sequence where each term an is the smallest natural number that has exactly n divisors.

Task

Show here, on this page, at least the first 15 terms of the sequence.

See also
Related tasks

C

Translation of: Go

<lang c>#include <stdio.h>

  1. define MAX 15

int count_divisors(int n) {

   int i, count = 0;
   for (i = 1; i * i <= n; ++i) {
       if (!(n % i)) {
           if (i == n / i)
               count++;
           else
               count += 2;
       }
   }
   return count;

}

int main() {

   int i, k, n, seq[MAX];
   for (i = 0; i < MAX; ++i) seq[i] = 0;
   printf("The first %d terms of the sequence are:\n", MAX);
   for (i = 1, n = 0; n <  MAX; ++i) {
       k = count_divisors(i);
       if (k <= MAX && seq[k - 1] == 0) {
           seq[k - 1] = i;
           ++n;
       }
   }
   for (i = 0; i < MAX; ++i) printf("%d ", seq[i]);
   printf("\n");
   return 0;

}</lang>

Output:
The first 15 terms of the sequence are:
1 2 4 6 16 12 64 24 36 48 1024 60 4096 192 144 

C++

Translation of: C

<lang cpp>#include <iostream>

  1. define MAX 15

using namespace std;

int count_divisors(int n) {

   int count = 0;
   for (int i = 1; i * i <= n; ++i) {
       if (!(n % i)) {
           if (i == n / i)
               count++;
           else
               count += 2;
       }
   }
   return count;

}

int main() {

   int i, k, n, seq[MAX];
   for (i = 0; i < MAX; ++i) seq[i] = 0;
   cout << "The first " << MAX << " terms of the sequence are:" << endl;
   for (i = 1, n = 0; n <  MAX; ++i) {
       k = count_divisors(i);
       if (k <= MAX && seq[k - 1] == 0) {
           seq[k - 1] = i;
           ++n;
       }
   }
   for (i = 0; i < MAX; ++i) cout << seq[i] << " ";
   cout << endl;
   return 0;

}</lang>

Output:
The first 15 terms of the sequence are:
1 2 4 6 16 12 64 24 36 48 1024 60 0 192 144 

Go

<lang go>package main

import "fmt"

func countDivisors(n int) int {

   count := 0
   for i := 1; i*i <= n; i++ {
       if n%i == 0 {
           if i == n/i {
               count++
           } else {
               count += 2
           }
       }
   }
   return count

}

func main() {

   const max = 15
   seq := make([]int, max)
   fmt.Println("The first", max, "terms of the sequence are:")
   for i, n := 1, 0; n < max; i++ {
       if k := countDivisors(i); k <= max && seq[k-1] == 0 {
           seq[k-1] = i
           n++
       }
   }
   fmt.Println(seq)

}</lang>

Output:
The first 15 terms of the sequence are:
[1 2 4 6 16 12 64 24 36 48 1024 60 4096 192 144]

Java

Translation of: C

<lang java>import java.util.Arrays;

public class OEIS_A005179 {

   static int count_divisors(int n) {
       int count = 0;
       for (int i = 1; i * i <= n; ++i) {
           if (n % i == 0) {
               if (i == n / i)
                   count++;
               else
                   count += 2;
           }
       }
       return count;
   }
   public static void main(String[] args) {
       final int max = 15;
       int[] seq = new int[max];
       System.out.printf("The first %d terms of the sequence are:\n", max);
       for (int i = 1, n = 0; n < max; ++i) {
           int k = count_divisors(i);
           if (k <= max && seq[k - 1] == 0) {        
               seq[k- 1] = i;
               n++;
           }
       }
       System.out.println(Arrays.toString(seq));
   }

}</lang>

Output:
The first 15 terms of the sequence are:
[1, 2, 4, 6, 16, 12, 64, 24, 36, 48, 1024, 60, 4096, 192, 144]

Kotlin

Translation of: Go

<lang scala>// Version 1.3.21

const val MAX = 15

fun countDivisors(n: Int): Int {

   var count = 0
   var i = 1
   while (i * i <= n) {
       if (n % i == 0) {
           count += if (i == n / i) 1 else 2
       }
       i++
   }
   return count

}

fun main() {

   var seq = IntArray(MAX)
   println("The first $MAX terms of the sequence are:")
   var i = 1
   var n = 0
   while (n < MAX) {
       var k = countDivisors(i)
       if (k <= MAX && seq[k - 1] == 0) {
           seq[k - 1] = i
           n++
       }
       i++
   }
   println(seq.asList())

}</lang>

Output:
The first 15 terms of the sequence are:
[1, 2, 4, 6, 16, 12, 64, 24, 36, 48, 1024, 60, 4096, 192, 144]

Perl

Library: ntheory

<lang perl>use strict; use warnings; use ntheory 'divisors';

print "First 15 terms of OEIS: A005179\n"; for my $n (1..15) {

   my $l = 0;
   while (++$l) {
       print "$l " and last if $n == divisors($l);
   }

}</lang>

Output:
First 15 terms of OEIS: A005179
1 2 4 6 16 12 64 24 36 48 1024 60 4096 192 144

Perl 6

Works with: Rakudo version 2019.03

<lang perl6>sub div-count (\x) {

   return 2 if x.is-prime;
   +flat (1 .. x.sqrt.floor).map: -> \d {
       unless x % d { my \y = x div d; y == d ?? y !! (y, d) }
   }

}

my $limit = 15;

put "First $limit terms of OEIS:A005179"; put (1..$limit).map: -> $n { first { $n == .&div-count }, 1..Inf };

</lang>

Output:
First 15 terms of OEIS:A005179
1 2 4 6 16 12 64 24 36 48 1024 60 4096 192 144

REXX

<lang rexx>/*REXX program finds and displays the smallest number with exactly N divisors.*/ parse arg N . /*obtain optional argument from the CL.*/ if N== | N=="," then N= 15 /*Not specified? Then use the default.*/ say '──divisors── ──smallest number with N divisors──' /*display title for the numbers.*/ @.= /*the @ array is used for memoization*/

       do i=1  for N                            /*step through a number of divisors.   */
          do j=1+(i\==1)  by 1+(i\==1)          /*now, search for a number that ≡ #divs*/
          if @.j==.  then iterate               /*has this number already been found?  */
          d= #divs(j);  if d\==i  then iterate  /*get # divisors;  Is not equal?  Skip.*/
          say center(i, 12)  right(j, 19)       /*display the #divs and the smallest #.*/
          @.j=.                                 /*mark as having found #divs for this J*/
          leave                                 /*found a number, so now get the next I*/
          end   /*j*/
       end      /*i*/

exit /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/

  1. divs: procedure; parse arg x 1 y /*X and Y: both set from 1st argument.*/
      if x<7  then do                           /*handle special cases for numbers < 7.*/
                   if x<3   then return x       /*   "      "      "    "  one and two.*/
                   if x<5   then return x - 1   /*   "      "      "    "  three & four*/
                   if x==5  then return 2       /*   "      "      "    "  five.       */
                   if x==6  then return 4       /*   "      "      "    "  six.        */
                   end
      odd= x // 2                               /*check if   X   is  odd  or not.      */
      if odd  then do;  #= 1;             end   /*Odd?   Assume  Pdivisors  count of 1.*/
              else do;  #= 3;    y= x%2;  end   /*Even?     "        "        "    " 3.*/
                                                /* [↑]   start with known num of Pdivs.*/
                 do k=3  for x%2-3  by 1+odd  while k<y  /*for odd numbers, skip evens.*/
                 if x//k==0  then do            /*if no remainder, then found a divisor*/
                                  #=#+2;  y=x%k /*bump  #  Pdivs,  calculate limit  Y. */
                                  if k>=y  then do;  #= #-1;  leave;  end      /*limit?*/
                                  end                                          /*  ___ */
                             else if k*k>x  then leave        /*only divide up to √ x  */
                 end   /*k*/                    /* [↑]  this form of DO loop is faster.*/
      return #+1                                /*bump "proper divisors" to "divisors".*/</lang>
output   when using the default input:
──divisors──  ──smallest number with N divisors──
     1                         1
     2                         2
     3                         4
     4                         6
     5                        16
     6                        12
     7                        64
     8                        24
     9                        36
     10                       48
     11                     1024
     12                       60
     13                     4096
     14                      192
     15                      144

Sidef

<lang ruby>func n_divisors(n) {

   1..Inf -> first_by { .sigma0 == n }

}

say 15.of { n_divisors(_+1) }</lang>

Output:
[1, 2, 4, 6, 16, 12, 64, 24, 36, 48, 1024, 60, 4096, 192, 144]

zkl

<lang zkl>fcn countDivisors(n)

  { [1.. n.toFloat().sqrt()].reduce('wrap(s,i){ s + (if(0==n%i) 1 + (i!=n/i)) },0) }

fcn A005179w{

  (1).walker(*).tweak(fcn(n){
     var N=0,cache=Dictionary();
     if(cache.find(n)) return(cache.pop(n));	// prune
     while(1){ 

if(n == (d:=countDivisors(N+=1))) return(N); if(n<d and not cache.find(d)) cache[d]=N;

     }
  })

}</lang> <lang zkl>N:=15; println("First %d terms of OEIS:A005179:".fmt(N)); A005179w().walk(15).concat(" ").println();</lang>

Output:
First 15 terms of OEIS:A005179:
1 2 4 6 16 12 64 24 36 48 1024 60 4096 192 144