Should I evaluate a range? - bash

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).

Related

Best practice for chaining comparisons in Ruby

In python, it is possible to chain comparisons like so:
0 < 1 < 2 and 5 > 4 > 3
The only practice I can figure to accomplish similar in Ruby is like so:
0 < 1 && 1 < 2 && 5 > 4 && 4 > 3
Which I find to be fairly unappealing visually.
I've searched google and found some class extensions to make Ruby work like Python, but I was wondering if there was an easier way to chain comparators using just core ruby?
1.between?(0,2)
between? works for any class which includes the Comparable module, e.g. dates, strings, arrays etc.
If you have basic lower and upper bounds you can use Enumberable#include? for range comparison like:
i = 10
(5 .. 20).include?(i)
So you know 5 is your lower-bound and 20 is your upper-bound.
Enumberable#include? uses == under the hood so it has to walk the range and compare each element, so this is poor performance for large ranges
Edit: steenslag answer above is way better. use that!

Why postfix (rpn) notation is more used than prefix?

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).

How to print the calculated process of a game like 24point? [duplicate]

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.

Algorithm for planning the creation of an object from dependencies

I am an alchemist. I can make things out of other things according to my recipe book. For instance:
2 lead + 1 bismuth -> 1 carbon
1 oxygen + 5 hydrogen + 3 nitrogen -> 2 carbon
5 carbon + 5 titanium -> 1 gold
...etc.
My recipe book contains thousands of recipes, each of which consumes some discrete amount of one or more inputs and produces a discrete amount of one output. Being a lazy alchemist, I don't want to remember all my recipes. I want to write a computer program to solve this problem for me. The input to the program is a description of what I want, like "2 gold", and a description of what I have in stock, like "5 titanium, 6 lead, 3 bismuth, 2 carbon, 1 gold". The output should be either "cannot be made" or a sequence of instructions for creating the thing. For the example given here, the output could be:
make 2 carbon out of 4 lead + 2 bismuth
make 1 gold out of 4 carbon + 4 titanium
Then, combined with the 1 gold I already have, I have the 2 gold I wanted.
One last note: the recipes are weighted; e.g. I prefer to make carbon out of lead and bismuth if I can.
Is there an elegant way to formulate and solve this problem? A naive recursive solution looks tempting, but I can think of recipe sets that would cause it to do an exponential amount of work.
(And, as a followup, someday my research might uncover a circular set of recipes---maybe I can make 1 hydrogen out of 1 helium and 1 helium out of 1 hydrogen---and I would like to be able to handle this case as well.)
The problem is NP-hard.
Given an instance of CNF-SAT, prepare alchemical tables with reagents for
each variable
each literal
each clause (unsatisfied version)
each clause (satisfied version)
the output.
The reactions are
variable to large supply of corresponding positive literal
variable to large supply of corresponding negative literal
clause (unsatisfied version) and satisfying literal to clause (satisfied version)
all clauses (satisfied versions) to the output.
The question is whether we can make the output given one of each variable and one of each clause (unsatisfied version).
This problem is related to the problem of determining reachability of vector addition systems/Petri nets; my reduction is based in part on reductions that appeared in that literature.

what is ^ used for in ruby? [duplicate]

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.

Resources