iOS 数独 解法

<span style="font-size:12px;">#import "RootVC.h"

@interface RootVC ()

@property (strong, nonatomic) NSMutableArray *array;
@property (strong, nonatomic) NSMutableArray *importantArray;
@property (strong, nonatomic) NSMutableArray *hypothesisArray;
@property (strong, nonatomic) NSMutableArray *oneArray;

@end

@implementation RootVC



- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    _array = [[NSMutableArray alloc]initWithCapacity:0];
    _importantArray = [[NSMutableArray alloc]initWithCapacity:0];
    _hypothesisArray = [[NSMutableArray alloc]initWithCapacity:0];
    _oneArray = [[NSMutableArray alloc]initWithCapacity:0];
    [super viewDidLoad];
    UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(110, 50-12, 2, 240 - 24)];
    imageView.backgroundColor = [UIColor redColor];
    [self.view addSubview:imageView];
    UIImageView *imageView2 = [[UIImageView alloc]initWithFrame:CGRectMake(110+24*3, 50-12, 2, 240 - 24)];
    imageView2.backgroundColor = [UIColor redColor];
    [self.view addSubview:imageView2];
    UIImageView *imageView3 = [[UIImageView alloc]initWithFrame:CGRectMake(50-12, 110, 240 - 24,2 )];
    imageView3.backgroundColor = [UIColor redColor];
    [self.view addSubview:imageView3];
    UIImageView *imageView4 = [[UIImageView alloc]initWithFrame:CGRectMake(50-12, 110+24*3, 240 - 24,2 )];
    imageView4.backgroundColor = [UIColor redColor];
    [self.view addSubview:imageView4];

    NSArray *array = @[@"400000008",@"570032040",@"000009002",@"609000000",@"035807000",@"004050000",@"000000070",@"300040080",@"000000009"];


//    初始化

    for (int i = 0; i<9; i++) {
        NSMutableArray *array_ = [[NSMutableArray alloc]initWithCapacity:0];
        for (int y = 0; y<9; y++) {
            NumberData *data = [[NumberData alloc]init];
            data.x = i;
            data.y = y;
            NSString *sss = array[i];
            NSString *str = [sss substringWithRange:NSMakeRange(y, 1)];
            if (![str isEqualToString:@"0"]) {
                data.sureNumber = str;
            }
            data.label.center = CGPointMake(50+y*24, 50+i*24);
            [self.view addSubview:data.label];
            [array_ addObject:data];
        }
        [_array addObject:array_];
    }

//    根据初始化  开始填数
    int have =[self haveChange:0];
    while (have == 1) {
      have = [self haveChange:0];
    }

//    当已经无法确定填数后,无果不满 则开始猜 然后继续填
    while  (![self isFull]) {

        NumberData *data = [self findtwo];// 如果不满  就 找一个 只有两个的 可能值 加上
        if (data) {
            [_importantArray addObject:data];
            [_hypothesisArray addObject:data];
            NSString *string = [data.canArray substringWithRange:NSMakeRange(0, 1)];
            data.isSure = YES;
            data.sureNumber = string;
            data.hypothesis = string;
            int h =[self haveChange:1];
            int ii = 0;
            while (h) {
                if (h == 2) {
                    ii++;
                    NumberData *data2 = [_importantArray objectAtIndex:[_importantArray count]- 1];
                    NSString *string2 = @"";
                    while  ([data2.sureNumber isEqualToString:[data2.canArray substringWithRange:NSMakeRange(1, 1)]]) {
                        [self removeHy:1];
                        data2 = [_importantArray objectAtIndex:[_importantArray count]- 1];
                    }
                    [self removeHy:0];
                    string2 = [data2.canArray substringWithRange:NSMakeRange(1, 1)];
                    data2.isSure = YES;
                    data2.sureNumber = string2;
                    data2.hypothesis = string2;
                }
                h =[self haveChange:1];
            }
        }
    }
}


// 分为 横,竖和9宫 27个数组来判断时候有可以确定的值。
// 返回0 则表示 以及没有可以确定的值了  如果不满,则需要猜测,
// 返回1 则表示有改变的值,继续判断。
// 返回2 则表示上一个猜测是错误的,换或者退格
-(int)haveChange:(int)sure{
    int have = 0;
//    横向检查
    for (int i = 0; i<9; i++) {
        NSArray *data = _array[i];
        int hhh = [self inspect:data type:sure];
        if (hhh != 0) {
            have = hhh;
        }else{

        }
        if (have == 2 && sure == 1) {
            return 2;
        }
    }

// 纵向检查
    for (int i = 0; i<9; i++) {
        NSMutableArray *array0 = [[NSMutableArray alloc]initWithCapacity:0];
        for (int y = 0; y<9; y++) {
            NumberData *data = _array[y][i];
            [array0 addObject:data];
        }
        int hhh = [self inspect:array0 type:sure];
        if (hhh != 0) {
            have = hhh;
        }
        if (have == 2 && sure == 1) {
            return 2;
        }
    }

// 九宫格检查
    for (int i = 0; i<9; i++) {
        NSMutableArray *array0 = [[NSMutableArray alloc]initWithCapacity:0];
        int h = i/3;
        int w = i%3;
        for (int x = 0; x<3; x++) {
            for (int y = 0; y<3; y++) {
                NumberData *data1 = _array[h*3+x][w*3+y];
                [array0 addObject:data1];
            }
        }
        int hhh = [self inspect:array0 type:sure];
        if (hhh != 0) {
            have = hhh;
        }
        if (have == 2 && sure == 1) {
            return 2;
        }
    }
    return have;
}


//检测 Array中 是否有 可以确定的,have = 0 则没有,have = 1 表示有改变, have = 2 表示有冲突。
-(int)inspect:(NSArray *)array type:(int)type{
    int have = 0;
    NSMutableArray *sureA = [[NSMutableArray alloc]initWithCapacity:0];
    NSMutableArray *noSure = [[NSMutableArray alloc]initWithCapacity:0];
    NSMutableString *string_ = [[NSMutableString alloc]initWithString:@"123456789"];

    for (int i = 0; i<[array count]; i++) {
        NumberData *data = array[i];
        if (data.isSure) {
            NSRange range = [string_ rangeOfString:data.sureNumber];
            if (range.length == 0) {
//  发现sureA成员的sureNumber 有重复的数值 说明有冲突 返回2
                return 2;
            }
            [string_ deleteCharactersInRange:range];
            [sureA addObject:data];
        }else{
            [noSure addObject:data];
        }
    }


/**
 *  第一种判断    每次把从sureA数组里面取出一个 Number 然后把nosure里面的所以成员的可能值 都去掉Number.sureNumber;
         如果某个nosure的可能值 只剩了一个  那么就认定这个nosure成员为sure,sureNumber = canArray;
    并将 这个成员从nosure中移除,加入到sureA中,
 */
    if ([sureA count]&&[noSure count]) {
        for (int i = 0; i<[sureA count]; i++) {
            NumberData *one = [sureA objectAtIndex:i];
            NSString *string = one.sureNumber;
            for (int y = 0; y<[noSure count]; y++) {
                NumberData *two = noSure[y];
                [two deleteStr:string];
                if (two.canArray.length == 1) {
                    have = 1;
                    two.sureNumber = two.canArray;
                    if (type == 1) {
                        [_hypothesisArray addObject:two];
                    }
                    NSRange range = [string_ rangeOfString:two.sureNumber];
                    if (range.length == 0) {// 发现重复,则说明假设有错误,返回2。
                        return 2;
                    }
                    [string_ deleteCharactersInRange:range];
                    [noSure removeObject:two];
                    [self removeArrayString:noSure dataString:two.sureNumber];
                    [sureA addObject:two];
                }
            }
        }
    }
/**
*第二种判断   如果某个数字(如5)所有nosure里面 只有一个 成员的canArray 有这个可能值 那么把这个 成员isSure了
    sureNumber为 这个数字 同时这个成员从nosure中移除,加入到sureA中,
 */
    if ([sureA count]&&[noSure count]) {
        for (int i = 0; i<string_.length; i++) {

            int count = 0;
            int hh = -1;
            NSString *string = [string_ substringWithRange:NSMakeRange(i, 1)];
            for (int x = 0; x<[noSure count]; x++) {
                NumberData *data = noSure[x];
                NSRange haveRange = [data.canArray rangeOfString:string];
                if (haveRange.length != 0) {
                    count++;
                    hh = x;
                }
            }
            if (count == 1) {
                NumberData *data = noSure[hh];
                have = 1;
                data.sureNumber = string;
                if (type == 1) {
                    [_hypothesisArray addObject:data];
                }
                [noSure removeObject:data];
                [sureA addObject:data];
                [self removeArrayString:noSure dataString:data.sureNumber];
            }
        }
    }
    return  have;
}

//判断是否已经填满
-(BOOL)isFull{
    BOOL have = YES;
    for (int i = 0;i<9; i++) {
        for (int h = 0; h<9; h++) {
            NumberData *data = _array[i][h];
            if (!data.isSure) {
                have = NO;
            }
        }
    }
    return have;
}


// 找到一个只有两个可能值的地方
-(NumberData *)findtwo{
    int i = 0;
    int y = 0;
    for (i = 0; i<9; i++) {
        for (y = 0; y<9; y++) {
            NumberData *data = _array[i][y];
            if ((!data.isSure)&&data.canArray.length == 2) {
                return data;
            }
        }
    }
    return nil;
}

//  type = 1的时候  _importantArray最后一个 的两个关键值 都猜测过了,都有矛盾,所以要移除
//  type = 0的时候  _importantArray最后一个 第一个猜测值是错误的,换第二个。 把_hypothesisArray中 根据错误猜测值确定的成员 都变成isSure = no;

-(void)removeHy:(int)type{

    if (type == 1) {
        NumberData *data = _importantArray[[_importantArray count]-1];
        data.sureNumber = @"";
        data.isSure = NO;
        data.canArray = @"123456789";
        [_importantArray removeObject:data];
        return;
    }
    NumberData *data = [_importantArray objectAtIndex:[_importantArray count]-1];
    for (int count = [_hypothesisArray count]-1; count>-1; count--) {
        NumberData *data2 = [_hypothesisArray objectAtIndex:count];
        if (data2 != data) {
            data2.sureNumber = @"";
            data2.isSure = NO;
            data2.canArray = @"123456789";
            [_hypothesisArray removeObject:data2];
        }else{
            break;
        }
    }
    for (int i = 0; i<9; i++) {
        for (int y = 0; y<9; y++) {
            NumberData *data = _array[i][y];
            if (!data.isSure) {
                data.canArray = @"123456789";
            }
        }
    }
}

-(void) removeArrayString:(NSArray  *)noSure dataString:(NSString *)string{
    for ( int i = 0; i<[noSure count]; i++) {
        NumberData *data = [noSure objectAtIndex:i];
        [data deleteStr:string];
    }
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}
@end
</span>

@interface NumberData : NSObject

@property (strong, nonatomic) UILabel *label;
@property (strong, nonatomic) NSString *canArray;
@property (strong, nonatomic) NSString *sureNumber;
@property (nonatomic) BOOL isSure;
@property (nonatomic) int x;
@property (nonatomic) int y;
@property (strong, nonatomic) NSString *hypothesis;
@property (strong, nonatomic) NumberData *hyData;
-(void)deleteStr:(NSString *)string;
@end

@implementation NumberData

-(id)init{
    self = [super init];
    if (self) {
        _x = -1;
        _y = -1;
        _canArray = @"123456789";
        _label = [[UILabel alloc]init];
        _label.frame = CGRectMake(0, 0, 24, 24);
        _label.layer.borderWidth = 0.5;
        _label.textAlignment = NSTextAlignmentCenter;
        _label.font = [UIFont systemFontOfSize:24];
        _label.layer.borderColor = [UIColor blackColor].CGColor;
        _isSure = NO;
        _sureNumber = @"";
    }
    return self;
}

-(void)setSureNumber:(NSString *)sureNumber{

    _sureNumber = sureNumber;
    _label.text = _sureNumber;
    _isSure = YES;
//    _canArray = _sureNumber;
}

-(void)deleteStr:(NSString *)string{

    NSMutableString *str = [[NSMutableString alloc]initWithString:_canArray];
    NSRange range = [str rangeOfString:string];
    if (range.length!= 0) {
        [str deleteCharactersInRange:range];
    }
    _canArray = str;
}

@end





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值