Special divisors: Difference between revisions

From Rosetta Code
Content added Content deleted
(Add APL)
(Add J)
Line 266: Line 266:
131 137 139 143 149 151 157 163 167 169 173 179 181 187 191 193 197 199
131 137 139 143 149 151 157 163 167 169 173 179 181 187 191 193 197 199
</pre>
</pre>

=={{header|J}}==
<lang J>([#~([:*./0=|.&.":"0@>:@I.@(0=>:@i.|])||.&.":)"0)>:i.200</lang>
{{out}}
<pre>1 2 3 4 5 6 7 8 9 11 13 17 19 22 23 26 27 29 31 33 37 39 41 43 44 46 47 53 55 59 61 62 66 67 69 71 73 77 79 82 83 86 88 89 93 97 99 101 103 107 109 113 121 127 131 137 139 143 149 151 157 163 167 169 173 179 181 187 191 193 197 199</pre>


=={{header|Julia}}==
=={{header|Julia}}==

Revision as of 13:05, 18 June 2021

Special 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.
Task

Numbers   n   such that   reverse(d)   divides   reverse(n)   for all divisors   d   of   n,   where   n  <  200

ALGOL 68

<lang algol68>BEGIN # find numbers where reverse(d) divides reverse(n) for all divisors d #

     # of n                                                                #
   # returns n with the digits reversed                                    #
   OP REVERSE = ( INT n )INT:
      BEGIN
           INT reverse := 0;
           INT v       := ABS n;
           WHILE v > 0 DO
               reverse *:= 10 +:= v MOD 10;
               v OVERAB 10
           OD;
           reverse * SIGN n
      END # REVERSE # ;
   # find the numbers up to 200                                            #
   INT rd count := 0;
   FOR n TO 199 DO
       INT  reverse n        = REVERSE n;
       BOOL reverse divisor := TRUE;
       FOR d FROM 2 TO n OVER 2 WHILE reverse divisor DO
           IF n MOD d = 0 THEN
               # have a divisor of n                                       #
               reverse divisor := reverse n MOD REVERSE d = 0
           FI
       OD;
       IF reverse divisor THEN
           # all the divisors of n reversed divide n reversed              #
           print( ( " ", whole( n, -3 ) ) );
           IF ( rd count +:= 1 ) MOD 10 = 0 THEN print( ( newline ) ) FI
       FI
   OD;
   print( ( newline, "Found ", whole( rd count, 0 ), " ""special divisors"" below 200", newline ) )

END</lang>

Output:
   1   2   3   4   5   6   7   8   9  11
  13  17  19  22  23  26  27  29  31  33
  37  39  41  43  44  46  47  53  55  59
  61  62  66  67  69  71  73  77  79  82
  83  86  88  89  93  97  99 101 103 107
 109 113 121 127 131 137 139 143 149 151
 157 163 167 169 173 179 181 187 191 193
 197 199
Found 72 "special divisors" below 200

ALGOL W

Translation of: ALGOL 68

<lang algolw>begin % find numbers where reverse(d) divides reverse(n) for all divisors d %

     % of n                                                                %
   % returns n with the digits reversed                                    %
   integer procedure reverse ( integer value n ) ;
   begin
       integer r, v;
       r := 0;
       v := abs n;
       while v > 0 do begin
           r := ( r * 10 ) + ( v rem 10 );
           v := v div 10
       end while_v_gt_0 ;
       if n < 0 then - r else r
   end reverse ;
   % find the numbers up to 200                                            %
   integer rdCount;
   rdCount := 0;
   for n := 1 until 199 do begin
       integer reverseN, d, maxD;
       logical reverseDivisor;
       reverseN       := reverse( n );
       reverseDivisor := true;
       d              := 1;
       maxD           := n div 2;
       while begin
                 d := d + 1;
                 d <= maxD and reverseDivisor
             end
       do begin
           if n rem d = 0 then begin
               % have a divisor of n                                       %
               reverseDivisor := reverseN rem reverse( d ) = 0
           end if_n_rem_d_eq_0
       end while_d_le_maxD_and_reverseDivisor ;
       if reverseDivisor then begin
           % all the divisors of n reversed divide n reversed              %
           writeon( i_w := 3, s_w := 0, " ", n );
           rdCount := rdCount + 1;
           if rdCount rem 10 = 0 then write()
       end if_reverseDivisor
   end for_n ;
   write( i_w := 1, s_w := 0, "Found ", rdCount, " ""special divisors"" below 200" )

end.</lang>

Output:

Same as the Algol 68 sample.

APL

Works with: Dyalog APL

<lang APL>(⊢(/⍨)(0∧.=(⍎⌽∘⍕)¨∘(⍸0=⍳|⊢)|(⍎⌽∘⍕))¨) ⍳200</lang>

Output:
1 2 3 4 5 6 7 8 9 11 13 17 19 22 23 26 27 29 31 33 37 39 41 43 44 46 47
      53 55 59 61 62 66 67 69 71 73 77 79 82 83 86 88 89 93 97 99 101
      103 107 109 113 121 127 131 137 139 143 149 151 157 163 167 169
      173 179 181 187 191 193 197 199

AppleScript

<lang applescript>on factors(n)

   set output to {}
   
   if (n > 0) then
       set sqrt to n ^ 0.5
       set limit to sqrt div 1
       if (limit = sqrt) then
           set end of output to limit
           set limit to limit - 1
       end if
       repeat with i from limit to 1 by -1
           if (n mod i is 0) then
               set beginning of output to i
               set end of output to n div i
           end if
       end repeat
   end if
   
   return output

end factors

on reversedIntVal(n, base)

   set r to n mod base as integer
   set n to n div base
   repeat until (n = 0)
       set r to r * base + n mod base
       set n to n div base
   end repeat
   
   return r

end reversedIntVal

on hasSpecialDivisors(n, base)

   set divisors to factors(n)
   if (divisors is {}) then return false
   set r to reversedIntVal(n, base)
   repeat with d in divisors
       if (r mod (reversedIntVal(d, base)) > 0) then return false
   end repeat
   
   return true

end hasSpecialDivisors

local output, base, n set output to {} set base to 10 repeat with n from 1 to 199

   if (hasSpecialDivisors(n, base)) then set end of output to n

end repeat return {|count|:(count output), finds:output}</lang>

Output:

<lang applescript>{|count|:72, finds:{1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 13, 17, 19, 22, 23, 26, 27, 29, 31, 33, 37, 39, 41, 43, 44, 46, 47, 53, 55, 59, 61, 62, 66, 67, 69, 71, 73, 77, 79, 82, 83, 86, 88, 89, 93, 97, 99, 101, 103, 107, 109, 113, 121, 127, 131, 137, 139, 143, 149, 151, 157, 163, 167, 169, 173, 179, 181, 187, 191, 193, 197, 199}}</lang>

Delphi

Translation of: Ring

<lang Delphi>program Special_Divisors; {$IFDEF FPC}

 {$MODE DELPHI}
uses
   SysUtils,
   StrUtils;

{$ELSE}

 {$APPTYPE CONSOLE}
uses
   System.SysUtils,
   System.StrUtils;

{$ENDIF}

const

 limit1 = 200;

var

 row, num, revNum, revDiv: Integer;
 flag: boolean;

procedure Main(); var

 n,m: NativeUint;

begin

 writeln('Working...'#10);
 row := 0;
 num := 0;
 for n := 1 to limit1 do
 begin
   flag := True;
   revNum := reversestring(n.ToString).ToInteger;
   for m := 1 to n div 2 do
   begin
     revDiv := reversestring(m.ToString).ToInteger;
     if n mod m = 0 then
       if revNum mod revDiv = 0 then
         flag := True
       else
       begin
         flag := False;
         Break;
       end;
   end;
   if flag then
   begin
     inc(num);
     inc(row);
     write(n: 4);
     if row mod 10 = 0 then
       Writeln;
   end;
 end;
 writeln(#10#10'Found ', num,
   ' special divisors N that reverse(D) divides reverse(N) for all divisors D of N, where  N  <  200');
 writeln('Done...');

end;

begin

 Main;
{$IFNDEF UNIX} readln; {$ENDIF}

end.</lang>

Output:
Working...

   1   2   3   4   5   6   7   8   9  11
  13  17  19  22  23  26  27  29  31  33
  37  39  41  43  44  46  47  53  55  59
  61  62  66  67  69  71  73  77  79  82
  83  86  88  89  93  97  99 101 103 107
 109 113 121 127 131 137 139 143 149 151
 157 163 167 169 173 179 181 187 191 193
 197 199

Found 72 special divisors N that reverse(D) divides reverse(N) for all divisors D of N, where  N  <  200
Done...

Factor

Works with: Factor version 0.99 2021-02-05

<lang factor>USING: grouping kernel math.functions math.parser math.primes.factors math.ranges prettyprint sequences ;

reverse-number ( n -- reversed ) 10 >base reverse dec> ;
special? ( n -- ? )
   [ reverse-number ] [ divisors ] bi
   [ reverse-number divisor? ] with all? ;

200 [1..b] [ special? ] filter 18 group simple-table.</lang>

Output:
1   2   3   4   5   6   7   8   9   11  13  17  19  22  23  26  27  29
31  33  37  39  41  43  44  46  47  53  55  59  61  62  66  67  69  71
73  77  79  82  83  86  88  89  93  97  99  101 103 107 109 113 121 127
131 137 139 143 149 151 157 163 167 169 173 179 181 187 191 193 197 199

J

<lang J>([#~([:*./0=|.&.":"0@>:@I.@(0=>:@i.|])||.&.":)"0)>:i.200</lang>

Output:
1 2 3 4 5 6 7 8 9 11 13 17 19 22 23 26 27 29 31 33 37 39 41 43 44 46 47 53 55 59 61 62 66 67 69 71 73 77 79 82 83 86 88 89 93 97 99 101 103 107 109 113 121 127 131 137 139 143 149 151 157 163 167 169 173 179 181 187 191 193 197 199

Julia

<lang julia>using Primes

function divisors(n)

   f = [one(n)]
   for (p,e) in factor(n)
       f = reduce(vcat, [f*p^j for j in 1:e], init=f)
   end
   return f[1:end-1]

end

function isspecialdivisor(n)::Bool

   isprime(n) && return true
   nreverse = evalpoly(10, reverse(digits(n)))
   for d in divisors(n)
       dreverse = evalpoly(10, reverse(digits(d)))
       !(nreverse ÷ dreverse ≈ nreverse / dreverse) && return false
   end
   return true

end

const specials = filter(isspecialdivisor, 1:200) foreach(p -> print(rpad(p[2], 4), p[1] % 18 == 0 ? "\n" : ""), enumerate(specials))

</lang>

Output:
1   2   3   4   5   6   7   8   9   11  13  17  19  22  23  26  27  29
31  33  37  39  41  43  44  46  47  53  55  59  61  62  66  67  69  71
73  77  79  82  83  86  88  89  93  97  99  101 103 107 109 113 121 127
131 137 139 143 149 151 157 163 167 169 173 179 181 187 191 193 197 199

Nim

<lang Nim>import strutils

func reversed(n: Positive): int =

 var n = n.int
 while n != 0:
   result = 10 * result + n mod 10
   n = n div 10

func divisors(n: Positive): seq[int] =

 result = @[1, n]
 var d = 2
 while d * d <= n:
   if n mod d == 0:
     result.add d
     if d * d != n:
       result.add n div d
   inc d

var count = 0 for n in 1..<200:

 let revn = reversed(n)
 block check:
   for d in divisors(n):
     if revn mod reversed(d) != 0:
       break check
   inc count
   stdout.write ($n).align(3), if count mod 12 == 0: '\n' else: ' '</lang>
Output:
  1   2   3   4   5   6   7   8   9  11  13  17
 19  22  23  26  27  29  31  33  37  39  41  43
 44  46  47  53  55  59  61  62  66  67  69  71
 73  77  79  82  83  86  88  89  93  97  99 101
103 107 109 113 121 127 131 137 139 143 149 151
157 163 167 169 173 179 181 187 191 193 197 199

Pascal

see http://rosettacode.org/wiki/Special_Divisors#Delphi%7CDelphi

Perl

Library: ntheory

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

my @sd; for my $n (1..199) {

   map { next if $_ != int $_ } map { reverse($n) / reverse $_ } divisors $n;
   push @sd, $n;

}

say @sd . " matching numbers:\n" .

   (sprintf "@{['%4d' x @sd]}", @sd) =~ s/(.{40})/$1\n/gr;</lang>
Output:
72 matching numbers:
   1   2   3   4   5   6   7   8   9  11
  13  17  19  22  23  26  27  29  31  33
  37  39  41  43  44  46  47  53  55  59
  61  62  66  67  69  71  73  77  79  82
  83  86  88  89  93  97  99 101 103 107
 109 113 121 127 131 137 139 143 149 151
 157 163 167 169 173 179 181 187 191 193
 197 199

Phix

function rev(integer n)
    integer r = 0
    while n do
        r = r*10+remainder(n,10)
        n = floor(n/10)
    end while
    return r
end function

function special_divisors(integer n)
    sequence fn = factors(n)
    if length(fn) then
        integer rn = rev(n)
        for i=1 to length(fn) do
            if remainder(rn,rev(fn[i])) then return false end if
        end for
    end if
    return true
end function

sequence res = apply(true,sprintf,{{"%3d"},filter(tagset(200),special_divisors)})
printf(1,"Found %d special divisors:\n%s\n",{length(res),join_by(res,1,18)})
Output:
Found 72 special divisors:
  1     2     3     4     5     6     7     8     9    11    13    17    19    22    23    26    27    29
 31    33    37    39    41    43    44    46    47    53    55    59    61    62    66    67    69    71
 73    77    79    82    83    86    88    89    93    97    99   101   103   107   109   113   121   127
131   137   139   143   149   151   157   163   167   169   173   179   181   187   191   193   197   199

Raku

<lang perl6>use Prime::Factor:ver<0.3.0+>;

say "{+$_} matching numbers:\n{.batch(10)».fmt('%3d').join: "\n"}"

   given (1..^200).grep: { all .flip «%%« .&divisors».flip };</lang>
Output:
72 matching numbers:
  1   2   3   4   5   6   7   8   9  11
 13  17  19  22  23  26  27  29  31  33
 37  39  41  43  44  46  47  53  55  59
 61  62  66  67  69  71  73  77  79  82
 83  86  88  89  93  97  99 101 103 107
109 113 121 127 131 137 139 143 149 151
157 163 167 169 173 179 181 187 191 193
197 199

REXX

<lang rexx>/*REXX program finds special divisors: numbers N such that reverse(D) divides ··· */ /*────────────────────────── reverse(N) for all divisors D of N, where N < 200. */ parse arg hi cols . /*obtain optional argument from the CL.*/ if hi== | hi=="," then hi= 200 /* " " " " " " */ if cols== | cols=="," then cols= 10 /* " " " " " " */ w= 10 /*width of a number in any column. */ title= ' special divisors N that reverse(D) divides reverse(N) for all divisiors' ,

      ' D  of  N,   where  N  < '    commas(hi)

if cols>0 then say ' index │'center(title, 1 + cols*(w+1) ) if cols>0 then say '───────┼'center("" , 1 + cols*(w+1), '─') found= 0; idx= 1 /*initialize # found numsers and index.*/ $= /*a list of numbers found (so far). */

    do j=1  for  hi-1;     r= reverse(j)        /*search for special divisors.         */
                   do k=2  to j%2               /*skip the first divisor (unity) & last*/
                   if j//k==0  then if r//reverse(k)\==0  then iterate J /*Not OK? Skip*/
                   end   /*m*/
    found= found+1                              /*bump the number of special divisors. */
    if cols<0              then iterate         /*Build the list  (to be shown later)? */
    c= commas(j)                                /*maybe add commas to the number.      */
    $= $ right(c, max(w, length(c) ) )          /*add a special div ─► list, allow big#*/
    if found//cols\==0     then iterate         /*have we populated a line of output?  */
    say center(idx, 7)'│'  substr($, 2);    $=  /*display what we have so far  (cols). */
    idx= idx + cols                             /*bump the  index  count for the output*/
    end   /*j*/

if $\== then say center(idx, 7)"│" substr($, 2) /*possible display residual output.*/ if cols>0 then say '───────┴'center("" , 1 + cols*(w+1), '─') say say 'Found ' commas(found) title exit 0 /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ commas: parse arg ?; do jc=length(?)-3 to 1 by -3; ?=insert(',', ?, jc); end; return ?</lang>

output   when using the default inputs:
 index │    special divisors  N  that reverse(D) divides reverse(N) for all divisiors  D  of  N,   where  N  <  200
───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────
   1   │          1          2          3          4          5          6          7          8          9         11
  11   │         13         17         19         22         23         26         27         29         31         33
  21   │         37         39         41         43         44         46         47         53         55         59
  31   │         61         62         66         67         69         71         73         77         79         82
  41   │         83         86         88         89         93         97         99        101        103        107
  51   │        109        113        121        127        131        137        139        143        149        151
  61   │        157        163        167        169        173        179        181        187        191        193
  71   │        197        199
───────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────

Found  72  special divisors  N  that reverse(D) divides reverse(N) for all divisiors  D  of  N,   where  N  <  200

Ring

<lang ring> load "stdlib.ring"

see "working..." + nl

row = 0 num = 0 limit1 = 200

for n = 1 to limit1

   flag = 1
   revNum = rever(string(n))
   revNum = number(revNum)
   for m = 1 to n/2
       revDiv = rever(String(m))
       revDiv = number(revDiv)
       if n%m = 0
          if revNum % revDiv = 0
             flag = 1
          else
             flag = 0
             exit
          ok
       ok
   next 
   if flag = 1
      num = num + 1
      row = row + 1
      see "" + n + " "
      if row%10 = 0
         see nl
      ok
   ok

next

see nl + "Found " + num + " special divisors N that reverse(D) divides reverse(N) for all divisors D of N, where N < 200" + nl see "done..." + nl

func rever(str)

    rev = ""
    for n = len(str) to 1 step -1
        rev = rev + str[n]
    next
    return rev

</lang>

Output:
working...
1 2 3 4 5 6 7 8 9 11 
13 17 19 22 23 26 27 29 31 33 
37 39 41 43 44 46 47 53 55 59 
61 62 66 67 69 71 73 77 79 82 
83 86 88 89 93 97 99 101 103 107 
109 113 121 127 131 137 139 143 149 151 
157 163 167 169 173 179 181 187 191 193 
197 199 
Found 72 special divisors N that reverse(D) divides reverse(N) for all divisors D of N, where  N  <  200
done...

Wren

Library: Wren-math
Library: Wren-seq
Library: Wren-fmt

<lang ecmascript>import "/math" for Int import "/seq" for Lst import "/fmt" for Fmt

var reversed = Fn.new { |n|

   var rev = 0
   while (n > 0) {
       rev = rev * 10 + n % 10
       n = (n/10).floor
   }
   return rev

}

var special = [] for (n in 1...200) {

   var divs = Int.divisors(n)
   var revN = reversed.call(n)
   if (divs.all { |d| revN % reversed.call(d) == 0 }) special.add(n)

} System.print("Special divisors in the range 0..199:") for (chunk in Lst.chunks(special, 12)) Fmt.print("$3d", chunk) System.print("\n%(special.count) special divisors found.")</lang>

Output:
Special divisors in the range 0..199:
  1   2   3   4   5   6   7   8   9  11  13  17
 19  22  23  26  27  29  31  33  37  39  41  43
 44  46  47  53  55  59  61  62  66  67  69  71
 73  77  79  82  83  86  88  89  93  97  99 101
103 107 109 113 121 127 131 137 139 143 149 151
157 163 167 169 173 179 181 187 191 193 197 199

72 special divisors found.

XPL0

<lang XPL0>func Reverse(N); \Reverse the order of the digits int N, M; [M:= 0; repeat N:= N/10;

       M:= M*10 + rem(0);

until N = 0; return M; ];

func Test(N); \Return 'true' if reverse(D) divides reverse(N) for all divisors D of N int N, D, RevNum, RevDiv; [RevNum:= Reverse(N); for D:= 1 to N/2 do

   if rem(N/D) = 0 then
       [RevDiv:= Reverse(D);
       if rem(RevNum/RevDiv) then return false;
       ];

return true; ];

int Count, N; [Count:= 0; for N:= 1 to 199 do

   [if Test(N) then
       [IntOut(0, N);
       Count:= Count+1;
       if rem(Count/10) = 0 then CrLf(0) else ChOut(0, 9\tab\);
       ];
   ];

CrLf(0); IntOut(0, Count); Text(0, " such numbers found."); ]</lang>

Output:
1       2       3       4       5       6       7       8       9       11
13      17      19      22      23      26      27      29      31      33
37      39      41      43      44      46      47      53      55      59
61      62      66      67      69      71      73      77      79      82
83      86      88      89      93      97      99      101     103     107
109     113     121     127     131     137     139     143     149     151
157     163     167     169     173     179     181     187     191     193
197     199     
72 such numbers found.