// Solutions to Test 2 Review 1 CompSci 6 Fall 2005


//------------------------------------------------------------
// Question 1
//

// Part A
public int pieceCount (String url)
{
    int pieces = 0;

    int index = url.indexOf("=");
    while (index >= 0)
    {
        pieces++;
        index = url.indexOf("=", index + 1);
    }
/*  OR:
    int pieces = 1;    // guaranteed to be at least one
    int index = url.indexOf("&");
    while (index >= 0)
    {
        pieces++;
        index = url.indexOf("&", index + 1);
    }
*/
/*
    OR:
    int pieces = 0;
    Scanner input = new Scanner(url);
    input.useDelimiter("&");
    while (input.hasNext())
    {
        input.next();
        pieces++;
    }
*/
    return pieces;
}

// Part B
public String getNthPiece (String url, int n)
{
    for (int k = 1; k < n; k++)
    {
        url = url.substring(url.indexOf("&") + 1);
    }

    int index = url.indexOf("&");
    if (index < 0) return url;
    else           return url.substring(0, index);
/*
    OR:
    String result = "";
    Scanner input = new Scanner(url);
    input.useDelimiter("&");
    for (int k = 0; k < n; k++)
    {
        result = input.next();
    }
    return result;
*/
}

// Part C
public void splitURL (String url, List<String> ids, List<String> values)
{
    int numPieces = pieceCount(url);
    for (int k = 1; k <= numPieces; k++)
    {
        String pair = getNthPiece(url, k);
        int index = pair.indexOf("=");
        ids.add(pair.substring(0, index));
        values.add(pair.substring(index + 1));
    }
}


//------------------------------------------------------------
// Question 2
//

public boolean isSubset (Set<Object> first, Set<Object> second)
{
    // cannot be a subset if it is bigger
    if (first.size() > second.size())
        return false;

    // check each element directly
    Iterator<Object> iter = first.iterator();
    while (iter.hasNext())
    {
        if (! second.contains(iter.next()))
            return false;
    }
    // only if all elements are contained, is it surely a subset
    return true;

/*  OR:
    // keep count and check that all values were counted
    int count = 0;
    Iterator<Object> iter = first.iterator();
    while (iter.hasNext())
    {
        if (second.contains(iter.next()))
            count++;
    }
    return (count == first.size());
*/
}


//------------------------------------------------------------
// Question 3
//

// Part A
public int digitSum (int num)
{
    int sum = 0;

    DigitIterator iter = new DigitIterator(num);
    while (iter.hasNext())
    {
        sum += iter.next().intValue();
    }

    return sum;
}

// Parts B and C
public class DigitIterator
{
    private String myNumber;
    private int myCurrentDigit;

    public DigitIterator (int number)
    {
        myNumber = "" + number;
        myCurrentDigit = myNumber.length() - 1;
    }

    public boolean hasNext ()
    {
        return (myCurrentDigit >= 0);
    }

    public Integer next ()
    {
        Integer result = new Integer(myNumber.substring(myCurrentDigit, 1));
        myCurrentDigit--;
        return result;
    }
}

// OR:
// using traditional math
public class DigitIterator
{
    private int myNumber;
    private int myCurrentDigit;

    public DigitIterator (int number)
    {
        myNumber = number;
        myCurrentDigit = 0;
        next();
    }

    public boolean hasNext ()
    {
        return (myCurrentDigit >= 0);
    }

    public Integer next ()
    {
        Integer result = new Integer(myCurrentDigit);
        if (myNumber > 0)
        {
            myCurrentDigit = myNumber % 10;
            myNumber /= 10;
        }
        else
        {
            myCurrentDigit = -1;
        }
        return result;
    }
}


//------------------------------------------------------------
// Question 4
//

// Part A
public class Date
{
    private int myDay;
    private int myMonth;
    private int myYear;

    public Date (String data)
    {
        Scanner input = new Scanner(data);
        input.useDelimiter("/");
        myMonth = input.nextInt();
        myDay = input.nextInt();
        myYear = input.nextInt();
        // OR:
        // int firstIndex = data.indexOf("/");
        // int lastIndex = data.lastIndexOf("/");
        // myMonth = Integer.parseInt(data.substring(0, firstIndex));
        // myDay = Integer.parseInt(data.substring(firstIndex + 1, lastIndex));
        // myYear = Integer.parseInt(data.substring(lastIndex + 1));
    }

    public boolean equals (Date other)
    {
        return (myYear == other.myYear && 
                myMonth == other.myMonth && 
                myDay == other.myDay);
        // OR:
        // return (compareTo(other) == 0);
    }

    public int compareTo (Date other)
    {
        int result = myYear - other.myYear;
        if (result == 0)
        {
            result = myMonth - other.myMonth;
            if (result == 0)
            {
                result = myDay - other.myDay;
            }
        }
        if (result > 0)      return 1;
        else if (result < 0) return -1;
        else                 return 0;
    }
}

// Part B
public List<Date> readDates (Scanner input)
{
    List<Date> results = new ArrayList<Date>();

    while (input.hasNext())
    {
        results.add(new Date(input.next()));
    }

    return results;
}

// Part C
public Date closestWithoutGoingOver (Date target, List<Date> dates)
{
    // assume first is closest
    Date closest = dates.get(0);

    for (int k = 1; k < dates.size(); k++)
    {
        Date current = dates.get(k);
        if (current.compareTo(target) < 0 &&
            current.compareTo(closest) > 0)
        {
            closest = current;
        }
    }

    if (closest.compareTo(target) > 0) return target;
    else                               return closest;
}
