今日は、radix sortっぽく動くiPhoneアプリのサンプルコードを描いてみます。
#import “ViewController.h”
@interface ViewController ()
@property (nonatomic, strong) NSMutableArray *cards;
@property int state;
@property int timeCounter;
@property (nonatomic, copy) NSNumber* (^simpleBlock)(id);
@property (nonatomic, weak) UIView *marker;
@end
@implementation ViewController
– (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor greenColor];
[self createTitle];
[self createCards];
[self createButton];
}
– (void)createTitle
{
UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(0, 20, 320, 60)];
title.text = @”radix sort?”;
title.textAlignment = NSTextAlignmentCenter;
title.font = [UIFont boldSystemFontOfSize:40];
title.textColor = [[UIColor whiteColor] colorWithAlphaComponent:0.7];
[self.view addSubview:title];
CALayer *line = [CALayer layer];
line.frame = CGRectMake(0, CGRectGetMaxY(title.frame), 320, 10);
line.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.8].CGColor;
[self.view.layer addSublayer:line];
}
– (void)createCards
{
self.cards = [NSMutableArray array];
for (int i=0; i<9; i++) {
UIView *card = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 30)];
card.tag = i + 1;
card.center = CGPointMake(160, i * 35 + 120);
card.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.9];
[self.view addSubview:card];
for (int j=0; j<3; j++) {
UILabel *number = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 20, 30)];
number.tag = j + 10; // i != j
number.text = [NSString stringWithFormat:@”%d”, (arc4random() % 8) + 1];
number.center = CGPointMake(j * 10 + 20, 15);
number.font = [UIFont boldSystemFontOfSize:18];
[card addSubview:number];
}
[self.cards addObject:card];
}
}
– (void)createButton
{
CALayer *line = [CALayer layer];
line.frame = CGRectMake(0, 470, 320, 10);
line.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.8].CGColor;
[self.view.layer addSublayer:line];
UIButton *sortButton = [UIButton buttonWithType:UIButtonTypeSystem];
[sortButton setTitle:@”sort” forState:UIControlStateNormal];
[sortButton setTitleColor:[[UIColor whiteColor] colorWithAlphaComponent:0.8] forState:UIControlStateNormal];
sortButton.titleLabel.font = [UIFont boldSystemFontOfSize:40];
[sortButton sizeToFit];
sortButton.center = CGPointMake(160, 520);
[sortButton addTarget:self action:@selector(sort) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:sortButton];
}
– (void)sort
{
if (!self.marker) {
UIView *marker = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 320)];
marker.backgroundColor = [[UIColor yellowColor] colorWithAlphaComponent:0.6];
[self.view addSubview:marker];
marker.center = CGPointMake(200, 260);
self.marker = marker;
}
CGPoint mp = self.marker.center;
int tag = 0;
if (self.state == 0) {
// sort one
tag = 12;
mp = CGPointMake(170, 260);
} else if (self.state == 1) {
// sort ten
tag = 11;
mp = CGPointMake(160, 260);
} else {
// sort hundred
tag = 10;
mp = CGPointMake(150, 260);
}
[UIView animateWithDuration:0.5 animations:^{
self.marker.center = mp;
}];
self.simpleBlock = ^(id card) {
if ([card isKindOfClass:[UIView class]]) {
return @(((UILabel *)[card viewWithTag:tag]).text.intValue);
}
return (NSNumber *)card;
};
[self mergeSort:self.cards indexP:0 indexR:(int)self.cards.count – 1];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[UIView animateWithDuration:0.2 animations:^{
int idx = 0;
for (UIView *v in self.cards) {
v.center = CGPointMake(v.center.x, idx * 35 + 120);
idx++;
}
}];
});
self.state++;
}
– (void)mergeSort:(NSMutableArray *)a indexP:(int)p indexR:(int)r
{
if (p < r) {
int q = (p + r) / 2;
[self mergeSort:a indexP:p indexR:q];
[self mergeSort:a indexP:q+1 indexR:r];
[self mergeSort:a indexP:p indexQ:q indexR:r];
}
}
– (void)mergeSort:(NSMutableArray *)a indexP:(int)p indexQ:(int)q indexR:(int)r
{
int n1 = q – p + 1;
int n2 = r – q;
NSMutableArray *L = [[a subarrayWithRange:NSMakeRange(p, n1)] mutableCopy];
NSMutableArray *R = [[a subarrayWithRange:NSMakeRange(q+1, n2)] mutableCopy];
[L addObject:@(HUGE_VAL)];
[R addObject:@(HUGE_VAL)];
int i=0;
int j=0;
for (int k=p; k<=r; k++) {
NSNumber *ln = self.simpleBlock(L[i]);
NSNumber *rn = self.simpleBlock(R[j]);
if ([ln doubleValue] <= [rn doubleValue]) {
a[k] = L[i];
i++;
} else {
a[k] = R[j];
j++;
}
self.timeCounter++;
}
}
– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end