彩票算法,告别穷人税——机选彩票中奖模拟

1,263 阅读4分钟

哎!实在太穷了,面对着房贷车贷,养家养娃,大笔支出,小小前端月入不到2w的工资更本不够花呀!楼主家楼下正好有一家彩票店,所以习惯每期买上十块钱的,机选五注,幻想着万一哪天能中个大奖,就能实现财富自由了。

最近,连着五期连最低将都没有中,感觉有点受打击,想写个小算法模拟一下中奖概率问题。

1.定义红球、蓝球和中奖规则

const redBall=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,
18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33];
const buleBall  = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
const ruler = [{
        //没中奖
        money:0,  //金额
        won:false,  // 是否中一等奖
    },
    {
        money:5, //蓝球中 红球三个以下    5
        won:false,
        ruler:[{  
            red:0,          
            bulue:true
        },{
            red:1,
            bulue:true
        },{
            red:2,
            bulue:true
        }]
    
    },{
        money:10, //蓝球中  ,红球==3 || 红球 ==4    10
        won:false,
        ruler:[{
            red:3,
            bulue:true
        },{
            red:4,
            bulue:false
        }]
   
    },{
        //bulue ==true ,red==4 || red ==5    200
        money:200,
        won:false,
        ruler:[{
            red:4,
            bulue:true
        },{
            red:5,
            bulue:false
        }]
    },{
        //bulue ==true ,red==6     3000
        money:3000,
        won:false,
        ruler:[{
            red:5,
            bulue:true
        }]
    },{
    //red==6    20W  奖金浮动,按照20W计算
    money:200000,
        won:false,
        ruler:[{
            red:6,
            bulue:false
        }]
    },{
        //bulue == true red == 6   500W   奖金浮动 按照500W计算
        money:5000000,
        won:true,
        ruler:[{
            red:6,
            bulue:true
        }] 
    }]

2.生产彩票

通过使用洗牌算法生产一注彩票号码

/**
 * 洗牌算法
 * @param {*} oldarr  数组
 */
function shuffle(oldarr){
     let arr = JSON.parse(JSON.stringify(oldarr))  ;//简单深拷贝,防止影响原数组
    let m = arr.length;
    while(m > 1){
        let index = parseInt(Math.random() * m--);
        [arr[index],arr[m]] = [arr[m],arr[index]];
    }
    return arr;
 }
 /**
 * 生产一注彩票号码
 */
 var caip = function(){
     var obj ={}
     var redArr =shuffle(redBall).slice(0,6) //洗牌后数组前6个
     obj.redBall = redArr.sort((a,b)=>{return a-b});//排序
     obj.buleBall = shuffle(buleBall).slice(0,1)//蓝球
     return obj
 }

3.校验是否中奖

针对一注彩票校验是否中奖,需要知道命中几个红球和蓝球是否命中

 /**
  * 校验一注彩票中奖结果
  * @param {*} item 彩票对象
  * @param {*} caipresult  开奖结果
  */
 var checkOneCaip = function(item,caipresult){
     let arr = getArrEqual(item.redBall,caipresult.redBall);//获取红球命中数
     let bulueRight = getArrEqual(item.buleBall,caipresult.buleBall).length>0;//懒得写了 直接复用红球的方法
     let result=ruler[0]
     switch(arr.length){
         case 0:
         case 1:
         case 2:
             if(bulueRight){
                 result = ruler[1]
             }
             break;
         case 3:
            if(bulueRight){
                result = ruler[2]
            }else{
                result = ruler[1]
            }
            break;
         case 4:
            if(bulueRight){
                result = ruler[3]
            }else{
                result = ruler[2]
            }
            break;
         case 5:
            if(bulueRight){
                result = ruler[4]
            }else{
                result = ruler[3]
            }
            break;
         case 6:
            if(bulueRight){
                result = ruler[6]
            }else{
                result = ruler[5]
            }
            break;
     }
     return result

 }
 /**
  * 数组重复个数算法
  * @param {*} arr1 
  * @param {*} arr2 
  */
 function getArrEqual(arr1, arr2) {
    let newArr = [];
    for (let i = 0; i < arr2.length; i++) {
        for (let j = 0; j < arr1.length; j++) {
            if(arr1[j] === arr2[i]){
                newArr.push(arr1[j]);
            }
        }
    }
    return newArr;
 }

4.统计

/**
  * 机选多注彩票
  * @param {*} index 数量
  */
var getCaips =function(index){    //一期机选彩票
     let arr = []
     for(var i=0;i<index;i++){
         arr.push(caip())
     }
     return arr
 }
 /**
  * 开奖结果
  */
 var getResult =function(){
    return caip()
 }
/**
 * 校验多注彩票
 * @param {*} arr 彩票数组
 * @param {*} result 彩票结果
 */
 var checkCaips = function(arr,result){
     var check={
        totalMoney:0,
        won:false
     }
     arr.forEach((item)=>{
         let itemCheck = checkOneCaip(item,result);
         check.totalMoney = check.totalMoney+ itemCheck.money
         check.won = check.won|| itemCheck.won
         if(check.won){
             console.log(arr,result)
         }
     })
     return check
 }
 /**
  * 日期计算方法
  * @param {*} AddDayCount 日期差值
  */
 function GetDateStr(AddDayCount) {   
     var dd = new Date();  
     dd.setDate(dd.getDate()+AddDayCount);//获取AddDayCount天后的日期  
     var y = dd.getFullYear();   
     var m = (dd.getMonth()+1)<10?"0"+(dd.getMonth()+1):(dd.getMonth()+1);//获取当前月份的日期,不足10补0  
     var d = dd.getDate()<10?"0"+dd.getDate():dd.getDate();//获取当前几号,不足10补0  
     return y+"年"+m+"月"+d+'日';   
 }  
 //调用入口
 let init= function(){
    var check={  //初始值
        userMoney:0,
        totalMoney:0,
        won:false,
        time:0
     }
     var str = '元'
     while(!check.won){ //没有中一等奖就循环
        let arr = getCaips(5);
        let result = getResult()
        let checkresult = checkCaips(arr,result)
        check.won = check.won || checkresult.won;
        check.totalMoney = check.totalMoney+checkresult.totalMoney;
        check.time += 1
        check.userMoney = check.userMoney + 10
        if(check.time%10==0){
            console.log('经过'+check.time+'期,花费'+check.userMoney+str+',累计奖金'+check.totalMoney)
        }
     }
     str = '元中一等奖'
     let days = check.time/3*7
     GetDateStr(days)
     console.log('经过'+check.time+'期,到'+GetDateStr(days)+'花费'+check.userMoney+str+',累计奖金'+check.totalMoney)
 }
 init() 

5.结果

方法写好,开始测试! 。。。。。。。

\color{rgb(255,0,0)}{经过1778260期,到13380年04月08日花费17782600元中一等奖,累计奖金12724590}

卧槽!什么鬼!要到一万年之后才中一等奖!一定是巧合! \color{rgb(255,0,0)}{经过2911433期,到20619年06月29日花费29114330元中一等奖,累计奖金17271415} \color{rgb(255,0,0)}{经过4320797期,到29623年02月21日花费43207970元中一等奖,累计奖金25868090}

一定是机选的错,嗯对,一定是!我固定选5注一定可以。 稍微修改一下

let init= function(){
    var check={
        userMoney:0,
        totalMoney:0,
        won:false,
        time:0
     }
     var str = '元'
     while (!check.won){
        let arr = [ { redBall: [ 2, 8, 9, 16, 20, 31 ], buleBall: [ 9 ] },
        { redBall: [ 4, 8, 11, 12, 28, 29 ], buleBall: [ 8 ] },
        { redBall: [ 8, 12, 15, 17, 19, 24 ], buleBall: [ 13 ] },
        { redBall: [ 1, 4, 18, 21, 27, 30 ], buleBall: [ 15 ] },
        { redBall: [ 1, 6, 15, 19, 23, 28 ], buleBall: [ 10 ] } ]
        let result = getResult()
        let checkresult = checkCaips(arr,result)
        check.won = check.won || checkresult.won;
        check.totalMoney = check.totalMoney+checkresult.totalMoney;
        check.time += 1
        check.userMoney = check.userMoney + 10
        if(check.time%10==0){
            console.log('经过'+check.time+'期,花费'+check.userMoney+str+',累计奖金'+check.totalMoney)
        }
     }
     str = '元中一等奖'
     let days = check.time/3*7
     GetDateStr(days)
     console.log('经过'+check.time+'期,到'+GetDateStr(days)+'花费'+check.userMoney+str+',累计奖金'+check.totalMoney)
    
 }

结果: \color{rgb(255,0,0)}{经过4218251期,到28968年01月12日花费42182510元中一等奖,累计奖金23220925} \color{rgb(255,0,0)}{经过118011期,到2773年11月09日花费1180110元中一等奖,累计奖金5424990} \color{rgb(255,0,0)}{经过4202794期,到28869年04月14日花费42027940元中一等奖,累计奖金25191010}

最快的要700年,可能是巧合。应该要要两万年才对。

嗯 两万年太久,只争朝夕,我再也不幻想能中彩票了!

源码地址:点击访问github

下次想写一下,彩票固守蓝球翻倍购买策略需要多少钱能回本