The only tricky part here is parsing the input to obtain the two integers and the operand. We can
use the regular expression on line 5 for this. This will look for any of the characters (+, -, *, or /)
and split the input into the integer that comes before and after the operator. When constructing the
regular expression, you'll need to use \\ to escape some of the characters.

int[0] will hold the first number. Thus, we can obtain the operator buy using the length of int[0]. This
is done on line 7. We can use Integer.parseInt() to get the integer values from the strings.

Then it's a simple matter of checking the value of the operator and performing the correct operation.

Thank you for taking the time to read this solution. I welcome
any feedback you may have.

For a detailed discussion of the Birthday Problem, see the wikipedia entry
here. This solution is based
on the formula given in the "Calculating the probability" section.

Essentially we're calculating the probability that there is not a match, and then adding more
and more people thus reducing that probability until a certain threshold is met. That threshold
is (1 - minOdds) since we're calculating the probability of not matching whereas minOdds is the
probability of a match.

We need to deal with two separate cases here: the color may meet the given definition of grey, or it may not.
The trouble is, we won't know if it's considered grey or not until we've examined all three colors. We'll
start by assuming that the color is grey, and then flip the isGrey flag to false if we find a red, green,
or blue value whose compliment exceeds GREY_TOLERANCE.

We start by creating the output array named compliment. Then for each value in rgb, we calculate the
corresponding compliment by subtracting the color in the current position of rgb from RGB_MAX. If the
difference between a color and its compliment exceeds GREY_TOLERANCE, then we'll set isGrey to false.

After red, green, and blue have all been evaluated, if isGrey is still true then we need to handle it according
to the instructions for a grey color. For each position in rgb, if the value is greater than or equal to 128,
we subtract 128, otherwise add 128. This value will overwrite the value in compliment[] that was stored
earlier.

Thank you for taking the time to read this solution. I welcome
any feedback you may have.

You might assume that you could use a built-in data structure, such as a linked list to solve the problem.
Just initialize the list, and then let it do the removals for you. However, it pays to take a look at
the constraints first. The number of elements can be up to 2,000,000,000 which is way too much to fit into
the allotted 64MB.

The solution is to think about how k's position changes as elements in front of it are removed. Elements
that are greater than k don't matter when they're removed since these won't affect k's position.

We start at the end work backwards through each String in remove. First, parse out the lo and hi elements of
the string. Then, if lo is less than k, we'll adjust k's position accordingly. The number of elements removed
is given by (hi - lo + 1). So, we increase k's value by that amount to get it's position before
the removals.

After working backward through all the elements in remove, the value of k will be it's original starting
position which is the value we want to return.

Be careful to check the value of k after each addition. If it's ever greater than n, we'll return -1. The
addition could also cause an overflow. You could convert k to a long to prevent this, or just check the
value to see if it becomes negative. Since the value of hi will be 2 billion or less, it will fit into
an int. Adding 2 billion to a positive int and causing an overflow will always result in a negative number.

Thank you for taking the time to read this solution. I welcome
any feedback you may have.

This is one of those problems where reading the description makes you think it's going to be much more
difficult than the problem actually is. All we need to do is for each of the four traits (shape, color,
fill pattern, and count) give the value of the string if the first and second card have the same value. Or,
if the first and second cards have different values, then we give the third (or odd man out) value.

The for loop in the findMatch() method just walks through each of the four traits, and calls getMatch() to
insert the correct value into the result array.

getMatch() compares the two strings, and if they're equal returns that value. Otherwise, it looks through
the values given in traits for a string that does not match s1 and does not match s2. Note that we should
never reach the return null statement on line 37, but it needs to be there to satisfy the compiler.

Nothing difficult here. Getting through the description actually took longer than writing the code.

Thank you for taking the time to read this solution. I welcome
any feedback you may have.

Note that the size of both the risers and treads must be integers, and that they are at most 1,000. This means
that a brute force search is certainly possible. We'll loop through all possible heights and count the number
of configurations that are possible.

For each riser height, we first check to see if it evenly divides the total height. If not, then we can
continue on with the next height. If so, then we'll look at the treads.

The number of treads will be one less than the number of risers. We can compute the number of risers with
(totalHeight / riserHeight). Then just subtract one from that result to get the number of treads.

Next, we look for ways to discount the current number of risers and treads. The problem statement says that
their must be at least one tread (and riser), so we can throw out any cases where the number of treads is
0. Again, just like with the risers, the total width must be evenly divided by the number of treads, so we can
skip any case where that isn't true. And finally, any case where the width of each tread
(totalWidth / numTreads) is smaller than the minimum allowed can also be skipped.

Passing each of those tests, leaves us with a valid configuration, so increment the counter. After looping
throug all possibilities, return the value in the counter.

Thank you for taking the time to read this solution. I welcome
any feedback you may have.

This solution basically just follows the rules for the election as given in the problem statement.
First, it creates a set of remaining candidates, then it enters a while loop which will not terminate
until either a winner is found, or the set of remaining candidates becomes empty.

For each iteration of the loop, we count up the number of first place votes that each active candidate
has received. If any of the candidates receives more than half of the possible votes, then they are
declared the winner. Be careful in checking for a majority, the equation on lines 34 and 35 is easy
to get wrong.

If there is no clear winner, then we look for the least number of first place votes, and remove any
candidate that has that number of first place votes. Here, we remove those candidates from both
the active candidates set, as well as from all the ballots. The easiest, although perhaps not the most
efficient way is to do the replacement on line 58.

Finally, if there are no more active candidates, then we return the empty string.

Thank you for taking the time to read this solution. I welcome
any feedback you may have.

This is a pretty easy Divison 1 problem, with just a few tricks to overcome. First, I'll
begin by saying I was tripped up by the ordering of the coordinates. I assumed that the
numbers were in the form (x, y). They're not. The description says they're given as (row, col).
In other words (y, x). After seeing my output sideways, I tracked the error down and fixed it.

The first problem to solve is parsing the input. For this, first I replaced all parenthesis and
commas with spaces. Then I created a scanner that uses whitespace as the delimeter. With that,
I can just use a pair of nextInt() calls to get the coordinates until they run out.

I find these problems much easier to work with using char arrays. I'll often convert the
given String[] into a char[][] just to simplify. In this case, I represent the mineField
as a char[][] and then convert it to a String[] when returning the result.

With the coordinates, and the mineField, the next problem is to add the mine to the
current board. That's just a matter of setting that location to 'M', and then updating
all the neighbors. I use a nested for loop to visit all the neighbors of the given location
working top to bottom and left to right. For each location, check to ensure that we're
not outside the boundaries of the array, and that the square is not already marked as
a mine. If that test passes, then increment the value stored there. Since we can
treat chars as ints here, mineField[r][c]++ will work nicely.

Thank you for taking the time to read this solution. I welcome
any feedback you may have.

The first step is to divide the crossword up into individual rows. For each row, we'll
add up the number of slots, and then return the sum.

The count the slots in an single row we'll step through each character of the given string
looking for 'X's since the 'X' character terminates a slot. If any character other than
an 'X' is encountered, we simply increase the number of spaces seen. When an 'X' appears,
we check to see if the number of spaces matches what we're looking for. If so, increment
the count for this line.

Be careful to include the case where the slot ends at the end of the string. The last
check - "if (spaces == size)" takes care of this.

Thank you for taking the time to read this solution. I welcome
any feedback you may have.

The problem can be solved by breaking it up into two pieces. First, obviously we're going
to need a method to determine if a character is a consonant or vowel. This is
handled by isVowel(). isVowel() first converts the character to upper-case, and then
compares it to the standard vowels A, E, I, O, and U. If it matches one of these, or if
it doesn't and also is not a 'Y' then we're done. 'Y's are the only tricky letter.

To determine if 'Y' is a vowel or not, isVowel() requires a boolean denoting whether
the previous character was a vowel or not. We can set prevIsVowel's initial value to true
since the behavior of a 'Y' at the beginning of a string is the same as a 'Y' following
a vowel.

With a reliable method of determining consonants and vowels, we just need to construct
the return String, and the only challenge there is eliminating duplicates. One way
to do this would be to keep track of the last character, and only append the next
character if it differed. An easier way is to just add all the characters, and
then use a regular expression to remove the duplicates. This is done in the
replaceAll() method of the return statement.

If you're not familiar with the assignment on line 10, all this does is assign the
result of isVowel() to both prevIsVowel and cvArray[i] in one line. First, isVowel()
is evaluated and the result is assigned to prevIsVowel. The result of this assignment,
which is either true or false, is then assigned to cvArray[i]. With that, we've
put the correct character (either a 'V' or a 'C') into the array, and set prevIsVowel
to the correct value for the next call into isVowel().

Thank you for taking the time to read this solution. I welcome
any feedback you may have.

This problem becomes very easy once you break it down into smaller steps. The first task
is to take the unwieldly String[] and convert it into an easy to use 3 dimensional array
of chars. This is handled on lines 15-23. Nothing trick here, except for a little bit
of math to get the right character out of the String.

With our 3-D array, we can now loop through each position and count the number of lines
starting at that position. Note that we'll count each row twice. Once starting from
each end and going to the other.

The countLinesStartingAt() method does just that. Given a 3-D coordinate, it returns
the number of lines starting from that position. Rather than writing out the 27 directions
that we could move out from for any given position, I have three nested loops and the
variables deltaX, deltaY, and deltaZ. Each of these variables moves from -1 to 1.

With that, we call isLine() providing the staring point, direction, and color. isLine()
just checks that we stay within the confines of the cube and stay on the correct color
as we move along the line.

Nothing really difficult here. It could probably have been a Division 2 Level 2.

Thank you for taking the time to read this solution. I welcome
any feedback you may have.

The first step is to determine how many seconds the skewed clock is away from the true time. This
is calculated on lines 18-27 and is stored in skewSeconds. Note that if skewSeconds is positive
then the skewed clock is behind true time. If skewSeconds is negative, then the skewed clock is
ahead of the true time.

If skewSeconds is 0, then we can simply return 0. Otherwise, we'll want to divide the number of seconds
the two clocks are off by the hourlyGain. This is fine if the skewed clock is ahead and hourlyGain is
negative; or if the skewed clock is behin and hourlyGain is positive. But we must account for two other
cases as well.

If the skewed clock is ahead, and the hourlyGain is positive, then it's distance ahead will keep increasing.
To fix this, we can just set the skewed clock back 12 hours. Similary, if the skewed clock is behind, and
the hourlyGain is negative, we can adjust the skewed clock ahead 12 hours. Be careful with the signs here,
it can get a little confusing.

Thank you for taking the time to read this solution. I welcome
any feedback you may have.

The solution starts by creating an array (heights) to store the two closest numbers. It sets
their initial values to Integer.MAX_VALUE to ensure they're far enough away from our height
that the first two numbers seen are guaranteed to be closers.

Then we make one pass through the list of candidate heights. If the height is closer than
the value in position 0, we move the closest into the second closest position, and insert
our candidate in position 0 as the next closest height.

If the height is not the closest, but it is closer than the second closest, then we simply
replace the the height in position 1 with our current candidate's height.

The method isCloser determines if the value is candidate is closer to height than the value of
current. Note that we must take the absolute value of the difference. In the event of a tie
closer is determined by if candidate is greater than current.

Thank you for taking the time to read this solution. I welcome
any feedback you may have.

A pretty easy problem for a Division 2 - Level 3. There's just two tricky things to take care of. First, we
need to divide the input into columns that are no wider than the given width. To do this, I create a single
list that contained all of the words. Note that the lines may have trailing and/or leading whitespace which
we want to remove. Combining trim() with .split("\\s+") gives us the individual words nicely.

Next, I divide the words by line into one column, such that the length of each line is less than or equal
to width. This is done easily enough by the loop on lines 28 - 62. We just test the length of the current
line plus a space plus the length of the next word. If that is greater than width, cut the line off and
put the word at the beginning of the next line.

Finally, we need to split the one column up into two columns with the lines interleaved. The easiest way
to do this is to assign all the even numbered positions first. Then upon reaching the end of the list,
come back to position 1, and start filling in the odd positions.

Thank you for taking the time to read this solution. I welcome
any feedback you may have.

I've created a class Team the implements Comparable so that we can use Java's built-in sort capabilities.
All the logic necessary for sorting the teams is contained in the Team.compareTo() method.

With that, it's just a matter of creating the team objects, and adding their finishing places. Lines 67-70
create an array of teams and assign each one it's name. Then the loop on lines 79-82 works through each of
the letters in finishOrder and calls addFinisher() on the corresponding team. We can get the correct team
by subtracting 'A' from the current letter. For example, if the letter is 'C', the 'C' - 'A' = 2, which
is the position in the teams array of team C.

The addFinisher() method handles the logic of determining if this runner's score counts toward the team's
score (it's a top 5 runner), or if we should store this score in tieBreaker (if it's the 6th runner for
that team).

Once all the team data is populated, we add only those teams with 5 or more runners to the qualifyingTeams
list, sort the list, and then add each team's name in order to the string that we return.

Thank you for taking the time to read this solution. I welcome
any feedback you may have.

The first task is to parse each string in the array to get the size of the die and
the number of rolls. This is easy enough using String.split(). By splitting on
the "d" character, we'll get the number of rolls in position 0, and the size
of the die in position 1 or the resulting array.

To get the minimum value, we just assume that the die always comes up one. So, minimum
is just equal to the number of die rolls.

To get the maximum value, we assume that die always comes up with it's largest possible value.
Here, we just multiple the number of rolls by the size of the die.

Then, we compute the average using the formula on line 22.

We these three values calculate, we just create an int[] to hold them, and return it.

Thank you for taking the time to read this solution. I welcome
any feedback you may have.

My first approach was a simple greedy algorithm. I sorted the opponents according to the amount of hit points
they had remaining, and then assigned the biggest attack to the opponent with most hit points remaining, the
next biggest attack to the next strongest opponent, and the last attack to the third strongest opponent. Then
I re-sorted the opponents, and repeated. As the first test shows, this approach does not work.

Instead, we'll need to try every possible combination.

The minimalAttacks(int,int,int) method begins by ensuring we don't allow the hit point values to go below 0.
Then it checks to see if we've already solved for this combination of x, y, and z. If so, then we can just
return that value This technique is called memoization, and allows up to skip the calculations that follow if
they've already been carried out.

If we don't already have a result, then the loops on lines 62-77 will recursively call minimalAttacks with
every possible combination of assigning attacks to the various opponents. We keep track of the best result
in the minAttacks variable, and then store this in the results matrix before returning it.

The minimalAttacks(int[]) method checks for a few easy cases (length of x is 0 or 1), and failing that
initializes the results matrix, and then uses minimalAttacks(int, int, int) to calculate the result.

Thank you for taking the time to read this solution. I welcome
any feedback you may have.

Imagine creating two Strings s1 and t1 such that s1 = s + s + s ... and t1 = t + t + t + t + ...
and the length of both s1 and t1 is equal to the least common multiple of the lengths of s and t.

For example if s = "ababab" and t = "abab", then the length of s is 6, the length of t is 4, and their
least common multiple is 12. Therefore, s1 = s + s = "abababababab" and t1 = t + t + t = "abababababab".
Since s1 == t1 we should return "Equal"

The important point is that if we step through the Strings s and t one character at a time, and loop
back to the beginning of the String when we reach the end; then we can stop when we reach the end
of both s and t at the same time. That's the condition that is checked for in the while loop.

The rest is just a matter of checking that the characters match at each position, and incrementing
and resetting the pointer to the current character.

Thank you for taking the time to read this solution. I welcome
any feedback you may have.

Easier than the 500 point solution RecurrenceRelation, Poetry
is pretty straight forward. There's just three things to take care of:

First, we need to split each line of the input up into words, and then examine the last word of the line.
Splitting it up is easy with the String.split() method, using the "\\s+" regular expression. Then
we need to check to make sure it wasn't an empty line. The word we're interested in is the last element
of the result of the split.

Next we need to determine the ending of the word. For this, we start at the end of the word and work
backward until we reach the first vowel. Then we continue backward so long as we continue getting vowels, and
we don't run past the beginning of the String.

Finally, we need a method to determine if a character is a vowel. This is trivial for characters other
than 'y'. 'y' is a vowel unless it is the first or last character of the word.

With that in place, the rest is just housekeeping. We create a char[] named result to hold the label for
each line. nextRhymeLabel holds the character we'll use for the next previously unseen word ending. When
a new ending is encountered, we assign it the value in nextRhymeLabel, and then increment nextRhymeLabel, or
set it to 'A' if it has reached 'z'. We use a HashMap to map endings that we've seen to the labels that
were assigned to them.

There's really nothing difficult about this problem. I'm really surprised that it was not just Division 2 -
500 points.

Thank you for taking the time to read this solution. I welcome
any feedback you may have.

The wording of this problem makes it sound much more difficult than it actually is. You may need to read
the description several times in order to understand what it's getting at. Basically, you're asked to
solve for the value of X[n], where X[n] is based on the values of X[n-1], X[n-2], etc. The number of
previous elements that combine to create the value of X[n] is K, where K is the length of both the
coefficients and initial arrays.

Start by creating an array of ints, X[], to hold these values. Then we initialize X[] using the values
from initial[]. Note that we need to perform the mod operation as described int the problem statement
before inserting any value into X[]. Also note that if the number we're being asked to solve for (N) is less
than, or equal to, the length of the initial[] array (N <= K), then we already have our answer. We can
just return the the value in X[N].

Otherwise, we need to solve for each value of X[n] up to n = N. To get the next value we multiply each
value in X[] by it's corresponding value in coefficients[] and note their sum. Then we shift all elements
in X[] down by 1 (dropping off the value in X[0]) and insert our new value into the right-most position - after
running it through the mod operation.

Once n == N, we have solved for the number that was asked for. The value we need is the most recent
solution found which is stored in the greatest element of X.

The method myMod() simply implements the mod function as described in the problem statement. It is the normal
% function, modified to handle negative numbers.

Again, the toughest part of the problem is just reading through the problem statement making sense of it. I
actually thought this was harder than the 1000 point problem
Poetry.

Thank you for taking the time to read this solution. I welcome
any feedback you may have.

Certainly one of the easiest problems to solve. Just loop through the values in expNeeded
until you find one that is greater than received. Then just return that next value minus
the amount of received.

Really the only thing to be careful of is the case where the amount received exactly
equals the amount needed for a level. In this case, return the amount needed to
reach the next level, and not 0.

Thank you for taking the time to read this solution. I welcome
any feedback you may have.

Tuesday, May 12, 2015

Determine the minimum time needed to search through a set of folders given a number of workers.
The workers must search a contiguous set of folders, and each folder may take a varying amount
of time to process.

FairWorkload is a problem that begs for a dynamic programming solution. To solve this, we'll build up a table
that holds the best finishing time we can achieve given a number of workers and a number of folders. We'll
start with the trivial case of just one worker. Using that information, we'll add additional workers and
folders until we've completed the table. The result will be the table shown below. With that, we can just
return the value of the cell in the bottom right corner.

Don't be confused by the number of workers; I've labeled the table using its indexes, so "Workers 0" is the
case with one worker. Same goes for folders across the top.

The table is initialized by filling in the top row. With just one worker, the number of sections searched
is just the sum of the sections in all previous folders, plus the number of sections in the current folder.
This could have been done more efficiently by keeping a running total of the number of sections, but since I
needed a sumSections() method anyway, I chose to rely on that here.

Note that we cannot satisfy the constraints of the problem if there are fewer folders than their are workers.
These cases are noted with a -1, although that never really comes into play.

Things begin to get interesting with the second worker. With 2 workers and 2 folders, we know that 1 worker
must look through 10 sections to complete 1 folder, and that worker 2 must look through 20 sections to complete
the next folder. Therefore the minimum number of sections is 20.

With 2 workers and three folders we have a choice in how to complete the task. We can either assign the
first 2 folders to worker 1, and the third to worker 2 (scenario 1)- or we can assign just the first folder to
worker 1, and the remaining two to worker 2 (scenario 2). We need to check both cases and see with gives the
better result. Scenario 1 gives 10 + 20 = 30 sections to worker 1 and 30 sections to worker 2. Scenario 2
gives 10 sections to worker 1 and 20 + 30 = 50 sections to worker 2. The max of 30 in scenario 1 is better
than the max of 50 in scenario 2, so 30 is our value here.

The loop on line 39 works through each scenario. In general, we want to minimize the maximum value of sections
as we move the dividing line across the range of folders. The dividing line separates the work done by
previous workers on one side (which can be pulled right out of the table), and the work done by the latest
worker, which is the sum of the number of sections remaining.

Folder / Number of Sections

0/10

1/20

2/30

3/40

4/50

5/60

6/70

7/80

8/90

Workers0

10

30

60

100

150

210

280

360

450

1

-1

20

30

60

90

110

150

210

240

2

-1

-1

30

40

60

90

110

150

170

3

-1

-1

-1

40

50

60

90

110

150

4

-1

-1

-1

-1

50

60

70

90

110

This is a great problem to hone you dynamic programming skills. Please take the time to make sure that you
understand what's going on. It's a great tool to have for many TopCoder problems.

To help make it as clear as I can, let me walk through the final cell. Imagine that the bottom right cell
was not yet filled in. From the previous row, we know the best solutions for each number of folders with one
less worker. Since each worker must have at least one folder, we can divide the 9 folders up as follows:

Folders 0 - 4 processed by workers 0 - 3 / Folders 5 - 8 processed by Worker 4. Again from the table, the
previous workers can do folders 0 - 4 with a max of 50. Worker 4 has 60 + 70 + 80 + 90 = 300 sections. Better
than before, but still not the best we can do.

It turns out the best solution is to have Folders 0 - 7 processed by workers 0 - 3 / and just Folder 8 processed
by worker 4. The previous workers have a max of 110 sections, and Worker 4 has just 90 sections. The
max of 110 is the best we can do, so that's what goes into the bottom right cell.

Thank you for taking the time to read this solution. I welcome
any feedback you may have.