original code
while(i<30){
// do something
i++;
}
unrolled while loop
while(i<15){
// do something twice
i+=2;
}
Cant we unroll it as shown above. Do we always have to do it like http://en.wikipedia.org/wiki/Loop_unrolling ?
In general, the answer is no. It works for 30 and 15 because 30 is even, but it would not work as easily for odd numbers. "Duff's device" was invented to deal with general case. It is quite ugly, though.
Related
I've a question about good or bad practice.
I've created a function which will generate a random number. And if the random number is equal to the previous random number it should generate a new number. So my question is. Is it bad practice to call the same method from the method?
func getRandomNumber(){ //<-- Method name
let randomNumber = Int.random(in: 0..<allPlayers.count)
if lastRoundNumber == randomNumber{
getRandomNumber() //<-- Like this
}
print(randomNumber)
}
Or should I do this is another way? If yes, how?
So is it bad practice to call the same method from the current method like I've done in the code above? Thanks in advance.
If yes, why is it bad? And how can you do this to get a "better" code?
There is nothing wrong with having a function call itself. It’s called recursion. When not implemented properly, it can introduce some overhead, but sometimes it can be a very elegant solution.
That having been said, you might not want to do it like you have here. What if it guessed the same number three times before it got one that wasn’t equal to lastRoundNumber? You’d see four print statements for one new value. Do you really want that behavior? If you were going to implement getRandomNumber as a recursive function, at the very least I’d suggest inserting a return statement after it calls itself recursively, so that you don’t get print statements for the iterations where it ended up with the same value as lastRoundNumber.
That having been said, we often only reach for recursion (and the overhead that entails) when that implementation is appreciably more elegant or intuitive than the non-recursive rendition. But in this case, the non-recursive rendition is probably just as clear, and as such, we’d likely favor it over the recursive version. It might look like:
func getRandomNumber() {
guard allPlayers.count > 1 else { return }
var randomNumber: Int
repeat {
randomNumber = .random(in: 0..<allPlayers.count)
} while randomNumber == lastRoundNumber
print(randomNumber)
}
Note, I’m checking that you have more than one player to avoid the possibility of infinite loop.
But let's say there were 100 players. And let’s say you called this 100 times. Is it OK if it returned player 1, then player 2, then player 1 again, then player 2 again, repeating again and again, never returning any players 3 through 100. This is unlikely, but it’s possible. Is that OK?
Often we want to return all players, but in a random order. In that case, you’d “shuffle” the list, e.g.
let players = (0..<allPlayers.count).shuffled()
That will ensure that you have an array of integer values, shuffled into random order, but never repeating any given number. That provides randomness while also ensuring that each value is returned only once.
It just depends upon your desired behavior.
If you call a method from the same method, it is called recursion.
You can find here an explanation how recursion in swift works.
You should make sure that your method has an exit condition, so you are not stuck in your call.
Let's look at an example call of your method. lastRoundNumber is 1.
Your generated number is also 1. So it will call the method again. Then you will generate the number 2.
With print(randomNumber) you will get the following output:
2
1
It will happen, because the print-statement will be excuted, even if you call the method again.
So you need to rework your if statement to the following:
if lastRoundNumber == randomNumber{
getRandomNumber() //<-- Like this
} else {
print(randomNumber)
}
In this way, it will only print the last generated value
I've used them, I'm familiar with the code and read a number tutorials but I still don't understand exactly how they work in that I can't run through my head what I'm doing and ultimately what I want to achieve, as opposed to say an if statement which can be read in English quite well.
For-loops have always been something I've struggled with through lack of understanding, can someone offer some insight please?
The for-in loop performs a set of statements for each item in a range or collection. Swift also provides two range operators a..<b and a...b, as a shortcut for expressing a range of values.
// prints 1-10
for i in 1...10 {
print(i)
}
// This way has been removed in Swift 3 so use the above
for var i = 1; i <= 10; i+=1 {
print(i)
}
The for-in loop is used for iterations on numbers, items in an array or characters in a string.
//I want my var res to be equal to 10:
for var nb = 0 in 0..10 {
nb += 1
print("my nb is \(nb)"
}
To understand for loops, one needs to understand the need for repeating lines of code (an unrolled loop) for a bunch of sequential numbers or array elements, etc. A "for-loop" tells the processor to do most of the repetition for you, without the need for you to copy-paste all those nearly identical lines of code a whole bunch (maybe millions or billions) of times.
A "for in" loop lets you specify the range (of numbers or array elements, etc.) over which you want the repetition, so the code doesn't go on repeating forever.
I have the following array assignment:
advances = if advance == 0 then [advance] else [advance, (0 - advance)]
I wonder if there is a more coffeescript way of doing this?
What about:
advances = [advance]
advances.push (0 - advance) if advance != 0
I think this is a bit more readable. But I guess that a matter of taste.
It also uses coffee-script's nice if-at-the-end feature, which I makes some statements such as this "conditional array growing" more readable (for me at least).
PS: I also changed the == 0 to != 0 to avoid the unless statement. It just confuses me when reading code.
PPS: Don't put everything on one line just for the sake of it (even if is coffee-script is good at that). Always think of the most readable (and well performing) code.
I think your own proposal is perfectly fine. It's simple, clear, and pure-functional.
If you think minimizing punctuation is part of the coffeescript way then you could drop the parentheses
advances = if advance == 0 then [advance] else [advance, 0 - advance]
You're perhaps thinking about list comprehensions, but I can't imagine how to utilize them here. I believe you'd get better result utilizing underscore.js (or some other library providing collection utilities):
advances = _.uniq([advance, (0 - advance)])
http://underscorejs.org/#uniq
Adam Ko has provided a magnificent solution to this question, thanks Adam Ko.
BTW if, like me, you love the c preprocessor (the thing that handles #defines), you may not be aware there is a handy thing in XCode: right click on the body of one of your open source files, go down near the bottom .. "Preprocess". It actually runs the preprocessor, showing you the overall "real deal" of what is going to be compiled. It's great!
This question is a matter of style and code clarity. Consider it similar to questions about subtle naming issues, or the best choice (more readable, more maintainable) among available idioms.
As a matter of course, one uses loops like this:
for(NSUInteger _i=0; _i<20; ++_i)
{
.. do this 20 times ..
}
To be clear, the effect is to to do something N times. (You are not using the index in the body.)
I want to signal clearly for the reader that this is a count-based loop -- ie, the index is irrelevant and algorithmically we are doing something N times.
Hence I want a clean way to do a body N times, with no imperial entanglements or romantic commitments. You could make a macro like this:
#define forCount(N) for(NSUinteger __neverused=0; __neverused<N; ++__neverused)
and that works. Hence,
forCount(20)
{
.. do this 20 times ..
}
However, conceivably the "hidden" variable used there could cause trouble if it collided with something in the future. (Perhaps if you nested the control structure in question, among other problems.)
To be clear efficiency, etc., is not the issue here. There are already a few different control structures (while, do, etc etc) that are actually of course exactly the same thing, but which exist only as a matter of style and to indicate clearly to the reader the intended algorithmic meaning of the code passage in question. "forCount" is another such needed control structure, because "index-irrelevant" count loops are completely basic in any algorithmic programming.
Does anyone know the really, really, REALLY cool solution to this? The #define mentioned is just not satisfying, and you've thrown in a variable name that inevitably someone will step on.
Thanks!
Later...
A couple of people have asked essentially "But why do it?"
Look at the following two code examples:
for ( spaceship = 3; spaceship < 8; ++spaceship )
{
beginWarpEffectForShip( spaceship )
}
forCount( 25 )
{
addARandomComet
}
Of course the effect is utterly and dramatically different for the reader.
After all, there are alresdy numerous (totally identical) control structures in c, where the only difference is style: that is to say, conveying content to the reader.
We all use "non-index-relative" loops ("do something 5 times") every time we touch a keyboard, it's as natural as pie.
So, the #define is an OKish solution, is there a better way to do it? Cheers
You could use blocks for that. For instance,
void forCount(NSUInteger count, void(^block)()) {
for (NSUInteger i = 0; i < count; i++) block();
}
and it could be used like:
forCount(5, ^{
// Do something in the outer loop
forCount(10, ^{
// Do something in the inner loop
});
});
Be warned that if you need to write to variables declared outside the blocks you need to specify the __block storage qualifier.
A better way is to do this to allow nested forCount structure -
#define $_TOKENPASTE(x,y) x##y
#define $$TOKENPASTE(x,y) $_TOKENPASTE(x, y)
#define $itr $$TOKENPASTE($_itr_,__LINE__)
#define forCount(N) for (NSUInteger $itr=0; $itr<N; ++$itr)
Then you can use it like this
forCount(5)
{
forCount(10)
{
printf("Hello, World!\n");
}
}
Edit:
The problem you suggested in your comment can be fixed easily. Simply change the above macro to become
#define $_TOKENPASTE(x,y) x##y
#define $$TOKENPASTE(x,y) $_TOKENPASTE(x, y)
#define UVAR(var) $$TOKENPASTE(var,__LINE__)
#define forCount(N) for (NSUInteger UVAR($itr)=0, UVAR($max)=(NSUInteger)(N); \
UVAR($itr)<UVAR($max); ++UVAR($itr))
What it does is that it reads the value of the expression you give in the parameter of forCount, and use the value to iterate, that way you avoid multiple evaluations.
On possibility would be to use dispatch_apply():
dispatch_apply(25, myQueue, ^(size_t iterationNumber) {
... do stuff ...
});
Note that this supports both concurrent and synchronous execution, depending on whether myQueue is one of the concurrent queues or a serial queue of your own creation.
To be honest, I think you're over addressing a non-issue.
If want to iterate over an entire collection use the Objective-C 2 style iterators, if you only want to iterate a finite number of times just use a standard for loop - the memory space you loose from an otherwise un-used integer is meaningless.
Wrapping such standard approaches up just feels un-necessary and counter-intuitive.
No, there is no cooler solution (not with Apple's GCC version anyways). The level at which C works requires you to explicitly have counters for every task that require counting, and the language defines no way to create new control structures.
Other compilers/versions of GCC have a __COUNTER__ macro that I suppose could somehow be used with preprocessor pasting to create unique identifiers, but I couldn't figure a way to use it to declare identifiers in a useful way.
What's so unclean about declaring a variable in the for and never using it in its body anyways?
FYI You could combine the below code with a define, or write something for the reader to the effect of:
//Assign an integer variable to 0.
int j = 0;
do{
//do something as many times as specified in the while part
}while(++j < 20);
Why not take the name of the variable in the macro? Something like this:
#define forCount(N, name) for(NSUInteger name; name < N; name++)
Then if you wanted to nest your control structures:
forCount(20, i) {
// Do some work.
forCount(100, j) {
// Do more work.
}
}
I want to to math operations with some kind of prepared formula that would look like tan(%f)*1000 or %f+%f where the %f has to be replaced by an argument.
Is there a function in Objective-C that I can pass the format of my formula and the required numbers to execute this prepared operation?
I hope the problem is described understandable, if not, leave a comment.
Thanks in advance.
Edit 1: Thanks for your answers so far, but I'm looking for something more dynamic. The block and inline function is great, but to static. I also understand that this may be something hard to achieve out of the box.
You may be interested in DDMathParser, found here. I believe it will do everything you're looking for.
There is nothing that would do it this way, however what you could do is rewrite your "format" into a function, and just pass the arguments it needs to have, much faster and much easier.
inline float add(float p_x,float p_y)
{ return p_x+p_y; }
inline is a compiler feature that you can use to speed things up. It will replace the function call with the code it executes when you compile. This will result in a lager binary though.
If I understand your question correctly, Objective-C Blocks are great for this.
typedef double (^CalcBlock)(double);
CalcBlock myBlock = ^(double input) {
return (tan(input) * 1000);
};
NSLog(#"Result: %f", myBlock(M_PI_2));
You can pass the block that contains your algorithm to other objects or methods.