Performing arithmetic operations on isolated arraylist elements - java

I am looking for a clear explanation to my question (NOT looking for code), but if a bit of code helps to explain yourself, then please do.. thank you :)
Question:
-using Java
-Main class asks user for 2 integer inputs, then places them into 2 arraylists, of type integer. Each digit is broken up and stored in its own index, so it is its own "element", so to speak.
For example, with my code right now, it goes something like this:
"Please enter an integer:"
688
"Please enter another integer:"
349
At this point now, internally, I have stored the input as 2 arraylists, that look like this:
ArrayList1: [6, 8, 8]
ArrayList2: [3, 4, 9]
Now, lets say I want to perform some addition, such as ArrayList1 + ArrayList2.
I'll probably go ahead and create a temporary 'result' arraylist, then move that answer over to arraylist1 when my calculation is complete.
But the part I am having trouble with, is coming up with a systematic clear way to add the arraylists together. Keep in mind that this example uses an arraylist which represents an integer of length 3, but this could be anything. I could, for example, have an arraylist with 50 elements, such as [2, 4, 4, 3, 7, 3, 6, 3,.............] which could represent a huge number in the trillions, etc.

Think about how you would do grade-school addition. You'd start up by lining up the numbers like this:
1 3 7
+ 4 5
-----------
Then, you'd add the last two digits to get
1 3 7
+ 4 5
-----------
2
And you'd have a carry of 1. You then add the next two digits, plus the carry:
1 3 7
+ 4 5
-----------
8 2
Now you have carry 0, so you can add the last digit and the missing digit to get
1 3 7
+ 4 5
-----------
1 8 2
The general pattern looks like this: starting from the last digit of each array, add the last two numbers together to get a sum and a carry. Write the units digit of the sum into the resulting array, then propagate the carry to the next column. Then add the values in that column (plus the carry) together, and repeat this process across the digits. Once you have exhausted all of the digits in one of the numbers, continue doing the sum, but pretend that there's a 0 as the missing digit. Once you have processed all the digits, you will have the answer you're looking for.
Hope this helps!

If you store digits backwards, your arrays will be much easier to manipulate, because their ones, tens, hundreds, etc. will be aligned with each other (i.e. they will be sitting at the same index).
You could then implement the addition the same way they teach in the elementary school: go through arrays of digits one by one, add them, check for digit overflow (>=10), and pay attention to the carry flag (result digit is (a+b) % 10, carry flag is (a+b)/10). If the carry flag is not zero when you are done with the addition, and there are no additional digits remaining on either side, add the carry flag to the end of the result array.
The only remaining issue is displaying the lists. You can do it with a simple backward loop.
P.S. If you would like to double-check your mulch-trilion calculation against something that is known to work, use BigInteger to compute the expected results, and check your results against theirs.

Think of an arraylist as a storage container. It can hold items in it that are of type "integer", but it's type is still "storage container". You can't perform math on these type of objects--only their contents.

you have
list1
list2
and need an extra variable
int carry
then
1 do add(0,0) on short list, so that at the end two lists have same length.
2 reversely loop the two list.
sum=(carry+(e1+e2))
set e1 (list1 element) = sum%10,
carry = sum/10,
till the first element.
3 if carry==1, list1.add(0,1)
now list1 stores the result.
Note, step1 is not a must. it could be done in loop by checking the short list's length.

Related

Searching for the amount of integers in multiple ArrayLists

I have been thinking about this, but i havent been able to come up with a solution.
I have 9 ArrayLists, which can have Integers from 1 to 10.
What i want to do is:
Find 2 Numbers(from 1 to 10), that occur in exactly 2 of these ArrayLists( Must be the same Array. For Example, the number 2 and 3 both appear only in List1 and List)4. Preferably also know in which ArrayLists these numbers occured.
Thanks for any help in advance
One method:
First: Create a Map<Integer, BitSet>. Call it m.
Next: Iterate through the 9 ArrayLists that you have. For each number n that you encounter in array #a:
m.putIfAbsent(n, new BitSet(9)); // Make there the number has a BitSet to start
m.get(n).set(a); // Set the bit indicating number n is in array a
After that, you just need to look for two BitSets in your Map having cardinality() == 2 and are BitSet.equals() equal to each other.

Find if an array can form a graph

[Interview Question] I got this question in a recent online interview. I had no clue how to solve it. Can anyone please help me solve this so that I can learn in Java.
Tom is very good in problem-solving. So to test Tom's skills, Jerry asks Tom a graph problem. Jerry gives Tom, an array A of N integers.
A graph is a simple graph, iff it has no self-loop or multi-edges.
Now Jerry asks Tom whether he can design a simple graph of N vertices or not. The condition is that Tom has to use each and every element of A exactly once for the degrees of vertices of the graph.
Now, Tom wants your help to design his graph. Print "YES" if the graph can be designed, otherwise print "NO" (without quotes).
Input
A single integer T, in the first line, denoting the number of test cases.
For each test case, there are 2 lines.
The first line is a single integer N, denoting the number of elements of array A.
The second line has N-space separated integers, representing elements of A.
Output
For each test case, print "YES" or "NO" (without quotes) whether the graph can be designed or not, in a new line.
Constraints
1<= T <= 100
1<= N <= 100
0<= Element of A <= 5000
Sample Test Cases
Input
1
2
1 1
Output
YES
Explanation
For this test case, a simple graph with 2 vertices can be designed, where each vertex has degree 1.
Input
2
3
1 2 1
3
1 1 1
Output
YES
NO
Explanation
For the first test case, we can design a simple graph of 3 vertices, which has degree sequence as [1, 2, 1]. The first vertex has degree 1, second, has 2 and third has 1.
For the second test case, we cannot make a simple graph of 3 vertices, which has degree sequence as [1, 1, 1].
One necessery condition is that sum of elements in A is even. That is due each edge
is counted twice in adjencency list.
Next is to try to construct graph, or at least 'allocate' pairs of nodes.
Sort elements of A in decending order,
Let the largest (first) element be a,
Check are element on positions 2 to a+1 larger than 0,
If there is a element with value 0 than it is not possible to construct a graph,
Decrease these a elements by 1 and set first element to 0,
Repeat process until all elements are 0.
Note that sorting in subsequent steps can be done in O(n) with merge sort step, since list consists
of three sorted parts:
first element (0) which can go to the end,
sorted part with a elements,
rest which is also sorted.

Optimal merging of triplets

I'm trying to come up with an algorithm for the following problem :
I've got a collection of triplets of integers - let's call these integers A, B, C. The value stored inside can be big, so generally it's impossible to create an array of size A, B, or C. The goal is to minimize the size of the collection. To do this, we're provided a simple rule that allows us to merge the triplets :
For two triplets (A, B, C) and (A', B', C'), remove the original triplets and place the triplet (A | A', B, C) if B == B' and C = C', where | is bitwise OR. Similar rules hold for B and C also.
In other words, if two values of two triplets are equal, remove these two triplets, bitwise OR the third values and place the result to the collection.
The greedy approach is usually misleading in similar cases and so it is for this problem, but I can't find a simple counterexample that'd lead to a correct solution. For a list with 250 items where the correct solution is 14, the average size computed by greedy merging is about 30 (varies from 20 to 70). The sub-optimal overhead gets bigger as the list size increases.
I've also tried playing around with set bit counts, but I've found no meaningful results. Just the obvious fact that if the records are unique (which is safe to assume), the set bit count always increases.
Here's the stupid greedy implementation (it's just a conceptual thing, please don't regard the code style) :
public class Record {
long A;
long B;
long C;
public static void main(String[] args) {
List<Record> data = new ArrayList<>();
// Fill it with some data
boolean found;
do {
found = false;
outer:
for (int i = 0; i < data.size(); ++i) {
for (int j = i+1; j < data.size(); ++j) {
try {
Record r = merge(data.get(i), data.get(j));
found = true;
data.remove(j);
data.remove(i);
data.add(r);
break outer;
} catch (IllegalArgumentException ignored) {
}
}
}
} while (found);
}
public static Record merge(Record r1, Record r2) {
if (r1.A == r2.A && r1.B == r2.B) {
Record r = new Record();
r.A = r1.A;
r.B = r1.B;
r.C = r1.C | r2.C;
return r;
}
if (r1.A == r2.A && r1.C == r2.C) {
Record r = new Record();
r.A = r1.A;
r.B = r1.B | r2.B;
r.C = r1.C;
return r;
}
if (r1.B == r2.B && r1.C == r2.C) {
Record r = new Record();
r.A = r1.A | r2.A;
r.B = r1.B;
r.C = r1.C;
return r;
}
throw new IllegalArgumentException("Unable to merge these two records!");
}
Do you have any idea how to solve this problem?
This is going to be a very long answer, sadly without an optimal solution (sorry). It is however a serious attempt at applying greedy problem solving to your problem, so it may be useful in principle. I didn't implement the last approach discussed, perhaps that approach can yield the optimal solution -- I can't guarantee that though.
Level 0: Not really greedy
By definition, a greedy algorithm has a heuristic for choosing the next step in a way that is locally optimal, i.e. optimal right now, hoping to reach the global optimum which may or may not be possible always.
Your algorithm chooses any mergable pair and merges them and then moves on. It does no evaluation of what this merge implies and whether there is a better local solution. Because of this I wouldn't call your approach greedy at all. It is just a solution, an approach. I will call it the blind algorithm just so that I can succinctly refer to it in my answer. I will also use a slightly modified version of your algorithm, which, instead of removing two triplets and appending the merged triplet, removes only the second triplet and replaces the first one with the merged one. The order of the resulting triplets is different and thus the final result possibly too. Let me run this modified algorithm over a representative data set, marking to-be-merged triplets with a *:
0: 3 2 3 3 2 3 3 2 3
1: 0 1 0* 0 1 2 0 1 2
2: 1 2 0 1 2 0* 1 2 1
3: 0 1 2*
4: 1 2 1 1 2 1*
5: 0 2 0 0 2 0 0 2 0
Result: 4
Level 1: Greedy
To have a greedy algorithm, you need to formulate the merging decision in a way that allows for comparison of options, when multiple are available. For me, the intuitive formulation of the merging decision was:
If I merge these two triplets, will the resulting set have the maximum possible number of mergable triplets, when compared to the result of merging any other two triplets from the current set?
I repeat, this is intuitive for me. I have no proof that this leads to the globally optimal solution, not even that it will lead to a better-or-equal solution than the blind algorithm -- but it fits the definition of greedy (and is very easy to implement). Let's try it on the above data set, showing between each step, the possible merges (by indicating the indices of triplet pairs) and resulting number of mergables for each possible merge:
mergables
0: 3 2 3 (1,3)->2
1: 0 1 0 (1,5)->1
2: 1 2 0 (2,4)->2
3: 0 1 2 (2,5)->2
4: 1 2 1
5: 0 2 0
Any choice except merging triplets 1 and 5 is fine, if we take the first pair, we get the same interim set as with the blind algorithm (I will this time collapse indices to remove gaps):
mergables
0: 3 2 3 (2,3)->0
1: 0 1 2 (2,4)->1
2: 1 2 0
3: 1 2 1
4: 0 2 0
This is where this algorithm gets it differently: it chooses the triplets 2 and 4 because there is still one merge possible after merging them in contrast to the choice made by the blind algorithm:
mergables
0: 3 2 3 (2,3)->0 3 2 3
1: 0 1 2 0 1 2
2: 1 2 0 1 2 1
3: 1 2 1
Result: 3
Level 2: Very greedy
Now, a second step from this intuitive heuristic is to look ahead one merge further and to ask the heuristic question then. Generalized, you would look ahead k merges further and apply the above heuristic, backtrack and decide the best option. This gets very verbose by now, so to exemplify, I will only perform one step of this new heuristic with lookahead 1:
mergables
0: 3 2 3 (1,3)->(2,3)->0
1: 0 1 0 (2,4)->1*
2: 1 2 0 (1,5)->(2,4)->0
3: 0 1 2 (2,4)->(1,3)->0
4: 1 2 1 (1,4)->0
5: 0 2 0 (2,5)->(1,3)->1*
(2,4)->1*
Merge sequences marked with an asterisk are the best options when this new heuristic is applied.
In case a verbal explanation is necessary:
Instead of checking how many merges are possible after each possible merge for the starting set; this time we check how many merges are possible after each possible merge for each resulting set after each possible merge for the starting set. And this is for lookahead 1. For lookahead n, you'd be seeing a very long sentence repeating the part after each possible merge for each resulting set n times.
Level 3: Let's cut the greed
If you look closely, the previous approach has a disastrous perfomance for even moderate inputs and lookaheads(*). For inputs beyond 20 triplets anything beyond 4-merge-lookahead takes unreasonably long. The idea here is to cut out merge paths that seem to be worse than an existing solution. If we want to perform lookahead 10, and a specific merge path yields less mergables after three merges, than another path after 5 merges, we may just as well cut the current merge path and try another one. This should save a lot of time and allow large lookaheads which would get us closer to the globally optimal solution, hopefully. I haven't implemented this one for testing though.
(*): Assuming a large reduction of input sets is possible, the number of merges is
proportional to input size, and
lookahead approximately indicates how much you permute those merges.
So you have choose lookahead from |input|, which is
the binomial coefficient that for lookahead ≪ |input| can be approximated as
O(|input|^lookahead) -- which is also (rightfully) written as you are thoroughly screwed.
Putting it all together
I was intrigued enough by this problem that I sat and coded this down in Python. Sadly, I was able to prove that different lookaheads yield possibly different results, and that even the blind algorithm occasionally gets it better than lookahead 1 or 2. This is a direct proof that the solution is not optimal (at least for lookahead ≪ |input|). See the source code and helper scripts, as well as proof-triplets on github. Be warned that, apart from memoization of merge results, I made no attempt at optimizing the code CPU-cycle-wise.
I don't have the solution, but I have some ideas.
Representation
A helpful visual representation of the problem is to consider the triplets as points of the 3D space. You have integers, so the records will be nodes of a grid. And two records are mergeable if and only if the nodes representing them sit on the same axis.
Counter-example
I found an (minimal) example where a greedy algorithm may fail. Consider the following records:
(1, 1, 1) \
(2, 1, 1) | (3, 1, 1) \
(1, 2, 1) |==> (3, 2, 1) |==> (3, 3, 1)
(2, 2, 1) | (2, 2, 2) / (2, 2, 2)
(2, 2, 2) /
But by choosing the wrong way, it might get stuck at three records:
(1, 1, 1) \
(2, 1, 1) | (3, 1, 1)
(1, 2, 1) |==> (1, 2, 1)
(2, 2, 1) | (2, 2, 3)
(2, 2, 2) /
Intuition
I feel that this problem is somehow similar to finding the maximal matching in a graph. Most of those algorithms finds the optimal solution by begining with an arbitrary, suboptimal solution, and making it 'more optimal' in each iteration by searching augmenting paths, which have the following properties:
they are easy to find (polynomial time in the number of nodes),
an augmenting path and the current solution can be crafted to a new solution, which is strictly better than the current one,
if no augmenting path is found, the current solution is optimal.
I think that the optimal solution in your problem can be found in the similar spirit.
Based on your problem description:
I'm given a bunch of events in time that's usually got some pattern.
The goal is to find the pattern. Each of the bits in the integer
represents "the event occurred in this particular year/month/day". For
example, the representation of March 7, 2014 would be [1 <<
(2014-1970), 1 << 3, 1 << 7]. The pattern described above allows us to
compress these events so that we can say 'the event occurred every 1st
in years 2000-2010'. – Danstahr Mar 7 at 10:56
I'd like to encourage you with the answers that MicSim has pointed at, specifically
Based on your problem description, you should check out this SO
answers (if you didn't do it already):
stackoverflow.com/a/4202095/44522 and
stackoverflow.com/a/3251229/44522 – MicSim Mar 7 at 15:31
The description of your goal is much more clear than the approach you are using. I'm scared that you won't get anywhere with the idea of merging. Sounds scary. The answer you get depends upon the order that you manipulate your data. You don't want that.
It seems you need to keep data and summarize. So, you might try counting those bits instead of merging them. Try clustering algorithms, sure, but more specifically try regression analysis. I should think you would get great results using a correlation analysis if you create some auxiliary data. For example, if you create data for "Monday", "Tuesday", "first Monday of the month", "first Tuesday of the month", ... "second Monday of the month", ... "even years", "every four years", "leap years", "years without leap days", ... "years ending in 3", ...
What you have right now is "1st day of the month", "2nd day of the month", ... "1st month of the year", "2nd month of the year", ... These don't sound like sophisticated enough descriptions to find the pattern.
If you feel it is necessary to continue the approach you have started, then you might treat it more as a search than a merge. What I mean is that you're going to need a criteria/measure for success. You can do the merge on the original data while requiring strictly that A==A'. Then repeat the merge on the original data while requiring B==B'. Likewise C==C'. Finally compare the results (using the criteria/measure). Do you see where this is going? Your idea of bit counting could be used as a measure.
Another point, you could do better at performance. Instead of double-looping through all your data and matching up pairs, I'd encourage you to do single passes through the data and sort it into bins. The HashMap is your friend. Make sure to implement both hashCode() and equals(). Using a Map you can sort data by a key (say where month and day both match) and then accumulate the years in the value. Oh, man, this could be a lot of coding.
Finally, if the execution time isn't an issue and you don't need performance, then here's something to try. Your algorithm is dependent on the ordering of the data. You get different answers based on different sorting. Your criteria for success is the answer with the smallest size after merging. So, repeatedly loop though this algorithm: shuffle the original data, do your merge, save the result. Now, every time through the loop keep the result which is the smallest so far. Whenever you get a result smaller than the previous minimum, print out the number of iterations, and the size. This is a very simplistic algorithm, but given enough time it will find small solutions. Based on your data size, it might take too long ...
Kind Regards,
-JohnStosh

Java permutations of offsets

Had a question regarding generating a list of 10-digit phone numbers on a PhonePad, given a set of possible moves and a starting number.
The PhonePad:
1 2 3
4 5 6
7 8 9
* 0 #
Possible moves:
The same number of moves a Queen in chess can make (so north, south, east, west, north-east, north-west, south-east, south-west... n-spaces per each orientation)
Starting number: 5
So far I have implemented the PhonePad as a 2-dimensional char array, implemented the possible moves a Queen can make in a HashMap (using offsets of x and y), and I can make the Queen move one square using one of the possible moves.
My next step is to figure out an algorithm that would give me all 10-digit permutations (phone numbers), using the possible moves in my HasMap. Repetition of a number is allowed. * and # are not allowed in the list of phone numbers returned.
I would imagine starting out with
- 5555555555, 5555555551, 5555555552... and so on up to 0,
- 5555555515, 5555555155, 5555551555.. 5155555555.. and with the numbers 2 upto 0
- 5555555151, 5555551515, 5555515155.. 5151555555.. and with numbers 2 upto 0
... and so on for a two digit combination
Any suggestions on a systematic approach generating 10-digit combinations? Even a pseudocode algorithm is appreciated! Let me know if further clarification is required.
Thanks in advance! :)
In more detail, the simplest approach would be a recursive method, roughly like:
It accepts a prefix string initially empty, a current digit (initially '5'), and a number of digits to generate (initially 10).
If the number of digits is 1, it will simply output the prefix concatenated with the current digit.
If the number of digits is greater than 1, then it will make a list of all possible next digits and call itself recursively with (prefix + (current digit), next digit, (number of digits)-1 ) as the arguments.
Other approaches, and refinements to this one, are possible of course. The "output" action could be writing to a file, adding to a field in the current class or object, or adding to a local variable collection (List or Set) that will be returned as a result. In that last case, the (ndigits>1) logic would have to combine results from multiple recursive calls to get a single return value.

Algorithm which tells if a number is obtainable from a given set using only '+' ,'*' and brackets

I have two list of numbers, for every member of the second one I must tell if it's obtainable using all the numbers of the first one and placing '+' or '*' and as many '(' ')' I want.
I can't change the order .
List1 can contain a max of 20 elements beetween 1 and 100.
List2 can contain max 5 elements beetween 1 and 20'000.
EX:
List1=[2 4 3 5]
List2=[19 15 24]
19-> 2+(4*3)+5 YES
15 NO
24->2*(4+3+5) YES
With brute force it takes ages to handle inputs with List1 larger than 10.
edit: numbers are always positive.
edit:
I find the max and min numbers that are obtainable from the list and then I discard all the possibilities that have the target outside this range, then I try all the remaining ones.
MAX=n1*n2*n3*....*ni if there are 1 thei r added to their smallest neighbour
MIN=n1+n2+....+ni 1 excluded
Still it's not fast enough when input are big (List1 longer than 10 or numbers in List2 bigger than 10000)
For each sublist of List1, compute the numbers between 1 and 20,000 that can be made with that sublist. The resulting DP bears resemblance to CYK.
I'm being somewhat vague here because this is almost certainly a programming contest problem.
#u mad is correct, but I'll give a little more detail.
Suppose that n = size of list 1. For each 0 <= i < j < n you need to compute all of the distinct values in the range (1..20_000) that can be made from the numbers in the interval [i, j-1]. You can do this with recursion and memoization.
Once you've done this then the problem is easy.
You could try a smart brute force which discards sets of equations by chunks.

Categories