I was wondering what this code really means. I mean, I would like to know what it does, in what order, and what do ? and : signs mean; all explained.
printf(" %c", ((sq & 8) && (sq += 7)) ? '\n' : pieces[board[sq] & 15]);
Thanks.
The first argument, " %c", means that printf needs to print out a character.
The second argument is the character that the function prints.
In this case, the second argument is a ternary operator. You can read the link provided, but in short, it's basically a short-hand for an if-else block. This is what it looks like in your example:
((sq & 8) && (sq += 7)) ? '\n' : pieces[board[sq] & 15]
Let's separate it into three parts:
((sq & 8) && (sq += 7))
'\n'
pieces[board[sq] & 15]
The first part is a condition (if);
this expression (sq & 8) uses what is called a bitwise AND operation (read more here). Basically, 8 in binary is 1000 and that part checks whether sq has a 1 in that position (it can be 1000, 11000, 101000 etc.); if it does, that expression equals 8 (any number bigger than zero means true) and if it doesn't, it equals 0 (which means false).
&& means AND, it just means that both left and right expression need to be true
sq += 7 will add 7 to sq and if it's not 0, it is true.
The second part \n is returned (and in your case printed out) if the condition is true; else the third part will be printed out (pieces[board[sq] & 15]).
This is fairly obfuscated code, so it's best to try to understand it in the context in which it appears. By obfuscating it in this way, the auther is trying to tell you "you don't really need to understand the details". So lets try to understand what this does from the 'top down' inferring the details of the context, rather than bottom up.
printf prints -- in this case " %c", which is a space and a single character. The single character will either be (from the ?-: ternary expression)
a newline '\n'
a piece from space sq on the board
which it will be depends on the condition before the ? -- it first tests a single bit of sq (the & 8 does a bitwise and with a constant with one set bit), and if that bit is set, adds 7 to sq and prints the newline1, while if it is not set, will print the piece.
So now we really need to know the context. This is probably in a loop that starts with sq = 0 and increments sq each time in the loop (ie, something like for (int sq = 0; ...some condition...; ++sq)). So what it is doing is printing out the pieces on some row of the board, and when it gets to the end of the row, prints a newline and goes on to the next row. A lot of this depends on how exactly the board array is organized -- it would seem to be a 1D array with a 2D board embedded in it; the first row at indexes 0..7, the second at indexes 16..23, the third at indexes 32..39 and so on2.
1technically, when the bit is set, it tests the result of adding 7, but that will be true unless sq was -7, which is probably impossible from the context (a loop that starts at 0 and only increments from there).
2The gaps here are inferred from the test in the line of code -- those indexes with bit 3 set (for which sq & 8 will be true) are not valid board spaces, but are instead "gaps" between the rows. They might be used for something else, elsewhere in the code
Ok, thank you all! I've looked at it and it now works as expected. Thanks!
Related
I'm trying to change the number of items in array, over which a for loop is running, during the for loop, with the objective that this changes the number of loops. In a very simplified version, the code would look something like this:
var loopArray: [Int] = []
loopArray.append(1)
loopArray.append(2)
loopArray.append(3)
loopArray.append(4)
loopArray.append(5)
for x in 0..<Int(loopArray.count) {
print(x)
if x == 4 {
loopArray.append(6)
}
}
When running this code, 5 numbers are printed, and while the number 6 is added to the Array, the loopArray.count does not seem to update. How can I make the .count dynamic?
This is a very simplified example, in the project I'm working on, appending numbers to the array depends on conditions that may or may not be met.
I have looked for examples online, but have not been able to find any similar cases. Any help or guidance is much appreciated.
sfung3 gives the correct way to do what you want, but I think there needs to be a bit of explanation as to why your solution doesn't work
The line
for x in 0..<Int(loopArray.count)
only evaluates loopArray.count once, the first time it is hit. This is because of the way for works. Conceptually a for loop iterates through the elements of a sequence. The syntax is something like
for x in s
where
s is a sequence, give it type S
x is a let constant (you can also make it a var but that is not relevant to the current discussion) with type S.Element
So the bit after the in is a sequence - any sequence. There's nothing special about the use of ..< here, it's just a convenient way to construct a sequence of consecutive integers. In fact, it constructs a Range (btw, you don't need the cast to Int, Array.count is already an Int).
The range is only constructed when you first hit the loop and it's effectively a constant because Range is a value type.
If you don't want to use Joakim's answer, you could create your own reference type (class) that conforms to Sequence and whose elements are Int and update the upper bound each time through the loop, but that seems like a lot of work to avoid a while loop.
you can use a while loop instead of a for loop.
var i = 0
while i < loopArray.count {
print(i)
if i == 4 {
loopArray.append(6)
}
i += 1
}
which prints
0 1 2 3 4 5
Image of problem
They lost me at the part where " = -1"
This is my understanding of the solution(so far).
They took the arr variable and scanned for elements that have a remainder of 1 when divided by 2. The = -1 part is where I'm confused.
What are the steps going on in here to replace those odd numbers as
negative 1?
Could someone explain in more depth how "arr[arr % 2 == 1]"
works? I think I have a very simple understanding of it.
Also, what is this particular technique called?
EDIT:
So I tried the solution they gave and it doesn't even run...Not sure if I did something wrong on my end.
Original site link: Source
Just like anything else you're trying to understand, take it step by step. Try printing out each of these intermediate expressions:
arr is a numpy array. This is important, because all of these steps depend on special numpy features - they wouldn't work on an ordinary list.
arr % 2 is an array of the same size, containing the parity of each of the original numbers - 0 for even, 1 for odd.
arr % 2 == 1 turns that into an array of booleans - False for even, True for odd.
arr[arr % 2 == 1] invokes numpy's special boolean indexing feature - it gives you a view of a (possibly discontiguous) subset of the array, wherever the index value was True. In this case, the view contains only the odd numbers of the original array.
arr[arr % 2 == 1] = -1 assigns the same value to each element in the view, overwriting all of the original odd numbers.
A key numpy concept used in all of the steps is "broadcasting" - basically, whenever an operation is attempted between an array and a single element, the single element is effectively replicated to match the size of the array. So, in arr % 2, the 2 notionally becomes an array of 2s, the same size as arr.
I'm doing a load test for a sign in page where the user needs to input 2 characters of their password.
I've created an array of characters to say 'password1'.
Using correlation parameters I'm able to get the character number required. What I'm now trying to do is get the character number and match the array i.e. -
Character 1 is required, it will scan the array and bring back char[0].
Character 2 is required, it will scan the array and bring back char[1] etc.
I was thinking of doing a for loop to go through the array and determine where in the array a character is stored. I can't think how to initiate this for loop:
char1 = (char1-1);
char2 = (char2-1);
for(i=0;i<10;i++){
lr_output_message("%s",p[i]);
if (p[i] == p[char1]){
char1 = p[i];
}
}
The for loop works but it equals 115 (s in ASCII), I need a way of converting the value to a character, but I keep getting memory violations.
Sorry if I've over-complicated this issue, but my head has been lost trying to think about how to solve a seemingly easy problem. No doubt some of you will look at it a different way and tell me I've over-complicated it a significant amount!
Closed - worked it out.
Using these buffers instead of for loop.
buf[0] = char1a;
buf[1] = ‘\0’;
buf2[0] = char2a;
buf2[1] = ‘\0’;
How can I run a loop in c for a very large count in c for eg. 2^1000 times?
Also, using two loops that run a and b no. of times, we get a resultant block that runs a*b no. of times. Is there any smart method for running a loop a^b times?
You could loop recursively, e.g.
void loop( unsigned a, unsigned b ) {
unsigned int i;
if ( b == 0 ) {
printf( "." );
} else {
for ( i = 0; i < a; ++i ) {
loop( a, b - 1 );
}
}
}
...will print a^b . characters.
While I cannot answer your first question, (although look into libgmp, this might help you work with large numbers), a way to perform an action a^b times woul be using recursion.
function (a,b) {
if (b == 0) return;
while (i < a) {
function(a,b-1);
}
}
This will perform the loop a times for each step until b equals 0.
Regarding your answer to one of the comments: But if I have two lines of input and 2^n lines of trash between them, how do I skip past them? Can you tell me a real life scenario where you will see 2^1000 lines of trash that you have to monitor?
For a more reasonable (smaller) number of inputs, you may be able to solve what sounds to be your real need (i.e. handle only relevant lines of input), not by iterating an index, but rather by simply checking each line for the relevant component as it is processed in a while loop...
pseudo code:
BOOL criteriaMet = FALSE;
while(1)
{
while(!criteriaMet)
{
//test next line of input
//if criteria met, set criteriaMet = TRUE;
//if criteria met, handle line of input
//if EOF or similar, break out of loops
}
//criteria met, handle it here and continue
criteriaMet = FALSE;//reset for more searching...
}
Use a b-sized array i[] where each cell hold values from 0 to a-1. For example - for 2^3 use a 3-sized array of booleans.
On each iteration. Increment i[0]. If a==i[0], set i[0] to 0 and increment i[1]. If 0==i[1], set i[1] to 0 and increment i[2], and so on until you increment a cell without reaching a. This can easily be done in a loop:
for(int j=0;j<b;++j){
++i[j];
if(i[j]<a){
break;
}
}
After a iterations, i[0] will return to zero. After a^2 iterations, i[0],i[1] will both be zero. AFter a^b iterations, all cells will be 0 and you can exit the loop. You don't need to check the array each time - the moment you reset i[b-1] you know the all the array is back to zero.
Your question doesn't make sense. Even when your loop is empty you'd be hard pressed to do more than 2^32 iterations per second. Even in this best case scenario, processing 2^64 loop iterations which you can do with a simple uint64_t variable would take 136 years. This is when the loop does absolutely nothing.
Same thing goes for skipping lines as you later explained in the comments. Skipping or counting lines in text is a matter of counting newlines. In 2006 it was estimated that the world had around 10*2^64 bytes of storage. If we assume that all the data in the world is text (it isn't) and the average line is 10 characters including newline (it probably isn't), you'd still fit the count of numbers of lines in all the data in the world in one uint64_t. This processing would of course still take at least 136 years even if the cache of your cpu was fed straight from 4 10Gbps network interfaces (since it's inconceivable that your machine could have that much disk).
In other words, whatever problem you think you're solving is not a problem of looping more than a normal uint64_t in C can handle. The n in your 2^n can't reasonably be more than 50-55 on any hardware your code can be expected to run on.
So to answer your question: if looping a uint64_t is not enough for you, your best option is to wait at least 30 years until Moore's law has caught up with your problem and solve the problem then. It will go faster than trying to start running the program now. I'm sure we'll have a uint128_t at that time.
So I have a for loop which goes like this:
for(span=N>>1;span;span>>=1)
I am assuming the start and end conditions are equivalent to as follows:
span = N>>1; //right shift N by 1 and initialize to span
while(span!=0)
{
span = span >> 1;
}
However it seems a little bizarre in the context of my code. Thanks in advance!
In every iteration you are dividing the variable span by 2 until it reaches 0.
so if initially N = 8, then values for span will be 4, 2, 1, 0 -> exit loop
That is correct.
The initializer sets span = N >> 1, right-shifting N by 1.
The loop condition is span, which is equivalent to span != 0.
Every time the loop comes around, span is right-shifted again by 1.
In the context of positive integers, this is equivalent to for(span=N/2;span>0;span/=2). However, without knowing your particular context I cannot comment whether this is or is not bizarre.
Short and sweet...Yes as far as you have shown the code, your interpretation stands firm and good.