<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Prashanth Ellina &#187; math</title>
	<atom:link href="http://blog.prashanthellina.com/category/math/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.prashanthellina.com</link>
	<description>In Pursuit of Truth</description>
	<lastBuildDate>Sun, 28 Nov 2010 09:35:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>My Dual Monitor Setup</title>
		<link>http://blog.prashanthellina.com/2009/04/21/my-dual-monitor-setup/</link>
		<comments>http://blog.prashanthellina.com/2009/04/21/my-dual-monitor-setup/#comments</comments>
		<pubDate>Tue, 21 Apr 2009 17:30:26 +0000</pubDate>
		<dc:creator>prashanthellina</dc:creator>
				<category><![CDATA[math]]></category>
		<category><![CDATA[dual monitor]]></category>
		<category><![CDATA[dual-head]]></category>
		<category><![CDATA[geforce]]></category>
		<category><![CDATA[nvidia]]></category>
		<category><![CDATA[samsung]]></category>
		<category><![CDATA[syncmaster]]></category>

		<guid isPermaLink="false">http://blog.prashanthellina.com/?p=77</guid>
		<description><![CDATA[Greetings webizen, I tried hard to get back to my blogging schedule but my laziness got the better of me. I am back truly with a new batch of posts which I will publish over the next few days. Recently, I went to Veveo&#8217;s main office near Boston, USA and had the privilege of experiencing [...]]]></description>
			<content:encoded><![CDATA[<p>Greetings webizen, I tried hard to get back to my blogging schedule but my laziness got the better of me. I am back truly with a new batch of posts which I will publish over the next few days.</p>
<p>Recently, I went to Veveo&#8217;s main office near Boston, USA and had the privilege of experiencing a finger freezing winter! (Not to mention a three day power-cut which I spent under multiple layers of blankets).</p>
<p>A few weeks before I was going to return to India, I started shopping. One of things I bought was a Refurbished NVidia GeForce 9800 GTX+ by EVGA. It was the best deal I could find on NewEgg in terms of value for money. I bought it primarily to have a betterr experience when flying over Paris &#8230; in Google Earth.</p>
<p>This is the first graphics card I bought ever and was very excited when I received it. I was surprised to see how big graphics cards have become nowadays (compared to S3 cards of the decade gone past). While oggling at the card I noticed that it had two video outputs. I had heard of dual-head setups but always considered them a distant reality considering my cash-strappedness as a college student. This sparked off an urge to finally setup my own Dual monitor setup back in Bangalore.</p>
<p>I got back to India and promptly headed to SP Road in Bangalore. After some asking around, I figured that the best choice at the moment was two Samsung SyncMaster 2233SW&#8217;s each capable of 1920&#215;1080 (Yes, HD). I bought both for about 22,000 Rupees (about USD 420).</p>
<p>I set them up in Linux and upgraded to the latest (at the time) Nvidia drivers (180.x). I spent a few hours trying to hide a satisfied smile lest people thing I had gone nuts.</p>
<p>Dual monitors give you more screen space to work with. They will help you reduce Window-Switching and Workspace-Switching which does save time as I have observed. Now that I have experience the dual-head setup, I am <strong>never</strong> going back to using a single monitor. It is painful <img src='http://blog.prashanthellina.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  So much did I feel this that I bought a low-end Nvidia GeForce card (7200) with dual-head support and stuck it into my computer at work <img src='http://blog.prashanthellina.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>If you do not already have a dual-head setup, definitely consider an upgrade. You are worth it:)</p>
<p><center><br />
<object width="400" height="300"><param name="flashvars" value="offsite=true&#038;lang=en-us&#038;page_show_url=%2Fphotos%2Fprashanthellina%2Fsets%2F72157617045645747%2Fshow%2F&#038;page_show_back_url=%2Fphotos%2Fprashanthellina%2Fsets%2F72157617045645747%2F&#038;set_id=72157617045645747&#038;jump_to="></param><param name="movie" value="http://www.flickr.com/apps/slideshow/show.swf?v=70933"></param><param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/slideshow/show.swf?v=70933" allowFullScreen="true" flashvars="offsite=true&#038;lang=en-us&#038;page_show_url=%2Fphotos%2Fprashanthellina%2Fsets%2F72157617045645747%2Fshow%2F&#038;page_show_back_url=%2Fphotos%2Fprashanthellina%2Fsets%2F72157617045645747%2F&#038;set_id=72157617045645747&#038;jump_to=" width="400" height="300"></embed></object></p>
<p><a href="http://www.flickr.com/photos/prashanthellina/sets/72157617045645747/">Go to flickr set for this</a><br />
</center></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.prashanthellina.com/2009/04/21/my-dual-monitor-setup/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Determining the difficulty of Arithmetic Operations</title>
		<link>http://blog.prashanthellina.com/2008/07/27/determining-the-difficulty-of-arithmetic-operations/</link>
		<comments>http://blog.prashanthellina.com/2008/07/27/determining-the-difficulty-of-arithmetic-operations/#comments</comments>
		<pubDate>Sun, 27 Jul 2008 16:51:22 +0000</pubDate>
		<dc:creator>prashanthellina</dc:creator>
				<category><![CDATA[math]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[arithmetic]]></category>
		<category><![CDATA[arithmetic algorithms]]></category>
		<category><![CDATA[borrow]]></category>
		<category><![CDATA[carry]]></category>
		<category><![CDATA[long division]]></category>
		<category><![CDATA[problem difficulty]]></category>
		<category><![CDATA[problem generator]]></category>

		<guid isPermaLink="false">http://blog.prashanthellina.com/?p=69</guid>
		<description><![CDATA[I am trying to write a program to test my arithmetic skills. The program should pose arithmetic problems involving the four basic operations &#8211; addition, subtraction, multiplication and division. When the testing session starts, the program should issue problems of less difficulty and the difficulty should be ramped up gradually. A score should be computed [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.prashanthellina.com/images/kid_math_problem.gif" align="left" alt="kid math problem" padding="5"/>I am trying to write a program to test my arithmetic skills. The program should pose arithmetic problems involving the four basic operations &#8211; addition, subtraction, multiplication and division. When the testing session starts, the program should issue problems of less difficulty and the difficulty should be ramped up gradually. A score should be computed based on number of questions and the difficulty of questions. The hope is that if I keep using this program for a little time every day, I&#8217;ll be able to improve my abysmal arithmetic performance <img src='http://blog.prashanthellina.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Note that you will need to have <a href="http://www.python.org">Python</a> installed to try out the script and the examples in this article. I believe that the code is simple enough to be understood with minimal or no understanding of the Python language. If any part of the article is not clear, feel free to point it out to me. Thank you.</p>
<h2>Estimating difficulty</h2>
<p>Let us take a look at the following problems.</p>
<p><strong>Problem 1</strong></p>
<pre lang="python">
5 +
3
</pre>
<p><br/></p>
<p><strong>Problem 2</strong></p>
<pre lang="python">
99999 +
12345
</pre>
<p><br/></p>
<p>Now, which problem is more difficult? It is quite obvious that Problem 2 is more difficult. But why? One answer would be &#8211; &#8220;because Problem 2 involves the addition of two large numbers&#8221;. Fine. Consider this now &#8230;</p>
<p><strong>Problem 3</strong></p>
<pre lang="python">
1000000 +
1000001
</pre>
<p><br/></p>
<p>Is Problem 3 more difficult than Problem 2 because the numbers undergoing addition are bigger? The intuitive answer is &#8220;No&#8221;. But why? Because the time it takes to compute the result is lesser. Why? Because the number of operations performed during the course of solving Problem 3 are lesser than those of Problem 2? No.</p>
<p>Problem 3 is easier than Problem 2 because the nature of the operations performed in Problem 3. The operations there are simpler.</p>
<pre lang="python">
0 + 1,
0 + 0,
1 + 1
</pre>
<p><br/></p>
<p>are arguably simpler operations than</p>
<pre lang="python">
9 + 5,
9 + 2,
4 + 9
</pre>
<p><br/></p>
<p>I&#8217;ve attempted to capture the basic operations we perform while doing arithmetic and assign a level of difficulty to each. I&#8217;ve then emulated the algorithms we follow to compute solutions to such problems. By doing the following, it becomes possible to estimate the &#8220;difficulty&#8221; of an arithmetic problem (involving the basic operations).</p>
<p><center><img src="http://www.prashanthellina.com/images/math_cartoon_yesterday_x.jpg" alt="math cartoon yesterday x"/></center></p>
<h2>Operation difficulties</h2>
<p><br/></p>
<h3>Addition</h3>
<pre lang="python">
addition_difficulties = {
    'digit_zero' : 1,   # any digit added to zero
    'even_even'  : 2,   # sum of even digits
    'odd_odd'    : 2,   # sum of odd digits
    'even_odd'   : 3,   # sum of even and odd digits
    'carry'      : 2    # difficulty of carry (for remembering and then adding)
}
</pre>
<p><br/></p>
<p>Here is the function which computes the addition difficulty. It is a recursive function that can compute the addition difficulty for n numbers. It computes the sum and difficulty of the first two numbers and then inserts the sum at the head of the list of n numbers in place of the two numbers just summed. It then calls itself with the modified list.</p>
<pre lang="python">
def compute_addition_difficulty(*numbers):
    '''
    Generates a difficulty number and sum for given
    list of numbers for the addition operation
    *args - integers
    returns: (sum, difficulty)

    >>> compute_addition_difficulty(0, 0)
    (0, 1)

    >>> compute_addition_difficulty(0, 1)
    (1, 1)

    >>> compute_addition_difficulty(1, 1)
    (2, 2)

    >>> compute_addition_difficulty(1, 2)
    (3, 3)

    >>> compute_addition_difficulty(2, 2)
    (4, 2)

    >>> compute_addition_difficulty(19, 9)
    (28, 5)

    >>> compute_addition_difficulty(99999, 12345)
    (112344, 22)
    '''

    numbers = list(numbers)
    if len(numbers) == 0: return 0, 0

    elif len(numbers) == 1: return numbers[0], 0

    num1, num2 = numbers[:2]
    num1 = str(num1)
    num2 = str(num2)

    max_length = max([len(num1), len(num2)])
    num1 = num1.rjust(max_length, '0')
    num2 = num2.rjust(max_length, '0')

    difficulty = 0
    carry = 0
    r = reversed
    ad = addition_difficulties
    sum = []

    for index, (d1, d2) in enumerate( izip( r(num1), r(num2) ) ):
        d1 = int(d1)
        d2 = int(d2)

        d1_is_even = is_even(d1)
        d2_is_even = is_even(d2)

        if not d1 or not d2: difficulty += ad['digit_zero']
        elif d1_is_even and d2_is_even: difficulty += ad['even_even']
        elif not d1_is_even and not d2_is_even: difficulty += ad['odd_odd']
        elif d1_is_even != d2_is_even: difficulty += ad['even_odd']

        dsum = d1 + d2 + carry

        if dsum > 9:
            carry = 1
            difficulty += ad['carry']
        else:
            carry = 0

        sum.append( str(dsum % 10) )

    if carry:
        sum.append( str(carry) )

    sum.reverse()
    sum = ''.join(sum)
    sum = int (sum)

    numbers = [sum] + numbers[2:]

    sum, sub_difficulty = compute_addition_difficulty(*numbers)

    difficulty += sub_difficulty

    return sum, difficulty
</pre>
<p><br/></p>
<h3>Subtraction</h3>
<pre lang="python">
subtraction_difficulties = {
    'digit_zero' : 1,    # difference of zero and any digit
    'same_digits': 1,    # difference of same values digits
    'even_even'  : 2,    # difference of even digits
    'odd_odd'    : 2,    # difference of odd digits
    'even_odd'   : 3,    # difference of even and odd digits
    'borrow'     : 2,    # doing a borrow
    'twodigit_digit' : 4 # difference of two-digit number and digit
}
</pre>
<p><br/></p>
<p>The subtraction function is also recursive and operates similar to addition in that respect. Before looking at the subtraction algorithm, take a look at how &#8220;borrowing&#8221; is implemented. Let us say we are trying to perform the following,</p>
<pre lang="python">
200005 -
     6
</pre>
<p><br/></p>
<p>After borrowing the number would be, 19999(1)5. We would then subtract 6 from 15 and proceed. The do_borrow() function captures this aspect of substraction.</p>
<pre lang="python">
def do_borrow(num, index):
    if index == len(num)-1: raise Exception('cannot perform borrow')

    num_borrows = 1
    next_digit = int(num[index+1])

    if next_digit > 0:
        num[index+1] = str(next_digit-1)

    else:
        num[index+1] = str(9)
        num_borrows += do_borrow(num, index+1)

    return num_borrows
</pre>
<p><br/></p>
<p>This implementation is a bit confusing so check out this example (do_borrow() applied to the problem mentioned above).</p>
<pre lang="python">
>>> x = list('200005')
>>> x.reverse()
>>> x
['5', '0', '0', '0', '0', '2']
>>> do_borrow(x, 1)
4
>>> ''.join(x)
'509991'
>>> x.reverse()
>>> x
['1', '9', '9', '9', '0', '5']
</pre>
<p><br/></p>
<p>Note that do_borrow returned 4, which indicates that the difficulty of performing this borrow operation is 4. Also note that do_borrow takes a list of digits in reversed order. It takes a list because the result is provided in-place (remember that Python strings are immutable). Now that you have seen how the borrowing works, all introduce the subtraction function.</p>
<pre lang="python">
def compute_subtraction_difficulty(*numbers):
    '''
    Generates a difficulty number and result for given
    list of numbers for the subtraction operation
    *args (tuple) - integers
    returns: (difference, difficulty)

    >>> compute_subtraction_difficulty(0,0)
    (0, 1)

    >>> compute_subtraction_difficulty(1,0)
    (1, 1)

    >>> compute_subtraction_difficulty(1,1)
    (0, 1)

    >>> compute_subtraction_difficulty(2,1)
    (1, 3)

    >>> compute_subtraction_difficulty(4,2)
    (2, 2)

    >>> compute_subtraction_difficulty(4,3)
    (1, 3)

    >>> compute_subtraction_difficulty(100,1)
    (99, 10)

    >>> compute_subtraction_difficulty(5000007,9)
    (4999998, 22)
    '''

    numbers = list(numbers)
    if len(numbers) == 0: return 0, 0
    elif len(numbers) == 1: return numbers[0], 0

    num1, num2 = numbers[:2]
    if num1 < num2: num1, num2 = num2, num1

    num1 = str(num1)
    num2 = str(num2)

    max_length = max([len(num1), len(num2)])
    num1 = list(num1.rjust(max_length, '0'))
    num2 = list(num2.rjust(max_length, '0'))

    difficulty = 0
    borrow = 0
    sd = subtraction_difficulties
    difference = []
    num1.reverse()
    num2.reverse()

    for index, (d1, d2) in enumerate( izip( num1, num2 ) ):
        d1 = int(d1)
        d2 = int(d2)

        d1_is_even = is_even(d1)
        d2_is_even = is_even(d2)

        if d1 > d2:
            if not d1 or not d2: difficulty += sd['digit_zero']
            elif d1_is_even and d2_is_even: difficulty += sd['even_even']
            elif not d1_is_even and not d1_is_even: difficulty += sd['odd_odd']
            elif d1_is_even != d2_is_even: difficulty += sd['even_odd']
            ddiff = d1 - d2

        elif d1 < d2:
            num_borrows = do_borrow(num1, index)
            difficulty += sd['borrow']*num_borrows
            ddiff = 10 + d1 - d2
            difficulty += sd['twodigit_digit']

        elif d1 == d2:
            difficulty += sd['same_digits']
            ddiff = 0

        difference.append( str(ddiff) )

    difference.reverse()
    difference = ''.join(difference)
    difference = int (difference)

    numbers = [difference] + numbers[2:]

    difference, sub_difficulty = compute_subtraction_difficulty(*numbers)

    difficulty += sub_difficulty

    return difference, difficulty
</pre>
<p><br/></p>
<h3>Multiplication</h3>
<pre lang="python">
multiplication_difficulties = {
    'carry'  : 1,   # carry operation, summation difficulty is seperate
    'offset' : 1,
}
</pre>
<p><br/></p>
<p>The basic operation of multiplying big numbers is one digit by one digit multiplication. I've tried to capture the difficulty of this operation as follows</p>
<pre lang="python">
def get_single_digit_multiplication_difficulty(d1, d2):
    '''
    Max value of multiplication of two digits is 81 (9*9).
    Difficulty of d1*d2 increases as the resulting value
    of the multiplication increases. thereby 9*9=81 is most difficult
    and 0*0 is least difficult.

    We will represent this difficult with value from 1-4 (inclusive)

    Note that the difficulty will be incremented by 1 for presence
    of odd digit in the operands (except for 1 and 5 because it is arguably
    easier to multiply)

    >>> get_single_digit_multiplication_difficulty(0, 1)
    (0, 1)
    >>> get_single_digit_multiplication_difficulty(1, 1)
    (1, 1)
    >>> get_single_digit_multiplication_difficulty(2, 5)
    (10, 1)
    >>> get_single_digit_multiplication_difficulty(2, 7)
    (14, 2)
    >>> get_single_digit_multiplication_difficulty(2, 6)
    (12, 1)
    >>> get_single_digit_multiplication_difficulty(8, 9)
    (72, 5)
    >>> get_single_digit_multiplication_difficulty(8, <img src='http://blog.prashanthellina.com/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' />
    (64, 4)
    '''

    if not d1 or not d2: return 0, 1 

    res = d1 * d2
    difficulty = math.ceil((4/81.) * res)

    # odd numbers are harder to multiply except 1 and 5
    if d1 not in [1,5] and d2 not in [1,5] and (is_odd(d1) or is_odd(d2)):
        difficulty += 1

    return res, int(difficulty)
</pre>
<p><br/></p>
<p>At the next level, the operation would be multiplying a multi-digit number by a single digit, which I call simple multiplication. Over here I take into account the difficulty of carry. I hope the following code is self explanatory.</p>
<pre lang="python">
def compute_simple_multiplication_difficulty(num, digit):
    '''
    >>> compute_simple_multiplication_difficulty(1, 0)
    (0, 1)
    >>> compute_simple_multiplication_difficulty(1, 1)
    (1, 1)
    >>> compute_simple_multiplication_difficulty(2, 1)
    (2, 1)
    >>> compute_simple_multiplication_difficulty(10, 1)
    (10, 2)
    >>> compute_simple_multiplication_difficulty(15, 1)
    (15, 2)
    >>> compute_simple_multiplication_difficulty(15, 5)
    (75, 7)
    >>> compute_simple_multiplication_difficulty(999, 7)
    (6993, 25)
    '''
    num = str(num)

    result = []
    md = multiplication_difficulties
    carry = 0
    difficulty = 0

    for index, d in enumerate(reversed(num)):
        d = int(d)
        res, s_diff = get_single_digit_multiplication_difficulty(d, digit)
        difficulty += s_diff

        if (carry):
            res, carry_sum_difficulty = compute_addition_difficulty(res, carry)
            difficulty += carry_sum_difficulty + md['carry']

        carry = res/10
        result_digit = int(str(res)[-1:])
        result.append( str(result_digit) )

    if carry:
        result.append( str(carry) )

    result.reverse()
    result = ''.join(result)
    result = int(result)

    return result, difficulty
</pre>
<p><br/></p>
<p>Simple multiplication is a basic operation of complex multiplication (multi-digit multiplied by multi-digit). Let us see an example of "complex multiplication" which the multiplication code follows.</p>
<pre lang="python">
    345 x
    123
  -----
   1035
   690x  # result is "offset" or multiplied by 10
  345xx  # result if "offset" or multiplied by 100
  -----
  42435  # result of summation of above numbers
  -----
</pre>
<p><br/></p>
<p>The first part of the multiplication is to perform simple multiplications - 345x3, 345x2, 345x1 and to offset the numbers accordingly. The second part of the operation is to sum the numbers. I used the addition algorithm to achieve the second part. Check out the multiplication function.</p>
<pre lang="python">
def compute_multiplication_difficulty(*numbers):
    '''
    Generates a difficulty number and result for given
    list of numbers for the multiplication operation
    *args (tuple) - integers
    returns: (product, difficulty)

    >>> compute_multiplication_difficulty(0,0)
    (0, 1)
    >>> compute_multiplication_difficulty(1,0)
    (0, 1)
    >>> compute_multiplication_difficulty(1,1)
    (1, 1)
    >>> compute_multiplication_difficulty(2,1)
    (2, 1)
    >>> compute_multiplication_difficulty(5,1)
    (5, 1)
    >>> compute_multiplication_difficulty(5,2)
    (10, 1)
    >>> compute_multiplication_difficulty(17,2)
    (34, 7)
    >>> compute_multiplication_difficulty(17,29)
    (493, 20)
    >>> compute_multiplication_difficulty(17,29,3)
    (1479, 31)
    >>> compute_multiplication_difficulty(1776,29,3)
    (154512, 77)
    '''

    numbers = list(numbers)
    if len(numbers) == 0: return 1, 0
    elif len(numbers) == 1: return numbers[0], 0

    num1, num2 = numbers[:2]
    if num1 < num2: num1, num2 = num2, num1

    num2 = str(num2)

    difficulty = 0
    borrow = 0
    md = multiplication_difficulties
    m_numbers = []

    for index, d in enumerate(reversed(num2)):

        d = int(d)

        m_number, m_diff = compute_simple_multiplication_difficulty(num1, d)
        difficulty += m_diff

        if index:
            m_number = int(m_number * math.pow(10, index))
            difficulty += md['offset']

        m_numbers.append(m_number)

    m_numbers_sum, m_numbers_diff = compute_addition_difficulty(*m_numbers)
    difficulty += m_numbers_diff

    numbers = [m_numbers_sum] + numbers[2:]
    product, m_diff = compute_multiplication_difficulty(*numbers)

    difficulty += m_diff

    return product, difficulty
</pre>
<p><br/></p>
<h3>Division</h3>
<pre lang="python">
division_difficulties = {
    # long division
    'use_digit'       : 1,  # brinding down digit from dividend
    'multiple_lookup' : 1,  # looking up precomputed multiple of divisor
    'quotient_update' : 1,  # updating quotient with digit or period
}
</pre>
<p><br/></p>
<p>Implementing long division posed a problem because my understanding of the mechanics behind the long division algorithm was minimal if not inexistent. I spent some time trying to "reverse-engineer" it. I came across "Egyptian Division" which made things clearer. With a little help, I managed to implement the following division algorithm. Please let me know, if you come up with a better approach.</p>
<pre lang="python">
def compute_division_difficulty(dividend, divisor, precision):
    '''
    Generates a difficulty number, quotient and remainder
    for dividend / divisor
    @precision (int) -- max required number of digits after decimal point in quotient
    returns: (quotient, remainder, difficulty)

    >>> compute_division_difficulty(54, 5, 0)
    (10.0, 4, 6)
    >>> compute_division_difficulty(50, 5, 0)
    (10.0, 0, 6)
    >>> compute_division_difficulty(575, 6, 0)
    (95.0, 5, 60)
    >>> compute_division_difficulty(575, 6, 1)
    (95.829999999999998, 20, 112)
    >>> compute_division_difficulty(6, 9, 1)
    (0.66000000000000003, 60, 50)
    >>> compute_division_difficulty(410, 2, 1)
    (205.0, 0, 54)
    '''

    if not divisor: raise Exception('Division by Zero')
    if not dividend: return 0, 0, 1

    dividend = str(dividend)

    divisor  = str(divisor)

    difficulty = 0
    previous_multiples_difficulty = 0
    precision_reached = 0
    decimal_point_used = 0
    dd = division_difficulties
    num = []
    quotient = []

    num = dividend[0]
    difficulty += dd['use_digit']
    index = 0

    while 1:
        q_digit = int(num) / int(divisor)

        multiple, multiple_difficulty = compute_multiples_difficulty(int(divisor), q_digit)
        difficulty += int(math.fabs(multiple_difficulty - previous_multiples_difficulty))
        if previous_multiples_difficulty: difficulty += dd['multiple_lookup']
        previous_multiples_difficulty = max(multiple_difficulty, previous_multiples_difficulty)

        quotient.append( str(q_digit) )
        difficulty += dd['quotient_update']

        if decimal_point_used:
            precision_reached += 1

        num, sub_difficulty = compute_subtraction_difficulty(int(num), multiple)
        difficulty += sub_difficulty
        num = str(num)

        index += 1

        if index == len(dividend):
            if precision == 0: break
            quotient.append('.')
            difficulty += dd['quotient_update']
            decimal_point_used = 1

        if not decimal_point_used:
            num += dividend[index]
        else:
            num += '0'

        difficulty += dd['use_digit']

        if (len(num) == 1 and not int(num)) or precision_reached >= precision + 1:
            break

    remainder = int(num)
    quotient = float(''.join(quotient))

    return quotient, remainder, difficulty
</pre>
<p><br/></p>
<p>You must've noticed the usage of compute_multiples_difficulty(). In long division, at every step, you will try to find the largest multiple of the divisor less than or equal to the number in hand to proceed further. During the process of division, if you've computed the 5th (say) multiple of the divisor with difficulty N. The computation of 6th multiple at a later point in the division is difficulty(lookup of 5th multiple) + difficulty(6-5th multiple).</p>
<h2>Results</h2>
<pre lang="python">
#Problem 1
>>> compute_addition_difficulty(5, 3)
(8, 2)

#Problem 2
>>> compute_addition_difficulty(99999, 12345)
(112344, 22)

#Problem 3
>>> compute_addition_difficulty(1000000, 1000001)
(2000001, <img src='http://blog.prashanthellina.com/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' />
</pre>
<p><br/></p>
<p>Problem 1: <strong>2</strong><br />
Problem 2: <strong>22</strong><br />
Problem 3: <strong>8</strong></p>
<h2>The End</h2>
<p>I wish I could have written a more detailed explanation instead of sprinkling this article with code. Time however prevents me from doing so <img src='http://blog.prashanthellina.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> . It is some relief that Python is a <a href="/2008/07/11/even-a-python-can-be-abused/">wonderful language for readability</a> and the code samples above are pretty close to pseudo-code.</p>
<p>I will post back when I complete the program to generate arithmetic problems by order of difficulty. Until then, Adios amigos. Almost forgot! Here is the <a href="http://code.prashanthellina.com/code/atrainer.py">code</a>.</p>
<p><center><img src="http://www.prashanthellina.com/images/meaningoflife.gif" alt="meaning of life math cartoon"/></center></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.prashanthellina.com/2008/07/27/determining-the-difficulty-of-arithmetic-operations/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

