Square but not cube

From Rosetta Code
Square but not cube 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

Show the first 30 positive integers which are squares but not cubes of such integers.

Optionally, show also the first 3 positive integers which are both squares and cubes - and mark them as such.

ALGOL 68[edit]

Avoids computing cube roots.

BEGIN
# list the first 30 numbers that are squares but not cubes and also #
# show the numbers that are both squares and cubes #
INT count := 0;
INT c := 1;
INT c3 := 1;
FOR s WHILE count < 30 DO
INT sq = s * s;
WHILE c3 < sq DO
c +:= 1;
c3 := c * c * c
OD;
print( ( whole( sq, -5 ) ) );
IF c3 = sq THEN
# the square is also a cube #
print( ( " is also the cube of ", whole( c, -5 ) ) )
ELSE
# square only #
count +:= 1
FI;
print( ( newline ) )
OD
END
Output:
    1 is also the cube of     1
    4
    9
   16
   25
   36
   49
   64 is also the cube of     4
   81
  100
  121
  144
  169
  196
  225
  256
  289
  324
  361
  400
  441
  484
  529
  576
  625
  676
  729 is also the cube of     9
  784
  841
  900
  961
 1024
 1089

AppleScript[edit]

on run
script listing
on |λ|(x)
set sqr to x * x
set strSquare to sqr as text
 
if isCube(sqr) then
strSquare & " (also cube)"
else
strSquare
end if
end |λ|
end script
 
unlines(map(listing, ¬
enumFromTo(1, 33)))
end run
 
-- isCube :: Int -> Bool
on isCube(x)
x = (round (x ^ (1 / 3))) ^ 3
end isCube
 
 
-- GENERIC FUNCTIONS -------------------------------------------------
 
-- 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
return lst
else
return {}
end if
end enumFromTo
 
-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
tell mReturn(f)
set lng to length of xs
set lst to {}
repeat with i from 1 to lng
set end of lst to |λ|(item i of xs, i, xs)
end repeat
return lst
end tell
end map
 
-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: First-class m => (a -> b) -> m (a -> b)
on mReturn(f)
if class of f is script then
f
else
script
property |λ| : f
end script
end if
end mReturn
 
-- unlines :: [String] -> String
on unlines(xs)
set {dlm, my text item delimiters} to ¬
{my text item delimiters, linefeed}
set str to xs as text
set my text item delimiters to dlm
str
end unlines
Output:
1 (also cube)
4
9
16
25
36
49
64 (also cube)
81
100
121
144
169
196
225
256
289
324
361
400
441
484
529
576
625
676
729 (also cube)
784
841
900
961
1024
1089

C[edit]

#include <stdio.h>
#include <math.h>
 
int main() {
int n = 1, count = 0, sq, cr;
for ( ; count < 30; ++n) {
sq = n * n;
cr = (int)cbrt((double)sq);
if (cr * cr * cr != sq) {
count++;
printf("%d\n", sq);
}
else {
printf("%d is square and cube\n", sq);
}
}
return 0;
}
Output:
Same as Ring example.

F#[edit]

 
let rec fN n g φ=if φ<31 then match compare(n*n)(g*g*g) with | -1->printfn "%d"(n*n);fN(n+1) g (φ+1)
| 0->printfn "%d cube and square"(n*n);fN(n+1)(g+1)φ
| 1->fN n (g+1) φ
fN 1 1 1
 
Output:
1 cube and square
4
9
16
25
36
49
64 cube and square
81
100
121
144
169
196
225
256
289
324
361
400
441
484
529
576
625
676
729 cube and square
784
841
900
961
1024
1089

Go[edit]

package main
 
import (
"fmt"
"math"
)
 
func main() {
for n, count := 1, 0; count < 30; n++ {
sq := n * n
cr := int(math.Cbrt(float64(sq)))
if cr*cr*cr != sq {
count++
fmt.Println(sq)
} else {
fmt.Println(sq, "is square and cube")
}
}
}
Output:
1 is square and cube
4
9
16
25
36
49
64 is square and cube
81
100
121
144
169
196
225
256
289
324
361
400
441
484
529
576
625
676
729 is square and cube
784
841
900
961
1024
1089

Haskell[edit]

import Data.List (partition, sortBy)
import Control.Monad (join)
import Data.Ord (comparing)
 
isCube :: Int -> Bool
isCube n = n == round (fromIntegral n ** (1 / 3)) ^ 3
 
both, only :: [Int]
(both, only) = partition isCube $ join (*) <$> [1 ..]
 
-- TEST -----------------------------------------------------------
main :: IO ()
main =
(putStrLn . unlines) $
uncurry ((++) . show) <$>
sortBy
(comparing fst)
((flip (,) " (also cube)" <$> take 3 both) ++ (flip (,) "" <$> take 30 only))

Or simply

import Control.Monad (join)
 
cubeRoot :: Int -> Int
cubeRoot = round . (** (1 / 3)) . fromIntegral
 
isCube :: Int -> Bool
isCube = (==) <*> ((^ 3) . cubeRoot)
 
-- TEST ---------------------------------------------
main :: IO ()
main =
(putStrLn . unlines) $
(\x ->
show x ++
if isCube x
then concat [" (also cube of ", show (cubeRoot x), ")"]
else []) <$>
take 33 (join (*) <$> [1 ..])

Or, if we prefer a finite series to an infinite one

isCube :: Int -> Bool
isCube n = n == round (fromIntegral n ** (1 / 3)) ^ 3
 
-- TEST ---------------------------------------------
main :: IO ()
main =
(putStrLn . unlines) $
(\x ->
let sqr = x * x
in show sqr ++
(if isCube sqr
then " (also cube)"
else "")) <$>
[1 .. 33]
Output:
1 (also cube)
4
9
16
25
36
49
64 (also cube)
81
100
121
144
169
196
225
256
289
324
361
400
441
484
529
576
625
676
729 (also cube)
784
841
900
961
1024
1089

JavaScript[edit]

(() => {
'use strict';
 
const main = () =>
unlines(map(
x => x.toString() + (
isCube(x) ? (
` (cube of ${cubeRootInt(x)} and square of ${
Math.pow(x, 1/2)
})`
) : ''
),
map(x => x * x, enumFromTo(1, 33))
));
 
// isCube :: Int -> Bool
const isCube = n =>
n === Math.pow(cubeRootInt(n), 3);
 
// cubeRootInt :: Int -> Int
const cubeRootInt = n => Math.round(Math.pow(n, 1 / 3));
 
 
// GENERIC FUNCTIONS ----------------------------------
 
// enumFromTo :: Int -> Int -> [Int]
const enumFromTo = (m, n) =>
m <= n ? iterateUntil(
x => n <= x,
x => 1 + x,
m
) : [];
 
// iterateUntil :: (a -> Bool) -> (a -> a) -> a -> [a]
const iterateUntil = (p, f, x) => {
const vs = [x];
let h = x;
while (!p(h))(h = f(h), vs.push(h));
return vs;
};
 
// map :: (a -> b) -> [a] -> [b]
const map = (f, xs) => xs.map(f);
 
// unlines :: [String] -> String
const unlines = xs => xs.join('\n');
 
// MAIN ---
return main();
})();
Output:
1 (cube of 1 and square of 1)
4
9
16
25
36
49
64 (cube of 4 and square of 8)
81
100
121
144
169
196
225
256
289
324
361
400
441
484
529
576
625
676
729 (cube of 9 and square of 27)
784
841
900
961
1024
1089

Kotlin[edit]

// Version 1.2.60
 
fun main(args: Array<String>) {
var n = 1
var count = 0
while (count < 30) {
val sq = n * n
val cr = Math.cbrt(sq.toDouble()).toInt()
if (cr * cr * cr != sq) {
count++
println(sq)
}
else {
println("$sq is square and cube")
}
n++
}
}
Output:
Same as Ring example.

Pascal[edit]

Only using addition :-)

program SquareButNotCube;
var
sqN,
sqDelta,
SqNum,
 
cbN,
cbDelta1,
cbDelta2,
CbNum,
 
CountSqNotCb,
CountSqAndCb : NativeUint;
 
begin
CountSqNotCb := 0;
CountSqAndCb := 0;
SqNum := 0;
CbNum := 0;
cbN := 0;
sqN := 0;
sqDelta := 1;
cbDelta1 := 0;
cbDelta2 := 1;
repeat
inc(sqN);
inc(sqNum,sqDelta);
inc(sqDelta,2);
IF sqNum>cbNum then
Begin
inc(cbN);
cbNum := cbNum+cbDelta2;
inc(cbDelta1,6);// 0,6,12,18...
inc(cbDelta2,cbDelta1);//1,7,19,35...
end;
IF sqNum <> cbNUm then
Begin
writeln(sqNum :25);
inc(CountSqNotCb);
end
else
Begin
writeln(sqNum:25,sqN:10,'*',sqN,' = ',cbN,'*',cbN,'*',cbN);
inc(CountSqANDCb);
end;
until CountSqNotCb >= 30;//sqrt(High(NativeUint));
writeln(CountSqANDCb,' where numbers are square and cube ');
end.
Output:
                        1         1*1 = 1*1*1
                        4
                        9
                       16
                       25
                       36
                       49
                       64         8*8 = 4*4*4
                       81
                      100
                      121
                      144
                      169
                      196
                      225
                      256
                      289
                      324
                      361
                      400
                      441
                      484
                      529
                      576
                      625
                      676
                      729        27*27 = 9*9*9
                      784
                      841
                      900
                      961
                     1024
                     1089
3 where numbers are square and cube

// there are 1625 numbers which are square and cube < High(Uint64)     
//18412815093994140625  4291015625*4291015625 = 2640625*2640625*2640625

Perl[edit]

Use a hash to track state (and avoid floating-point math).

while ($cnt < 30) {
$n++;
$h{$n**2}++;
$h{$n**3}--;
$cnt++ if $h{$n**2} > 0;
}
 
print "First 30 positive integers that are a square but not a cube:\n";
print "$_ " for sort { $a <=> $b } grep { $h{$_} == 1 } keys %h;
 
print "\n\nFirst 3 positive integers that are both a square and a cube:\n";
print "$_ " for sort { $a <=> $b } grep { $h{$_} == 0 } keys %h;
Output:
First 30 positive integers that are a square but not a cube:
4 9 16 25 36 49 81 100 121 144 169 196 225 256 289 324 361 400 441 484 529 576 625 676 784 841 900 961 1024 1089

First 3 positive integers that are both a square and a cube:
1 64 729

Perl 6[edit]

my @square-and-cube = map { .}, 1..Inf;
 
my @square-but-not-cube = (1..Inf).map({ .² }).grep({ $_@square-and-cube[^@square-and-cube.first: * > $_, :k]});
 
put "First 30 positive integers that are a square but not a cube: \n", @square-but-not-cube[^30];
 
put "\nFirst 15 positive integers that are both a square and a cube: \n", @square-and-cube[^15];
Output:
First 30 positive integers that are a square but not a cube: 
4 9 16 25 36 49 81 100 121 144 169 196 225 256 289 324 361 400 441 484 529 576 625 676 784 841 900 961 1024 1089

First 15 positive integers that are both a square and a cube: 
1 64 729 4096 15625 46656 117649 262144 531441 1000000 1771561 2985984 4826809 7529536 11390625

REXX[edit]

Programming note:   line   11   could've been written as:

         sq= j**2;          cube= j**3           /*compute the square of J and the cube.*/

It would've been slightly easier to read,   but a bit slower to compute.

/*REXX pgm shows N ints>0 that are squares and not cubes, & which are squares and cubes.*/
parse arg N . /*obtain optional argument from the CL.*/
if N=='' | N=="," then N=30 /*Not specified? Then use the default.*/
w= length(N) + 3 /*W: used for aligning output columns.*/
say ' count ' /*display the 1st line of the title. */
say ' ───────' /* " " 2nd " " " " */
@@= 'is a square and' /*a text literal used for the displays.*/
$.= 0; @.= 0 /*arrays for computed: squares; cubes.*/
#=0 /*count (integer): squares & not cubes.*/
do j=1 until #==N /*loop 'til enough " " " " */
sq= j*j; cube= sq*j /*compute the square of J and the cube.*/
$.sq= 1; @.cube= 1 /*populate square array; pop cube array*/
if $.j then do; z= @.j /*if J is a square, then get value. */
if \@.j then #= #+1 /*bump counter of squares and not cubes*/
if @.z then _= right(j, 3*w) @@ "a cube"
else _= right(#': ' right(j, w), 3*w) @@ " not a cube"
say _
end
end /*j*/ /*stick a fork in it, we're all done. */
output   when using the default input:
   count
  ───────
              1 is a square and a cube
     1:       4 is a square and  not  a cube
     2:       9 is a square and  not  a cube
     3:      16 is a square and  not  a cube
     4:      25 is a square and  not  a cube
     5:      36 is a square and  not  a cube
     6:      49 is a square and  not  a cube
             64 is a square and a cube
     7:      81 is a square and  not  a cube
     8:     100 is a square and  not  a cube
     9:     121 is a square and  not  a cube
    10:     144 is a square and  not  a cube
    11:     169 is a square and  not  a cube
    12:     196 is a square and  not  a cube
    13:     225 is a square and  not  a cube
    14:     256 is a square and  not  a cube
    15:     289 is a square and  not  a cube
    16:     324 is a square and  not  a cube
    17:     361 is a square and  not  a cube
    18:     400 is a square and  not  a cube
    19:     441 is a square and  not  a cube
    20:     484 is a square and  not  a cube
    21:     529 is a square and  not  a cube
    22:     576 is a square and  not  a cube
    23:     625 is a square and  not  a cube
    24:     676 is a square and  not  a cube
            729 is a square and a cube
    25:     784 is a square and  not  a cube
    26:     841 is a square and  not  a cube
    27:     900 is a square and  not  a cube
    28:     961 is a square and  not  a cube
    29:    1024 is a square and  not  a cube
    30:    1089 is a square and  not  a cube

Ring[edit]

 
# Project : Square but not cube
 
limit = 30
num = 0
sq = 0
while num < limit
sq = sq + 1
sqpow = pow(sq,2)
flag = iscube(sqpow)
if flag = 0
num = num + 1
see sqpow + nl
else
see "" + sqpow + " is square and cube" + nl
ok
end
 
func iscube(cube)
for n = 1 to cube
if pow(n,3) = cube
return 1
ok
next
return 0
 

Output:

1 is square and cube
4
9
16
25
36
49
64 is square and cube
81
100
121
144
169
196
225
256
289
324
361
400
441
484
529
576
625
676
729 is square and cube
784
841
900
961
1024
1089

Sidef[edit]

Translation of: Perl 6
var square_and_cube = Enumerator({|f|
1..Inf -> each {|n| f(n**6) }
})
 
var square_but_not_cube = Enumerator({|f|
1..Inf -> lazy.map {|n| n**2 }.grep {|n| !n.is_power(3) }.each {|n| f(n) }
})
 
say "First 30 positive integers that are a square but not a cube:"
say square_but_not_cube.first(30).join(' ')
 
say "First 15 positive integers that are both a square and a cube:"
say square_and_cube.first(15).join(' ')
Output:
First 30 positive integers that are a square but not a cube:
4 9 16 25 36 49 81 100 121 144 169 196 225 256 289 324 361 400 441 484 529 576 625 676 784 841 900 961 1024 1089
First 15 positive integers that are both a square and a cube:
1 64 729 4096 15625 46656 117649 262144 531441 1000000 1771561 2985984 4826809 7529536 11390625

zkl[edit]

println("First 30 positive integers that are a square but not a cube:");
squareButNotCube:=(1).walker(*).tweak(fcn(n){
sq,cr := n*n, sq.toFloat().pow(1.0/3).round(); // cube root(64)<4
if(sq==cr*cr*cr) Void.Skip else sq
});
squareButNotCube.walk(30).concat(",").println("\n");
 
println("First 15 positive integers that are both a square and a cube:");
println((1).walker(*).tweak((1).pow.unbind().fp1(6)).walk(15));
Output:
First 30 positive integers that are a square but not a cube:
4,9,16,25,36,49,81,100,121,144,169,196,225,256,289,324,361,400,441,484,529,576,625,676,784,841,900,961,1024,1089

First 15 positive integers that are both a square and a cube:
L(1,64,729,4096,15625,46656,117649,262144,531441,1000000,1771561,2985984,4826809,7529536,11390625