Distinct power numbers: Difference between revisions

From Rosetta Code
Content added Content deleted
m (→‎{{header|BQN}}: ∧ is Sort)
(Added R.)
Line 518: Line 518:
{{Out}}
{{Out}}
<pre>[4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125]</pre>
<pre>[4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125]</pre>

=={{header|R}}==
This only takes one line.
<lang R>unique(sort(rep(2:5, each = 4)^rep(2:5, times = 4)))</lang>
{{out}}
<pre> [1] 4 8 9 16 25 27 32 64 81 125 243 256 625 1024 3125</pre>


=={{header|Raku}}==
=={{header|Raku}}==

Revision as of 15:27, 9 October 2021

Distinct power numbers is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
Task

Compute all combinations of where a and b are integers between 2 and 5 inclusive.

Place them in numerical order, with any repeats removed.

You should get the following sequence of 15 distinct terms:
4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125

ALGOL 68

<lang algol68>BEGIN # show in order, distinct values of a^b where 2 <= a <= b <= 5 #

   INT max number = 5;
   INT min number = 2;
   # construct a table of a ^ b                                            #
   INT length     = ( max number + 1 ) - min number;
   [ 1 : length * length ]INT a to b;
   INT pos := 0;
   FOR i FROM min number TO max number DO
       a to b[ pos +:= 1 ] := i * i;
       FOR j FROM min number + 1 TO max number DO
           INT prev = pos;
           a to b[ pos +:= 1 ] := a to b[ prev ] * i
       OD
   OD;
   # sort the table                                                        #
   # it is small and nearly sorted so a bubble sort should suffice         #
   FOR u FROM UPB a to b - 1 BY -1 TO LWB a to b
   WHILE BOOL sorted := TRUE;
         FOR p FROM LWB a to b BY 1 TO u DO
             IF a to b[ p ] > a to b[ p + 1 ] THEN
                 INT t            = a to b[ p     ];
                 a to b[ p     ] := a to b[ p + 1 ];
                 a to b[ p + 1 ] := t;
                 sorted := FALSE
             FI
         OD;
         NOT sorted
   DO SKIP OD;
   # print the table, excluding duplicates                                 #
   INT last := -1;
   FOR i TO UPB a to b DO
       INT next = a to b[ i ];
       IF next /= last THEN print( ( " ", whole( next, 0 ) ) ) FI;
       last := next
   OD;
   print( ( newline ) )

END</lang>

Output:
 4 8 9 16 25 27 32 64 81 125 243 256 625 1024 3125

APL

Works with: Dyalog APL

<lang APL>(⊂∘⍋⌷⊣)∪,∘.*⍨1+⍳4</lang>

Output:
4 8 9 16 25 27 32 64 81 125 243 256 625 1024 3125

AppleScript

Idiomatic

Uses an extravagantly long list, but gets the job done quickly and easily. <lang applescript>on task()

   script o
       property output : {}
   end script
   
   repeat (5 ^ 5) times
       set end of o's output to missing value
   end repeat
   
   repeat with a from 2 to 5
       repeat with b from 2 to 5
           tell (a ^ b as integer) to set item it of o's output to it
           tell (b ^ a as integer) to set item it of o's output to it
       end repeat
   end repeat
   
   return o's output's integers

end task

task()</lang>

Output:

<lang applescript>{4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125}</lang>


Functional

Composing a solution from generic primitives, for speed of drafting, and ease of refactoring:

<lang applescript>use framework "Foundation" use scripting additions



DISTINCT POWER VALUES -----------------

-- distinctPowers :: [Int] -> [Int] on distinctPowers(xs)

   script powers
       on |λ|(a, x)
           script integerPower
               on |λ|(b, y)
                   b's addObject:((x ^ y) as integer)
                   b
               end |λ|
           end script
           
           foldl(integerPower, a, xs)
       end |λ|
   end script
   
   sort(foldl(powers, ¬
       current application's NSMutableSet's alloc's init(), xs)'s ¬
       allObjects())

end distinctPowers



TEST -------------------------

on run

   distinctPowers(enumFromTo(2, 5))

end run



GENERIC ------------------------

-- enumFromTo :: Int -> Int -> [Int] on enumFromTo(m, n)

   if m ≤ n then
       set lst to {}
       repeat with i from m to n
           set end of lst to i
       end repeat
       lst
   else
       {}
   end if

end enumFromTo


-- foldl :: (a -> b -> a) -> a -> [b] -> a on foldl(f, startValue, xs)

   tell mReturn(f)
       set v to startValue
       set lng to length of xs
       repeat with i from 1 to lng
           set v to |λ|(v, item i of xs, i, xs)
       end repeat
       return v
   end tell

end foldl


-- mReturn :: First-class m => (a -> b) -> m (a -> b) on mReturn(f)

   -- 2nd class handler function lifted into 1st class script wrapper. 
   if script is class of f then
       f
   else
       script
           property |λ| : f
       end script
   end if

end mReturn


-- sort :: Ord a => [a] -> [a] on sort(xs)

   ((current application's NSArray's arrayWithArray:xs)'s ¬
       sortedArrayUsingSelector:"compare:") as list

end sort</lang>

Output:
{4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125}

AppleScriptObjC

Throwing together a solution using the most appropriate methods for efficiency and legibility. <lang applescript>use AppleScript version "2.4" -- Mac OS X 10.10 (Yosemite) or later. use framework "Foundation"

on task()

   set nums to {}
   repeat with a from 2 to 5
       repeat with b from 2 to 5
           set end of nums to (a ^ b) as integer
           set end of nums to (b ^ a) as integer
       end repeat
   end repeat
   
   set nums to current application's class "NSSet"'s setWithArray:(nums)
   set descriptor to current application's class "NSSortDescriptor"'s sortDescriptorWithKey:("self") ascending:(true)
   return (nums's sortedArrayUsingDescriptors:({descriptor})) as list

end task

task()</lang>

Output:

<lang applescript>{4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125}</lang>

BCPL

<lang bcpl>get "libhdr"

let pow(n, p) =

   p=0 -> 1, 
   n * pow(n, p-1)

let sort(v, length) be

   if length > 0
   $(  for i=0 to length-2
           if v!i > v!(i+1) 
           $(  let t = v!i
               v!i := v!(i+1)
               v!(i+1) := t
           $)
       sort(v, length-1)
   $)

let start() be $( let v = vec 15

   let i = 0
   for a = 2 to 5 for b = 2 to 5
   $(  v!i := pow(a,b)
       i := i+1
   $)
   sort(v, 16)
   for i = 0 to 15
       if i=0 | v!i ~= v!(i-1) do writef("%N ", v!i)
   wrch('*N')

$)</lang>

Output:
4 8 9 16 25 27 32 64 81 125 243 256 625 1024 3125

BQN

<lang bqn>∧⍷⥊⋆⌜˜ 2+↕4</lang>

Output:
⟨ 4 8 9 16 25 27 32 64 81 125 243 256 625 1024 3125 ⟩

C

<lang c>#include <stdio.h>

  1. include <stdlib.h>
  2. include <math.h>

int compare(const void *a, const void *b) {

   int ia = *(int*)a;
   int ib = *(int*)b;
   return (ia>ib) - (ia<ib);

}

int main() {

   int pows[16];
   int a, b, i=0;
   
   for (a=2; a<=5; a++)
       for (b=2; b<=5; b++)
           pows[i++] = pow(a, b);
   
   qsort(pows, 16, sizeof(int), compare);
   
   for (i=0; i<16; i++)
       if (i==0 || pows[i] != pows[i-1]) 
           printf("%d ", pows[i]);
   
   printf("\n");
   return 0;

}</lang>

Output:
4 8 9 16 25 27 32 64 81 125 243 256 625 1024 3125

C++

<lang cpp>#include <iostream>

  1. include <set>
  2. include <cmath>

int main() {

   std::set<int> values;
   for (int a=2; a<=5; a++)
       for (int b=2; b<=5; b++)
           values.insert(std::pow(a, b));
   
   for (int i : values)
       std::cout << i << " ";
   
   std::cout << std::endl;
   return 0;

}</lang>

Output:
4 8 9 16 25 27 32 64 81 125 243 256 625 1024 3125

F#

<lang fsharp> set[for n in 2..5 do for g in 2..5->pown n g]|>Set.iter(printf "%d ") </lang>

Output:
4 8 9 16 25 27 32 64 81 125 243 256 625 1024 3125

Factor

Works with: Factor version 0.99 2021-06-02

<lang factor>USING: kernel math.functions math.ranges prettyprint sequences sets sorting ;

2 5 [a,b] dup [ ^ ] cartesian-map concat members natural-sort .</lang>

Output:
{ 4 8 9 16 25 27 32 64 81 125 243 256 625 1024 3125 }

Go

Translation of: Wren
Library: Go-rcu

<lang go>package main

import (

   "fmt"
   "rcu"
   "sort"

)

func main() {

   var pows []int
   for a := 2; a <= 5; a++ {
       pow := a
       for b := 2; b <= 5; b++ {
           pow *= a
           pows = append(pows, pow)
       }
   }
   set := make(map[int]bool)
   for _, e := range pows {
       set[e] = true
   }
   pows = pows[:0]
   for k := range set {
       pows = append(pows, k)
   }
   sort.Ints(pows)
   fmt.Println("Ordered distinct values of a ^ b for a in [2..5] and b in [2..5]:")
   for i, pow := range pows {
       fmt.Printf("%5s ", rcu.Commatize(pow))
       if (i+1)%5 == 0 {
           fmt.Println()
       }
   }
   fmt.Println("\nFound", len(pows), "such numbers.")

}</lang>

Output:
Ordered distinct values of a ^ b for a in [2..5] and b in [2..5]:
    4     8     9    16    25 
   27    32    64    81   125 
  243   256   625 1,024 3,125 

Found 15 such numbers.

Haskell

<lang haskell>import qualified Data.Set as S



DISTINCT POWER NUMBERS ----------------

distinctPowerNumbers :: Int -> Int -> [Int] distinctPowerNumbers a b =

 (S.elems . S.fromList) $
   (fmap (^) >>= (<*>)) [a .. b]



TEST -------------------------

main :: IO () main =

 print $
   distinctPowerNumbers 2 5</lang>
Output:
[4,8,9,16,25,27,32,64,81,125,243,256,625,1024,3125]


or, as a one-off list comprehension:

<lang haskell>import qualified Data.Set as S

main :: IO () main =

 (print . S.elems . S.fromList) $
   (\xs -> [x ^ y | x <- xs, y <- xs]) [2 .. 5]</lang>

or a liftA2 expression: <lang haskell>import Control.Applicative (liftA2) import Control.Monad (join) import qualified Data.Set as S

main :: IO () main =

 (print . S.elems . S.fromList) $
   join
     (liftA2 (^))
     [2 .. 5]</lang>

which can always be reduced (shedding imports) to the pattern: <lang haskell>import qualified Data.Set as S

main :: IO () main =

 (print . S.elems . S.fromList) $
     (\xs -> (^) <$> xs <*> xs)
     [2 .. 5]</lang>
Output:
[4,8,9,16,25,27,32,64,81,125,243,256,625,1024,3125]

J

<lang j>~./:~;^/~2+i.4</lang>

Output:
4 8 9 16 25 27 32 64 81 125 243 256 625 1024 3125

jq

Works with: jq

Works with gojq, the Go implementation of jq

For relatively small integers, such as involved in the specified task, the built-in function `pow/2` does the job:

<lang jq>[range(2;6) as $a | range(2;6) as $b | pow($a; $b)] | unique</lang>
Output:
[4,8,9,16,25,27,32,64,81,125,243,256,625,1024,3125]

However, if using gojq, then for unbounded precision, a special-purpose "power" function is needed:<lang jq>def power($b): . as $in | reduce range(0;$b) as $i (1; . * $in);

[range(2;6) as $a | range(2;6) as $b | $a|power($b)] | unique</lang>

Output:

As above.

Julia

<lang julia>println(sort(unique([a^b for a in 2:5, b in 2:5])))</lang>

Output:
[4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125]

Mathematica/Wolfram Language

<lang Mathematica>Union @@ Table[a^b, {a, 2, 5}, {b, 2, 5}]</lang>

Output:
{4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125}

Nim

<lang Nim>import algorithm, math, sequtils, strutils, sugar

let list = collect(newSeq):

            for a in 2..5:
              for b in 2..5: a^b

echo sorted(list).deduplicate(true).join(" ")</lang>

Output:
4 8 9 16 25 27 32 64 81 125 243 256 625 1024 3125

Phix

with javascript_semantics
function sqpn(integer n) return sq_power(n,{2,3,4,5}) end function
sequence res = apply(true,sprintf,{{"%,5d"},unique(join(apply({2,3,4,5},sqpn),""))})
printf(1,"%d found:\n%s\n",{length(res),join_by(res,1,5," ")})
Output:
15 found:
    4     8     9    16    25
   27    32    64    81   125
  243   256   625 1,024 3,125

Perl

<lang perl>#!/usr/bin/perl -l

use strict; # https://rosettacode.org/wiki/Distinct_power_numbers use warnings; use List::Util qw( uniq );

print join ', ', sort { $a <=> $b } uniq map { my $e = $_; map $_ ** $e, 2 .. 5} 2 .. 5;</lang>

Output:
4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125

Python

<lang python>from itertools import product print(sorted(set(a**b for (a,b) in product(range(2,6), range(2,6)))))</lang>

Output:
[4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125]


Or, for variation, generalizing a little in terms of starmap and pow: <lang python>Distinct power numbers

from itertools import product, starmap


  1. distinctPowerNumbers :: Int -> Int -> [Int]

def distinctPowerNumbers(a):

   Sorted values of x^y where x, y <- [a..b]
   
   def go(b):
       xs = range(a, 1 + b)
       return sorted(set(
           starmap(pow, product(xs, xs))
       ))
   return go


  1. ------------------------- TEST -------------------------
  2. main :: IO ()

def main():

   Distinct powers from integers [2..5]
   print(
       distinctPowerNumbers(2)(5)
   )


  1. MAIN ---

if __name__ == '__main__':

   main()</lang>
Output:
[4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125]

R

This only takes one line. <lang R>unique(sort(rep(2:5, each = 4)^rep(2:5, times = 4)))</lang>

Output:
 [1]    4    8    9   16   25   27   32   64   81  125  243  256  625 1024 3125

Raku

<lang perl6>put squish sort [X**] (2..5) xx 2;</lang>

Output:
4 8 9 16 25 27 32 64 81 125 243 256 625 1024 3125

REXX

With this version of REXX,   there's no need to sort the found numbers,   or to eliminate duplicates. <lang rexx>/*REXX pgm finds and displays distinct power integers: a^b, where a and b are 2≤both≤5*/ parse arg lo hi cols . /*obtain optional arguments from the CL*/ if lo== | lo=="," then lo= 2 /*Not specified? Then use the default.*/ if hi== | hi=="," then hi= 5 /* " " " " " " */ if cols== | cols=="," then cols= 10 /* " " " " " " */ w= 11 /*width of a number in any column. */ title= ' distinct power integers, a^b, where a and b are: ' lo "≤ both ≤" hi say ' index │'center(title, 1 + cols*(w+1) ) say '───────┼'center("" , 1 + cols*(w+1), '─') @.= .; $$= /*the default value for the @. array.*/

       do    a=lo  to  hi                       /*traipse through  A  values (LO──►HI).*/
          do b=lo  to  hi                       /*   "       "     B     "     "    "  */
          x= a ** b;   if @.x\==.  then iterate /*Has it been found before?  Then skip.*/
          @.x= x;      $$= $$  x                /*assign power product; append to  $$  */
          end   /*b*/
       end      /*a*/

$=; idx= 1 /*$$: a list of distinct power integers*/

   do j=1  while words($$)>0;  call getMin $$   /*obtain smallest number in the $$ list*/
   $= $  right(commas(z), max(w, length(z) ) )  /*add a distinct power number ──► list.*/
   if j//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.*/ say '───────┴'center("" , 1 + cols*(w+1), '─') say say 'Found ' commas(j-1) 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 ? /*──────────────────────────────────────────────────────────────────────────────────────*/ getMin: parse arg z .; p= 1; #= words($$) /*assume min; # words in $$.*/

         do m=2  for #-1;    a= word($$, m);    if a>=z  then iterate;     z= a;     p= m
         end   /*m*/;    $$= delword($$, p, 1);    return /*delete the smallest number.*/</lang>
output   when using the default inputs:
 index │                            distinct power integers, a^b, where  a  and  b  are:  2 ≤ both ≤ 5
───────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   1   │           4           8           9          16          25          27          32          64          81         125
  11   │         243         256         625       1,024       3,125
───────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Found  15  distinct power integers, a^b, where  a  and  b  are:  2 ≤ both ≤ 5
output   when using the inputs of:     0   5
 index │                            distinct power integers, a^b, where  a  and  b  are:  0 ≤ both ≤ 5
───────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   1   │           0           1           2           3           4           5           8           9          16          25
  11   │          27          32          64          81         125         243         256         625       1,024       3,125
───────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
output   when using the inputs of:     0   9
 index │                            distinct power integers, a^b, where  a  and  b  are:  0 ≤ both ≤ 9
───────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   1   │           0           1           2           3           4           5           6           7           8           9
  11   │          16          25          27          32          36          49          64          81         125         128
  21   │         216         243         256         343         512         625         729       1,024       1,296       2,187
  31   │       2,401       3,125       4,096       6,561       7,776      15,625      16,384      16,807      19,683      32,768
  41   │      46,656      59,049      65,536      78,125     117,649     262,144     279,936     390,625     531,441     823,543
  51   │   1,679,616   1,953,125   2,097,152   4,782,969   5,764,801  10,077,696  16,777,216  40,353,607  43,046,721 134,217,728
  61   │ 387,420,489
───────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Found  61  distinct power integers, a^b, where  a  and  b  are:  0 ≤ both ≤ 9

Ring

<lang ring> load "stdlib.ring"

see "working..." + nl see "Distinct powers are:" + nl row = 0 distPow = []

for n = 2 to 5

   for m = 2 to 5
       sum = pow(n,m)
       add(distPow,sum)
   next

next

distPow = sort(distPow)

for n = len(distPow) to 2 step -1

   if distPow[n] = distPow[n-1]
      del(distPow,n-1)
   ok

next

for n = 1 to len(distPow)

   row++
   see "" + distPow[n] + " "
   if row%5 = 0
      see nl
   ok

next

see "Found " + row + " numbers" + nl see "done..." + nl </lang>

Output:
working...
Distinct powers are:
4 8 9 16 25 
27 32 64 81 125 
243 256 625 1024 3125 
Found 15 numbers
done...

Sidef

<lang ruby>[2..5]*2 -> cartesian.map_2d {|a,b| a**b }.sort.uniq.say</lang>

Alternative solution: <lang ruby>2..5 ~X** 2..5 -> sort.uniq.say</lang>

Output:
[4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125]

Wren

Library: Wren-seq
Library: Wren-fmt

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

var pows = [] for (a in 2..5) {

   var pow = a
   for (b in 2..5) {
       pow = pow * a
       pows.add(pow)
   }

} pows = Lst.distinct(pows).sort() System.print("Ordered distinct values of a ^ b for a in [2..5] and b in [2..5]:") for (chunk in Lst.chunks(pows, 5)) Fmt.print("$,5d", chunk) System.print("\nFound %(pows.count) such numbers.")</lang>

Output:
Ordered distinct values of a ^ b for a in [2..5] and b in [2..5]:
    4     8     9    16    25
   27    32    64    81   125
  243   256   625 1,024 3,125

Found 15 such numbers.

XPL0

<lang XPL0>int A, B, N, Last, Next; [Last:= 0; loop [Next:= -1>>1; \infinity

       for A:= 2 to 5 do       \find smallest Next
           for B:= 2 to 5 do   \ that's > Last
               [N:= fix(Pow(float(A), float(B)));
               if N>Last & N<Next then Next:= N;
               ];
       if Next = -1>>1 then quit;
       IntOut(0, Next);  ChOut(0, ^ );
       Last:= Next;
       ];

]</lang>

Output:
4 8 9 16 25 27 32 64 81 125 243 256 625 1024 3125