I have a question when it comes to - / operators in postfix vs infix.
From the assignment
The input string 5 4 + 3 10 * + is equivalent to the infix expression
(5 + 4) + (3 * 10) The answer is 39.
I follow that. Then I get confused by this statement.
We also have to worry about the non-commuting operators – and / . We
will evaluate the postfix string 4 5 – as 4 – 5 and,
likewise, will evaluate 4 5 / as 4 / 5 .
When I do that however...I get different results with infix vs postfix.
Modifying the first example to include subtraction.
infix
(5 - 4) + (3 * 10) = 31
postfix
5 4 - 3 10 * +
29....right?
SO I'm confused. The results of infix and postfix are supposed to be the same right? Is this a typo in the actual assignment or am I doing something wrong?
The postfix also evaluates to 31.
Let's go through this step by step: Our expression is
5 4 - 3 10 * +
So the stack progresses as follows:
5
5 4
1 # after evaluating -, i.e. popping 5 and 4 and pushing 5 - 4
1 3
1 3 10
1 30 # after evaluating *, i.e. popping 3 and 10 and pushing 3 * 10
31 # after evaluating +, i.e. popping 1 and 30 and pushing 1 + 30
I think you may have been confused because the example is 4-5 and your example is 5-4 for the infix notation.
To evaluate the postfix 5 4 - 3 10 * +:
5 4 - = 5 - 4 = 1
3 10 * = 3 * 10 = 30
1 30 + = 1 + 30 = 31
The second statement from your assignment just clarifies that if you have something like 4 5 -, that it will be 4 - 5 and not 5 - 4.
When you're evaluating postfix you use a stack: you push operands and when you get to an operator you pop the required operands and push the evaluated result.
In the case of commutative operators like + it doesn't matter which order the operands are in. So for example:
5 4 +
can be evaluated as
PUSH 5
PUSH 4
PUSH (POP + POP)
where the first POP will yield 4 and the second POP 5. So you have really evaluated 4+5.
But in the case of non-commutative operators, this won't work. You have to evaluate 5 / 4, not 4 / 5. So you need either to use temporary variables:
PUSH 5
PUSH 4
let d = POP; // divisor = 4
let q = POP; // quotient = 5
PUSH q/d; // push the dividend
or else introduce a SWAP operation, which swaps the top two items on the stack:
PUSH 5
PUSH 4
SWAP
PUSH (POP / POP)
or else compile the postfix so as to push in the opposite order:
PUSH 4
PUSH 5
PUSH (POP/POP)
In the statement about - and /, it's 4 5 -. That's -1, i.e. 4-5.
In the longer expression: 5 4 - 3 10 * +
It's 5 - 4, because the 5 comes first. Thus, it is (5-4) + (3*10) = 31.
If it was 4 5 - 3 10 * + then that would evaluate to 29 (i.e. (4-5) + (3*10)). This doesn't have to do with prefix or postfix notation, but the order that we evaluate the arguments in, because - and / are non commutative. The assignment specifies that they will be evaluated in the "intuitive" order, i.e. that x y - means x - y.
Related
For a work shift optimization problem, I've defined a binary variable in PuLP as follows:
pulp.LpVariable.dicts('VAR', (range(D), range(N), range(T)), 0, 1, 'Binary')
where
D = # days in each schedule we create (=28, or 4 weeks)
N = # of workers
T = types of work shift (=6)
For the 5th and 6th type of work shift (with index 4 and 5), I need to add a constraint that any worker who works these shifts must do so for seven consecutive days... and not any seven days but the seven days starting from Monday (aka a full week). I've tried defining the constraint as follows, but I'm getting an infeasible solution when I add this constraint and try to solve the problem (it worked before without it)
I know this constraint (along with the others from before) should theoretically be feasible because we manually schedule work shifts with the same set of constraints. Is there anything wrong with the way I've coded the constraint?
## looping over each worker
for j in range(N):
## looping for every Monday in the 28 days
for i in range(0,D,7):
c = None
## accessing only the 5th and 6th work shift type
for k in range(4,T):
c+=var[i][j][k]+var[i+1][j][k]+var[i+2][j][k]+var[i+3][j][k]+var[i+4][j][k]+var[i+5][j][k]+var[i+6][j][k]
problem+= c==7
If I understand correctly then your constraint requires that each worker is required to work the 4th and 5th shift in every week. This is because of c == 7, i.e. 7 of the binaries in c must be set to 1. This does not allow any worker to work in shift 0 through 3, right?
You need to change the constraint so that c == 7 is only enforced if the worker works any shift in that range. A very simple way to do that would be something like
v = list()
for k in range(4,T):
v.extend([var[i][j][k], var[i+1][j][k], var[i+2][j][k], var[i+3][j][k], var[i+4][j][k], var[i+5][j][k], var[i+6][j][k]])
c = sum(v)
problem += c <= 7 # we can pick at most 7 variables from v
for x in v:
problem += 7 * x <= c # if any variable in v is picked, then we must pick 7 of them
This is by no means the best way to model that (indicator variables would be much better), but it should give you an idea what to do.
Just to offer an alternative approach, assuming (as I read it) that for any given week a worker can either work some combination of shifts in [0:3] across the seven days, or one of the shifts [4:5] every day: we can do this by defining a new binary variable Y[w][n][t] which is 1 if in week w worker n does a restricted shift t, 0 otherwise. Then we can relate this variable to our existing variable X by adding constraints so that the values X can take depend on the values of Y.
# Define the sets of shifts
non_restricted_shifts = [0,1,2,3]
restricted_shifts = [4,5]
# Define a binary variable Y, 1 if for week w worker n works restricted shift t
Y = LpVariable.dicts('Y', (range(round(D/7)), range(N), restricted_shifts), cat=LpBinary)
# If sum(Y[week][n][:]) = 1, the total number of non-restricted shifts for that week and n must be 0
for week in range(round(D/7)):
for n in range(N):
prob += lpSum(X[d][n][t] for d in range(week*7, week*7 + 7) for t in non_restricted_shifts) <= 1000*(1-lpSum(Y[week][n][t] for t in restricted_shifts))
# If worker n has 7 restricted shift t in week w, then Y[week][n][t] == 1, otherwise it is 0
for week in range(round(D/7)):
for n in range(N):
for t in restricted_shifts:
prob += lpSum(X[d][n][t] for d in range(week*7, week*7+7)) <= 7*(Y[week][n][t])
prob += lpSum(X[d][n][t] for d in range(week*7, week*7+7)) >= Y[week][n][t]*7
Some example output (D=14, N=2, T=6):
/ M T W T F S S / M T W T F S S / M T W T F S S / M T W T F S S
WORKER 0
Shifts: / 2 3 1 3 3 2 2 / 1 0 2 3 2 2 0 / 3 1 2 2 3 1 1 / 2 3 0 3 3 0 3
WORKER 1
Shifts: / 3 1 2 3 1 1 2 / 3 3 2 3 3 3 3 / 4 4 4 4 4 4 4 / 1 3 2 2 3 2 1
WORKER 2
Shifts: / 1 2 3 1 3 1 1 / 3 3 2 2 3 2 3 / 3 2 3 0 3 1 0 / 4 4 4 4 4 4 4
WORKER 3
Shifts: / 2 2 3 2 1 2 3 / 5 5 5 5 5 5 5 / 3 1 3 1 0 3 1 / 2 2 2 2 3 0 3
WORKER 4
Shifts: / 5 5 5 5 5 5 5 / 3 3 1 0 2 3 3 / 0 3 3 3 3 0 2 / 3 3 3 2 3 2 3
I tried parsing a common string depiction of ranges (e.g. 1-9) into actual ranges (e.g. 1 .. 9), but often got weird results when including two digit numbers. For example, 1-10 results in the single value 1 instead of a list of ten values and 11-20 gave me four values (11 10 21 20), half of which aren't even in the expected numerical range:
put get_range_for('1-9');
put get_range_for('1-10');
put get_range_for('11-20');
sub get_range_for ( $string ) {
my ($start, $stop) = $string.split('-');
my #values = ($start .. $stop).flat;
return #values;
}
This prints:
1 2 3 4 5 6 7 8 9
1
11 10 21 20
Instead of the expected:
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
(I figured this out before posting this question, so I have answered below. Feel free to add your own answer if you'd like to elaborate).
The problem is indeed that .split returns Str rather than Int, which the original answer solves. However, I would rather implement my "get_range_for" like this:
sub get_range_for($string) {
Range.new( |$string.split("-")>>.Int )
}
This would return a Range object rather than an Array. But for iteration (which is what you most likely would use this for), this wouldn't make any difference. Also, for larger ranges the other implementation of "get_range_for" could potentially eat a lot of memory because it vivifies the Range into an Array. This doesn't matter much for "3-10", but it would for "1-10000000".
Note that this implementation uses >>.Int to call the Int method on all values returned from the .split, and then slips them as separate parameters with | to Range.new. This will then also bomb should the .split return 1 value (if it couldn't split) or more than 2 values (if multiple hyphens occurred in the string).
The result of split is a Str, so you are accidentally creating a range of strings instead of a range of integers. Try converting $start and $stop to Int before creating the range:
put get_range_for('1-9');
put get_range_for('1-10');
put get_range_for('11-20');
sub get_range_for ( $string ) {
my ($start, $stop) = $string.split('-');
my #values = ($start.Int .. $stop.Int).flat; # Simply added .Int here
return #values;
}
Giving you what you expect:
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
So, I know that Ada offers two remainder operators, rem and mod, but what exactly is the difference between them? I was able to find this, but I'm not sure I'm fully grasping the difference.
There's no difference between A mod B and A rem B if A is nonnegative and B is positive. If A is negative and B is positive, mod gives you the true mathematical modulo operation; thus, for example, if B is 5, here are the results of A mod 5 and A rem 5 for values of A:
A = -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8
A mod 5 = 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3
A rem 5 = 0 -4 -3 -2 -1 0 -4 -3 -2 -1 0 1 2 3 4 0 1 2 3
Note the pattern in the A mod 5 results.
rem corresponds to the way the % operator works in C-style languages (but not Python or Ruby, apparently). It may be faster on some processors. If you have to deal with negative values for A, my hunch is that mod is much more likely to be useful, but there may be some uses for rem also. I don't think there's much use at all for mod or rem with a negative right-hand operand, so I wouldn't worry too much about the definition.
See also http://en.wikipedia.org/wiki/Modulo_operation.
According to the LRM, the difference is which operand's sign is associated with the result.
Integer division and remainder are defined by the relation
A = (A/B)*B + (A rem B)
where (A rem B) has the sign of A and an absolute value less than the absolute value of B. Integer division satisfies the identity
(-A)/B = -(A/B) = A/(-B)
The result of the modulus operation is such that (A mod B) has the sign of B and an absolute value less than the absolute value of B; in addition, for some integer value N, this result must satisfy the relation
A = B*N + (A mod B)
How can I use a collection of nested for loops (or any other type) to produce a sequence like this with these variables:
length is how many digts to go to
max is the maximum number
min is the minimum number
Lets say for this case:
length = 2
max = 3
min = 1
it would produce:
11
12
13
21
22
23
31
32
33
This works "ok" for only length = 1, but not really, since I still have annoying 0's at the start
For i = 1 To length
For ii = 0 To i
For iii = 1 To 5
Console.WriteLine(Str(ii) + Str(iii))
Next
Next
Next
As this looks like a homework problem, I am going to attempt to help you think through this problem without actually giving you the answer in code.
Let's think through this problem...
You have the range 1-3. So your first sequence is easy:
1, 2, 3
Now you want to produce a sequence from 11 to 13. What's the change, or difference, between 1 through 3 and 11 through 13? The answer is you've added 10.
The same is true for 21 through 23 - you've added 10 again.
So, what you want to do is iterate from 1 through 3.
Then, iterate from 1 through 3 this time adding 10.
Then, iterate from 1 through 3 this time adding 20.
Thinking about this, you are essentially doing this:
1
2
3
10 + 1
10 + 2
10 + 3
10 + 10 + 1
10 + 10 + 2
10 + 10 + 3
etc
Or, you could also think about it like this:
(0 * 10) + 1
(0 * 10) + 2
(0 * 10) + 3
(1 * 10) + 1
(1 * 10) + 2
(1 * 10) + 3
(2 * 10) + 1
(2 * 10) + 2
(2 * 10) + 3
etc
Can you see a pattern forming?
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 11 years ago.
Improve this question
Write code to determine if a number is divisible by 3. The input to the function is a single bit, 0 or 1, and the output should be 1 if the number received so far is the binary representation of a number divisible by 3, otherwise zero.
Examples:
input "0": (0) output 1
inputs "1,0,0": (4) output 0
inputs "1,1,0,0": (6) output 1
This is based on an interview question. I ask for a drawing of logic gates but since this is stackoverflow I'll accept any coding language. Bonus points for a hardware implementation (verilog etc).
Part a (easy): First input is the MSB.
Part b (a little harder): First input is the LSB.
Part c (difficult): Which one is faster and smaller, (a) or (b)? (Not theoretically in the Big-O sense, but practically faster/smaller.) Now take the slower/bigger one and make it as fast/small as the faster/smaller one.
There's a fairly well-known trick for determining whether a number is a multiple of 11, by alternately adding and subtracting its decimal digits. If the number you get at the end is a multiple of 11, then the number you started out with is also a multiple of 11:
47278 4 - 7 + 2 - 7 + 8 = 0, multiple of 11 (47278 = 11 * 4298)
52214 5 - 2 + 2 - 1 + 4 = 8, not multiple of 11 (52214 = 11 * 4746 + 8)
We can apply the same trick to binary numbers. A binary number is a multiple of 3 if and only if the alternating sum of its bits is also a multiple of 3:
4 = 100 1 - 0 + 0 = 1, not multiple of 3
6 = 110 1 - 1 + 0 = 0, multiple of 3
78 = 1001110 1 - 0 + 0 - 1 + 1 - 1 + 0 = 0, multiple of 3
109 = 1101101 1 - 1 + 0 - 1 + 1 - 0 + 1 = 1, not multiple of 3
It makes no difference whether you start with the MSB or the LSB, so the following Python function works equally well in both cases. It takes an iterator that returns the bits one at a time. multiplier alternates between 1 and 2 instead of 1 and -1 to avoid taking the modulo of a negative number.
def divisibleBy3(iterator):
multiplier = 1
accumulator = 0
for bit in iterator:
accumulator = (accumulator + bit * multiplier) % 3
multiplier = 3 - multiplier
return accumulator == 0
Here... something new... how to check if a binary number of any length (even thousands of digits) is divisible by 3.
-->((0))<---1--->()<---0--->(1) ASCII representation of graph
From the picture.
You start in the double circle.
When you get a one or a zero, if the digit is inside the circle, then you stay in that circle. However if the digit is on a line, then you travel across the line.
Repeat step two until all digits are comsumed.
If you finally end up in the double circle then the binary number is divisible by 3.
You can also use this for generating numbers divisible by 3. And I wouldn't image it would be hard to convert this into a circuit.
1 example using the graph...
11000000000001011111111111101 is divisible by 3 (ends up in the double circle again)
Try it for yourself.
You can also do similar tricks for performing MOD 10, for when converting binary numbers into base 10 numbers. (10 circles, each doubled circled and represent the values 0 to 9 resulting from the modulo)
EDIT: This is for digits running left to right, it's not hard to modify the finite state machine to accept the reverse language though.
NOTE: In the ASCII representation of the graph () denotes a single circle and (()) denotes a double circle. In finite state machines these are called states, and the double circle is the accept state (the state that means its eventually divisible by 3)
Heh
State table for LSB:
S I S' O
0 0 0 1
0 1 1 0
1 0 2 0
1 1 0 1
2 0 1 0
2 1 2 0
Explanation: 0 is divisible by three. 0 << 1 + 0 = 0. Repeat using S = (S << 1 + I) % 3 and O = 1 if S == 0.
State table for MSB:
S I S' O
0 0 0 1
0 1 2 0
1 0 1 0
1 1 0 1
2 0 2 0
2 1 1 0
Explanation: 0 is divisible by three. 0 >> 1 + 0 = 0. Repeat using S = (S >> 1 + I) % 3 and O = 1 if S == 0.
S' is different from above, but O works the same, since S' is 0 for the same cases (00 and 11). Since O is the same in both cases, O_LSB = O_MSB, so to make MSB as short as LSB, or vice-versa, just use the shortest of both.
Here is an simple way to do it by hand.
Since 1 = 22 mod 3, we get 1 = 22n mod 3 for every positive integer.
Furthermore 2 = 22n+1 mod 3. Hence one can determine if an integer is divisible by 3 by counting the 1 bits at odd bit positions, multiply this number by 2, add the number of 1-bits at even bit posistions add them to the result and check if the result is divisible by 3.
Example: 5710=1110012.
There are 2 bits at odd positions, and 2 bits at even positions. 2*2 + 2 = 6 is divisible by 3. Hence 57 is divisible by 3.
Here is also a thought towards solving question c). If one inverts the bit order of a binary integer then all the bits remain at even/odd positions or all bits change. Hence inverting the order of the bits of an integer n results is an integer that is divisible by 3 if and only if n is divisible by 3. Hence any solution for question a) works without changes for question b) and vice versa. Hmm, maybe this could help to figure out which approach is faster...
You need to do all calculations using arithmetic modulo 3. This is the way
MSB:
number=0
while(!eof)
n=input()
number=(number *2 + n) mod 3
if(number == 0)
print divisible
LSB:
number = 0;
multiplier = 1;
while(!eof)
n=input()
number = (number + multiplier * n) mod 3
multiplier = (multiplier * 2) mod 3
if(number == 0)
print divisible
This is general idea...
Now, your part is to understand why this is correct.
And yes, do homework yourself ;)
The idea is that the number can grow arbitrarily long, which means you can't use mod 3 here, since your number will grow beyond the capacity of your integer class.
The idea is to notice what happens to the number. If you're adding bits to the right, what you're actually doing is shifting left one bit and adding the new bit.
Shift-left is the same as multiplying by 2, and adding the new bit is either adding 0 or 1. Assuming we started from 0, we can do this recursively based on the modulo-3 of the last number.
last | input || next | example
------------------------------------
0 | 0 || 0 | 0 * 2 + 0 = 0
0 | 1 || 1 | 0 * 2 + 1 = 1
1 | 0 || 2 | 1 * 2 + 0 = 2
1 | 1 || 0 | 1 * 2 + 1 = 0 (= 3 mod 3)
2 | 0 || 1 | 2 * 2 + 0 = 1 (= 4 mod 3)
2 | 1 || 2 | 2 * 2 + 1 = 2 (= 5 mod 3)
Now let's see what happens when you add a bit to the left. First, notice that:
22n mod 3 = 1
and
22n+1 mod 3 = 2
So now we have to either add 1 or 2 to the mod based on if the current iteration is odd or even.
last | n is even? | input || next | example
-------------------------------------------
d/c | don't care | 0 || last | last + 0*2^n = last
0 | yes | 1 || 0 | 0 + 1*2^n = 1 (= 2^n mod 3)
0 | no | 1 || 0 | 0 + 1*2^n = 2 (= 2^n mod 3)
1 | yes | 1 || 0 | 1 + 1*2^n = 2
1 | no | 1 || 0 | 1 + 1*2^n = 0 (= 3 mod 3)
1 | yes | 1 || 0 | 2 + 1*2^n = 0
1 | no | 1 || 0 | 2 + 1*2^n = 1
input "0": (0) output 1
inputs "1,0,0": (4) output 0
inputs "1,1,0,0": (6) output 1
shouldn't this last input be 12, or am i misunderstanding the question?
Actually the LSB method would actually make this easier. In C:
MSB method:
/*
Returns 1 if divisble by 3, otherwise 0
Note: It is assumed 'input' format is valid
*/
int is_divisible_by_3_msb(char *input) {
unsigned value = 0;
char *p = input;
if (*p == '1') {
value &= 1;
}
p++;
while (*p) {
if (*p != ',') {
value <<= 1;
if (*p == '1') {
ret &= 1;
}
}
p++;
}
return (value % 3 == 0) ? 1 : 0;
}
LSB method:
/*
Returns 1 if divisble by 3, otherwise 0
Note: It is assumed 'input' format is valid
*/
int is_divisible_by_3_lsb(char *input) {
unsigned value = 0;
unsigned mask = 1;
char *p = input;
while (*p) {
if (*p != ',') {
if (*p == '1') {
value &= mask;
}
mask <<= 1;
}
p++;
}
return (value % 3 == 0) ? 1 : 0;
}
Personally I have a hard time believing one of these will be significantly different to the other.
I think Nathan Fellman is on the right track for part a and b (except b needs an extra piece of state: you need to keep track of if your digit position is odd or even).
I think the trick for part C is negating the last value at each step. I.e. 0 goes to 0, 1 goes to 2 and 2 goes to 1.
A number is divisible by 3 if the sum of it's digits is divisible by 3.
So you can add the digits and get the sum:
if the sum is greater or equal to 10 use the same method
if it's 3, 6, 9 then it is divisible
if the sum is different than 3, 6, 9 then it's not divisible