Scala: decrement for-loop - list

I noticed that the following two for-loop cases behave differently sometimes while most of the time they are the same. I couldn't figure out the pattern, does anyone have any idea? Thanks!
case 1:
for (i <- myList.length - 1 to 0 by -1) { ... }
case 2:
for (i <- myList.length - 1 to 0) { ...}

Well, they definitely don't do the same things. n to 0 by -1 means "start at n and go to 0, counting backwards by 1. So:
5 to 0 by -1
// res0: scala.collection.immutable.Range = Range(5, 4, 3, 2, 1, 0)
Whereas n to 0 means "start at n and got to 0 counting forward by 1". But you'll notice that if n > 0, then there will be nothing in that list, since there is no way to count forward to 0 from anything greater than zero.
5 to 0
// res1: scala.collection.immutable.Range.Inclusive = Range()
The only way that they would produce the same result is if n=0 since counting from 0 to 0 is the same forwards and backwards:
0 to 0 by -1 // Range(0)
0 to 0 // Range(0)
In your case, since you're starting at myList.length - 1, they will produce the same result when the length of myList is 1.
In summary, the first version makes sense, because you want to count down to 0 by counting backward (by -1). And the second version doesn't make sense because you're not going to want to count forward to 0 from a length (which is necessarily non-negative).

First, we need to learn more about how value members to and by works.
to - Click Here for API documentation
to is a value member that appears in classes like int, double etc.
scala> 1 to 3
res35: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3)
Honestly, you don't have to use start to end by step and start.to(end, step) will also work if you are more comfortable working with in this world. Basically, to will return you a Range.Inclusive object if we are talking about integer inputs.
by - Click Here for API documentation
Create a new range with the start and end values of this range and a new step
scala> Range(1,8) by 3
res54: scala.collection.immutable.Range = Range(1, 4, 7)
scala> Range(1,8).by(3)
res55: scala.collection.immutable.Range = Range(1, 4, 7)
In the end, lets spend some time looking at what happens when the step is on a different direction from start to end. Like 1 to 3 by -1
Here is the source code of the Range class and it is actually pretty straightforward to read:
def by(step: Int): Range = copy(start, end, step)
So by is actually calling a function copy, so what is copy?
protected def copy(start: Int, end: Int, step: Int): Range = new Range(start, end, step)
So copy is literally recreate a new range with different step, then lets look at the constructor or Range itself.
Reading this paragraph of code
override final val isEmpty = (
(start > end && step > 0)
|| (start < end && step < 0)
|| (start == end && !isInclusive)
)
These cases will trigger the exception and your result will be a empty Range in cases like 1 to 3 by -1..etc.
Sorry the length of my post is getting out of control since I am also learning Scala now.
Why don't you just read the source code of Range, it is written by Martin Odersky and it is only 500 lines including comments :)

Related

code debugging: 'take a list of ints between 0-9, return largest number divisible by 3'

I'm trying to understand what is wrong with my current solution.
The problem is as follows:
using python 2.7.6"
You have L, a list containing some digits (0 to 9). Write a function answer(L) which finds the largest number that can be made from some or all of these digits and is divisible by 3. if it is not possible to make such a number, return 0 as the answer. L will contain anywhere from 1 to 9 digits. The same digit may appear multiple times in the list, but each element in the list may only be used once.
input: (int list) l = [3, 1, 4, 1]
output: (int) 4311
input (int list) l = [3 ,1 ,4 ,1 ,5, 9]
output: (int) = 94311
This is my code to tackle the problem:
import itertools
def answer(l):
'#remove the zeros to speed combinatorial analysis:'
zero_count = l.count(0)
for i in range(l.count(0)):
l.pop(l.index(0))
' # to check if a number is divisible by three, check if the sum '
' # of the individual integers that make up the number is divisible '
' # by three. (e.g. 431: 4+3+1 = 8, 8 % 3 != 0, thus 431 % 3 != 0)'
b = len(l)
while b > 0:
combo = itertools.combinations(l, b)
for thing in combo:
'# if number is divisible by 3, reverse sort it and tack on zeros left behind'
if sum(thing) % 3 == 0:
thing = sorted(thing, reverse = True)
max_div_3 = ''
for digit in thing:
max_div_3 += str(digit)
max_div_3 += '0'* zero_count
return int(max_div_3)
b -= 1
return int(0)
I have tested this assignment many times in my own sandbox and it always works.
However when I have submitted it against my instructor, I end up always failing 1 case.. with no explanation of why. I cannot interrogate the instructor's tests, they are blindly pitched against the code.
Does anyone have an idea of a condition under which my code fails to either return the largest integer divisible by 3 or, if none exists, 0?
The list always has at least one number in it.
It turns out that the problem was with the order of itertools.combinations(l, b)
and sorted(thing, reverse = True). The original code was finding the first match of n%3 == 0 but not necessarily the largest match. Performing sort BEFORE itertools.combinations allowed itertools to find the largest n%3 == 0.

Having trouble understanding a portion of code (bit operation)

I can't understand how to count number of 1's in binary representation.
I have my code, and I hope someone can explain it for me.
Code:
int count (int x)
{
int nr=0;
while(x != 0)
{
nr+=x%2;
x/=2;
}
return nr;
}
Why while ? For example if i have 1011, it wouldn't stop at 0?
Why nr += x%2 ?
Why x/=2 ?!
First:
nr += x % 2;
Imagine x in binary:
...1001101
The Modulo operator returns the remainder from a / b.
Now the last bit of x is either a 0, in which case 2 will always go into x with 0 remainder, or a 1, in which case it returns a 1.
As you can see x % 2 will return (if the last bit is a one) a one, thus incrementing nr by one, or not, in which case nr is unchanged.
x /= 2;
This divides x by two, and because it is a integer, drops the remainder. What this means is is the binary was
....10
It will find out how many times 2 would go into it, in this case 1. It effectively drops the last digit of the binary number because in base 2 (binary) the number of times 2 goes into a number is just the same as 'shifting' everything down a space (This is a poor explanation, please ask if you need elaboration). This effectively 'iterates' through the binary number, allowing the line about to check the next bit.
This will iterate until the binary is just 1 and then half that, drop the remainder and x will equal 0,
while (x != 0)
in which case exit the loop, you have checked every bit.
Also:
'count`is possibly not the most descriptive name for a function, consider naming it something more descriptive of its purpose.
nr will always be a integer greater or equal to zero, so you should probably have the return type unsigned int
int count (int x)
{
int nr=0;
while(x != 0)
{
nr+=x%2;
x/=2;
}
return nr;
}
This program basically gives the numbers of set bits in a given integer.
For instance, lets start with the example integer 11 ( binary representation - 1011).
First flow will enter the while loop and check for the number, if it is equal to zero.
while(11 != 0)
Since 11 is not equal to zero it enter the while loop and nr is assigned the value 1 (11%2 = 1).nr += 11%2;
Then it executes the second line inside the loop (x = x/2). This line of code assigns the value 5 (11/2 = 5 ) to x.
Once done with the body of the while loop, it then again checks if x ie 5 is equal to zero.
while( 5 != 0).
Since it is not the case,the flow goes inside the while loop for the second time and nr is assigned the value 2 ( 1+ 5%2).
After that the value of x is divided by 2 (x/2, 5/2 = 2 )and it assigns 2 to x.
Similarly in the next loop, while (2 != 0 ), nr adds (2 + 2%2), since 2%2 is 0, value of nr remains 2 and value of x is decreased to 1 (2/2) in the next line.
1 is not eqaul to 0 so it enters the while loop for the third time.
In the third execution of the while loop nr value is increased to 3 (2 + 1%2).
After that value of x is reduced to 0 ( x = 1/2 which is 0).
Since it fails the check (while x != 0), the flow comes out of the loop.
At the end the value of nr (Which is the number of bits set in a given integer) is returned to the calling function.
Best way to understand the flow of a program is executing the program through a debugger. I strongly suggest you to execute the program once through a debugger.It will help you to understand the flow completely.

Lua if A != (X or Y or Z)?

So I have this function that takes in an integer. But It doesn't work and I suspect that the if statement is not valid, I could not find anything on google regarding the issue, maybe my googling skills just suck.
if mynumber != (0 or 1 or 2 or 3 or 4 or 5 or 6 or 7 or 8) then
print("Please choose an integer number between 1-8")
end
Thanks for any help!!
Correct. That is not how you test things like that. You cannot test multiple values that way.
or requires expressions on either side and evaluates to a single expression. So (0 or 1 or 2 or 3 or 4 or 5 or 6 or 7 or 8) evaluates to 0 and your final expression is just if mynumber != 0 then.
To test multiple values like that you need to use or around multiple comparison expressions.
if (mynumber ~= 0) or (mynumber ~= 1) or (mynumber ~= 2) ... then (also notice ~= is the not-equal operator not !=).
Also be sure to note YuHao's answer about the logic in this line and how to test for this correctly.
Others have pointed the major problems you have, i.e, 0 or 1 or 2 or 3 or 4 or 5 or 6 or 7 or 8 evaluates as 0, the rest is ignored because of short-circuit. You need to test the number with these numbers one by one.
However, there's one last trap. The condition
if mynumber ~= 0 or mynumber ~= 1 then
is always true, because a number is either not equal to 0, in which case mynumber ~= 0 is true; or it is equal to 0, in which case mynumber ~= 1 is true.
The correct logic should be:
if mynumber ~= 0 and mynumber ~= 1 then
Etan's answer explains the behaviour as observed in lua. I'd suggest writing a custom FindIn function for searching:
function FindIn( tInput, Value )
for _ in pairs( tInput ) do
if Value == tInput[_] then return true end
end
return false
end
if FindIn( {1,2,3,4,5,6,7,8}, mynumber ) then
-- ...
end
try this:
In Lua You check if two items are NOT EQUAL by "~=" instead of "!=",
If You compare two items in if statement, then always remember that items should return booleans, so: instead of mynumber != (0 or 1 or...) try something like (mynumber ~= 0) or (mynumber ~= 1) ...
You can do it simple with .... (mynumber have to be integer variable)
if mynumber<0 or mynumber>8 then
print("Please choose an integer number between 1-8")
end

Split string using special parameters

I have the following string:
1,1,1,0,1,1,2,1,1,1,1,2,1,1,1,0,1,1,0,1,1,1,
0-->rupture
2-->continuity
When i have 1s between two 0s it means that i have a document
[0,1,1,1,0] = D
when i have 1s between a 2 and a 0 it means that i have a fragment [2,1,...,1,0] = f and i add all the fragments to a list of fragments F and it signifies the end of the sub-fragments
when i have 1s between a 2 and a 2 it means that i also have a fragment [2,1,...,1,2] = f
As a solution I must have in the end :
3 documents D1,D2,D3 which are located between the indices [0,3],
[15,18], [18,21]
A Fragment F between [3,15] containing 3 sub-fragments , f1 between [3,6] ,f2 between [6,11] and f3 between [11,15].
Note: We consider that the string starts with a 0 and ends with a 0
This is why we have a document between [0,3] and another document between [18,21]
I am trying to formulate this problem but i can't come up with a solid idea. Please tell me if it is clear. and what can I use as an algorithm to help solve this problem, can I use a specific data-structure like a tree...
Thank you,
Hani.
If your string is:
1,1,1,0,1,1,2,1,1,1,1,2,1,1,1,0,1,1,0,1,1,1
Initialize lastPos = 0, lastType = 0 {lastType = 0 for 0 and 2 for 2}
Traverse the array. You find the next 0 at position 3. Since lastType was equal to 0, you know that you have found a sequence of 1s between 2 zeroes. Do whatever.
Make lastType = 0, lastPos = 3.
Continue till the end.
Order of time complexity: O(n)
Order of space complexity: O(1)

How do I build this finite automaton?

I'm studying for a Discrete Mathematics test and I found this exercise which I can't figure out.
"Build a basic finite automaton (DFA,NFA,NFA-lambda) for the language in the alphabet Sigma = {0,1,2} where the sum of the elements in the string is even AND this sum is more than 3"
I have tried using Kleene's Theorem concatenating two languages like concatenating the one associated with this regular expression:
(00 U 11 U 22 U 02 U 20)* - the even elements
with this one
(22 U 1111 U 222 U 2222)* - the ones whose sum is greater than 3
Does this make any sense?? I think my regex are flabby.
I find your notation a bit fuzzy, so perhaps I'm completely misunderstanding. If so, disregard the following. It seems you're not there yet:
I assume the * means '0 or more times'. However, one of the strings with sum >= 3 must occur. It's say you need a + ('1 or more times').
112 and 211 are missing in the list of strings with sum >= 3.
222 and 2222 in that list are superfluous.
All of these strings may be arbitraryly interspersed with 0s.
The sum of 00 is no more even than the sum of 0.
Edit: how about this (acc is the only accepting state, dot-source):
automaton http://student.science.uva.nl/~sschroev/so/885411.png
At states a and c the string sum is always odd. At states start, b and acc the sum is always even. Furthermore, at start the sum is 0, at b it is 2 and at d it is >= 4. This can be proved rather easily. Hence the accepting state acc meets all criteria.
Edit 2: I'd say this is a regex which accepts the requested language:
0*(2|(1(0|2)*1))(0*(2|(1(0|2)*1))+
Not sure if this is answering your question, but: do you need to submit a regular expression? or will an FSM do?
At any rate, it might be helpful to draw the FSM first, and I think this is a correct DFA:
FSM http://img254.imageshack.us/img254/5324/fsm.png
If that is the case, when constructing your regular expression (which, remember, has different syntax than programming "regex"):
0* to indicate "0 as many times as you want". This makes sense, since 0 in your string doesn't change the state of the machine. (See, in the FSM, 0 just loops back to itself)
You'd need to account for the different combinations of "112" or "22" etc - until you reach at least 4 in your sum.
If your sum is greater than 3, and even, then (0|2)* would keep you at a final state. Otherwise (sum > 3, and odd) you'd need something like 1(0|2)* in order to put you at an accepting state.
(don't know if this helps, or if its right - but it might be a start!)
Each expression, as guided by Stephan, may be:
(0*U 2* U 11)* - the even sums
with this one
(22 U 11 U 222 U 112 U 211 U 121)+ - the ones whose sum is greater than 3
I don't know if it could be simplfied more, it would help designing the automaton.
I find it easier just to think in terms of states. Use five states: 0, 1, 2, EVEN, ODD
Transitions:
State, Input -> New State
(0, 0) -> 0
(0, 1) -> 1
(0, 2) -> 2
(1, 0) -> 1
(1, 1) -> 2
(1, 2) -> ODD
(2, 0) -> 2
(2, 1) -> ODD
(2, 2) -> EVEN
(ODD, 0) -> ODD
(ODD, 1) -> EVEN
(ODD, 2) -> ODD
(EVEN, 0) -> EVEN
(EVEN, 1) -> ODD
(EVEN, 2) -> EVEN
Only EVEN is an accepting state.