Distinct power numbers: Difference between revisions
m →{{header|Haskell}}: A variation on liftA2 |
|||
Line 378: | Line 378: | ||
(\xs -> [x ^ y | x <- xs, y <- xs]) [2 .. 5]</lang> |
(\xs -> [x ^ y | x <- xs, y <- xs]) [2 .. 5]</lang> |
||
or liftA2 expression: |
or a liftA2 expression: |
||
<lang haskell>import Control.Applicative (liftA2) |
<lang haskell>import Control.Applicative (liftA2) |
||
import Control.Monad (join) |
import Control.Monad (join) |
||
Line 389: | Line 389: | ||
(liftA2 (^)) |
(liftA2 (^)) |
||
[2 .. 5]</lang> |
[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> |
|||
{{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> |
Revision as of 07:43, 18 August 2021
- 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
<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
C
<lang c>#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;
}</lang>
- Output:
4 8 9 16 25 27 32 64 81 125 243 256 625 1024 3125
C++
<lang cpp>#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;
}</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
<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
<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
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]
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
- 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()</lang>
- Output:
[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. <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= 10 /*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), '─') @.= .; mx= 0 /*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; mx= max(mx, x) /*assign the power product; fix the max*/ end /*b*/ end /*a*/
found= 0; idx= 1 /*initialize # distinct power integers.*/ $= /*a list of distinct power integers. */
do j=0 for mx+1; if @.j==. then iterate /*Number not found in 1st DO loop? Skip*/ found= found + 1; c= commas(j) /*maybe add commas to the number. */ $= $ right(c, max(w, length(c) ) ) /*add a distinct power number ──► list.*/ 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.*/ 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 │ 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
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
<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.