iPhone最大公約数

ユークリッドの互除法で最大公約数を計算するiPhoneアプリのサンプルコードを描いてみます。

動かすとこんな感じです

サンプルコード

#import “ViewController.h”

@interface ViewController () <UITextFieldDelegate>

@property (nonatomic, weak) UITextField *fieldA;

@property (nonatomic, weak) UITextField *fieldB;

@property (nonatomic, weak) UIButton *button;

@end

@implementation ViewController

@synthesize fieldA, fieldB, button;

– (void)viewDidLoad

{

    [super viewDidLoad];

    self.view.backgroundColor = [UIColor orangeColor];

    

    [self createTitle];

    [self createExpression];

    [self createButton];

}

– (void)createTitle

{

    UILabel *title = [[UILabel alloc] init];

    title.text = @”Greatest Common Divisor”;

    title.textColor = [UIColor whiteColor];

    title.font = [UIFont fontWithName:@”Noteworthy-Light” size:28];

    [title sizeToFit];

    title.center = CGPointMake(CGRectGetMidX(self.view.frame), 50);

    [self.view addSubview:title];

}

– (void)createExpression

{

    // Euclidean algorithm

    // b = qa + r

    

    fieldA = [self createTextField];

    fieldA.center = CGPointMake(80, 150);

    

    fieldB = [self createTextField];

    fieldB.center = CGPointMake(240, 150);

}

– (void)createButton

{

    UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];

    btn.frame = CGRectMake(0, 0, 60, 60);

    [btn setTitle:@”?” forState:UIControlStateNormal];

    [btn setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];

    [btn setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];

    btn.titleLabel.font = [UIFont fontWithName:@”Noteworthy-Light” size:28];

    btn.backgroundColor = [UIColor whiteColor];

    btn.center = CGPointMake(270, CGRectGetMaxY(self.view.frame) – 50);

    btn.layer.cornerRadius = 10;

    [self.view addSubview:btn];

    

    [btn addTarget:self action:@selector(calculation) forControlEvents:UIControlEventTouchUpInside];

    

    button = btn;

}

– (UITextField*)createTextField

{

    UITextField *field = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 120, 60)];

    field.textAlignment = NSTextAlignmentCenter;

    field.font = [UIFont fontWithName:@”Noteworthy-Light” size:28];

    field.textColor = [UIColor whiteColor];

    field.keyboardType = UIKeyboardTypeNumberPad;

    field.delegate = self;

    field.layer.borderColor = [UIColor whiteColor].CGColor;

    field.layer.borderWidth = 5;

    

    [self.view addSubview:field];

    return field;

}

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

{

    [[self view] endEditing:YES];

}

– (void)calculation

{

    // clear old label

    NSPredicate *pred = [NSPredicate predicateWithFormat:@”tag == %d”, 1];

    [[self.view.subviews filteredArrayUsingPredicate:pred] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

        [obj removeFromSuperview];

    }];

    

    if (fieldA.text.length && fieldB.text.length) {

        int a = [fieldA.text intValue];

        int b = [fieldB.text intValue];

        [self gcdParamA:a paramB:b row:0];

    }

}

– (void)gcdParamA:(int)a paramB:(int)b row:(int)row

{

    int remainder = a % b;

    int quotient = a / b;

    

    NSArray *words = @[

                      [@(a) stringValue],

                      @”÷”,

                      [@(b) stringValue],

                      @”=”,

                      [@(quotient) stringValue],

                      @”…”,

                      [@(remainder) stringValue]

                      ];

    

    float x = 50;

    for (int i=0; i < words.count; i++) {

        NSString *s = words[i];

        UILabel *label = [[UILabel alloc] init];

        label.tag = 1;

        label.text = s;

        label.textAlignment = NSTextAlignmentCenter;

        label.font = [fieldA.font fontWithSize:18];

        label.textColor = [UIColor whiteColor];

        [label sizeToFit];

        label.center = CGPointMake(x, row * 30 + 220);

        [self.view addSubview:label];

        

        // next position x

        x = x + label.frame.size.width + 10;

        

        // animation

        label.transform = CGAffineTransformMakeTranslation(320, 0);

        [UIView animateWithDuration:0.5 animations:^{

            label.transform = CGAffineTransformIdentity;

        }];

    }

    

    BOOL divisible = (remainder == 0);

    if (!divisible) {

        double delayInSeconds = 0.5;

        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));

        dispatch_after(popTime, dispatch_get_main_queue(), ^(void){

            [self gcdParamA:b paramB:remainder row:row+1];

        });

    } else {

        [UIView animateWithDuration:0.5 animations:^{

            button.layer.transform = CATransform3DMakeRotation(M_PI/2.0, 0, 1, 0);

        } completion:^(BOOL finished) {

            [button setTitle:[@(b) stringValue] forState:UIControlStateNormal];

            [UIView animateWithDuration:0.5 animations:^{

                button.layer.transform = CATransform3DIdentity;

            }];

        }];

    }

}

– (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

{

    NSRegularExpression *numbersOnly = [NSRegularExpression regularExpressionWithPattern:@”[0-9]+” options:NSRegularExpressionCaseInsensitive error:nil];

    

    NSInteger numberOfMatches = [numbersOnly numberOfMatchesInString:string options:0 range:NSMakeRange(0, string.length)];

    

    if (numberOfMatches != 1 && string.length != 0)

        return NO;

    

    if (![button.titleLabel.text isEqualToString:@”?”]) {

        [button setTitle:@”?” forState:UIControlStateNormal];

    }

    

    return YES;

}

@end