Five Digit Primes in a 5x5 Grid - java

|---|---|---|---|---|
| 1 | 1 | 3 | 5 | 1 |
|---|---|---|---|---|
| 3 | 3 | 2 | 0 | 3 |
|---|---|---|---|---|
| 3 | 0 | 3 | 2 | 3 |
|---|---|---|---|---|
| 1 | 4 | 0 | 3 | 3 |
|---|---|---|---|---|
| 3 | 3 | 3 | 1 | 1 |
|---|---|---|---|---|
(Figure 1)
Figure 1 shows a square. Each row, each column and the two diagonals can be read as a five digit prime number. The rows are read from left to right. The columns are read from top to bottom. Both diagonals are read from left to right. Using the data in the INPUT.TXT file, write a program that constructs such squares.
The prime numbers must have the same digit sum (11 in the example).
The digit in the top left-hand corner of the square is pre-determined (1 in the example).
A prime number may be used more than once in the same square.
If there are several solutions, all must be presented.
A five digit prime number cannot begin with zeros, ie 00003 is NOT a five digit prime number.
Input Data
11
1
I am attempting to do a question from IOI'94 Competition - Problem 3 - The Primes.
I have built most of the helper functions...
Used Sieve of Eratosthenes to generate 5 digit primes (between 9999 & 100000)
Built a function to compute the sum of digits (12345 = 1+2+3+4+5 = 15)
Built a function to check an array if the sum of digits are the same throughout
Built a function to check if a number startsWith a specified digit (startWith(12345,1) return true)
Question: The issue is I don't know how to full the array or use the backtracking capability to keep checking :(. Can anyone help me please? How to I go about filling the 2D array so that it contains values from the prime table and the sum is correct on all angle?
*NB: The Sieve of Eratosthenes method that generates the 5 digit prime, also as the capability of filtering values that starts with X and values sum up to M *
Complete question : http://olympiads.win.tue.nl/ioi/ioi94/contest/day1prb3/problem.html
Prospective order of adding values, just don't know how to do it :(.
1 2 3 4 5
6 13 14 12 15
7 16 11 18 19
8 10 20 22 23
9 17 21 24 25

From what you write I assume that you have a list of 5 digit prime numbers already.
Filter the list so that it contains only the primes with the right sum of digits.
You'll need a function valid to check for a valid square, given 1 to 5 numbers that go in the columns. (It is clear that the column numbers determine the other rows and diagonals. So, if the 3rd digit of the 1st column is a 7, but there is no prime that starts with 7, we know that we can't use this prime in the first column. Without looking at all the other numbers, this will prune your search tree early.)
You need another function to get sets of all valid prime numbers that have a certain digit at position n (1..5). Perhaps you want to precalculate this and store it in some tree or array.
The major work is done in valid, which must check whether there exist prime numbers for the rows and diagonals with the digits in the positions determined so far by the primes in the columns.
Then the list of solutions is:
[ (c1, c2, c3, c4, c5) | c1 <- primes, valid [c1],
c2 <- primes, valid [c1,c2],
c3 <- primes, valid [c1,c2,c3],
c4 <- primes, valid [c1,c2,c3,c4],
c5 <- primes, valid [c1,c2,c3,c4,c5] ]
or, put imperatively:
for each c1 in primes
if valid(c1) then foreach c2 in primes
if valid(c1,c2) then foreach c3 in primes
if valid(c1,c2,c3) then foreach c4 in primes
if valid(c1,c2,c3,c4) then foreach c5 in primes
if valid(c1,c2,c3,c4,c5) then print solution
Addendum: Since we need only to look for numbers that begin with a seqeuence of certain digits, the solution can be made more efficient.
Consider the case that c1,c2, annd c3 are given and valid() is about to check row 3. It takes the 3rd digit of c1, c2 and c3 and we can interpret these as the leading 3 digits of the number that must appear in row 3. We need only to fill it up with zeroes and can then check if we know a prime number that is greater than this number, but the difference must be lower than 100 (so that the leading digits are preserved). But if we have a sorted array of prime number candidated, this requires not more than a binary search in that array.

Related

Limit Rows in Result Set By Column Values

This question deals with building a correct Criteria in Hibernate for the following case.
Suppose I start with a table like this:
id ts metric value carrier
1 1 distance 4 alice
2 1 count 2 alice
3 2 distance 3 alice
4 2 count 1 alice
5 1 distance 3 becky
6 1 count 2 becky
7 2 distance 4 becky
8 2 count 1 becky
9 1 distance 10 other
10 1 count 10 other
11 2 distance 10 other
12 2 distance 10 other
What this is is a time-bucketed set of metrics recording how far alice, becky and a general other carried some count of items some distance.
I'd like to roll it up in the following fashion: metrics with 'other' or the 'winner' as decided by distance for each time bucket are kept. Thus, the above table would yield the following result set:
id ts metric value carrier
1 1 distance 4 alice
2 1 count 2 alice
7 2 distance 4 becky
8 2 count 1 becky
9 1 distance 10 other
10 1 count 10 other
11 2 distance 10 other
12 2 distance 10 other
Ultimately this is translated to this:
ts carrier distance count
1 alice 4 2
1 other 10 10
2 becky 4 1
2 other 10 10
But this translation I already understand how to do. What I'm unclear on is how to build the criteria to keep the 'top n' metrics. Which brings us to the wrinkle: while this example is simplified, there would be a large number of 'carriers', and what I'm interested in is the top n such carriers, discarding the rest. Thus in the example above n = 1, but it's likely to be greater than 1 in most cases.
I know that I can use addOrder(Order.desc("value"), but that poses both a problem in that other is intermixed and distances and counts will be incorrectly intermingled. I'm looking for something that sorts 'blocks' of rows which are decided, in order by ts, then carrier, then using the metric = "distance" for the sort order.

Number of ways to sum the items in a set to get a target value - Order matters

I'm practicing for programming interviews, and I stumbled upon this question on GlassDoor: "Find the number of ways we can sum the items in the set to get our target value. Order matters."
Apparently, the interviewer couldn't come up with an answer, but he left this comment on GlassDoor: "This was more of a math question than a programming question."
This problem seems to be different than this one: Finding all possible combinations of numbers to reach a given sum.
So my questions is: what is the correct approach to solve this problem, given that order matters? And also, what would be an efficient algorithm to solve the problem of finding all the ways to sum the items in the set to reach the target value, and order matters?
If you can provide working code, that would be awesome. Also, I'm practicing in Java, so I'd prefer a Java solution, but any language would also be fine.
Thanks so much.
Use Dynamic Programming. Let's say we have items [1, 2, 3, 4, 5] and the goal is 10. To solve this problem we will calculate the number of ways to target any value from 0 to 10 with subsets [1], [1,2].. [1,2,3,4,5].
So what if we already knew the number of ways we can sum any value from 0 to 10 with [1,2,3]? How to get the number of ways to sum any value with one more item: [1,2,3,4]? It's pretty easy: we can simple not include this new item: it's all previous values. And for every targeted value x there is an addition number of ways = number of ways targeting value (x - 4) with previous set `[1,2,3]': Let's illustrate it with table:
| sum | 1 | 2 | 3 | 4 |
| 1 | 1 | 1 |(1)| 1 |
| 2 | 0 | 1 | 1 | 1 |
| 3 | 0 | 1 | 2 | 2 |
| 4 | 0 | 0 | 1 | 1 |
| 5 | 0 | 0 |(1)|(1)+(1)| - this means that we can target 5 with 1 way
| 6 | 0 | 0 | 0 | 0 + 1 | from set `[1,2,3]` and 1 way to achieve 5 - 4
| 7 | 0 | 0 | 0 | 0 + 2 | with the same set `[1,2,3]
| 8 | 0 | 0 | 0 | 0 + 1 |
And it's easy to get initial value. With item 1 we can target only 1.
This is like a change-making problem, but you don't want the minimum number of "coins", you want to keep track of the number of ways. Furthermore, it is important to note that order matters. Use dynamic programming as follows. Suppose we want to show how to make 10 from sums of 1, 3, 5 where order doesn't matter (i.e. 1 + 3 + 1 + 5 is the same as 1 + 1 + 3 + 5). Make an array indexed to 10 (11 items). You can make 00 in 1 way. All negative indexes can be made in 0 ways.
00 01 02 03 04 05 06 07 08 09 10
1
You then count the number of ways you can make 1. If you subtract coin value 1 from 1 you get 1. If you subtract any larger coin value from 1, you get a negative index which means zero ways. You sum up the results 1 way (subtracting 1) + 0 ways (subtracting 3) + 0 ways (subtracting 5). So we have
00 01 02 03 04 05 06 07 08 09 10
1 1
Take a value of 2. We can subtract 1 cent coin to get 1 of which there is 1 way; 3 cent coin to get -1 of which there is 0 ways; 5 cent coin to get -3 of which there is 0 ways. Total 1 + 0 + 0 = 1 way to get 2 cents.
00 01 02 03 04 05 06 07 08 09 10
1 1 1
For 3 cents, we can subtract 1 to access all the ways of making change for 2 cents, or subtract 3 cents to access all the ways of making 0 cents, or subtract 5 cents to access all the ways of making -2 cents; sum of ways is 1 + 1 + 0 = 2.
00 01 02 03 04 05 06 07 08 09 10
1 1 1 2
For 4 cents, we can do it in 2 + 1 + 0 = 3 ways. However, note that the 3 ways include 1+1+1+1, 3+1, and 1+3. 1+3 and 3+1 are in different categories since they end in different numbers.
Continuing in this manner, we have
00 01 02 03 04 05 06 07 08 09 10
1 1 1 2 3 5 8 12 19 30 47
Now that we see how to construct the numbers, we can look for faster ways of doing so. Note that we have to deal with negative indices for the first few, which is a bit messy, so we might as well start with the first 5 values as given. What we need to calculate now is a recursive function: f(n) = f(n-1) + f(n-3) + f(n-5) with the condition that f(0),...,f(4) are given by the table above.
There are many ways to calculate that recursive function. This is where it becomes a real test of depth of knowledge. The naive approach would be to use recursion in the programming language. The first problem would be that your numbers will overflow because f has exponential growth. You can mitigate that situation for a time by using long instead of int. But long will quickly overflow too, so you'll have to use BigInteger to get exact results for n bigger than (I'm guessing) 20 or so.
Next, using recursive functions will be slow, because calculating f(n) might involve recalculating smaller f(x) over and over again. To mitigate that problem, use memoization to store f(x) for smaller values. Next, you'll experience stack overflow if you try to calculate from larger n to smaller. If you're calculating for a particular n, you should build up from lower values, instead of down from higher values of n.
Next, you'll experience out of memory. You can get around that by not remembering every value of f(x) as x increases, but only the last 5 values (in my example). Eventually you'll experience out of memory storing BigIntegers, but there's nothing you can do about that unless the question changes.
There are some more accelerations you can use if you're looking to improve the speed of the program. f(n) can be computed in log n operations rather than n operations in the following manner. Note that there is a matrix multiplication way of writing the recursion, where at each stage we need to remember 5 values to calculate the next one:
|1 0 1 0 1| |f(n-1)| | f(n) |
|1 0 0 0 0| |f(n-2)| |f(n-1)|
|0 1 0 0 0| |f(n-3)| = |f(n-2)|
|0 0 1 0 0| |f(n-4)| |f(n-3)|
|0 0 0 1 0| |f(n-5)| |f(n-4)|
So we can calculate f(n) if we can calculate powers of the matrix:
|1 0 1 0 1|^(n-4)
|1 0 0 0 0|
|0 1 0 0 0|
|0 0 1 0 0|
|0 0 0 1 0|
We can accelerate that process by using the binary expansion of n. Suppose n = 6, as it would be if we wanted f(10). Note that 6 = 4 + 2 in binary. Denote the matrix by M. We have M^1. We calculate M^2 = M^1 * M^1 and M^4 = M^2 * M^2, then M^6 = M^2 * M^4.
There may be other accelerations, depending on the particular example, but that should get you started.

Increasing the Elements of an Array Like a Number

I'm attempting to make a Sudoku solving program. To reach the puzzle's solution, the program interprets 0's as empty slots, and then makes an array that has a length equivalent to the number of zeros in the entire puzzle. From there, it sets all of the values in the array to 1 (the minimum value any slot can have in a Sudoku puzzle). What I'm trying to do is simulate a number's incremental pattern in the array starting from the element with the greatest index.
For example, a puzzle with three empty slots would result in an array of 3 elements. The array would then increase based on the pattern mention above:
0 0 0 (Initiation)
1 1 1 (Set to possible values)
1 1 2
1 1 3
1 1 4
1 1 5
1 1 6
1 1 7
1 1 8
1 1 9
1 2 1 (Skips 1 2 0 since it would include a 0)
1 2 2
etc.
This is a modified form of a base 10 number increment. Instead of 0-9, it uses 1-9. How may I build a method that will increment the array in this manner?
The basic algorithm here is to increment the right most digit then, if it overflows, increment the next to the left and so on. Recursion is a neat way of solving this. I'll do it in pseudocode and leave you to convert to Java
function increment(array, digit)
if (array[digit] < 9)
array[digit] += 1
else if (digit > 0)
array[digit] == 1;
increment(array, digit - 1)
else
you are finished
Then each time you call this with: increment(array, array.length - 1)

Java Binary to Integer

I looked a couple of different way to convert binary to integer in JAVA.
But I couldn't figure out why this works?
int res = 0;
res += 1 << 1;
The res turns out to be 2, I know it shifts towards left 1 bit and became 10 in binary. But I'm confusing how it converts from binary to integer, i want to know the mechanism.
Thanks
First of all, let's clear up some terminology first. What you believe to be an integer is actually a number in the base 10 notation, which in case of Java is a natural number that is represented using the ten digits from 0 to 9 (hence base 10).
In binary notation we are dealing with just two digits instead to represent all natural numbers. Both binary (base 2) and decimal numbers (base 10) are integers.
Digit shifting is multiplication or division by the base of the number
The bit shifting effect you observed can be easily explained using base 10 numbers you are already familiar with. Imagine you have a strip of square fields pre-filled with 0s. In each field you can write a digit from 0 to 9, and lets assume these fields are called "bits". You write the number 7 into that strip aligned to the right hand side:
0|0|0|0|0|7
Imagine that whole strip represents the integer 7 now. What bit shifting effectively does, is moving those digits in that strip either to the left or the right, while filling up the previously occupied spots with 0s. Imagine, we are shifting our 7 to the left by one spot:
0|0|0|0|7|0
By shifting the number to the left we practically performed a quick multiplication by 10 (remember, that is the base of our numeral system we're dealing with here).
When you shift that number to the right by one spot, you perform a division by 10.
Bit shifting is multiplication or division by 2
The same applies to binary numbers, the dominant storage format for numbers in computers. Binary numbers are comprised of just two digits, 1s and 0s.
Just take a quick look at the following table for getting a better understanding of binary numbers:
+-------------------+
| Decimal | Binary |
+---------+---------+
| 0000001 | 0000001 |
| 0000002 | 0000010 |
| 0000003 | 0000011 |
| 0000004 | 0000100 |
| 0000005 | 0000101 |
| 0000006 | 0000110 |
| 0000007 | 0000111 |
| ... | ... |
+---------+---------+
We perform multiplications by 2 when we shift the number in our strip to the left, and we perform divisions by 2 when we shift the number to the right. Just check out the table, and look up the decimal number 1. Multiply it by 2 and look at the binary representation. Multiply that again by 2 (decimal 4) and look at the binary notation. The binary digit 1 just moves to the left one by one due to the multiplication by two.
res+= 1<<1; can be written as res = res + 1<<1;
if you take 1<<1 which means 1 is represented as 0x00000001 = 00000000 00000000 00000000 00000001
when you do a right shift it becomes 00000000 00000000 00000000 00000010
which is 0x00000002 which is 2 in decimal value

Coin Change - Finding maximum Number

I'm having a hard time figuring out how to explain this problem. I'm currently trying to create a program for extra credit in my programming class, but I don't even understand the math behind it.... So I would love if someone could help me out. Alright:
Say you have 1 cent coin and a 4 cent coin. And the total number of coins allowed is 4. The maximal coverage of the value is 11. The chart is below.
Value | 1 cent | 4 cent
1 | 1
2 | 2
3 | 3
4 | 4
5 | 1 | 1
6 | 2 | 1
7 | 3 | 1
8 | | 2
9 | 1 | 2
10 | 2 | 2
11 | Maximum
S0 that's an example. I need to make this for something that is a much larger number. But I would love if someone can help explain the math for me. Or what the equation is... It's driving me insane.
I was trying to implement a version of the knapsack algorithm, but it doesn't seem to be doing the trick. If anyone can help it would be much appreciated. I'm not sure if I'm able to do that or if I need to use the greedy algorithm for this solution. It's basically a twist on the greedy algorithm.
EDIT: changed to 11
Dynamic programming (DP) is the way to solve the problem. DP generally involves finding some basic property you can compute based on other values of that property -- a form of inductive reasoning.
In your case, the basic question you need to ask is: "can I make n cents using exactly k coins". That's a simple boolean yes/no; because you can reuse coins, you don't need to know how to make n cents with k coins, only whether it is possible. This implicitly defines a boolean matrix A[n][k], where A[n][k] = TRUE iff you can make n cents with k of the given sorts of coins.
Study the relationships between the various entries in this truth table. For example, if I can make 5 cents with 2 coins, then it follows I can make 6 and 9 cents each with 3 coins (why?); thus A[5][2] implies A[6][3] and A[9][3].
Good luck!
Note: I'm re-posting because the other answer was deleted while updating to provide more context.
This appears to be the original problem author and his Java source code solution, if you'd like to study it further.
However, here's the summary of how this algorithm works, using dynamic programming:
Assumptions:
Each value in T is constrained by Integer.MAX_VALUE
T is constrained by Integer.MAX_VALUE -1
Definitions:
D = {d1, d2, ..., dk}∀ d∈ℤ, ∀ w_d = 1
T = W = Total Weight of Knapsack = Total Coins Available for Use
How the algorithm works:
Ensures W > 0 and that by 1 ∈ D
Ensures constraints above are met
Create a dynamically-sized array MinCoins[0] = 0
Let n=1 and iterate by 1 as n→∞
For each iteration, set MinCoins[ n ] = Integer.MAX_VALUE
Iterate over each element in D, let each value be known as d during iteration
If d > n skip this iteration
Let z represent the optimal number of coins for this iteration
Get the optimal number of coins from the previous iteration, and add one more (of this value) to it: z = MinCoins [ n - d ] + 1
Now compare z to MinCoins[ n ]
If z < MinCoins[ n ] a new optimal solution has been found (save it), else iterate to next d
Let the optimal solution found for this iteration be defined as q = MinCoins[ n ]
If q < T then continue to next iteration. Else, no maximum solution was found this iteration and break the loop.
https://bitbucket.org/asraful/coin-change

Categories

Resources