48
\$\begingroup\$

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., true or false, 1 or 0) - truthy if the input is a perfect square, falsey if it's not.
  • This is 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
\$\endgroup\$
10
  • \$\begingroup\$ @Neil I realized my mistake. I retract that suggestion, and instead offer 18014398509481982 (2**54-2), which is representable with a double, and causes answers that use sqrt to fail. \$\endgroup\$ – user45941 Jun 8 '17 at 12:24
  • \$\begingroup\$ @Mego I'm probably wrong or just misunderstanding what you're saying, but I'm sure 2**54-2 is still larger than a double can safely handle, at least in JavaScript 18014398509481982 > 9007199254740991 \$\endgroup\$ – Tom Jun 8 '17 at 12:32
  • \$\begingroup\$ @Mego I think the limiting value is 9007199515875288. It's not the square of 94906267, because that's not representable in a double, but if you take its square root, then you get that integer as the result. \$\endgroup\$ – Neil Jun 8 '17 at 12:33
  • \$\begingroup\$ @Tom Type 2**54-2 into a JS console, and compare what you get with 18014398509481982 (the exact value). JS outputs the exact value, therefore 2**54-2 is representable with a double. If that still doesn't convince you, take the binary data 0100001101001111111111111111111111111111111111111111111111111111, interpret it as a IEEE-754 double-precision float, and see what value you get. \$\endgroup\$ – user45941 Jun 8 '17 at 12:41
  • 4
    \$\begingroup\$ Sorry, guys, stepped away for lunch and ... well, that escalated! And there I thought this would be a nice, simple challenge! Would adding a rule that you need not handle inputs that lead to floating point inaccuracies in your chosen language cover it? \$\endgroup\$ – Shaggy Jun 8 '17 at 13:17

72 Answers 72

1 2
3
1
\$\begingroup\$

Python 3, 27 25 24 bytes

saved bytes by simplifying order of operation and comparing roots instead of squared value

lambda n:n**.5//1==n**.5

Try it online!

\$\endgroup\$
5
  • \$\begingroup\$ Hello and welcome to PPCG. I think you should specify that you are using Python 3. Furthermore, is %1==0 not shorter and accomplishes the same? \$\endgroup\$ – Jonathan Frech Mar 3 '19 at 13:52
  • \$\begingroup\$ @JonathanFrech This works in 2 and 3. And yes, %1==0 is shorter and wins. Is there an easy way to filter past answers by language of implementation so I can quickly see what other users have already submitted? \$\endgroup\$ – vo1stv Mar 3 '19 at 14:11
  • 1
    \$\begingroup\$ It only works in some newer Python 2 versions. \$\endgroup\$ – Jonathan Frech Mar 3 '19 at 14:16
  • \$\begingroup\$ @JonathanFrech Ah. I don't have access to old versions of python 2. Any site like TIO that tests all versions? \$\endgroup\$ – vo1stv Mar 3 '19 at 14:19
  • \$\begingroup\$ Explicit untrue division was introduced in Python 2.2; no, unfortunately I do not know of any online Python version history interpreter site. \$\endgroup\$ – Jonathan Frech Mar 3 '19 at 14:54
1
\$\begingroup\$

SNOBOL4 (CSNOBOL4), 61 bytes

	N =INPUT
T	OUTPUT =EQ(X * X,N) 1
	X =LT(X,N) X + 1	:S(T)
END

Try it online!

Increment X until either X ^ 2 is equal to N in which case the program outputs 1 or until X > N in which case the program outputs nothing.

\$\endgroup\$
1
\$\begingroup\$

brainfuck, 42 bytes

->>,[[-<<<+>>>]<<++[[-<]<+>>>]<<<[<]>>>]<.

Try it online!

Outputs the NUL byte for square numbers and SOH for non-squares. Uses the property that square numbers are the cumulative sum of odd numbers, i.e. 1, 1+3, 1+3+5 etc.

There might be a better way of arranging the cells so as to reduce the number of pointer movements and save bytes.

\$\endgroup\$
6
  • \$\begingroup\$ Just tested this quickly on my phone and it seems to be giving different outputs for inputs of 1 & 64. \$\endgroup\$ – Shaggy Aug 27 '19 at 16:12
  • \$\begingroup\$ @Shaggy On TIO it is using input as a character code, so 1 (49) will be square but 64 (54) won't be. @ and SOH both output the NUL byte for me. You can use an interpreter like copy.sh to test actual numbers more easily \$\endgroup\$ – Jo King Aug 27 '19 at 21:11
  • \$\begingroup\$ You're not taking input as a number. Look at @Shaggy s comment on my answer. \$\endgroup\$ – Kamila Szewczyk Aug 28 '19 at 12:34
  • \$\begingroup\$ I'm using the interpreter from copy.sh which does allow input as a number. I could have sworn there was an answer under standard IO that allowed numerical input as byte code, but I can't find it. I guess I'll add it and see if it passes community consensus \$\endgroup\$ – Jo King Aug 28 '19 at 12:42
  • \$\begingroup\$ Ah, here it is. I wonder why it isn't under standard IO \$\endgroup\$ – Jo King Aug 28 '19 at 12:43
1
\$\begingroup\$

Brain-Flak, 92 bytes

(({})){{}([(({}[({})({}())])[(())])](<>)){({}())<>}{}{((<{}>))<>{}}{}<>{}}{}({()(<{}>)}{}<>)

Try it online!

\$\endgroup\$
1
\$\begingroup\$

k4, 12 9 bytes

 x=_x:sqrt

with num(s) to be checked passed right-side, e.g.

 x=_x:sqrt 36 35 25
101b

get square root and check if the it is equal to the square root cast to int. if not a square number, the square root will have a decimal place and the cast will cut the decimal off

edit: -3 thanks to ngn :)


K (oK), 8 bytes

x=`i$x:%

Try it online!

Same logic but in oK, an implementation of k6 (no online k4 interpreter that i'm aware of). Test like:

 x=`i$x:% 16 24 81
1 0 1
\$\endgroup\$
7
  • \$\begingroup\$ Could you add a TIO (or equivalent)? From your explanation, it sounds like you may have posted this to the wrong challenge. \$\endgroup\$ – Shaggy Aug 27 '19 at 9:01
  • \$\begingroup\$ @Shaggy, apologies... i did. deleting \$\endgroup\$ – scrawl Aug 27 '19 at 9:03
  • \$\begingroup\$ @Shaggy corrected \$\endgroup\$ – scrawl Aug 27 '19 at 9:17
  • \$\begingroup\$ Thanks. Could you add a link to somewhere we can test it, though? \$\endgroup\$ – Shaggy Aug 27 '19 at 10:00
  • \$\begingroup\$ @Shaggy i have added a solution in oK which can be tested at TIO! \$\endgroup\$ – scrawl Aug 27 '19 at 13:52
1
\$\begingroup\$

Forth (gforth), 31 bytes

: f dup s>f fsqrt f>s dup * = ;

Try it online!

The input is a positive signed single-cell integer (0 <= n < 2^63 for 64-bit systems). To support full unsigned integer range, do 0 d>f instead of s>f.

Using floats turns out to be shorter than a loop.

How it works

: f ( n -- f )  \ Takes a positive signed int and gives whether it's a square or not
  dup           \ Duplicate n
  s>f fsqrt f>s \ Move to floating-point stack, take sqrt and move back (truncate)
  dup * =       \ Square the result and compare with n
;

gforth's comparison operators give -1 for true, 0 for false.

\$\endgroup\$
1
\$\begingroup\$

05AB1E, 2 bytes

Ų

Try it online!

A built-in function that checks if a number is a perfect square.

\$\endgroup\$
0
\$\begingroup\$

Python 2, 33 bytes

 g = lambda x: (x**.5).is_integer()
\$\endgroup\$
3
  • \$\begingroup\$ Welcome to PPCG! There seems to be a bit of unnecessary whitespace in your entry, such as after the colon, and also anonymous lambdas are valid submissions, meaning you can omit the g= from the start. Also I believe %1!=0 is shorter than .is_integer() \$\endgroup\$ – Skidsdev Jun 15 '17 at 7:57
  • \$\begingroup\$ @Mayube You probably meant ==0? \$\endgroup\$ – Martin Ender Jun 15 '17 at 8:04
  • \$\begingroup\$ @MartinEnder I did, yes \$\endgroup\$ – Skidsdev Jun 15 '17 at 8:48
0
\$\begingroup\$

Python 2, 25 bytes

lambda n:int(n**.5)**2==n

Try it online!

\$\endgroup\$
0
\$\begingroup\$

C++, 43 bytes

bool c(int n){int t=sqrt(n);return t*t==n;}

New version: https://repl.it/repls/CompatibleJumpyCoordinates

If your number is perfect square then it will return 1, otherwise it will return 0;

Old version: https://repl.it/repls/WateryTroubledProjects (not valid because it is the snippet only by @Jonathan Frech)

If your number is perfect square then it will be exited with status 1, otherwise it will not exist;

\$\endgroup\$
3
  • \$\begingroup\$ Note that in its current form, this answer would be regarded as a snippet, which is not allowed. Please fix your answer to be of a valid form, i.e. a full program or function. \$\endgroup\$ – Jonathan Frech Mar 3 '19 at 15:43
  • \$\begingroup\$ @JonathanFrech, thank you for your comment, can I add only the function like my answer above? \$\endgroup\$ – Chau Giang Mar 3 '19 at 16:17
  • \$\begingroup\$ Yes, in its current form your answer appears to be valid. \$\endgroup\$ – Jonathan Frech Mar 3 '19 at 18:31
0
\$\begingroup\$

BFASM, 204 bytes

The function is taking input in r2 and outputs its value into r1.

lbl 1
mov r3,1
lbl 2
mov r4,r3
mul r4,r3
le_ r4,r2
jz_ r4,3
mov r4,r2
mod r4,r3
jz_ r4,4
lbl 5
inc r3
jmp 2
lbl 4
mov r4,r2
div r4,r3
eq_ r4,r3
jz_ r4,5
mov r1,1
ret
lbl 3
clr r1
ret
\$\endgroup\$
10
  • \$\begingroup\$ I think you may have posted this to the wrong challenge. \$\endgroup\$ – Shaggy Aug 27 '19 at 9:48
  • \$\begingroup\$ @Shaggy why did I? \$\endgroup\$ – Kamila Szewczyk Aug 27 '19 at 9:48
  • \$\begingroup\$ The challenge is about determining whether a number is a perfect square or not, which neither of your solutions appears to do. \$\endgroup\$ – Shaggy Aug 27 '19 at 9:51
  • \$\begingroup\$ @Shaggy I'm streteching the I/O rules a bit, because it's inpractical as heck to read a number in Brainfuck, therefore I perform a single read. There are some integer based brainfuck interpreters so theoretically this solution is valid. \$\endgroup\$ – Kamila Szewczyk Aug 27 '19 at 9:52
  • \$\begingroup\$ Unless we have a consensus on this input format, I'm going to say it's not valid for this challenge as the spec explicitly states that you will be given an integer as input. \$\endgroup\$ – Shaggy Aug 27 '19 at 9:55
0
\$\begingroup\$

BRASCA, 8 bytes

ig:s2^=n

Try it!

Explanation

ig          - Turn input into digits, and concatenate
  :s2^      - Dupe original number, sqrt it, then square it
      =n    - Are the original and the modified number the same? Print the result (0 or 1)
\$\endgroup\$
1 2
3

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.