[google面试题]新研发的64种医药里有1种是致命毒药(64选1)

此题来至吴军的《信息论》

新研发的[0-63]号新药,64种新药里有一个序号的药会致命,无毒的药混吃没事,只要吃了致命毒药一天内必死,现在只剩一天时间。

要求:最少用多少只小鼠测试出致命毒药的序号。理解为最小成本的 64选1。

分析:信息量为 log64 ( 2^6 = 64) 最少用到 6 bit (6只小鼠)。

代码思路:

每个新药的序号都用二进制表示,不足6位的用0左补齐6位。

            进制对照

十进制二进制
0号000000
1号000001
............
62号111110
63号111111

 

 

 

 

 

 

64种新药用数据结构来表示

'0':  药序号

binaryList: [......] 药序号的二进制数组

flag:  true 布尔值(只有一个毒药是 false)

{  
  '0': { binaryList: [ '0', '0', '0', '0', '0', '0' ], flag: true },
  '1': { binaryList: [ '0', '0', '0', '0', '0', '1' ], flag: true },
  '2': { binaryList: [ '0', '0', '0', '0', '1', '0' ], flag: true },
......
  '38': { binaryList: [ '1', '0', '0', '1', '1', '0' ], flag: false },
......
  '59': { binaryList: [ '1', '1', '1', '0', '1', '1' ], flag: true },
  '60': { binaryList: [ '1', '1', '1', '1', '0', '0' ], flag: true },
  '61': { binaryList: [ '1', '1', '1', '1', '0', '1' ], flag: true }
}

6只小鼠初始数据状态用 mouseStatus:  [ '0', '0', '0', '0', '0', '0' ] 来表示。

mouseStatus 与 binaryList, 6 列 竖着对应起来。

3号:binaryList: [ '0', '0', '0', '0', '1', '1' ]

4号:binaryList: [ '0', '0', '0', '1', '0', '0' ]

鼠: mouseStatus :  [ '0', '0', '0', '0', '0', '0' ]

从索引 0 开始   binaryList[0] 值为 0 时不吃该序号的药,为 1 就吃药。

吃了药时判断该序号的 flag 是否为 false(毒药),将小鼠的状态值 0 改为 1 表示该小鼠挂了。

最后小鼠的状态值(0为活,1为挂)转换为十进制得到毒药序号。

下面是 js 实现的 64选1

// 范围内随机数
const randomRange = (max, min = 0) => (
  ~~(Math.random() * (max - min) + min)
)

// 补足长度位
String.prototype.fillLeft = function (n, fill = 0) {
  let str = this.toString()
  if (str.length >= n) return str
  return (Array(n - str.length + 1).join(fill) + str)
}

// 新药的序号生成二进制
const medicamentGroup = (num) => {
  let medicamentObj = {}
    , numBinaryLength = (num - 1).toString(2).length
  ;

  for (let i = 0; i < num; i++) {
    medicamentObj[i] = {
      binaryList: (i).toString(2).fillLeft(numBinaryLength).split(''),
      flag: true
    }
  }

  return {medicamentObj, numBinaryLength}
}

// 测试新药
const makeDrugTest = (num) => {
  let {medicamentObj, numBinaryLength} = medicamentGroup(num)
    , mouseStatus = Array(numBinaryLength).fill(0)
    , drug = randomRange(num)
  ;

  // 打印出随机毒药序号
  medicamentObj[drug]['flag'] = false
  console.log(`drug: ${drug}`);

  for (let index in mouseStatus) {
    for (let item in medicamentObj) {
      let medicament = medicamentObj[item]
        , binaryList = medicament.binaryList
      ;
      // 模拟 0 不吃药,1 吃药
      if (parseInt(binaryList[index])) {
        // 吃到毒药 小鼠挂了,状态改为 1
        medicament.flag || (mouseStatus[index] = 1)
      }
    }
  }

  let drugTest = mouseStatus.join('')
  // 二进制转十进制
  return parseInt(drugTest, 2);
}


let num = 64
console.log(
  makeDrugTest(num)
);

 

毒药的序号是随机的结果也是随机数,大家复制代码测试看结果。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值