I'm working on modernizing Rosetta Code's infrastructure. Starting with communications. Please accept this time-limited open invite to RC's Slack.. --Michael Mol (talk) 20:59, 30 May 2020 (UTC)

Distinct power numbers

From Rosetta Code
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

Action![edit]

INCLUDE "D2:SORT.ACT" ;from the Action! Tool Kit
 
INT FUNC Power(INT a,b)
INT res,i
 
res=1
FOR i=1 TO b
DO
res==*a
OD
RETURN (res)
 
BYTE FUNC Contains(INT ARRAY a INT count,x)
INT i
 
FOR i=0 TO count-1
DO
IF a(i)=x THEN
RETURN (1)
FI
OD
RETURN (0)
 
PROC Main()
INT ARRAY a(100)
INT i,j,x,count
 
Put(125) PutE() ;clear the screen
 
count=0
FOR i=2 TO 5
DO
FOR j=2 TO 5
DO
x=Power(i,j)
IF Contains(a,count,x)=0 THEN
a(count)=x
count==+1
FI
OD
OD
SortI(a,count,0)
FOR i=0 TO count-1
DO
PrintI(a(i)) Put(32)
OD
RETURN
Output:

Screenshot from Atari 8-bit computer

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

ALGOL 68[edit]

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
Output:
 4 8 9 16 25 27 32 64 81 125 243 256 625 1024 3125

APL[edit]

Works with: Dyalog APL
(⊂∘⍋⌷⊣)∪,∘.*⍨1+⍳4
Output:
4 8 9 16 25 27 32 64 81 125 243 256 625 1024 3125

AppleScript[edit]

Idiomatic[edit]

Uses an extravagantly long list, but gets the job done quickly and easily.

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()
Output:
{4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125}

Functional[edit]

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

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
Output:
{4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125}

AppleScriptObjC[edit]

Throwing together a solution using the most appropriate methods for efficiency and legibility.

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()
Output:
{4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125}

BCPL[edit]

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')
$)
Output:
4 8 9 16 25 27 32 64 81 125 243 256 625 1024 3125

BQN[edit]

∧⍷⥊⋆⌜˜ 2+↕4
Output:
⟨ 4 8 9 16 25 27 32 64 81 125 243 256 625 1024 3125 ⟩

C[edit]

#include <stdio.h>
#include <stdlib.h>
#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;
}
Output:
4 8 9 16 25 27 32 64 81 125 243 256 625 1024 3125

C++[edit]

#include <iostream>
#include <set>
#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;
}
Output:
4 8 9 16 25 27 32 64 81 125 243 256 625 1024 3125

F#[edit]

 
set[for n in 2..5 do for g in 2..5->pown n g]|>Set.iter(printf "%d ")
 
Output:
4 8 9 16 25 27 32 64 81 125 243 256 625 1024 3125

Factor[edit]

Works with: Factor version 0.99 2021-06-02
USING: kernel math.functions math.ranges prettyprint sequences
sets sorting ;
 
2 5 [a,b] dup [ ^ ] cartesian-map concat members natural-sort .
Output:
{ 4 8 9 16 25 27 32 64 81 125 243 256 625 1024 3125 }

FreeBASIC[edit]

 
redim arr(-1) as uinteger
dim as uinteger i
for a as uinteger = 2 to 5
for b as uinteger = 2 to 5
redim preserve arr(0 to ubound(arr)+1)
i = ubound(arr)
arr(i) = a^b
while arr(i-1)>arr(i) and i > 0
swap arr(i-1), arr(i)
i -= 1
wend
next b
next a
 
for i = 0 to ubound(arr)
if arr(i)<>arr(i-1) then print arr(i),
next i
 

Go[edit]

Translation of: Wren
Library: Go-rcu
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.")
}
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[edit]

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
Output:
[4,8,9,16,25,27,32,64,81,125,243,256,625,1024,3125]


or, as a one-off list comprehension:

import qualified Data.Set as S
 
main :: IO ()
main =
(print . S.elems . S.fromList) $
(\xs -> [x ^ y | x <- xs, y <- xs]) [2 .. 5]

or a liftA2 expression:

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]

which can always be reduced (shedding imports) to the pattern:

import qualified Data.Set as S
 
main :: IO ()
main =
(print . S.elems . S.fromList) $
(\xs -> (^) <$> xs <*> xs)
[2 .. 5]
Output:
[4,8,9,16,25,27,32,64,81,125,243,256,625,1024,3125]

J[edit]

~./:~;^/~2+i.4
Output:
4 8 9 16 25 27 32 64 81 125 243 256 625 1024 3125

jq[edit]

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:

[range(2;6) as $a | range(2;6) as $b | pow($a; $b)] | unique
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:
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
Output:

As above.

Julia[edit]

println(sort(unique([a^b for a in 2:5, b in 2:5])))
Output:
[4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125]

Mathematica/Wolfram Language[edit]

Union @@ Table[a^b, {a, 2, 5}, {b, 2, 5}]
Output:
{4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125}

Nim[edit]

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(" ")
Output:
4 8 9 16 25 27 32 64 81 125 243 256 625 1024 3125

Phix[edit]

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[edit]

#!/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;
Output:
4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125

Python[edit]

from itertools import product
print(sorted(set(a**b for (a,b) in product(range(2,6), range(2,6)))))
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:

'''Distinct power numbers'''
 
from itertools import product, starmap
 
 
# 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
 
 
# ------------------------- TEST -------------------------
# main :: IO ()
def main():
'''Distinct powers from integers [2..5]'''
 
print(
distinctPowerNumbers(2)(5)
)
 
 
# MAIN ---
if __name__ == '__main__':
main()
Output:
[4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125]

R[edit]

This only takes one line.

unique(sort(rep(2:5, each = 4)^rep(2:5, times = 4)))
Output:
 [1]    4    8    9   16   25   27   32   64   81  125  243  256  625 1024 3125

Raku[edit]

put squish sort [X**] (2..5) xx 2;
Output:
4 8 9 16 25 27 32 64 81 125 243 256 625 1024 3125

REXX[edit]

With this version of REXX,   there's no need to sort the found numbers,   or to eliminate duplicates.

/*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.*/
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[edit]

 
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
 
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[edit]

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

Alternative solution:

2..5 ~X** 2..5 -> sort.uniq.say
Output:
[4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125]

Wren[edit]

Library: Wren-seq
Library: Wren-fmt
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.")
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[edit]

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;
];
]
Output:
4 8 9 16 25 27 32 64 81 125 243 256 625 1024 3125