I have a program that I'm trying to decode. It is translated to C from another language (whose name is not spoken here), and as I want to understand how it works, I am slowly rewriting the code and simplifying it to use all the nice logical constructs C has to offer.
The following little bit keeps popping up in my code, with varying values of X
and Y
:
ptr[X]--;
while(ptr[X])
{
ptr[X]--;
ptr += Y;
}
ptr
is of type char *
, and I can't really make assumptions about the state of the array at any point because it's pretty deeply embedded in loops and dependent on input and output. I can successfully "simplify" that to:
for(ptr[X]--; ptr[X]; ptr[X]--, ptr += Y);
But that's just awful. Ever so slightly better is:
for(ptr[X]--; ptr[X]; ptr += Y) ptr[X]--;
I want to know if anyone can come up with a better simplification of the above code, I would greatly appreciate it. This occurs in no less than five places, and is impairing my ability to simplify and understand the flow control, so if anyone can provide a more consise/readable version, that would be awesome. If anyone can just offer any sort of fancy insight into that code, that would be awesome too, although I basically understand what it does.
Insight into the code for a specific X
and/or Y
can also help. Y
tends to be between -2 and 2, and X
is usually 1, for what its worth.
I'll throw in:
first evaluate, then decrement (for while condition, that is)
Edit: OK, i'll hate myself in the morning. Goto's are ok at this level, right?
(i honestly dont know whether to leave this or not.)
EDIT2: so, how about this one? (tcc didn't complain)
EDIT 2 1/2;
If all else fails..
EDIT3: Last one for tonight.
ptr[X]
is equivalent to*(ptr + X)
, so we can rewrite it as follows:Now there's a lot of redundancy here, so we can simplify this to:
Then we can get rid of
ptr_plus_x
entirely:In English, we visit the memory locations at offsets X, X+Y, X+2Y, X+3Y, ..., decrementing each memory location, until we find a memory location that is 0. But, the test for 0 always occurs after the decrement, so we're really looking for the first memory location in that sequence with a value of 1. Once we find that, we decrement it to 0 and quit.
If Y is 1, then we decrement a string of consecutive memory locations going forwards, up to and including the first 1. If Y is -1, the same thing happens, but searching backwards from offset X. If Y is 0, an infinite loop occurs. If Y is any other value, the search pattern skips various entries.
It's not a very intuitive function, so I can see why you're confused.
It's quite simple as is, already. Instead of trying to write less statements, I would rather try to grasp the intent and add some comment.
An example of 'a' meaning of the snippet: decrease all elements of a column (X) of a matrix of Y columns. You would need that to draw a vertical line of +'ses, for instance, in a language that has no direct assignment.
You could clarify this meaning by showing the indices directly:
Good luck :)
The website for it-which-shall-not-be-named states:
So it seems like it should be fairly easy to convert it over to C.
EDIT: Here is the Hello World BF converted to C++.