- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
8
Admin
Select 8 from comments
Admin
Seems to me the 4,000 Records solution is exactly the correct one is most circumstances - it minimises effort, retesting and chance of any unintended consequences.
If this was in a production application, The only circumstances under which I would normally let one of my developers spend time rewriting this module to do dynamic allocation would be if (a) if I thought the amount of data would was likely grow to 10 times its current value within the lifetime of the application (and even then I would be tempted to just increase the size of the array further, or (b) the allocation of 40000 records used an excessive amount of memory.
Admin
It's funny cause there's no while loop in that last one.
Admin
Because it takes so much time to change struct foo foo[4000]; to struct foo *foo = malloc(sizeof(foo) * count);
Admin
Hmm no, it's recursive. I don't know C(++?) but it actually seems to work.
Admin
Re 8's - nobody reads reports.
At my first job, some secretary pestered me to write a longer status report than the 2 lines I had written. I appended several relevant source listings and a very large hex core-dump to my status report. It got included up the chain until 3 weeks later somebody finally noticed that the status report took too long to open in mail, scanned through it and found out why. For the next 5 years, I never had to write another status report :)
Admin
Should be 'return binsearch(...)'
but nevertheless hardly a WTF
Admin
Can't agree with you there.
If the application were to be replaced, strictly non-critical, not security-sensitive, used by technical users, and poorly-coded, I might be tempted then to simply increase the size of the array. But only then. It is not the correct solution.
Admin
The real WTF is that the char arrays are not const.
Admin
Admin
Admin
The real WTF is they store numbers using char[] array.
Admin
Admin
The recursion isn't much use without checking the returned result.
Admin
➈
Admin
Since the function 'falls of the bottom' without returning a value, the return value will be the value that happens to be in the correct register. This will be the value from the inner call - so will be correct!
The compiler will also, alomost certainly, use 'tail recursion' - converting the code into a loop.
Admin
Problems with the binary search function:
1, 3, 4 and 5 indicate to me that this was originally implemented as an iterative function, then made recursive. Why, I can't fathom.
Admin
The binary search code is messy, but I think it does work. The only real error is omitting the return statement. This is undefined behaviour, but apparently their compiler generates code that happens to return false at the end of the function.
Then we have:
So while I agree this is sloppy coding, none of it makes me scream out WTF?!
Admin
The algorithm on the binary search is essentially correct. The implementation is buggy and the recursiveness suboptimal, unless you are SURE it will optimize the tail recursion.
I worry, though, about the atoi(). An IMSI has 15 digits, so the chances of an integer being enough aren't very good.
Admin
If IMSI is what I think it is (international mobile subscriber identity), the immense likelihood is that it's stored internally as BCD. Therefore storing it as a char[] rather than int isn't such a WTF.
Admin
TRWTF is that the 4000 record program crashed when it reached 4001 records. Unless of course "crash" is new shorthand for aborting execution with an error message like "Unrecoverable error: Found 4001 records in results. Only expected a maximum of 4000 records."
Admin
well the binsearch function can be wright or wrong, coding such a basic algorithm shows blatant ignorance of common libraries. This is typically a beginner's mistake...
Admin
I work at a telecom company, and at least here, its common practice to store numbers like an IMSI, MSISDN, etc as plaintext in strings because it makes working with it much easier than having to deal with BCD all the time. The only time you really need it in BCD is when sending it in MAP messages.
Admin
For some reason, people seem to prefer to solve things recursively even when that is a ridiculously bad approach.
Consider this problem:
George bought a sack of 100 pieces of candy at the store. 90 of the pieces are lemon flavored and ten are cherry flavored. Of the two, George prefers the lemon flavored candies.
Every day George randomly picks a piece of candy out of the bag. If it is lemon flavored, he eats it and puts the bag away for the next day.
But if the candy he chose is cherry flavored, he puts it back in the bag and then randomly picks a candy out of the bag and eats it regardless of the flavor. In other words, he'll only put a piece of candy back at most once per day.
What are the odds that when one piece of candy remains, it will be lemon flavored?
I posed the problem at a company where I used to work. All but one person tried to do it recursively. The remaining person tried to do it using an Excel spreadsheet!!!
Admin
There is nothing wrong with that function as far as I can tell. The real WTF here is why people keep submitting good code that is above their heads?
The only thing I would be concerned about is: atof(imsi) > atof(sr[test])
But the data set/validation might make it logical to do.
As far as the "it fails to check return values" goes; there really is no need. false can only be hit on the first iteration and true is set by the last iteration of the function before the self recursive function ends.
I doubt the recursive function is executing enough to cause stack overflow issues on a 32 bit system but that might be something to watch out for if you increase the dataset size.
Admin
This assumes that you have "foo" beforehand. Not true if you're reading from a file or a socket.
Admin
They all set up an e-mail filter to delete the report.
Admin
New word of the day: "segmentaiton", noun, definition: victim of Hooked on Phonics and/or dyslexia.
Admin
Don't get it. I mean a spreadsheet seems a sensible approach (ok, ignoring issues about rounding etc.) Have a row for each number of remaining candies, and a cell in each row for the number of cherries (so up to 11 cells per row for 0 to 10). The entry is the probability of that combination occurring when we have got to that number of remaining candies.
I assume the issue is meant to be that people should use their brains to solve it and therefore there is a cute answer. I can't see the solution but I can guess the answer on the following logic.
These kind of puzzles, the answer is always 0, 1/2, or 1. It can't be either 0 or 1, because there is a non-zero chance of picking out lemons until there are none left, or cherries till there are none left.
Therefore the answer is a half.
Actually there's a small chance that the answer is either 1/100 or 99/100, because those numbers come up sometime, but I think 1/2 is more likely.
Admin
AFAIK tail recursion folding isn't typically done by C/C++ compilers (not that it's impossible, but I wouldn't count on it).
Ah, an IMSI is some integer number? They are actually using atof() which parses (double-precision) floating point numbers, which happen to support storing 53-bit integers too, so maybe they use atof() as a kludge to support larger integers (up to at least 15 decimal digits without loss of precision).Admin
Mark left out some essential information: an IMSI is a 15-digit number that identifies a mobile telephone, or at least its SIM card. So yes, you could think of it as a very big number, but in reality it's a string.
The Real WTF is that, instead of using a string comparison, he converted this 15-digit string into a floating point number and compared with that.
And I got the numbers wrong with the '4000' and '40,000': it was actually '900' and '90,000'.
You have no idea what sort of tripe I came along when I had to go through his code. Basically every single violation of good programming practices imaginable was there, and even a few that are unimaginable. It took me a couple of months to remedy the worst excesses.
Admin
Admin
No: for a lemon to be taken out it needs only be picked at random, but for a cherry to be taken out two cherries need to be picked in succession. That'll shift the distribution substantially towards the end.
Admin
And, on top of that, the entire array is passed on the stack. Every recursive call, 20 kilobytes are copied onto the stack. I sincerely hope the compiler is smart enough to optimize out the tail recursion.
Admin
The arrays are passed as a pointer. However the integers are copied.
Admin
Huh, what? C/C++ doesn't even support passing arrays on the stack...
Admin
Had Tim mentioned a smarter answer, he might have had more takers for a static allocation.
Where's the file coming from ? We just hear it's "imported". From where ? What's the input to that file ? Is it something that 3rd party folks can add/manipulate ?
If so, every one of you doinks suggesting full dynamic allocation just introduced a different security vulnerability. With 4000 (and better error checking than a plain crash), potential smash the stack. With dynamic, you introduce other exploitable memory issues. Say the size is -1, malloc fails, and you start writing all over memory. Or the size is 4 billion, same issue.
Admin
The sad bit is that this file read a BER encoded file, looks for some magic numbers (the ASN.1 tags) and stores them into those 900 (or 90,000) records. Then it goes over these records, finds the starting and ending sequence numbers, the start and end date, and how many records were processed. (It actually outputs an SQL query.) None of this information actually requires all these records to be in memory.
Some more code from the same program:
Why use the 'break' statement if C offers a perfectly good 'goto' statement?
Or this:
Apart from stuff like global variables, for each and every record it uses strftime to find the century. And, incidentally, it takes the current date, rather than the date of the input file.
It just goes on and on...
Admin
(Segmentation Fault|Segfault)
bene: 'I have bene here forever' -- Spelling Nazi
Admin
I liked the first WTF.
Admin
Admin
Ok, maybe I've been watching too many of those sort of movies, because when I read "DP" I thought of something about as far removed from statistical analysis as you can get...
Captcha: opto (stop it, it'll make you go blind)
Admin
TRWTF is
is susceptible to signed integer overflow. Not pretty.Admin
Agreed with 0.8181. Done in Excel, by the way. Just a 10x90 grid to brute-force the whole path through the possibility space. In each cell, sum the probability of getting there from the cell directly above, with the probability of getting there from the cell to the left, and it all converges down to an answer at the bottom left.
I'm not sure I can see any greatly simpler solution, so I'd be delighted if the OP could enlighten us on this one.
Admin
You're a manger right? ok, where? I want to make sure I don't send my resume there. I understand the bottom dollar idea, but a buffer overrun only has to "destroy everything" once.
Admin
ugh, typo in the post giving x10 error. Actual figure is 0.08181... as previously given. Sorry.
Admin
But it's easier to read and understand if written recursively and most compilers are smart enough to understand tail recursion and will create a sequence of operations equivalent if not even better to manually done iteration.
Have a look at this http://dl.fefe.de/optimizer-isec.pdf
I totally agree with the rest of your points.
Admin
That is a much better algorithm than a purely recursive one... I believe we call that dynamic programming. With the caveat that dynamic programming is sort of recursive. I too would like to know the trick to solving this one from the OP.
Admin
Oh my, I totally missed the atof(). I was obsessing over the fact that the function never checked return value of its recursive calls and would fall off the end without returning, plus that it had no way I could see of communicating back the index at which it had found a match.