How do I square a number without using multiplication? - ruby

Was wondering if there is a way to write a method which squares a number (integer or decimal/float) without using the operational sign (*). For example: square of 2 will be 4, square of 2.5 will be 6.25, and 3.5's will be 12.25.
Here is my approach:
def square(num)
number = num
number2 = number
(1...(number2.floor)).each{ num += number }
num
end
puts square(2) #=> 4 [Correct]
puts square(16) #=> 256 [Correct]
puts square(2.5) #=> 5.0 [Wrong]
puts square(3.5) #=> 10.5 [Wrong]
The code works for integers, but not with floats/decimals. What am I doing wrong here? Also, if anybody has a fresh approach to this problem then please share. Algorithms are also welcome. Also, considering performance of the method will be a plus.

There are a few tricks you could use, arranged here in order of increasing trickery.
Logarithms
Observe that k * k = e^log(k*k) = e^(log(k) + log(k)), and use that rule:
Math.exp(Math.log(5.2) + Math.log(5.2))
# => 27.04
No multiplication here!
Division
As another commenter suggested, you could take the reciprocal operation, division: k/(1.0/k) == k^2. However, this introduces additional floating-point errors, since k / (1.0 / k) is two floating-point operations, whereas k * k is only one.
Exponentiation
Or, since this is Ruby, if you want exactly the same value as the floating-point operation and you don't want to use the multiplication operator, you can use the exponentiation operator: k**2 == k * k.
Call a web service
It's not multiplying if you don't do it yourself!
require 'wolfram' # https://github.com/cldwalker/wolfram
query = 'Square[5.2]'
result = Wolfram.fetch(query)
Blatant cheating
Finally, if you're feeling really cheap, you could avoid actually employing the literal "*" operation, and use something equivalent:
n = ...
require 'base64'
n.send (Base64.decode64 'Kg==').to_sym, n # => n * n

Didn't use any operation sign.
def square(num)
num.send 42.chr, num
end

Well, the inverse of multiplication is division, so you can get the same result* by dividing by its inverse. That is: square(n) = n / (1.0 / n). Just make sure you don't inadvertently do integer division.
*Technically dividing twice introduces a second opportunity for rounding error in floating-point arithmetic since it performs two operations. So, this will not produce exactly the same result as floating-point multiplication - but this was also not a requirement in the question.

Related

Is there an IDIOMATIC way to get a random Fixnum in Ruby?

I'm playing with an algorithm which uses random numbers. It would be nice to be able to maximize the randomness I can get while keeping the number a nice reasonably-performant integer, so ideally they'd be in the range Fixnum::MIN .. Fixnum::MAX, but 0..Fixnum::MAX ought to be fine too.
OH WAIT. Those constants aren't actually things that exist. So when you read that Random.rand returns a float unless you pass it an integer argument the only obvious course of action is to resort to terrible hacks like these.
Is there any more-idiomatic way to get a random integer in Ruby, or does Yukihiro just expect me to make my code hideous and duplicate dubious integer-size exponentiation if I want this sort of capability?
Random Values from 0..FIXNUM_MAX
When Fixnum overflows, Ruby will just convert to Bignum. However, this related answer shows how to calculate the minimum and maximum values of Fixnum for your platform. Using that as a starting point, you can get a positive integer in the desired range with:
FIXNUM_MAX = (2**(0.size * 8 -2) -1)
Random.rand FIXNUM_MAX
Negative Integers
If you insist on having negative numbers too, then the following may be "close enough" for your purposes, even though FIXNUM_MIN.abs == FIXNUM_MAX may be false on your platform:
FIXNUM_MAX = (2**(0.size * 8 -2) -1)
random_num = Random.rand FIXNUM_MAX
random_num.even? ? random_num : random_num * -1
See Also
Kernel#rand
Random#rand
SecureRandom#random_number
This should get you a fairly large number of sample integers:
require "securerandom"
exponent = rand(1..15)
puts (SecureRandom.random_number * 10**exponent).to_i
a faster working algo that produces same or possibly better randomness:
r = Random.new
exponent = rand(1..15)
puts (r.rand * 10**exponent).to_i
or even a simpler way:
FIXNUM_MAX = (2**(0.size * 8 -2) -1)
FIXNUM_MIN = -(2**(0.size * 8 -2))
p rand(FIXNUM_MIN..FIXNUM_MAX)

Cubic root of large number

I'm trying to identify the cubic root of a large number. I found a solution which works for smaller numbers, but not in this case:
require 'openssl'
q = OpenSSL::BN::generate_prime(2048)
ti = q.to_i #=> 3202718747...
ti3 = ti ** 3 #=> 328515909...
m = ti3 ** (1/3.0) #=> Infinity
I was hoping to see m = the original output of ti. Yes, this is a part of a Matasano challenge. I've put a lot of effort into not seeking help thus far, but I've reached a point where it's just a "how do I do something otherwise simple, in Ruby". Any assistance appreciated.
In ruby operations on integers automatically get promoted to bignums (arbitrary precision integers), so you never get an overflow.
The same is not true of floating point operations: you end up with infinity because raising to the power 1/3 is a floating point operation and the first thing it does is try to convert your number to a float. The biggest number a float in ruby can represent is about 10^308 whereas your number is probably around the 10^1800 mark, so it bails out and returns Infinity
Ruby has a BigDecimal class for this. You might therefore be tempted to do
BigDecimal.new(ti3) ** (1/3.0)
This gives a wildly wrong answer for me - I suspect because (1/3.0) is a float, so only approximately 1/3
BigDecimal.new(ti3) ** Rational(1,3)
On the other hand produces the correct result for me (with negligible error). Rational is Ruby's class for representing fractions in an exact manner. In ruby 2.1 you can shorten this to
BigDecimal.new(ti3) ** (1r/3)
The docs do say that only integer exponents are supported but this seems to be a hangover from the ruby 1.8 days
The following code was put forward based on the two pieces of advice given.
def nthroot(n, a, precision = 1e-1024)
x = a
begin
prev = x
x = ((n - 1) * prev + a / (prev ** (n - 1))) / n
end while (prev - x).abs > precision
x
end
It was based on an implementation of Newton's method which dealt with floats, but also just returned infinity. This version deals with integers only, but works for large integers.
Of course, an nthroot, may be called with n = 3.
I don't know what the Matasano challenge is, but what comes to mind is Newton's Method
The wikipedia page on Cube Roots also suggests using Newton's Method

BigDecimal loses precision after multiplication

I'm getting a strange behaviour with BigDecimal in ruby. Why does this print false?
require 'bigdecimal'
a = BigDecimal.new('100')
b = BigDecimal.new('5.1')
c = a / b
puts c * b == a #false
BigDecimal doesn't claim to have infinite precision, it just provides support for precisions outside the normal floating point ranges:
BigDecimal provides similar support for very large or very accurate floating point numbers.
But BigDecimal values still have a finite number of significant digits, hence the precs method:
precs
Returns an Array of two Integer values.
The first value is the current number of significant digits in the BigDecimal. The second value is the maximum number of significant digits for the BigDecimal.
You can see things starting to go awry if you look at your c:
>> c.to_s
=> "0.19607843137254901960784313725E2"
That's a nice clean rational number but BigDecimal doesn't know that, it is still stuck seeing c as a finite string of digits.
If you use Rational instead, you'll get the results you're expecting:
>> a = Rational(100)
>> b = Rational(51, 10)
>> c * b == a
=> true
Of course, this trickery only applies if you are working with Rational numbers so anything fancy (such as roots or trigonometry) is out of bounds.
This is normal behaviour, and not at all strange.
BigDecimal does not guarantee infinite accuracy, it allows you to specify arbitrary accuracy, which is not the same thing. The value 100/5.1 cannot be expressed with complete precision using floating point internal representation. Doesn't matter how many bits are used.
A "big rational" approach could achieve it - but would not give you access to some functions e.g. square roots.
See http://ruby-doc.org/core-1.9.3/Rational.html
# require 'rational' necessary only in Ruby 1.8
a = 100.to_r
b = '5.1'.to_r
c = a / b
c * b == a
# => true

Getting a list of square-free numbers

One way to get that is for the natural numbers (1,..,n) we factorise each and see if they have any repeated prime factors, but that would take a lot of time for large n. So is there any better way to get the square-free numbers from 1,..,n ?
You could use Eratosthenes Sieve's modified version:
Take a bool array 1..n;
Precalc all squares that are less than n; that's O(sqrt(N));
For each square and its multiples make the bool array entry false...
From http://mathworld.wolfram.com/Squarefree.html
There is no known polynomial time
algorithm for recognizing squarefree
integers or for computing the
squarefree part of an integer. In
fact, this problem may be no easier
than the general problem of integer
factorization (obviously, if an
integer can be factored completely,
is squarefree iff it contains no
duplicated factors). This problem is
an important unsolved problem in
number theory because computing the
ring of integers of an algebraic
number field is reducible to computing
the squarefree part of an integer
(Lenstra 1992, Pohst and Zassenhaus
1997).
The most direct thing that comes to mind is to list the primes up to n and select at most one of each. That's not easy for large n (e.g. here's one algorithm), but I'm not sure this problem is either.
One way to do it is to use a sieve, similar to Eratosthenes'.
#Will_Ness wrote a "quick" prime sieve as follows in Python.
from itertools import count
# ideone.com/
def postponed_sieve(): # postponed sieve, by Will Ness
yield 2; yield 3; yield 5; yield 7; # original code David Eppstein,
sieve = {} # Alex Martelli, ActiveState Recipe 2002
ps = postponed_sieve() # a separate base Primes Supply:
p = next(ps) and next(ps) # (3) a Prime to add to dict
q = p*p # (9) its sQuare
for c in count(9,2): # the Candidate
if c in sieve: # c's a multiple of some base prime
s = sieve.pop(c) # i.e. a composite ; or
elif c < q:
yield c # a prime
continue
else: # (c==q): # or the next base prime's square:
s=count(q+2*p,2*p) # (9+6, by 6 : 15,21,27,33,...)
p=next(ps) # (5)
q=p*p # (25)
for m in s: # the next multiple
if m not in sieve: # no duplicates
break
sieve[m] = s # original test entry: ideone.com/WFv4f
With a little effort, this can be used to pop out square-free integers, using the postponed_sieve() to serve as a basis for sieving by as few squares as possible:
def squarefree(): # modified sieve of Will Ness
yield 1; yield 2; yield 3; # original code David Eppstein,
sieve = {} # Alex Martelli, ActiveState Recipe 2002
ps = postponed_sieve() # a base Primes Supply:
p = next(ps) # (2)
q = p*p # (4)
for c in count(4): # the Candidate
if c in sieve: # c's a multiple of some base square
s = sieve.pop(c) # i.e. not square-free ; or
elif c < q:
yield c # square-free
continue
else: # (c==q): # or the next base prime's square:
s=count(2*q,q) # (4+4, by 4 : 8,12,16,20...)
p=next(ps) # (3)
q=p*p # (9)
for m in s: # the next multiple
if m not in sieve: # no duplicates
break
sieve[m] = s
It's pretty quick, kicking out the first million in about .8s on my laptop.
Unsurprisingly, this shows that this is effectively the same problem as sieving primes, but with much greater density.
You should probably look into the sieve of Atkin. Of course this eliminates all non-primes (not just perfect squares) so it might be more work than you need.
Googling a little bit I've found this page where a J program is explained. A part from the complex syntax, the algorithm allows to check whether a number is square-free or not:
generate a list of perfect square PS,
take your number N and divide it by
the numbers in the list PS
if there is only 1 whole number in the list,
then N is square-free
You could implement the algorithm in your preferred language and iterate it on any number from 1 to n.
http://www.marmet.org/louis/sqfgap/
Check out the section "Basic algorithm: the sieve of Eratosthenes", which is what Armen suggested. The next section is "Improvements of the algorithm".
Also, FWIW, the Moebius function and square-free numbers are related.
I have found a better algorithm to calculate how many square-free numbers in a interval such as [n,m]. We can get prime that less than sqrt(m), then we should minus the multiples of those prime's square, then plus the multiples of each two primes' product less than m, then minus tree ,then plus four.... at the last we will get the answer. Certainly it runs in O(sqrt(m)).
import math
def squarefree(n):
t=round(math.sqrt(n))
if n<2:
return True
if t*t==n:
return False
if t<=2:
return True
for i in range(2,t):
if n%(i*i)==0:
return False
else:
return True

How to implement square root and exponentiation on arbitrary length numbers?

I'm working on new data type for arbitrary length numbers (only non-negative integers) and I got stuck at implementing square root and exponentiation functions (only for natural exponents). Please help.
I store the arbitrary length number as a string, so all operations are made char by char.
Please don't include advices to use different (existing) library or other way to store the number than string. It's meant to be a programming exercise, not a real-world application, so optimization and performance are not so necessary.
If you include code in your answer, I would prefer it to be in either pseudo-code or in C++. The important thing is the algorithm, not the implementation itself.
Thanks for the help.
Square root: Babylonian method. I.e.
function sqrt(N):
oldguess = -1
guess = 1
while abs(guess-oldguess) > 1:
oldguess = guess
guess = (guess + N/guess) / 2
return guess
Exponentiation: by squaring.
function exp(base, pow):
result = 1
bits = toBinary(powr)
for bit in bits:
result = result * result
if (bit):
result = result * base
return result
where toBinary returns a list/array of 1s and 0s, MSB first, for instance as implemented by this Python function:
def toBinary(x):
return map(lambda b: 1 if b == '1' else 0, bin(x)[2:])
Note that if your implementation is done using binary numbers, this can be implemented using bitwise operations without needing any extra memory. If using decimal, then you will need the extra to store the binary encoding.
However, there is a decimal version of the algorithm, which looks something like this:
function exp(base, pow):
lookup = [1, base, base*base, base*base*base, ...] #...up to base^9
#The above line can be optimised using exp-by-squaring if desired
result = 1
digits = toDecimal(powr)
for digit in digits:
result = result * result * lookup[digit]
return result
Exponentiation is trivially implemented with multiplication - the most basic implementation is just a loop,
result = 1;
for (int i = 0; i < power; ++i) result *= base;
You can (and should) implement a better version using squaring with divide & conquer - i.e. a^5 = a^4 * a = (a^2)^2 * a.
Square root can be found using Newton's method - you have to get an initial guess (a good one is to take a square root from the highest digit, and to multiply that by base of the digits raised to half of the original number's length), and then to refine it using division: if a is an approximation to sqrt(x), then a better approximation is (a + x / a) / 2. You should stop when the next approximation is equal to the previous one, or to x / a.

Resources