查看原文
其他

C语言验证6174数学问题

IT服务圈儿 2022-09-10

The following article is from 嵌入式Linux Author 写代码的篮球球痴


作者 l 写代码的篮球球痴

来源 l 本文转载自公众号:嵌入式Linux(ID:Linux-c-world)

有意思的数学问题

任意4位不完全一样的数字,能组合出的最大数字减去能组合出的最小数字,得到一个新的数字(3位数补0),重复以上操作,不超过7个循环,必然得到一个数:6174

这个问题是之前发布的文章,有读者朋友在文章留言提到这个,我觉得比较有意思,就拿出来分享,最近迷上这类有意思的东西,而且是热乎原创的。


输入一个数3256,将他从小到大输出,就是2356

1、我写的代码

刚开始写的第一份代码,有个缺陷,写完后看到另一个读者提交的答案,已经考虑到了这个问题,自我感觉,大神还是挺多的。

我说下我代码里面的几个重点

1、我使用get来获取输入的字符,所以呢,再使用arr[i] - 0x30把ascii码转换成数字,比如字符1转换成数字1,就需要把字符1对应的值0x31减去0x30得到数字1

2、关于冒泡排序,冒泡排序网上有很多讲解,第一个for循环是从0开始到len-1结束的,关键在于第二个for循环,第二个for循环从第一个for循环的值的下一个位置开始到len结束。

关于冒泡排序的思路,我做了一组图示,如附图1

#include "stdio.h"
#include "stdbool.h"
/*判断数组里面是否有一样的数*/
int j(char *arr,int len)
{
 int i,j;
 for(i=0;i<len;i++) 
  arr[i] = arr[i] - 0x30;/*字符转成数字*/
 for(i=0;i<len-1;i++)
  for(j=i+1;j<len;j++)
   if(arr[i] == arr[j])
    return false;
 return true;
}

/*判断是否不足够4位数字*/
int j2(int diff)
{
 if(diff<10){
  diff=diff*1000;
 }else if(diff<100){
  diff = diff*100;
 }else if(diff<1000){
  diff=diff*10;
 }
}

/*升序*/
int m(char *arr,int len) 
{
 int i,j;
 for(i=0;i<len-1;i++)
  for(j=i+1;j<len;j++)/*和之后的位置比较*/
   if( arr[i] < arr[j]){
    arr[i] ^= arr[j];
    arr[j] ^= arr[i];
    arr[i] ^= arr[j];
   } 
}
/*降序*/
int n(char *arr,int len) 
{
 int i,j;
 for(i=0;i<len-1;i++)
  for(j=i+1;j<len;j++)
   if( arr[i] > arr[j]){
    arr[i] ^= arr[j];
    arr[j] ^= arr[i];
    arr[i] ^= arr[j];
   }
 //printf("%d%d%d%d\n",arr[0],arr[1],arr[2],arr[3]); 
}

int main(void)
{
 int dmax,dmin,diff,i;
 char nums[4];
 char max[4];
 char min[4]; 
 
 /*输入4个不同的数字*/
 while(j(nums,4) == false)
 {
  printf("input:");
  gets(nums);
 }
 
    /*7个循环进行判断*/
 for(i=0;i<7;i++)
 {
         /*排序*/
  m(nums,4);
  //printf("%d%d%d%d\n",nums[0],nums[1],nums[2],nums[3]);
  dmax = nums[0]*1000 + nums[1]*100+nums[2]*10+nums[3];
  /*排序*/
         n(nums,4);
  //printf("%d%d%d%d\n",nums[0],nums[1],nums[2],nums[3]);
  dmin = nums[0]*1000 + nums[1]*100+nums[2]*10+nums[3];
  diff = dmax - dmin;
  diff = j2(diff);
  printf("dmax:%d dmin:%d diff:%d\n",dmax,dmin,diff);
  if(diff == 6174){
   printf("find 6174\n");
   break;
  }
  nums[0] = diff/1000;
  nums[1] = diff%1000/100;
  nums[2] = diff%1000%100/10;
  nums[3] = diff%10;
 }
 
 getchar();
 return (0); 

代码输出

input:1234
dmax:4321 dmin:1234 diff:3087
dmax:8730 dmin:378 diff:8352
dmax:8532 dmin:2358 diff:6174
find 6174

基于严谨性,我写了个测试程序来检验我的这段代码,我总是觉得这样的理论不可思议,用一个数字是不可能代表所有的可能性的,所以有了下面的这段代码。

#include "stdio.h"
#include "stdbool.h"
#include "time.h"

/*判断数组里面是否有一样的数*/
int j(char *arr,int len)
{
 int i,j;
 for(i=0;i<len;i++) 
  arr[i] = arr[i] - 0x30;/*字符转成数字*/
 for(i=0;i<len-1;i++)
  for(j=i+1;j<len;j++)
   if(arr[i] == arr[j])
    return false;
 return true;
}

/*判断是否不足够4位数字*/
int j2(int diff)
{
 if(diff<10){
  diff=diff*1000;
 }else if(diff<100){
  diff = diff*100;
 }else if(diff<1000){
  diff=diff*10;
 }
}

/*升序*/
int m(char *arr,int len) 
{
 int i,j;
 for(i=0;i<len-1;i++)
  for(j=i+1;j<len;j++)/*和之后的位置比较*/
   if( arr[i] < arr[j]){
    arr[i] ^= arr[j];
    arr[j] ^= arr[i];
    arr[i] ^= arr[j];
   } 
}
/*降序*/
int n(char *arr,int len) 
{
 int i,j;
 for(i=0;i<len-1;i++)
  for(j=i+1;j<len;j++)
   if( arr[i] > arr[j]){
    arr[i] ^= arr[j];
    arr[j] ^= arr[i];
    arr[i] ^= arr[j];
   }
 //printf("%d%d%d%d\n",arr[0],arr[1],arr[2],arr[3]); 
}

/******************************************************************************
*函数名称:void get_random(char * random)
*函数功能:产生一个各位数不相等的四位随机数
*入口参数:random为返回的随机数
*返 回 值:无
*备 注:先生成一个0-9的整数数组,再随机从中取四个数,每取一个将该位置为-1
*******************************************************************************/

void get_random(char * random)
{
    int i, j[10], k;
    for (i = 0; i < 10; i++){
        j[i] = i;
    }
    for(i = 0; i < 4; i++){
        //生成第i个随机数
        k = (int)rand() % 10;//k为下标
        while (j[k] == -1){
            k = (k + 1) % 10;
        }
        random[i] = '0' + j[k];
        j[k] = -1;
    }
}

int main(void)
{
 int dmax,dmin,diff,i,r,count;
 long t;
 char nums[4],max[4],min[4];

 
 srand((unsigned)time(&t));
 
 for(count = 0;count <10000;count++){
  
  get_random(nums);
  printf("%c%c%c%c\n",nums[0],nums[1],nums[2],nums[3]);
  
  for(i=0;i<7;i++){
   m(nums,4);
   dmax = nums[0]*1000 + nums[1]*100+nums[2]*10+nums[3];
   n(nums,4);
   dmin = nums[0]*1000 + nums[1]*100+nums[2]*10+nums[3];
   diff = dmax - dmin;
   diff = j2(diff);
   if(diff == 6174){
    printf("find 6174 %d\n",count);
    break;
   }
   
   if(i == 6 && diff != 6174)
    goto error;
   
   nums[0] = diff/1000;
   nums[1] = diff%1000/100;
   nums[2] = diff%1000%100/10;
   nums[3] = diff%10;
  }
 }
 getchar();
 return (0);
 error:
  printf("Can't find 6174 %d\n",count);
 getchar();
 return (0); 

我在代码里面测试了 10000 次数据,意思就是我输入10000个不同的数据,来测试是不是结果都是6174,结果确实是这样。

代码输出,因为输出比较多,我只截取了最后的一些

find 6174 9985
9802
find 6174 9986
5908
find 6174 9987
3127
find 6174 9988
9124
find 6174 9989
5027
find 6174 9990
5304
find 6174 9991
7864
find 6174 9992
8213
find 6174 9993
4795
find 6174 9994
0184
find 6174 9995
2410
find 6174 9996
2134
find 6174 9997
5340
find 6174 9998
3294
find 6174 9999

2、有个读友提供的代码

基本思路都差不多,而且里面用到的排序思路都是一样的。

#include <stdio.h>

int getMax(int byte[]){
 int max;

 for(int i=0;i<3;i++){
  for(int j=i+1;j<4;j++){
   if(byte[i]<byte[j]){
    int t=byte[i];
    byte[i] = byte[j];
    byte[j] = t;
   }
  }

 }
 // printf(" sort byte is  %d  %d  %d  %d\n",byte[0],byte[1],byte[2],byte[3]);
 // printf("<<<<<<<<<<<<<<<<<\n"); 
 max = byte[0]*1000+byte[1]*100+byte[2]*10+byte[3];

 return max;
}

int getMin(int byte[]){
 int min;


 for(int i=0;i<3;i++){
  for(int j=i+1;j<4;j++){
   if(byte[i]>byte[j]){
    int t=byte[i];
    byte[i] = byte[j];
    byte[j] = t;
   }
  }

 }
 // printf(" sort byte is  %d  %d  %d  %d\n",byte[0],byte[1],byte[2],byte[3]);
 // printf(">>>>>>>>>>>>>>>>>\n"); 
 min = byte[0]*1000+byte[1]*100+byte[2]*10+byte[3];


 return min; 
}

int main(){
   int a = 0;
   printf("input the num :\n");
 int max;
 int min;
 scanf("%d",&a);

 for(int i=0;i<7;i++){
  printf("the num:%d\n",a);
  if(a<10){
   a=a*1000;
  }
  else if(a<100){
   a = a*100;
  }else if(a<1000){
   a=a*10;
  }
  printf("deal num:%d\n",a);


 int byte[4]={0};

 byte[0]=a/1000;
 byte[1]=a/100%10;
 byte[2] = a/10%10;
 byte[3] = a%10;
 // printf(">>>>>>>>>>>>>>>>>\n"); 

 // printf("byte is  %d  %d  %d  %d\n",byte[0],byte[1],byte[2],byte[3]);

  if(a == 6174){
   printf("bingo!!!\n");
   break;
  }
  max = getMax(byte);
  min = getMin(byte);

  printf("the max:%d\n",max);
  printf("the min:%d\n",min);
  a=max-min;
 }
 return 0;
}

代码运行输出

weiqifa@bsp-ubuntu1804:~/c$ gcc 6174.c && ./a.out
input the num :
1234
the num:1234
deal num:1234
the max:4321
the min:1234
the num:3087
deal num:3087
the max:8730
the min:378
the num:8352
deal num:8352
the max:8532
the min:2358
the num:6174
deal num:6174
bingo!!!
weiqifa@bsp-ubuntu1804:~/c$


附图1













有偿征稿IT服务圈儿正式开启投稿通道,稿费:60~5000元不等,长期有效!!!
点此查看详情


1、如丝般顺滑!4 行代码就能创建一个数据流工具!

2、夜深了,源代码里突然来了一个新朋友!

3、推荐一款IDEA神器!一键查看Java字节码以及其他类信息

4、漫画 | 一台Linux服务器最多能支撑多少个TCP连接?

识别关注我们

了解更多精彩内容

点分享

点点赞

点在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存