Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8338177
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 9, 20262026-06-09T04:30:38+00:00 2026-06-09T04:30:38+00:00

I was working on Project Euler #22 , and got my solution in about

  • 0

I was working on Project Euler #22, and got my solution in about 9.6ms. Here’s what I have:

#import <Foundation/Foundation.h>

NSUInteger valueOfName(NSString *name) {
    NSUInteger sum = 0;
    for (int i = 0; i < [name length]; i++) {
        unichar character = [name characterAtIndex:i];
        sum += (character - 64);
    }
    return sum;
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        CFAbsoluteTime currentTime = CFAbsoluteTimeGetCurrent();
        NSMutableString *names = [NSMutableString stringWithContentsOfFile:[@"~/Documents/Developer/Project Euler/Problem22/names.txt" stringByExpandingTildeInPath] encoding:NSASCIIStringEncoding error:nil];
        CFAbsoluteTime diskIOTime = CFAbsoluteTimeGetCurrent();
        [names replaceOccurrencesOfString:@"\"" withString:@"" options:NSLiteralSearch range:NSMakeRange(0, [names length])];
        NSArray *namesArray = [names componentsSeparatedByString:@","];
        namesArray = [namesArray sortedArrayUsingSelector:@selector(compare:)];
        // Marker 1
            int totalScore = 0;
        for (int i = 0; i < [namesArray count]; i++) {
            NSString *name = namesArray[i];
            NSUInteger sum = valueOfName(name);
            NSUInteger position = i + 1;
            totalScore += (sum * position);
        }
        // Marker 2
        CFAbsoluteTime endTime = CFAbsoluteTimeGetCurrent();
        double timeDiff = (endTime - currentTime) * 1000;
        printf("Total score: %d\n", totalScore);
        printf("Disk IO Time: %fms\tTime: %fms\n", ((diskIOTime - currentTime) * 1000), timeDiff);
    }
    return 0;
}

It’s a good time, but I started thinking about how I could make it faster by using multiple threads. With a quad-core CPU, theoretically I should be able to process a quarter of the names on separate threads and then get the total from there. Here’s what I tried (replacing the code between the markers above):

__block int totalScore = 0;
        int quarterArray = [namesArray count] /4 ;
        typedef void(^WordScoreBlock)(void);
        WordScoreBlock block1 = ^{
            for (int i = 0; i < quarterArray; i++) {
                NSString *name = namesArray[i];
                NSUInteger sum = valueOfName(name);
                NSUInteger position = i + 1;
                totalScore += (sum * position);
            }
            printf("Total score block 1: %d\n", totalScore);
        };
        WordScoreBlock block2 = ^{
            for (int i = quarterArray; i < (quarterArray * 2); i++) {
                NSString *name = namesArray[i];
                NSUInteger sum = valueOfName(name);
                NSUInteger position = i + 1;
                totalScore += (sum * position);
            }
        };
        WordScoreBlock block3 = ^{
            for (int i = (quarterArray * 2); i < (quarterArray * 3); i++) {
                NSString *name = namesArray[i];
                NSUInteger sum = valueOfName(name);
                NSUInteger position = i + 1;
                totalScore += (sum * position);
            }
        };
        WordScoreBlock block4 = ^{
            for (int i = (quarterArray * 3); i < [namesArray count]; i++) {
                NSString *name = namesArray[i];
                NSUInteger sum = valueOfName(name);
                NSUInteger position = i + 1;
                totalScore += (sum * position);
            }
        };
        dispatch_queue_t processQueue = dispatch_queue_create("Euler22", NULL);
        dispatch_async(processQueue, block1);
        dispatch_async(processQueue, block2);
        dispatch_async(processQueue, block3);
        dispatch_async(processQueue, block4);

However, I’m getting a result of 0, but my times are about a millisecond quicker.

  • Is this multi-threaded approach possible?
  • If so, how would I implement it?
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-09T04:30:39+00:00Added an answer on June 9, 2026 at 4:30 am

    Do you really want loading the file as part of the timing?

    Also, if you want to do them concurrently, you need to use a concurrent queue. You are creating a serial queue, so all the blocks will execute one after the other.

    // Create a concurrent queue
    dispatch_queue_t processQueue = dispatch_queue_create("Euler22", DISPATCH_QUEUE_CONCURRENT);
    

    Or, you can call *dispatch_get_global_queue*, and ask for a concurrent queue.

    Now, when you add tasks, GCD will farm them out to available worker threads.

    Now that the tasks are farmed out, you need to wait for them to complete. This can be accomplished in several ways. If you are using multiple queues, dispatch groups are probably the best approach.

    With the same queue though, after all your *dispatch_sync*() calls, you can place a barrier block that will wait until all the previous blocks have completed, and then run…

    dispatch_barrier_async(processQueue, ^{
        // We know that all previously enqueued blocks have finished, even if running
        // concurrently.  So, we can process the final results of those computations.
    });
    

    However, in this case, we are using one queue (though being concurrent, it will execute multiple tasks at the same time… though it pulls the off the queue in the order they were enqueued).

    Probably the easiest thing is to use *dispatch_apply*, because it is designed for this exact purpose. You call the same block multiple times, passing in an index. The block gets the index, and you can use that to partition your data array.

    EDIT

    OK, an attempt at using apply on your specific problem (using your block code as example… I assume it does what you want). Note, I just typed it in (no syntax highlighting here either), so you may need to play with it a bit to get it to compile… but it should give you the general idea).

    // You need to separate both source and destination data.
    size_t const numChunks = 4; // number of concurrent chunks to execute
    __block int scores[numChunks];
    size_t dataLen = [namesArray count];
    size_t chunkSize = dataLen / numChunks; // amount of data to process in each chunk
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
    dispatch_apply(numChunks, queue, ^(size_t index) {
        // GCD will schedule these tasks concurrently as best as possible.
        // You know the current iteration index from the parameter.
        size_t beginIndex = index * chunkSize; // beginning of chunk
        size_t endIndex = beginIndex + chunkSize; // one past end of chunk
        if (endIndex > dataLen) endIndex = dataLen;
        int score = 0;
        for (size_t i = beginIndex; i < endIndex; ++i) {
            NSString *name = namesArray[i];
            NSUInteger sum = valueOfName(name);
            NSUInteger position = i + 1;
            score += (sum * position);
        }
        scores[index] = score;
    });
    
    // Since dispatch_apply waits for all bucks to complete, by the time you
    // get here you know that all the blocks are done.  If your result is just
    // a sum of all the individual answers, sum them up now.
    int totalScore = 0;
    for (size_t i = 0; i < numChunks; ++i) {
        totalScore += scores[i];
    }
    

    Hopefully, that makes sense. Let me know if you get it working.

    Now, if you ever get into a situation where you really need math performance, you should look into the Accelerate framework. One word. Awesome.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm working on Project Euler Problem 14. Here's my solution. import Data.List collatzLength ::
I'm working on Project Euler #14 in C and have figured out the basic
I'm currently working on a project Euler problem (www.projecteuler.net) for fun but have hit
Possible Duplicate: Project Euler, Problem 10 java solution not working So, I'm attempting to
I'm very new to Scala! However, I have the following working solution to Euler
You may have heard of a website called Project Euler (projecteuler.net). I'm working through
I've started working on some Project Euler problems, and have solved number 4 with
I'm have been working on solving Project Euler #14 for a while now in
I am currently working on Project Euler for fun, and use Haskell for practicing.
Working on the problems on Project Euler to try to learn Clojure. I'm on

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.