This question already has answers here:
Writing an algorithm to decide whether a target number can be reached with a set of other numbers and specific operators?
(3 answers)
Closed 8 years ago.
Here's the problem:
Given 4 numbers, I need to give a calculated process which results 24. All the operations I can use are addition, subtraction, multiplication, division. How to print the calculated process?
Ex:
Input: 4,7,8,8
Output: (7-(8/8))*4=24.
(The following is an expansion on an idea suggested by Sayakiss)
One option would be enumerating all possible combinations of numbers and arithmetic operations performed on them.
If you have 4 numbers, there are only 24 different ways to write them in a list (the following example is for numbers 4, 7, 8, 9 - i changed the last number in your example to make them all different):
4 7 8 9
4 7 9 8
4 8 7 9
4 8 9 7
...
9 8 7 4
If some numbers are identical, some of the above lists will appear twice (not a problem).
For each of the above orderings, there are 64 different ways to insert an arithmetic operation between the numbers:
4+7+8+9
4+7+8-9
4+7+8*9
4+7+8/9
4+7-8+9
...
4/7/8/9
For each of the above sequences, there are 5 ways to place parentheses:
((4-7)-8)-9
(4-7)-(8-9)
(4-(7-8))-9
4-((7-8)-9)
4-(7-(8-9))
When you combine all 3 "aspects" mentioned above, you get 24 * 64 * 5 = 7680 expressions; evaluate each one and check whether its value is 24 (or whatever number you need it to be).
It may be convenient to generate the expressions in a tree form, to simplify evaluation (this depends on the programming language you want to use; e.g. in C/C++ there is no eval function) . For example, the expression 4*((7-8)+9) may be represented by the following tree:
*
/ \
4 +
/ \
- 9
/ \
7 8
Some notes:
You may want to tweak the choice of arithmetic operations to allow for expressions like 47+88 - not sure whether the rules of your game permit that.
Many of the evaluated expressions may be annoyingly verbose, like ((4+7)+8)+8 and 4+(7+(8+8)) (which are also examined twice, with the order of the 8's switched); you could prevent that by inserting some dedicated checks into your algorithm.
Related
Re-asking this here, since it doesn't belong in the Code Review SE.
I was always taught to never have static expressions in code, as it is an unnecessary operation that will always have the same output. For example, you would never have if 6 < 7 (aside from people slapping the occasional while true around).
That being said, I have a functioning bash script as follows:
#!/usr/bin/env bash
for i in {0..9}
do
...some stuff...
done
However, PyCharm is giving my hell for this re-iterating my concern in my first paragraph. It's counter suggestion is to have:
#!/usr/bin/env bash
for i in 0 1 2 3 4 5 6 7 8 9
do
...some stuff...
done
The logic is that it will not have to evaluate the range itself, thus increasing speed.
My Question
I think that the range looks nicer and, as far as I know, it won't actually affect speed (I don't mean noticeably, I mean at all), as it is simply iterating as it goes. Am I incorrect in thinking so?
It's a peeve of mine to waste cycles, but it's a greater peeve of mine to write grotesque looking code.
The best practice approach in bash or other shells adopting ksh extensions is a C-style for loop:
for ((i=0; i<=9; i++)); do
echo "Doing some stuff with $i"
done
This has advantages over the {0..9} syntax in that it works with variables ({$min..$max} doesn't work, because brace expansions happens before variable expansions do) and avoids needing to store the full list in memory at once, and it has advantages over 0 1 2 3 4 5 6 7 8 9 because the latter is hard to check for typos (it's trickier to visually spot the problems with 0 1 2 3 5 4 6 7 8 9 or 0 1 2 3 4 6 7 8 9).
By use I mean its use in many calculators like HP35-
My guesses (and confusions) are -
postfix is actually more memory efficient -( SO post comments here ). (confusion - The evaluation algorithm of both are similar with a stack)
keyboard input type in calculators back then(confusion - this shouldn't have mattered much as it only depends on order of operators given first or last)
Another way this question can be asked is what advantages postfix notation have over prefix?
Can anyone enlighten me?
For one it is easier to implement evaluation.
With prefix, if you push an operator, then its operands, you need to have forward knowledge of when the operator has all its operands. Basically you need to keep track of when operators you've pushed have all their operands so that you can unwind the stack and evaluate.
Since a complex expression will likely end up with many operators on the stack you need to have a data structure that can handle this.
For instance, this expression: - + 10 20 + 30 40 will have one - and one + on the stack at the same time, and for each you need to know if you have the operands available.
With suffix, when you push an operator, the operands are (should) already on the stack, simply pop the operands and evaluate. You only need a stack that can handle operands, and no other data structure is necessary.
Prefix notation is probably used more commonly ... in mathematics, in expressions like F(x,y). It's a very old convention, but like many old systems (feet and inches, letter paper) it has drawbacks compared to what we could do if we used a more thoughtfully designed system.
Just about every first year university math textbook has to waste a page at least explaining that f(g(x)) means we apply g first then f. Doing it in reading order makes so much more sense: x.f.g means we apply f first. Then if we want to apply h "after" we just say x.f.g.h.
As an example, consider an issue in 3d rotations that I recently had to deal with. We want to rotate a vector according to XYZ convention. In postfix, the operation is vec.rotx(phi).roty(theta).rotz(psi). With prefix, we have to overload * or () and then reverse the order of the operations, e.g., rotz*roty*rotx*vec. That is error prone and irritating to have to think about that all the time when you want to be thinking about bigger issues.
For example, I saw something like rotx*roty*rotz*vec in someone else's code and I didn't know whether it was a mistake or an unusual ZYX rotation convention. I still don't know. The program worked, so it was internally self-consistent, but in this case prefix notation made it hard to maintain.
Another issue with prefix notation is that when we (or a computer) parses the expression f(g(h(x))) we have to hold f in our memory (or on the stack), then g, then h, then ok we can apply h to x, then we can apply g to the result, then f to the result. Too much stuff in memory compared to x.f.g.h. At some point (for humans much sooner than computers) we will run out of memory. Failure in that way is not common, but why even open the door to that when x.f.g.h requires no short term memory. It's like the difference between recursion and looping.
And another thing: f(g(h(x))) has so many parentheses that it's starting to look like Lisp. Postfix notation is unambiguous when it comes to operator precedence.
Some mathematicians (in particular Nathan Jacobson) have tried changing the convention, because postfix so much easier to work with in noncommutative algebra where order really matters, to little avail. But since we have a chance to do things over, better, in computing, we should take the opportunity.
Basically, because if you write the expression in postfix, you can evaluate that expression using just a Stack:
Read the next element of the expression,
If it is an operand, push into Stack,
Otherwise read from Stack operands required by the Operation, & push the result into Stack.
If not the end of the expression, go to 1.
Example
expression = 1 2 + 3 4 + *
stack = [ ]
Read 1, 1 is Operand, Push 1
[ 1 ]
Read 2, 2 is Operand, Push 2
[ 1 2 ]
Read +, + is Operation, Pop two Operands 1 2
Evaluate 1 + 2 = 3, Push 3
[ 3 ]
Read 3, 3 is Operand, Push 3
[ 3 3 ]
Read 4, 4 is Operand, Push 4
[ 3 3 4 ]
Read +, + is Operation, Pop two Operands 3 4
Evaluate 3 + 4 = 7, Push 7
[ 3 7 ]
Read *, * is Operation, Pop two Operands 3 7
Evaluate 3 * 7 = 21, Push 21
[ 21 ]
If you like your human reading order to match the machine's stack-based evaluation order then postfix is a good choice.
That is, assuming you read left-to-right, which not everyone does (e.g. Hebrew, Arabic, ...). And assuming your machine evaluates with a stack, which not all do (e.g. term rewriting - see Joy).
On the other hand, there's nothing wrong with the human preferring prefix while the machine evaluates "back to front/bottom-to-top". Serialization could be reversed too if the concern is evaluation as tokens arrive. Tool assistance may work better in prefix notation (knowing functions/words first may help scope valid arguments), but you could always type right-to-left.
It's merely a convention I believe...
Offline evaluation of both notation is same in theoretical machine
(Eager evaluation strategy)Evaluating with only one stack(without putting operator in stack)
It can be done by evaluating Prefix-notation right-to-left.
- 7 + 2 3
# evaluate + 2 3
- 7 5
# evaluate - 7 5
2
It is same as evaluating Postfix-notation left-to-right.
7 2 3 + -
# put 7 on stack
7 2 3 + -
# evaluate 2 3 +
7 5 -
# evaluate 7 5 -
2
(Optimized short-circuit strategy) Evaluating with two stacks(one for operator and one for operand)
It can be done by evaluating Prefix-notation left-to-right.
|| 1 < 2 3
# put || in instruction stack, 1 in operand stack or keep the pair in stack
instruction-stack: or
operand-stack: 1
< 2 3
# push < 2 3 in stack
instruction-stack: or, less_than
operand-stack: 1, 2, 3
# evaluate < 2 3 as 1
instruction-stack: or
operand-stack: 1, 1
# evaluate || 1 1 as 1
operand-stack:1
Notice that we can do short-circuit optimization for the boolean expression here easily(compared to previous evaluation sequence).
|| 1 < 2 3
# put || in instruction stack, 1 in operand stack or keep the pair in stack
instruction-stack: or
operand-stack: 1
< 2 3
# Is it possible to evaluate `|| 1` without evaluating the rest ? Yes !!
# skip < 2 3 and put place-holder 0
instruction-stack: or
operand-stack: 1 0
# evaluate || 1 0 as 1
operand-stack: 1
It is same as evaluating Postfix-notation right-to-left.
(Optimized short-circuit strategy) Evaluating with one stack that takes a tuple (same as above)
It can be done by evaluating Prefix-notation left-to-right.
|| 1 < 2 3
# put || 1 in tuple-stack
stack tuple[or,1,unknown]
< 2 3
# We do not need to compute < 2 3
stack tuple[or,1,unknown]
# evaluate || 1 unknown as 1
1
It is same as evaluating Postfix-notation right-to-left.
Online evaluation in a calculator while human entering data in left-to-right
When putting numbers in a calculator, the Postfix-notation 2 3 + can be evaluated instantly without any knowledge of the symbol human is going to put. It is opposite of Prefix notation because when we have - 7 + we have nothing to do, not until we get something like - 7 + 2 3.
Online evaluation in a calculator while human entering data in right-to-left
Now the Prefix-notation can evaluate + 2 3 instantly, while the Postfix-notation waits for further input when it has 3 + - .
Please refer to #AshleyF note that the Arabic-language writes from right-to-left in contrast to English-language that writes from left-to-write !
I guess little-endian and big-endian is something related to this prefix/postfix notation.
One final comment, Reverse-Polish notation is strongly supported by Dijkstra (he is strong opponent of short-circuit optimization and regarded as the inventor of Reverse-Polish notation). It is your choice to support his opinion or not(I do not).
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to convert byte size into human readable format in java?
Given an integer, I'd like to print it in a human-readable way using kilo, mega, giga etc. multipliers. How do I pick the "best" multiplier?
Here are some examples
1 print as 1
12345 print as 12.3k
987654321 print as 988M
Ideally the number of digits printed should be configurable, e.g. in the last example, 3 digits would lead to 988M, 2 digits would lead to 1.0G, 1 digit would lead to 1G, and 4 digits would lead to 987.7M.
Example: Apple uses an algorithm of this kind, I think, when OSX tells me how many more bytes have to be copied.
This will be for Java, but I'm more interested in the algorithm than the language.
As a starting point, you could use the Math.log() function to get the "magnitude" of your value, and then use some form of associative container for the suffix (k, M, G, etc).
var magnitude = Math.log(value) / Math.log(10);
Hope this helps somehow
This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Use of caret symbol( ^ ) in Ruby
So I was playing around with some code and I tried to play around with the power operator. So I thought that perhaps I could use the caret (^) for this purpose, but after using it in:
for i in 0..10
puts "#{i} #{1^i}\n"
end
I got some really funky results
0 - 1
1 - 0
2 - 3
3 - 2
4 - 5
5 - 4
6 - 7
7 - 6
8 - 9
9 - 8
10 - 11
The only pattern I see is -1 on an odd number and +1 on an even number, but then when I try:
for i in 0..10
puts "#{i} #{2^i}\n"
end
i get:
0 - 2
1 - 3
2 - 0
3 - 1
4 - 6
5 - 7
6 - 4
7 - 5
8 - 10
9 - 11
10 - 8
wth! So then I kept going up to 4^i and plotted them, the 1^i & 3^i came out with decent patterns but 2^i & 4^i were just all over the place with no visible patterns (though highly unlikely) with just 11 plotting points, so I've come to you ladies and gents asking you:
What on earth is ^ used for?!
In most programming languages, ^ is the XOR operator (Exclusive Or in Wikipedia). XOR is one of the most essential operations in the CPU, it often employed to zero registers (think of a ^= a) because it is fast and has a short opcode.
For the power function, you have to use e.g. ** (e.g. in ruby), java.lang.Math.pow, math.pow, pow etc.
In fact, I couldn't name a programming language that uses ^. It is used in LaTeX for formatting (as superscript, not power function, technically). But the two variants I see all the time are ** (as the power function is directly related to multiplication) and pow(base, exp).
Note that you can compute integer powers of 2 faster using shifts.
I'm a Computer Science major, interested in how assembly languages handle a integer divide function. It seems that simply adding up to the numerator, while giving both the division and the mod, is way too impractical, so I came up with another way to divide using bit shifting, subtracting, and 2 look up tables.
Basically, the function takes the denominator, and makes "blocks" based on the highest power of 2. So dividing by 15 makes binary blocks of 4, dividing by 5 makes binary blocks of 3, etc. Then generate the first 2^block-size multiple of the denominator. For each multiple, write the values AFTER the first block into the look up table, keyed by the value of the first block.
Example: Multiples of 5 in binary - block size 3 (octal)
000 000 **101** - 5 maps to 0
000 001 **010** - 2 maps to 1
000 001 **111** - 7 maps to 1
000 010 **100** - 4 maps to 2
000 011 **001** - 1 maps to 3
000 011 **110** - 6 maps to 3
000 100 **011** - 3 maps to 4
000 101 **000** - 0 maps to 5
So the actual procedure involves getting the first block, left bit-shifting over the first block, and subtracting the value that the blocks maps to. If the resulting number comes out to 0, then it's perfectly divisible, and if the value becomes negative, it's not.
If you add another enumeration look up table, where you map the values to a counter as they come in, you can calculate the result of the division!
Example: Multiples of 5 again
5 maps to 1
2 maps to 2
7 maps to 3
4 maps to 4
1 maps to 5
6 maps to 6
3 maps to 7
0 maps to 8
Then all that's left is mapping every block to the counter-table, and you have your answer.
There are a few problems with this method.
If the answer isn't perfectly divisible, then the function returns back junk.
For high Integer values, this won't work, because a 5 block size will get truncated at the end of a 32 bit or 64 bit integer.
It's about 100 times slower than the standard division in C.
If the denominator is a factor of the divisor, then your blocks must map to multiple values, and you need even more tables. This can be solved with prime factorization, but all the methods I've read about easy/quick prime factorization involve dividing, defeating the purpose of this.
So I have 2 questions: First, is there an algorithm similar to this out there already? I've looked around, and I can't seem to find any like it. Second, How do actual assembly languages handle Integer division?
Sorry if there are any formatting mistake, this is my first time posting to stack overflow.
Sorry i answer so late. Ok, first regarding the commenters of your question: they think you are trying to do what the assembly memonic DIV or IDIV achieves by using different instructions in assembly. To me it seems you want to know how the op-codes that are selected by DIV and IDIV achieve division in hardware. To my knowledge Intel uses the SRT algorithm (uses a lookup-table) and AMD uses the Goldschmidt algorithm. I think what you are doing is similar to SRT. You can take a look at both of them here:
http://en.wikipedia.org/wiki/Division_%28digital%29