# iterative.py
# Steve Marschner (srm2) and Lillian Lee (ljl2)
# March 28, 2013
"""Lecture demo: iterative versions of the problems in the recursion lab.
Some are solved already; the rest are for you to try yourself.
"""

def numberof(thelist, v):
    """Returns: number of times v occurs in thelist.

    Note: Does the same thing as thelist.count(v).
    
    Precondition: thelist is a list of ints
                  v is an int"""
    count = 0
    for n in thelist:
        if n == v:
            count += 1
    return count


def replace(thelist,a,b):
    """Returns: a COPY of thelist but with all occurrences of a replaced by b.
    The original list is not modified.
    
        Example: replace([1,2,3,1], 1, 4) = [4,2,3,4].
        
    Precondition: thelist is a list of ints
                  a and b are ints"""
    result = []
    for n in thelist:
        if n == a:
            result.append(b)
        else:
            result.append(n)
    return result


def remove_dups(thelist):
    """Returns: a COPY of thelist with adjacent duplicates removed.
    The original list is not modified.
    
        Example: for thelist = [1,2,2,3,3,3,4,5,1,1,1],
        the answer is [1,2,3,4,5,1]
    
    Precondition: thelist is a list of ints"""
    result = thelist[:1]
    for n in thelist[1:]:
        if n != result[-1]:
            result.append(n)
    return result


def remove_dups2(thelist, N):
    """Returns: a COPY of part of thelist with adjacent duplicates removed.
    The original list is not modified.  The returned list has size at most N.
    
        Example: for thelist = [1,2,2,3,3,3,4,5,1,1,1],
        the answer is [1,2,3,4,5,1]
    
    Precondition: thelist is a list of ints"""
    result = thelist[:1]
    i = 1
    while i < len(thelist) and len(result) < size:
        n = thelist[i]
        if n != result[-1]:
            result.append(n)
    return result


def remove_first(thelist, v):
    """Returns: a COPY of thelist but with the FIRST occurrence of v
    removed (if present).  The original list is not modified.

    We are thinking of an iterative solution, not a solution using 
    the index() method.

    Precondition: thelist is a list of ints
                  v is an int"""
    return [] # Stub return.  Replace this.


def into(n, c):
    """Returns: The number of times that c divides n,
    
        Example: into(5,3) = 0 because 3 does not divide 5.
        Example: into(3*3*3*3*7,3) = 4.
    
    Precondition: n >= 1 and c > 1 are ints."""
    return 0 # Stub return.  Replace this.


def num_digits(n):
    """Yields: number of the digits in the decimal representation of n.

        Example: num_digits(0) = 1
        Example: num_digits(3) = 1
        Example: num_digits(34) = 2
        Example: num_digits(1356) = 4

    We are thinking of a recursive solution using arithmetic 
    operations and numerical comparisons, rather than a solution
    based on converting the number to a string.
    
    Precondition: n >= 0 is an int"""
    return 0 # Stub return.  Replace this.


def sum_digits(n):
    """Returns: sum of the digits in the decimal representation of n.
    
        Example: sum_digits(0) = 0
        Example: sum_digits(3) = 3
        Example: sum_digits(34) = 7
        Example: sum_digits(345) = 12
    
    Precondition: n >= 0 is an int."""
    return 0 # Stub return.  Replace this.

def reverse1(thelist):
    """Returns: a COPY of thelist that is the reverse of the list.
    The original list is not modified.
    
        Example: the reverse of [1,2,3] is [3,2,1]
    
    Produces the same result as making a copy of the list and
    then calling the reverse() method.

    Implement this function with the following idea:
    The reverse of thelist can be constructed by appending the
    items in the list to the empty list, in reverse order.

    Precondition: thelist is a list of ints"""
    return [] # Stub return.  Replace this.


def reverse2(thelist):
    """Returns: a COPY of thelist that is the reverse of the list.
    The original list is not modified.
    
        Example: the reverse of [1,2,3] is [3,2,1]
    
    Produces the same result as making a copy of the list and
    then calling the reverse() method.

    Implement this method with the following idea:
    The reverse of thelist can be constructed by inserting the
    items at the head of a new list (which starts empty), in
    the usual order.

    Precondition: thelist is a list of ints"""
    return [] # Stub return.  Replace this.


def number_not(thelist, v):
    """Returns: number of elements in thelist that are NOT v.
    
    Precondition: thelist is a list of ints
                  v is an int"""
    count = 0
    for n in thelist:
        count += (n != v)
    return count


def sum_list(thelist):
    """Returns: the sum of the integers in thelist.
    
    Does the same thing as the built-in function sum().
        Example: sum_list([34]) is 34
        Example: sum_list([7,34,1,2,2]) is 46
    
    Precondition: thelist is a list of ints"""
    return 0 # Stub return.  Replace this.


def sum_to(n):
    """Returns: sum of numbers 1 to n.
    
        Example: sum_to(3) = 1+2+3 = 6, 
        Example: sum_to(5) = 1+2+3+4+5 = 15

    We are thinking of a recursive solution, rather than a solution
    using the closed-form formula.
    
    Precondition: n >= 1 is an int."""
    return 0 # Stub return.  Replace this.


def num_digits(n):
    """Yields: number of the digits in the decimal representation of n.

        Example: num_digits(0) = 1
        Example: num_digits(3) = 1
        Example: num_digits(34) = 2
        Example: num_digits(1356) = 4

    We are thinking of a recursive solution using arithmetic 
    operations and numerical comparisons, rather than a solution
    based on converting the number to a string.
    
    Precondition: n >= 0 is an int"""
    return 0 # Stub return.  Replace this.


def sum_digits(n):
    """Returns: sum of the digits in the decimal representation of n.
    
        Example: sum_digits(0) = 0
        Example: sum_digits(3) = 3
        Example: sum_digits(34) = 7
        Example: sum_digits(345) = 12
    
    Precondition: n >= 0 is an int."""
    return 0 # Stub return.  Replace this.


def number2(n):
    """Returns: the number of 2's in the decimal representation of n.
    
        Example: number2(0) = 0
        Example: number2(2) = 1
        Example: number2(234252) = 3
        
    We are thinking of a recursive solution using arithmetic 
    operations and numerical comparisons, rather than a solution
    based on converting the number to a string.
    
    Precondition: n >= 0 is an int."""
    return 0 # Stub return.  Replace this.


def exp(b, c):
    """Returns: b ** c, i.e. b multiplied by itself c times.
    
    Also called b "to the power" c.
    Hints: b ** 0 = 1.
    if c is even, b**c == (b*b) ** (c/2)
    if c > 0, b**c =  b * (b ** (c-1)).
    
    Precondition: c >= 0 is an int"""
    return 0 # Stub return.  Replace this.