Challenge - Finally Complete!


Wow, so I guess go ahead and call me a dunce, but I feel pretty much COMPLETELY unprepared and outclassed by this challenge. I have hit all of the previous ones out of the park, and have felt very confident with everything that I’ve learned from the book up until this point, but this one just totally beat me. It seems like every road I start down turns out to be a dead end. I get the concept of making students have to research some things on their own, but I feel just totally lost, like I am spinning my wheels. I guess I’ll just go copy the guy’s solution from the forum topic for the first edition of the book and then try to understand what he did.

UPDATE: Well, sorry about being so whiny. I actually did finally figure out how to do this thing, and I didn’t use the other guy’s solution. My real problem was that I took a 3 or 4 week break from the book right before diving into chapter 40, and I forgot some of the basics with bitwise & and | operators. Once I remembered how to dereference memory addresses and think in binary again, I eventually came up with the solution. Below is my code for the dataWithSpeakableString method (codeTable is a const char * array declared above the two methods):

[code]+ (NSData *)dataWithSpeakableString:(NSString *)s
error:(NSError *__autoreleasing *)e
if (!s) {
return nil;

NSMutableData *data = [NSMutableData data];
NSArray *dataArray = [s componentsSeparatedByString:@" "];

unsigned char addByte = 0;
for (int i = 0; i < ([dataArray count] - 1); i++) {
    if (!(i % 2)) {
        addByte = addByte | ([dataArray[i] intValue] - 2);
    } else {
        BOOL success = NO;
        for (int j = 0; j < 32; j++) {
            if ([dataArray[i] isEqualToString:[NSString stringWithCString:codeTable[j] encoding:NSUTF8StringEncoding]]) {
                addByte = addByte | (j << 3);
                [data appendBytes:&addByte length:1];
                addByte = 0;
                success = YES;
        if (!success) {
            if (e) {
                NSDictionary *userInfo = @{NSLocalizedDescriptionKey : @"Unable to parse"};
                *e = [NSError errorWithDomain:@"SpeakableBytes" code:1 userInfo];
            return nil;

return [data copy];