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

3
\$\begingroup\$

Ohm, 2 bytes

Ʋ

Uses CP-437 encoding.

Explanation

Implicit Input -> Perfect square built-in -> Implicit Output...

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

Java 8, 20 bytes

n->Math.sqrt(n)%1==0

Input is an int.

Try it here.

\$\endgroup\$
3
  • \$\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 Jun 8 '17 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 using n-> 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 from int c(int n){return ...;} to (int n)->... makes more sense than n->... (even though I personally prefer the second since shorter of course). \$\endgroup\$ – Kevin Cruijssen Jun 8 '17 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 Jun 9 '17 at 8:05
3
\$\begingroup\$

Add++, 24 13 11 bytes

+?
S
%1
N
O

Try it online!

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

Try it online!

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
\$\endgroup\$
3
\$\begingroup\$

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

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ what about f=lambda x:int(x**.5)**2==x 27bytes \$\endgroup\$ – mdahmoune Jul 3 '17 at 15:30
2
\$\begingroup\$

CJam, 12 bytes

{_),2f##)!!}

Try it online!

\$\endgroup\$
2
\$\begingroup\$

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)};`)

Try it online!

\$\endgroup\$
3
  • \$\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 Jun 8 '17 at 14:00
  • \$\begingroup\$ Also works for Firefox \$\endgroup\$ – WORNG ALL Jul 3 '17 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 Jul 10 '17 at 13:27
2
\$\begingroup\$

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)

Try it online!

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.

\$\endgroup\$
7
  • \$\begingroup\$ Your outputs are the wrong way 'round ;) \$\endgroup\$ – Shaggy Jun 8 '17 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 Jun 8 '17 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 Jun 8 '17 at 13:30
  • 1
    \$\begingroup\$ @Shaggy Yes, done. \$\endgroup\$ – L3viathan Jun 8 '17 at 13:38
  • 1
    \$\begingroup\$ Use x*x instead of x**2, saves 1 byte :) \$\endgroup\$ – Gábor Fekete Jun 8 '17 at 14:29
2
\$\begingroup\$

Actually, 6 bytes

;ur♂²c

Try it online!

-2 bytes from Erik the Outgolfer

Explanation:

;ur♂²c
;ur       range(n+1) ([0, n])
   ♂²     square each element
     c    does the list contain the input?

This takes a while for large inputs - TIO will timeout.

\$\endgroup\$
3
  • \$\begingroup\$ Can't you replace íub with c? \$\endgroup\$ – Erik the Outgolfer Jun 9 '17 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 Jun 10 '17 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 Jun 10 '17 at 10:09
2
\$\begingroup\$

C (gcc), 66 43 42 bytes

f(float n){return!(sqrt(n)-(int)sqrt(n));}

Try it online!

Thanks to TheLethalCoder for the tip!

@hvd Thanks for saving a byte!

\$\endgroup\$
4
  • \$\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 Jun 8 '17 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 Jun 8 '17 at 12:26
  • \$\begingroup\$ There's no need for a space between return and !. \$\endgroup\$ – hvd Jun 11 '17 at 13:54
  • 1
    \$\begingroup\$ Suggest f(n) instead of f(float n) and (n=sqrt(n)) instead of (int)sqrt(n). \$\endgroup\$ – ceilingcat Nov 2 '17 at 4:33
2
\$\begingroup\$

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:

Try it online!

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.

\$\endgroup\$
2
2
\$\begingroup\$

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;
  }
}

Try it online.

\$\endgroup\$
2
\$\begingroup\$

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)

\$\endgroup\$
1
  • 1
    \$\begingroup\$ For a Rockstar answer, anything can be forgiven. \$\endgroup\$ – user Mar 22 at 0:57
2
\$\begingroup\$

V (vim), 34 bytes

C<C-r>=sqrt(<C-r>")
<esc>:s/.\+\.0\n
:s/.\+/1

Try it online!

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.
\$\endgroup\$
1
\$\begingroup\$

Pyth, 5 bytes

/^R2h

Try it here!

\$\endgroup\$
1
  • \$\begingroup\$ An alternative 5-byte solution that doesn't work for larger numbers (e.g. 2**127 - 1) would be sI@Q2, but I have to admit that I am quite fond of your right map answer. \$\endgroup\$ – notjagan Jun 8 '17 at 15:19
1
\$\begingroup\$

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).

\$\endgroup\$
4
  • \$\begingroup\$ Can you add a TIO (or equivalent)? \$\endgroup\$ – Shaggy Jun 8 '17 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 Jun 8 '17 at 13:23
  • \$\begingroup\$ I just wanted to check if it returns true for 0. \$\endgroup\$ – Shaggy Jun 8 '17 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 Jun 8 '17 at 13:28
1
\$\begingroup\$

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=.(=~<.)@%:
\$\endgroup\$
2
  • \$\begingroup\$ Could you add a TIO (or equivalent) to this, please? \$\endgroup\$ – Shaggy Jun 9 '17 at 8:19
  • \$\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 21 it will return a table with a row of 1s on top of a row of 0s, as expected. I tried putting the same into the "Code" section of TIO and then hitting run, but I get no output. \$\endgroup\$ – Jonah Jun 9 '17 at 18:24
1
\$\begingroup\$

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.

Try it online!

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

Pari/GP, 8 bytes

issquare

Try it online!

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

Pyke, 3 bytes

,$P

Try it here!

,   -   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.

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

Charcoal, 8 bytes

¬﹪XN·⁵¦¹

Try it online!

Explanation

¬           Not
 ﹪      ¦¹ Modulo 1
   X  ·⁵   To the power of .5
     N     Next input as number, 
\$\endgroup\$
1
\$\begingroup\$

05AB1E, 5 3 bytes

t.ï

Try it online!

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)
\$\endgroup\$
1
\$\begingroup\$

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

Try it Online

\$\endgroup\$
2
  • \$\begingroup\$ Welcome to the site! Just FYI, you could remove a space after in \$\endgroup\$ – DJMcMayhem Jun 9 '17 at 20:04
  • \$\begingroup\$ Could you add a TIO or equivalent, please? \$\endgroup\$ – Shaggy Jul 3 '17 at 16:11
1
\$\begingroup\$

Excel, 18 16 bytes

=MOD(A1^0.5,1)=0
\$\endgroup\$
1
\$\begingroup\$

Common Lisp, 30 bytes

(defun g(x)(=(mod(sqrt x)1)0))

Try it online!

or, with the same length,

(defun g(x)(integerp(sqrt x)))
\$\endgroup\$
1
\$\begingroup\$

><>, 22+3 = 25 bytes

01-\:*=n;
(?!\1+::*{:}

Try it online!

Input is expected on the stack at program start, so +3 bytes for the -v flag.

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

Ruby, 16 bytes

->n{n**0.5%1==0}

Trivial solution.

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

tinylisp, 67 bytes

(load library
(d S(q((n)(contains?(map(q((x)(* x x)))(c 0(1to n)))n

Try it online!

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

Try it online!

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.

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

Julia 0.6, 12 bytes

n->√n%1==0

Try it online!

Pretty straightforward, having the Unicode for square-root saves a few bytes.

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

Japt -¡E, 2 bytes

¬d

Run it online

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

PowerShell, 26 bytes

!([math]::Sqrt("$args")%1)

Try it online!

\$\endgroup\$

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.