Challenge
So, um, it seems that, while we have plenty of challenges that work with square numbers or numbers of other shapes, we don't have one that simply asks:
Given an integer n (where n>=0) as input return a truthy value if n is a perfect square or a falsey value if not.
Rules
- You may take input by any reasonable, convenient means as long as it's permitted by standard I/O rules.
- You need not handle inputs greater than what your chosen language can natively handle nor which would lead to floating point inaccuracies.
- Output should be one of two consistent truthy/falsey values (e.g.,
trueorfalse,1or0) - truthy if the input is a perfect square, falsey if it's not. - This is code-golf so lowest byte count wins.
Test Cases
Input: 0
Output: true
Input: 1
Output: true
Input: 64
Output: true
Input: 88
Output: false
Input: 2147483647
Output: false
84 Answers 84
Ohm, 2 bytes
Æ2
Uses CP-437 encoding.
Explanation
Implicit Input -> Perfect square built-in -> Implicit Output...
-
\$\begingroup\$ Not debatable: the question explicitly says "Given an integer n (where n>=0)". The shortest answer is the best. Edit: won't +1 until the shortest answer isn't the first :p \$\endgroup\$Olivier Grégoire– Olivier Grégoire2017年06月08日 13:03:59 +00:00Commented Jun 8, 2017 at 13:03
-
\$\begingroup\$ @OlivierGrégoire Hmm, that's a good way to look at it. But you still wouldn't know whether it's an
int,long,short. And with questions where they ask for an integer but the input format is flexible, I sometimes use a String input to save some bytes. Personally I think usingn->is fine, and you should just state what the type is, but apparently not everyone agrees with this. On the other hand, coming from a Java 7 answer history, going fromint c(int n){return ...;}to(int n)->...makes more sense thann->...(even though I personally prefer the second since shorter of course). \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2017年06月08日 13:10:06 +00:00Commented Jun 8, 2017 at 13:10 -
2\$\begingroup\$ @OlivierGrégoire Ok, I've changed it. After reading the discussion in this answer, I came to the conclusion that stating the input is an integer in Java, is no difference than stating the input is a list of two Strings in CJam or a cell array of strings in MATL. \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2017年06月09日 08:05:10 +00:00Commented Jun 9, 2017 at 8:05
-
\$\begingroup\$ nvm, I'm stupid :P \$\endgroup\$0xff– 0xff2021年10月16日 12:55:36 +00:00Commented Oct 16, 2021 at 12:55
Add++, (削除) 24 (削除ここまで) (削除) 13 (削除ここまで) 11 bytes
+?
S
%1
N
O
I removed the clunky function at the top and rewrote it into the body of the question to remove 11 bytes.
As the first section is already explained below, let's only find out how the new part works
S Square root
%1 Modulo by 1. Produced 0 for integers and a decimal for floats
N Logical NOT
Old version, 24 bytes
D,i,@,1@%!
+?
^.5
$i,x
O
The function at the top (D,i,@,1@%!) is the main part of the program, so let's go into more detail.
D, Create a function...
i, ...called i...
@, ...that takes 1 argument (for this example, let's say 3.162 (root 10))
1 push 1 to the stack; STACK = [1, 3.162]
@ reverse the stack; STACK = [3.162, 1]
% modulo the stack; STACK = [0.162]
! logical NOT; STACK = [False]
+? Add the input to accumulator (x)
^.5 Square root (exponent by 0.5)
$i,x Apply function i to x
O Output the result
Python 3, (削除) 28 27 (削除ここまで) 25 bytes
- Thanks to @mdahmoune for 1 byte: compare int of root squared with original
- 2 bytes saved: lambda shortened
lambda x:int(x**.5)**2==x
-
1\$\begingroup\$ what about f=lambda x:int(x**.5)**2==x 27bytes \$\endgroup\$mdahmoune– mdahmoune2017年07月03日 15:30:36 +00:00Commented Jul 3, 2017 at 15:30
JavaScript on NodeJS & Chrome, 51 bytes
// OLD: t=n=>{i=Number.isSafeInteger;return i(n)&&i(n**.5)}
i=Number.isSafeInteger;t=n=>i(n)&&i(n**.5)
// TestCases:
let l=console.log;l(`t(1): ${t(1)}; t(64): ${t(64)}; t(88): ${t(88)};`)
-
\$\begingroup\$ Welcome to PPCG. You don't need to include the
t=in your byte count nor is input validation required for this challenge. \$\endgroup\$Shaggy– Shaggy2017年06月08日 14:00:49 +00:00Commented Jun 8, 2017 at 14:00 -
\$\begingroup\$ Also works for Firefox \$\endgroup\$WORNG ALL– WORNG ALL2017年07月03日 14:57:53 +00:00Commented Jul 3, 2017 at 14:57
-
\$\begingroup\$ @rickhitchcock does have a point - input validation should not be required! Quote: "You need not handle inputs greater than what your chosen language can natively handle nor which would lead to floating point inaccuracies." \$\endgroup\$BogdanBiv– BogdanBiv2017年07月10日 13:27:37 +00:00Commented Jul 10, 2017 at 13:27
Python, (削除) 53 (削除ここまで) (削除) 50 (削除ここまで) (削除) 49 (削除ここまで) (削除) 48 (削除ここまで) (削除) 49 (削除ここまで) 48 bytes
This should in theory work for an input of any size. Returns True if the given number is a square, False otherwise.
f=lambda n,x=0:x<=n if~-(x<=n!=x*x)else f(n,x+1)
Explanation:
f= # assign a name so we can call it
lambda n,x=0: # counter variable x
x<=n # counter bigger than input?
if~-( ) # "negate" inner condition
x<=n # counter not bigger
n!=x*x # and n not square of x
else f(n,x+1) # else recurse
The condition is just a de-Morgan'd if x>n or n==x**2, i.e. we return if the counter is bigger than the input, or we found a proof for squareness.
Saved 1 byte thanks to Gábor Fekete.
-
\$\begingroup\$ Your outputs are the wrong way 'round ;) \$\endgroup\$Shaggy– Shaggy2017年06月08日 13:21:44 +00:00Commented Jun 8, 2017 at 13:21
-
\$\begingroup\$ Technically, my output is "one of two consistent truthy/falsey values". But if you deem this invalid, I can correct it at the cost of one byte. \$\endgroup\$L3viathan– L3viathan2017年06月08日 13:27:31 +00:00Commented Jun 8, 2017 at 13:27
-
\$\begingroup\$ I'll edit the question to clarify, I see now that my phrasing in the rules was open to "interpretation", although it was clearer in the intro. \$\endgroup\$Shaggy– Shaggy2017年06月08日 13:30:39 +00:00Commented Jun 8, 2017 at 13:30
-
1\$\begingroup\$ @Shaggy Yes, done. \$\endgroup\$L3viathan– L3viathan2017年06月08日 13:38:55 +00:00Commented Jun 8, 2017 at 13:38
-
1\$\begingroup\$ Use
x*xinstead ofx**2, saves 1 byte :) \$\endgroup\$Gábor Fekete– Gábor Fekete2017年06月08日 14:29:27 +00:00Commented Jun 8, 2017 at 14:29
Actually, 6 bytes
;ur♂2c
-2 bytes from Erik the Outgolfer
Explanation:
;ur♂2c
;ur range(n+1) ([0, n])
♂2 square each element
c does the list contain the input?
This takes a while for large inputs - TIO will timeout.
-
\$\begingroup\$ Can't you replace
íubwithc? \$\endgroup\$Erik the Outgolfer– Erik the Outgolfer2017年06月09日 15:09:16 +00:00Commented Jun 9, 2017 at 15:09 -
\$\begingroup\$ @EriktheOutgolfer You're absolutely right I believe, and I have a lot of answers to update because I didn't think about that. \$\endgroup\$user45941– user459412017年06月10日 01:30:12 +00:00Commented Jun 10, 2017 at 1:30
-
\$\begingroup\$ I actually tried to outgolf you, but then I thought the algorithm was way too similar to post, so I converted it to a golfing tip instead... \$\endgroup\$Erik the Outgolfer– Erik the Outgolfer2017年06月10日 10:09:36 +00:00Commented Jun 10, 2017 at 10:09
C (gcc), (削除) 66 (削除ここまで) (削除) 43 (削除ここまで) 42 bytes
f(float n){return!(sqrt(n)-(int)sqrt(n));}
Thanks to TheLethalCoder for the tip!
@hvd Thanks for saving a byte!
-
\$\begingroup\$ Can you just do:
bool f(float n){return !sqrt(n)-(int)sqrt(n)>0;}or similar? Been a while since I've used C. \$\endgroup\$TheLethalCoder– TheLethalCoder2017年06月08日 12:21:05 +00:00Commented Jun 8, 2017 at 12:21 -
\$\begingroup\$ @TheLethalCoder yea absolutely man. :) i would have to incluede stdbool.h though, therefore int as return type would be shorter. \$\endgroup\$Abel Tom– Abel Tom2017年06月08日 12:26:38 +00:00Commented Jun 8, 2017 at 12:26
-
\$\begingroup\$ There's no need for a space between
returnand!. \$\endgroup\$hvd– hvd2017年06月11日 13:54:33 +00:00Commented Jun 11, 2017 at 13:54 -
1\$\begingroup\$ Suggest
f(n)instead off(float n)and(n=sqrt(n))instead of(int)sqrt(n). \$\endgroup\$ceilingcat– ceilingcat2017年11月02日 04:33:24 +00:00Commented Nov 2, 2017 at 4:33
MIPS, 112 bytes
main:li $v0,7
syscall
sqrt.d $f0,$f0
mfc1 $a0,$f0
li $v0,1
beqz $a0,t
li $a0,0
syscall
b e
t:li $a0,1
syscall
e:
Outputs 1 if the input is square, 0 if not.
Explanation
main:li $v0,7 #Start of program. Load service 7 (read input as float to $f0).
#Input can be an integer, but MIPS will interpret it as a float.
syscall #Execute.
sqrt.d $f0,$f0 #Overwrite $f0 with its square root, stored as a double.
mfcl $a0,$f0 #Move $f0 to $a0.
li $v0,1 #Load service 1 (print int from $a0).
beqz $a0,t #Branch to label 't' if $a0 = 0. Otherwise continue.
#If input is non-square...
li $a0,0 #Load 0 into $a0.
syscall #Execute (print $a0).
b e #Branch to label 'e'.
#If input is square...
t:li $a0,1 #Start of label 't'. Load 1 into $a0.
syscall #Execute (print $a0).
e: #Start of label 'e'. Used to avoid executing 't' when input isn't square.
A double in MIPS is 16 hexes. It shares its address with a float containing its low-order 8 hexes ($f0 in this case). The high-order hexes are stored in the next register ($f1), also as a float.
float double
$f0 0000 0000 1111 1111 0000 0000
$f1 1111 1111
Taking the square root of a non-square number requires the entire double in order to be stored, meaning the high and low floats are populated. The square root of a square number only needs a few hexes from the double to be stored, and it is stored specifically in its high-order hexes. This means the low float is left at 0.
If the low float equals 0, the input is a square number.
-
\$\begingroup\$ you have a bit of superfluous whitespace \$\endgroup\$ASCII-only– ASCII-only2019年03月13日 03:49:07 +00:00Commented Mar 13, 2019 at 3:49
-
\$\begingroup\$ 91? \$\endgroup\$ASCII-only– ASCII-only2019年03月13日 04:17:31 +00:00Commented Mar 13, 2019 at 4:17
Whitespace, 95 bytes
[S S S N
_Push_0][S N
S _Duplicate_top][T N
T T _Read_STDIN_as_integer][N
S S N
_Create_Label_LOOP][S N
S _Duplicate_top][S N
S _Duplicate_top][T S S N
_Multiply_top_two][S S S N
_Push_0][T T T _Retrieve_input][S N
T _Swap_top_two][T S S T _Subtract][S N
S _Duplicate_top][N
T S S N
_If_0_jump_to_Label_TRUE][N
T T T N
_If_negative_jump_to_Label_FALSE][S S S T N
_Push_1][T S S S _Add][N
S N
N
_Jump_to_Label_LOOP][N
S S S N
_Create_Label_TRUE][S S S T N
_Push_1][T N
S T _Print_as_integer][N
N
N
_Stop_program][N
S S T N
_Create_Label_FALSE][S S S N
_Push_0][T N
S T _Print_as_integer]
Letters S (space), T (tab), and N (new-line) added as highlighting only.
[..._some_action] added as explanation only.
Outputs 1/0 for truthy/falsey respectively. A few bytes could be saved if something like 00/0 for truthy/falsey is allowed instead.
Try it online (with raw spaces, tabs and new-lines only).
Explanation in pseudo-code:
Read STDIN as integer, and store it in the heap
Integer i = 0
Start LOOP:
Integer temp = i*i - input from heap
If(temp == 0):
Call function TRUE
If(temp < 0):
Call function FALSE
i = i + 1
Go to next iteration of LOOP
function TRUE:
Print 1 as integer
Stop program
function FALSE:
Print 0 as integer
(implicitly stop the program with an error)
Here a port of this approach in Java:
int func(int input){
for(int i=0; /*infinite loop*/; i++){
int m = input - i*i;
if(m==0) return 1;
if(m<1) return 0;
}
}
Rockstar, 55 bytes
First time posting a solution to one of my own challenges, if you'll forgive me the indulgence.
Outputs 1 for truthy or nothing for falsey.
listen to N
X's0
while N-X
let X be+1
if X*X is N
say 1
Try it here (Code will need to be pasted in)
-
1\$\begingroup\$ For a Rockstar answer, anything can be forgiven. \$\endgroup\$user– user2021年03月22日 00:57:40 +00:00Commented Mar 22, 2021 at 0:57
V (vim), 34 bytes
C<C-r>=sqrt(<C-r>")
<esc>:s/.\+\.0\n
:s/.\+/1
Returns empty string for a square, 1 for non-square.
Explanation
C<C-r>=sqrt(<C-r>")
C cut the input line, enter insert mode
<C-r>= evaluate the following math command:
sqrt( ) square root of
<C-r>" cut input line in register "
<esc>:s/.\+\.0\n/
<esc> exit insert mode
:s/.\+\.0\n/ remove instance of <digits>.0
this removes a perfect square root.
:s/.\+/1 replace any other non-newline chars left with
a single 1.
JavaScript, 44 bytes
n=>{for(i=0n;i<=n;){if(i++**2n==n)return 1}}
Obligatory bigger but BigInt answer.
Returns 1 if a square, or undefined when not a square.
+4 bytes if you want to actually get your answer today:
n=>{for(i=0n;i**2n<=n;){if(i++**2n==n)return 1}}
-
\$\begingroup\$ @emanresuA could you elaborate on how the first one would be but not the second? because the only thing I can think of is
inot fitting in your memory at some point, but that can happen for both \$\endgroup\$Leaf– Leaf2024年03月07日 09:49:54 +00:00Commented Mar 7, 2024 at 9:49 -
1\$\begingroup\$ Ah, never mind, I misread it as not having a condition on the loop. Sorry \$\endgroup\$emanresu A– emanresu A2024年03月07日 18:36:42 +00:00Commented Mar 7, 2024 at 18:36
Knight, (削除) 32 (削除ここまで) (削除) 33 (削除ここまで) (削除) 32 (削除ここまで) 30 bytes
;=i+1=xP;W!>0=i-i 1|-^i 2xQ1Q0
Takes input from standard in, outputs by error code (1 if input is square, 0 otherwise).
Expanded code:
;=i +1 (=x PROMPT)
;WHILE !> 0(=i -i 1)
| (-(^i 2) x)
QUIT 1
QUIT 0
+1 bytes from @Jonah because I somehow didn't notice this failed on input 1
-2 bytes from @Jonah by using short circuit evaluation of | instead of IF
-
\$\begingroup\$ I think
Q?0xcan just beQ0because if you get there we know it's not square. \$\endgroup\$Jonah– Jonah2022年08月06日 20:29:38 +00:00Commented Aug 6, 2022 at 20:29 -
1\$\begingroup\$ @Jonah if the input is 0, then the while loop will never run, so it will go straight to the "false" case -- I need to check for that. \$\endgroup\$97.100.97.109– 97.100.97.1092022年08月06日 20:32:43 +00:00Commented Aug 6, 2022 at 20:32
-
\$\begingroup\$ I see. Looks like current answer fails for 1. \$\endgroup\$Jonah– Jonah2022年08月06日 20:36:38 +00:00Commented Aug 6, 2022 at 20:36
-
1\$\begingroup\$ -2 with
;=i+1=xP;W!>0=i-i 1|-^i 2xQ1Q0\$\endgroup\$Jonah– Jonah2022年08月06日 21:14:36 +00:00Commented Aug 6, 2022 at 21:14
-
\$\begingroup\$ An alternative 5-byte solution that doesn't work for larger numbers (e.g.
2**127 - 1) would besI@Q2, but I have to admit that I am quite fond of your right map answer. \$\endgroup\$notjagan– notjagan2017年06月08日 15:19:25 +00:00Commented Jun 8, 2017 at 15:19
QBIC, (削除) 16 (削除ここまで) 18 bytes
[:|~b/a=a|_Xq}?b=0
Added two bytes for 0-case
This runs through i = 1 ... n to see if n / i == i. Prints 1 if such an i is found, prints -1 for N=0 and 0 in all other cases. Both 1 and -1 are considered truthy in QBasic (-1 being the actual value for true, but IF (n) only is false on n=0).
-
\$\begingroup\$ Can you add a TIO (or equivalent)? \$\endgroup\$Shaggy– Shaggy2017年06月08日 13:21:06 +00:00Commented Jun 8, 2017 at 13:21
-
\$\begingroup\$ @Shaggy unfortunately not. My attempts to have QBasic / QBIC / DosBox run on a webpage have been unfruitful, to put it mildly... I've considered running it from CGI, but QBasic is just too powerful to do that, that's asking for exploits... I'm open to suggestions. \$\endgroup\$steenbergh– steenbergh2017年06月08日 13:23:40 +00:00Commented Jun 8, 2017 at 13:23
-
\$\begingroup\$ I just wanted to check if it returns
truefor0. \$\endgroup\$Shaggy– Shaggy2017年06月08日 13:25:28 +00:00Commented Jun 8, 2017 at 13:25 -
\$\begingroup\$ @Shaggy it would print 0 for N=0. It never enters the FOR loop and jumps straight to the last statement. I'll fix that \$\endgroup\$steenbergh– steenbergh2017年06月08日 13:28:52 +00:00Commented Jun 8, 2017 at 13:28
J, 8 bytes
(=~<.)%:
Explanation:
%:square root=~is the argument equal to itself<.floor of=~<.a J hook, which modifies the right argument by applying<.- so, "is the floor of the square root equal to itself?"
Note: If we want to save the above to a variable as a verb, we must do, eg:
issq=.(=~<.)@%:
-
-
\$\begingroup\$ I tried it, but it's not producing any output. Not sure if the J interpreter is down or if I'm missing something, but if you paste the following test into jconsole:
(=~<.)%: 1 4 9 16 ,: 2 3 7 21it will return a table with a row of1s on top of a row of0s, as expected. I tried putting the same into the "Code" section of TIO and then hitting run, but I get no output. \$\endgroup\$Jonah– Jonah2017年06月09日 18:24:05 +00:00Commented Jun 9, 2017 at 18:24
C, 33 bytes
#define f(x)sqrt(x)==(int)sqrt(x)
Takes an integer x. Checks if the square root of x is the square root of x rounded to an integer.
Pyke, 3 bytes
,$P
, - sqrt(input)
$ - float(^)
P - is_int(^)
This could be two bytes (and is in older versions) if Pyke didn't helpfully automatically cast the results of sqrt to an integer if it's a square number.
Charcoal, 8 bytes
¬%XN·5¦1
Explanation
¬ Not
% ¦1 Modulo 1
X ·5 To the power of .5
N Next input as number,
05AB1E, (削除) 5 (削除ここまで) 3 bytes
t.ï
(削除) Longer than @Erik's but just wanted to give it a shot. (削除ここまで)
Now shorter than Erik's but fails for large numbers...
Explanation
t # square roots the input
.ï # checks if number on stack is an int
# implicit output of result (0 or 1)
Python 3, (削除) 39 (削除ここまで) 38 Bytes
lambda n:n in(i*i for i in range(n+1))
@mathmandan I had the same idea, and this implementation is 1 byte shorter. I wanted to comment on your post but do not yet have 50 reputation. I hope you see this!
This is just brute force, and I did not get it to complete 2147483647 in a
reasonable amount of time.
Thanks @DJMcMayhem for suggesting i remove the space after in
-
\$\begingroup\$ Welcome to the site! Just FYI, you could remove a space after
in\$\endgroup\$DJMcMayhem– DJMcMayhem2017年06月09日 20:04:33 +00:00Commented Jun 9, 2017 at 20:04 -
Excel, (削除) 18 (削除ここまで) 16 bytes
=MOD(A1^0.5,1)=0
Common Lisp, 30 bytes
(defun g(x)(=(mod(sqrt x)1)0))
or, with the same length,
(defun g(x)(integerp(sqrt x)))
Ruby, 16 bytes
->n{n**0.5%1==0}
Trivial solution.
tinylisp, 67 bytes
(load library
(d S(q((n)(contains?(map(q((x)(* x x)))(c 0(1to n)))n
Generates a list of numbers from 0 through n, maps a lambda function that squares each one, and checks if n is in the resulting list of squares. Wildly inefficient, of course.
Here's a 77-byte solution that doesn't use the library and runs an order of magnitude faster:
(d _(q((x n s)(i(e n s)1(i(l n s)0(_(a x 1)n(a s(a x(a x 1
(d S(q((n)(_ 0 n 0
This one uses a helper function _ which tracks a counter x and its square s. At each level of recursion, we return success if s equals n and failure if s is greater than n; otherwise, if s is still less than n, we recurse, incrementing x and calculating the next s by the formula (x+1)^2 = x^2 + x + x + 1.
Explore related questions
See similar questions with these tags.
18014398509481982(2**54-2), which is representable with a double, and causes answers that usesqrtto fail. \$\endgroup\$2**54-2is still larger than a double can safely handle, at least in JavaScript18014398509481982 > 9007199254740991\$\endgroup\$2**54-2into a JS console, and compare what you get with18014398509481982(the exact value). JS outputs the exact value, therefore2**54-2is representable with a double. If that still doesn't convince you, take the binary data0100001101001111111111111111111111111111111111111111111111111111, interpret it as a IEEE-754 double-precision float, and see what value you get. \$\endgroup\$