Can all RPN expressions be represented such that all operators appear on the left and all operands appear on the right? - rpn

I've convinced myself that they can't.
Take for example:
4 4 + 4 /
stack: 4
stack: 4 4
4 + 4 = 8
stack: 8
stack: 8 4
8 / 4 = 2
stack: 2
There are two ways that you could write the above expression with the
same operators and operands such that the operands all come first: "4
4 4 + /" and "4 4 4 / +", neither of which evaluate to 2.
"4 4 4 + /"
stack: 4
stack: 4 4
stack: 4 4 4
4 + 4 = 8
stack: 4 8
4 / 8 = 0.5
stack: 0.5
"4 4 4 / +"
stack: 4
stack: 4 4
stack: 4 4 4
4 / 4 = 1
stack: 4 1
4 + 1 = 5
stack: 5
If you have the ability to swap items on the stack then yes, it's possible, otherwise, no.
Thoughts?

Consider the algebraic expression:
(a + b) * (c + d)
The obvious translation to RPN would be:
a b + c d + *
Even with a swap operation available, I don't think there is a way to collect all the operators on the right:
a b c d +
a b S
where S is the sum of c and d. At this point, you couldn't use a single swap operation to get both a and b in place for a + operation. Instead, you would need a more sophisticated stack operation (such as roll) to get a and b in the right spot. I don't know whether a roll operation would be sufficient for all cases, either.

Actually, you've not only given the answer but a conclusive proof as well, by examining a counter-example which is enough to disprove the assumption implied in the title.

I know this is a very old thread, but I just found it today and wanted to say that I believe the answer to the original question is YES. I am confident all RPN expressions can be represented such that all operators appear on the left and all operands appear on the right, if in addition to the normal arithmetic operations, we are allowed to include three additional 'navigational' operators in the representation.
Any arithmetic expression can be represented as a binary tree, with variables and constants at the leaf nodes, binary arithmetic operations at the forks in the tree, and unary operations such as negation, reciprocal, or square root along any branches. The three additional operations I suggest represent building a left branch, building a right branch, or reaching a leaf node in a binary tree. Now if we place all the operands to the left of the input string according to the position of their respective leaves in the tree, we can supply the remainder of the input string with operations telling how to reconstruct the appropriate binary tree in memory and insert the operands and mathematical operations into it at the correct points. Finally a depth-first tree-traversal algorithm is applied to calculate the result.
I don't know if this has any practical application. It's probably too inefficient as way to encode and decode expressions. But as an academic exercise, I am sure it is workable.

It is enough to show one that can't in order to tell you the answer to this.
If you can't reorder the stack contents, then the expression (2+4)*(7+8) can't be rearranged.
2 4 + 7 8 + *
No matter how you reorder this, you'll end up with something that needs to be summed before you go on.
At least I believe so.

Related

Can you get smaller integer in any low level language independent of architecture?

An integer could be 8 bytes, which is 2^64. A lot of values.
Let say I wanted to write a small program that would store value like this in a file:
3 1 5 6 2 8 9 0 1 2 ....
at no point my value is going to be higher that 9. So I only need 10 combinations,
that I can get by data type that takes 2^4 (16 combinations) only. Not 2^64.
won't it be more efficient.. how can I accomplish that. Does C++ has native single digit type.
You can make such a type, but you probably don't want to.
I would suggest you use unsigned char or signed char, which are both single-byte types. (You may consider using the type aliases std::uint8_t and std::int8_t, which better express your intent to store 8-bit numbers.)
It is possible to create a class with a single-byte numeric member that can store two separate digits, but you will lose performance since operations will have to extract the digit you care about, possibly shift it, and then the reverse operation when assigning to it. That is to say, statements like:
numbers[1] = v;
Would wind up being implemented something like:
combined_numbers[0] = (combined_numbers[0] & 0x0f) | (v << 4);

Using Dynamic Programming To Group Numbers

Let's say you have a group of numbers. You need to eliminate numbers until there is only one left. This is hard to explain, so let me provide you with an example.
The numbers are 3, 6, 9, and 10.
You pair 3 with 9. You eliminate 3. (Note: either one of them could be eliminated). Now there are 6, 9, and 10 left. You pair 6 with 9. You eliminate 9. Now there are 6 and 10 left. You pair 6 with 10 (only option).
The problem is: I want to find the maximum value obtained from this elimination. Each time a number is eliminated, the XOR value of those two numbers is added to the count. In the previous example, the total value would be (3 ^ 6) + (6 ^ 9) + (6 ^ 10) = 10 + 15 + 12 = 37. This happens to be the maximum value that can be obtained from any elimination combination.
How would I solve this problem in Java with 2000 numbers? I know I can find every possible combination using brute force, but the run time of this was more than two seconds, and I prefer my solutions to be under two seconds. The only option left is Dynamic Programming.
Does anyone know how to solve this with Dynamic Programming?

C++ two dimensional array of bitsets

I have an assignment where we're tackling the traveling salesman problem.
I'm not going to lie, the part I'm doing right now I actually don't understand fully that they're asking, so sorry if I phrase this question weirdly.
I sort of get it, but not fully.
We're calculating an approximate distance for the salesman. We need to create a two-dimensional array, of bitsets I believe? Storing the values in binary anyway.
0 represents that the city hasn't been visited, and 1 represents that is has been visited.
We've been given an algorithm that helps significantly, and I should be able to finish it if anyone here can help with the first step:
Create memoisation table [N][(1 << N)]
(where N = number of cities).
I get that 1 << N means convert the number of cities (e.g. 5) to binary, then move the set to the left by one place.
My main issues are:
Converting N to binary (I think this is what I need to do?)
Moving the set to the left by one
Actually creating the 2-dimensional array of these sizes...
I could be wrong here, in fact that's probably pretty likely... any help is appreciated, thanks!
Here is the general rule "<<" operator means left shift and ">>" means right shift. Right shifting any number by 1 is equivalent to divide by 2 and left shift any numbers by 2 is equivalent to multiply by 2. For example lets say a number 7 (Binary 111). So 7 << 1 will become 1110 which is 7 * 2 = 14 and 7 >> 1 will become 11 which is 7 / 2 = 3 .
So for algorithm to convert a number N to a bitset array as binary is
N mod 2 (take the remainder if you divide N by 2)
Store the remainder in a collection (i.e, List, Array, Stack )
Divide N by 2
If N/2 >1 Repeat from step 1 with N/2
Else reverse the array and you have your bitset.
Moving the set left to one, If you meant leftshift by one you can do it by N<<1
This is how you create 2 dimensional array in C++
[Variable Type] TwoDimensionalArray[size][size];
For this problem though I believe you might want to read about C++ bitset and you can easily implement it using bitset. For that you just have to figure out the size of the bitset you want to use. For example if the highest value of N is 15 then you need a bitset size of 4. Because with 4 bit the maximum number you can represent is 15 (Binary 1111). Hope this helps.

Compression of sorted data with small difference

I have sorted data sequence of integers. Maximal difference between 2 numbers is 3. So data looks for example like this:
Data: 1 2 3 5 7 8 9 10 13 14
Differences: (start 1) 1 1 2 2 1 1 1 3 1
Is there a better way to store (compress) this type of sequences, than save difference values? Because if I use dictionary based methods, It failed to compress, because of randomness of numbers 1,2 and 3. If I use "PAQ" style compression, result are better, but still not quite satisfying. Huffman and Arithmetic coder is worse than dictionary based methods.
Is there some way with prediction?
For example to use regression for original data and than store differences (which could be smaller or more consistent)
Or use some kind of prediction based on histogram of differences?
Or something totally different.... or its not possible at all (which is, in my oppinion, the real answer :))
Since you say in the comments that you're already storing four differences per byte, you're likely to not do much better. If the differences 0, 1, 2, and 3 were random and evenly distributed, then there would be no way to do better.
If they are not evenly distributed, then you might be able to do better with a Huffman or arithmetic code. E.g. if 1 is more common than 0, which is more common than 2 and 3, then you could store 1 as 0, 0 as 10, 2 as 110, and 3 as 111. Or if 0 never happens, 1 as 0, 2 and 3 as 10 and 11. You could do better with an arithmetic code for the case you quote where 1 occurs 80% of the time. Or a poor man's arithmetic code by coding pairs of symbols. E.g.:
11 0
13 100
21 101
12 110
31 1110
22 111100
23 111101
32 111110
33 111111
would be a good code for 1 80%, 2 10%, 3 10%. (That doesn't quite handle the case of an odd number of differences, but you could deal with that with just a bit at the start indicating an even or odd number, and a few more bits at the end if odd.)
There might be a better predictor than the previous value. This would be a function of n previous values instead of just one previous value. However this would be highly data dependent. For example you could assume that the current value is likely to fall on the line made by the previous two values. Or that it falls on the parabola made by the previous three values. Or some other function, e.g. a sinusoid with some frequency, if the data is so biased.

Arbitrary precision arithmetic with GMP

I'm using the GMP library to make a Pi program, that will calculate about 7 trillion digits of Pi. Problem is, I can't figure out how many bits are needed to hold that many decimal places.
7 trillion digits can represent any of 10^(7 trillion) distinct numbers.
x bits can represent 2^x distinct numbers.
So you want to solve:
2^x = 10^7000000000000
Take the log-base-2 of both sides:
x = log2(10^7000000000000)
Recall that log(a^b) = b * log(a):
x = 7000000000000 * log2(10)
I get 23253496664212 bits. I would add one or two more just to be safe. Good luck finding the petabytes to hold them, though.
I suspect you are going to need a more interesting algorithm.
I wanna just correct one thing about what was written in the response answer:
Recall that log(a^b) = a * log(b)
well it is the opposite :
log(a^b) = b * log(a)
2^10 = 1024, so ten bits will represent slightly more than three digits. Since you're talking about 7 trillion digits, that would be something like 23 trillion bits, or about 3 terabytes, which is more than I could get on one drive from Costco last I visited.
You may be getting overambitious. I'd wonder about the I/O time to read and write entire disks for each operation.
(The mathematical way to solve it is to use logarithms, since a number that takes 7 trillion digits to represent has a log base 10 of about 7 trillion. Find the log of the number in the existing base, convert the base, and you've got your answer. For shorthand between base 2 and base 10, use ten bits==three digits, because that's not very far wrong. It says that the log base 10 of 2 is .3, when it's actually more like .301.)