You are given a positive integer
$N
.Write a script to calculate the integer square root of the given number.
Please avoid using built-in function. Find out more about it here.
Input: $N = 10
Output: 3
Input: $N = 27
Output: 5
Input: $N = 85
Output: 9
Input: $N = 101
Output: 10
The challenging part of this challenge is:
Please avoid using built-in function.
Calculating the integer root of a number $n
not using built-in functions
is easy. The module Math::Prime::Utils
provides a function
sqrtint
which does exactly what is asked. But it doesn't print it.
And both say
and print
are built-in functions.
So, we have to do something else. Our solution is pass the bucket to
AWK, and have AWK calculate the integer root. But how to call AWK?
Both exec
and system
are build-in functions, and so is
open
.
Which leaves us backticks (``
). But we can't just use backticks
and leave it like that, as the backticks run the given command, and
collect its output, which is returned. However, we cannot print that,
for the same reasons as explained above.
So, we will have AWK print directly to the terminal. AWK can redirect
output the same way as the shell can, using > file
after a print
statement. /dev/tty
is the pseudo-file representing the terminal.
There is one more snag we have to tackle. Since we're reading
numbers from standard input, every read number ends with a newline.
And AWK treats newlines as statement terminators without any regard
to context (basically, if the newline is not escaped, it will terminate
the statement). So, we have to get rid of it, but we cannot use
chop
nor chomp
, due to the "no build-in" restriction.
But we have s///
available, which we use to remove anything which
isn't an ASCII digit.
Which gives us the following program:
`awk 'BEGIN {print (int (sqrt (${\s/[^0-9]+//gr}))) > "/dev/tty"}'` for <>;
Find the full program on GitHub.