iPhone powmod

k乗をmで割った余りを求めるiPhoneアプリ(C++)のサンプルコードを描いてみます。

#import “ViewController.h”

#include <memory>

using namespace std;

class PowmodCalculator {

public:

    int powmod(int, int, int);

private:

    void notify(int, int, int);

    void notifyAns(int);

};

int PowmodCalculator::powmod(int a, int k, int m) {

    

    notify(a, k, m); // for uiview

    

    if (k == 0)

        return 1;

    

    long t = powmod(a, k / 2, m);

    t = (t * t) % m;

    if (k % 2 == 1)

        t = (t * a) % m;

    notifyAns((int)t);

    

    return (int)t;

}

void PowmodCalculator::notify(int a, int k, int m) {

    [[NSNotificationCenter defaultCenter] postNotificationName:@”my message” object:@[@(a), @(k), @(m)]];

}

void PowmodCalculator::notifyAns(int t) {

    [[NSNotificationCenter defaultCenter] postNotificationName:@”my answer” object:@(t)];

}

@interface ViewController ()

@property (nonatomic) int counter;

@property (nonatomic) int answer;

@property (nonatomic, strong) NSMutableArray *queue;

@property (nonatomic, strong) NSMutableArray *queueAnswer;

@property (nonatomic) uint64_t start;

@property (nonatomic) shared_ptr<PowmodCalculator> cppClass;

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

    self.view.backgroundColor = [UIColor colorWithHue:0.25 saturation:0.5 brightness:0.5 alpha:1];

    

    shared_ptr<PowmodCalculator> cppClass(new PowmodCalculator);

    

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveMessage:) name:@”my message” object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveAnswer:) name:@”my answer” object:nil];

}

– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

    self.answer = self.cppClass->powmod(2, 100000, 345);

}

– (void)receiveMessage:(NSNotification *)notify {

    if (!self.queue) {

        self.queue = [NSMutableArray array];

    }

    [self.queue addObject:notify.object];

    if([notify.object[1] intValue] == 0) {

        [self updateLabel];

    }

}

– (void)receiveAnswer:(NSNotification *)notify {

    if (!self.queueAnswer) {

        self.queueAnswer = [NSMutableArray array];

    }

    [self.queueAnswer addObject:notify.object];

}

– (void)updateLabel {

    

    ++self.counter;

    

    if (self.queue.count == 0) {

        [self updateAnswer];

        return;

    }

    

    NSArray *object = self.queue.firstObject;

    [self.queue removeObjectAtIndex:0];

    

    UIView *bar = [[UIView alloc] initWithFrame:CGRectMake(CGRectGetMidX(self.view.bounds), 800, 300, 30)];

    bar.backgroundColor = [UIColor yellowColor];

    bar.layer.borderWidth = 1;

    bar.layer.borderColor = [UIColor lightGrayColor].CGColor;

    

    UILabel *a = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 50, 30)];

    a.font = [UIFont systemFontOfSize:30];

    a.text = [NSString stringWithFormat:@”%d”, [object[0] intValue]];

    [bar addSubview:a];

    

    UILabel *k = [[UILabel alloc] initWithFrame:CGRectMake(50, 0, 80, 20)];

    k.font = [UIFont systemFontOfSize:20];

    k.text = [NSString stringWithFormat:@”%d”, [object[1] intValue]];

    [bar addSubview:k];

    

    UILabel *m = [[UILabel alloc] initWithFrame:CGRectMake(120, 0, 120, 30)];

    m.font = [UIFont systemFontOfSize:30];

    m.text = [NSString stringWithFormat:@”%% %d”, [object[2] intValue]];

    [bar addSubview:m];

    

    [self.view addSubview:bar];

    [UIView animateWithDuration:0.2 animations:^{

        bar.center = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMaxY(self.view.bounds) – self.counter * 3080);

    }];

    

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

        [self updateLabel];

    });

}

– (void)updateAnswer {

    self.counter;

    if (self.queueAnswer.count == 0) {

        return;

    }

    

    int object = [self.queueAnswer.firstObject intValue];

    [self.queueAnswer removeObjectAtIndex:0];

    

    UILabel *ans = [[UILabel alloc] initWithFrame:CGRectMake(0, –100, 120, 30)];

    ans.font = [UIFont systemFontOfSize:30];

    ans.text = [NSString stringWithFormat:@”= %d”, object];

    [self.view addSubview:ans];

    

    [UIView animateWithDuration:0.2 animations:^{

        ans.center = CGPointMake(320, CGRectGetMaxY(self.view.bounds) – self.counter * 3050);

    }];

    

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

        [self updateAnswer];

    });

    

}

@end