A Fun Perfect Square Checker Using Integer Arithmetic Only... ;o)
A recent Python upload on another site gave me the inspiration to do an unusual bash version...
This is a little tongue-in-cheek but an enjoyable bit of fun.
It took around 11 seconds to prove 90000000000 had a perfect square of 300000...
It is a stand alone program and has a degree of INPUT error correction...
It was done on a MacBook Pro, OSX 10.7.5, default bash terminal and should work on Linux and UNIX flavours but it is untested...
Enjoy finding simple solutions to often very difficult problems...
Bazza...
Code:
#!/bin/bash
# perfect_square <number>
number=$1
if [ "$number" -eq "$number" ] > /dev/null 2>&1
then
if [ $number -lt 0 ]
then
echo "Warning! Integer is negative!!!"
echo "Set input integer to the DEMO value of 99..."
number=99
fi
else
echo "Invalid Argument! Set input integer to the DEMO value of 100..."
number=100
fi
series=1
square=1
root=1
while true
do
if [ $square -le $number ]
then
if [ $square -eq $number ]
then
echo "$number is the perfect square of $root..."
exit 0
fi
root=$((root+1))
series=$((series+2))
square=$((square+series))
else
echo "Integer $number is not a perfect square..."
exit 1
fi
done
exit 0
# Last login: Tue Sep 16 20:12:27 on ttys000
# AMIGA:barrywalker~> chmod 755 perfect_square
# AMIGA:barrywalker~> ./perfect_square ierooeirt
# Invalid Argument! Set input integer to the DEMO value of 100...
# 100 is the perfect square of 10...
# AMIGA:barrywalker~> ./perfect_square -345
# Warning! Integer is negative!!!
# Set input integer to the DEMO value of 99...
# Integer 99 is not a perfect square...
# AMIGA:barrywalker~> ./perfect_square 0
# Integer 0 is not a perfect square...
# AMIGA:barrywalker~> ./perfect_square 123.9
# Invalid Argument! Set input integer to the DEMO value of 100...
# 100 is the perfect square of 10...
# AMIGA:barrywalker~> ./perfect_square 625
# 625 is the perfect square of 25...
# AMIGA:barrywalker~> ./perfect_square 1
# 1 is the perfect square of 1...
# AMIGA:barrywalker~> ./perfect_square 11111
# Integer 11111 is not a perfect square...
# AMIGA:barrywalker~> ./perfect_square oiwero11234ldkf
# Invalid Argument! Set input integer to the DEMO value of 100...
# 100 is the perfect square of 10...
# AMIGA:barrywalker~> ./perfect_square -0.0
# Invalid Argument! Set input integer to the DEMO value of 100...
# 100 is the perfect square of 10...
# AMIGA:barrywalker~> ./perfect_square -1.25
# Invalid Argument! Set input integer to the DEMO value of 100...
# 100 is the perfect square of 10...
# AMIGA:barrywalker~> ./perfect_square -1
# Warning! Integer is negative!!!
# Set input integer to the DEMO value of 99...
# Integer 99 is not a perfect square...
# AMIGA:barrywalker~> _
This User Gave Thanks to wisecracker For This Post:
On the same system, using ksh instead of bash, try:
Code:
#!/bin/ksh
# perfect_square <number>
number=$1
if [ "$number" -eq "$((int(number)))" ] > /dev/null 2>&1
then
if [ "$number" -lt 0 ]
then
echo "Warning! Integer is negative!!!"
echo "Set input integer to the DEMO value of 99..."
number=99
fi
else
echo "Invalid Argument! Set input integer to the DEMO value of 100..."
number=100
fi
root=$((int(number ** .5)))
square=$((root ** 2))
if [ $square -eq $number ]
then
echo "$number is the perfect square of $root..."
exit 0
else
echo "Integer $number is not a perfect square..."
exit 1
fi
PS Timing the script:
Code:
time perfect_square 90000000000
90000000000 is the perfect square of 300000...
real 0m0.00s
user 0m0.00s
sys 0m0.01s
Unfortunately, however, this only works with a 1993 or later version of ksh.
Last edited by Don Cragun; 08-19-2015 at 06:48 PM..
Reason: Adding timing results (11 seconds vs. .01 seconds) and disclaimer.
This User Gave Thanks to Don Cragun For This Post:
mute@tiny:~$ time gawk -f ./square1 <<< $'90000000000\n4\n1'
90000000000 is the perfect square of 300000
4 is the perfect square of 2
1 is the perfect square of 1
real 0m0.081s
user 0m0.063s
sys 0m0.016s
Code:
{
number=$1
series=1
square=1
root=1
while (square <= number) {
if (square == number) {
printf("%d is the perfect square of %d\n", number, root)
next
}
root++
series+=2
square+=series
}
print "Not a perfect square"
next
}
---------- Post updated at 10:58 PM ---------- Previous update was at 10:45 PM ----------
using a binary search was idea taken from friend.. they implemented in bash and I again convert to awk. using "one true awk" is a tad faster than gawk
Code:
mute@tiny:~$ time bawk -f ./square2 90000000000
90000000000 is a perfect square of 300000
real 0m0.002s
user 0m0.001s
sys 0m0.001s
Code:
#!/usr/bin/awk -f
BEGIN {
num = ARGV[1]
i = 10
while (i * i < num)
i *= 10
lower = i/10
upper = i
while ( (avg = (upper + lower) / 2) != lower )
if (avg * avg > num)
upper = avg
else
lower = avg
if (avg * avg == num)
print num" is a perfect square of "avg
else
print num" is not a perfect square"
exit
}
Last edited by neutronscott; 08-21-2015 at 01:04 PM..
These 2 Users Gave Thanks to neutronscott For This Post:
Don cheated!!
... ... ... ---------- Post updated at 10:58 PM ---------- Previous update was at 10:45 PM ----------
using a binary search was idea taken from friend.. they implemented in bash and I again convert to awk.
... ... ...
Let me get this straight... I use a different algorithm in a ksh script and get better times than using the original algorithm in a bash script, and I'm cheating...
But neutronscott uses a different algorithm in awk to get times similar to my ksh script and that's OK???
Sounds like a different standard of fairness to me.
EDIT: :doh: nevermind to much of math/conditition issues here atm, this is just one of those times i wish one could delete one owns post as long noone else has replied to the thread.
I seem to have created a riot on this thread; now let me mediate.
Firstly I did quote using "INTEGER arithmetic".
Secondly I also quoted "it is a little tongue-in-cheek".
And thirdly it uses builtins only...
At Don...
Don, in his defence, used builtins although not INTEGER arithmetic; he admitted that ksh93 was used as he expended on my original upload using ksh's floating point - root=$((int(number ** .5))) ; I am assuming 'int' is part of ksh's arithmetic...
So Don, as bash cannot do floating point then you did cheat... ;oD
At neutronscott...
Well what can I say... ;oD
Using various [?]awk commands are not builtins so you also cheated... ;oD
At sea...
It would have been interesting to see your result too...
One very serious question however:-
How accurate is either "[?]awk's" or "ksh's" floating point?
Would there be a situation where there would be a false result due to a floating point __error__?
I have to find last delimiter in each line of a file and store the value after the last '/' in a variable in ksh script...Pls Pls help me:(The file is as shown below:
/opt/apps/cobqa/apps/abadv/bind/advc0007.bnd
/opt/apps/cobqa/apps/abbrio/bind/naac6115.bnd... (5 Replies)
I want to print only the lines that meet the criteria : "worde:" and "wordo;"
I got this far:
sed -n '/\(*\)\1e:\1o;/p;'
But it doesn't quite work.
Can someone please perfect it and tell me exactly how its a fixed version/what was wrong with mine?
Thanks heaps, (1 Reply)
Hi All,
I have a text file which looks like this:
computer programming
systems engineering
I want to get rid of these square brackets and also the text that is inside these brackets. So that my final text file looks like this:
computer programming
systems engineering
I am using... (3 Replies)
I've got an aix-box somewhere on the network and a PC on my desk. Nothing fancy so far.
The PC is made dual-boot:
- windowsXP with putty & winSCP
or
- slackware 13 with xfce4 installed.
The aix-box runs DB2 v8.2 and I've installed db2top to monitor the database.
db2top is a character... (0 Replies)
Here's my work of testing whether a number input is perfect or not..
echo Enter a number
read no
i=1
ans=0
while
do
if
then
ans='expr $ans + $i'
fi
i='expr $i + 1'
done
if
then
echo $no is perfect
else
echo $no is NOT perfect
fi (12 Replies)
Hi All,
I have a file of the following format.
<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
<role rolename="tomcat"/>
<role rolename="role1"/>
<role rolename="manager"/>
<role rolename="admin"/>
<user username="tomcat" password="tomcat" roles="tomcat"/>
<user... (5 Replies)