• 【Python】先玩个魔术 ,再讲二进制 - 心灵感应魔法


    哈利波特之心灵感应魔法是一种常见的儿童益智游戏。表演者首先会要求观众在心中默想一个60以内的整数,然后依次将下述卡片1到卡片6出示给观众看,并询问观众他所默想的数字是否在卡片上。在卡片出示的过程中,卡片是背对表演者的,即表演者是看不到卡片的。在听完观众的6个回答之后,表演者即可"猜"出观众默想的数字,仿佛掌握了"读心术"。

    本文引用自作者编写的下述图书; 本文允许以个人学习、教学等目的引用、讲授或转载,但需要注明原作者"海洋饼干叔
    叔";本文不允许以纸质及电子出版为目的进行抄摘或改编。
    1.《Python编程基础及应用》,陈波,刘慧君,高等教育出版社。免费授课视频 Python编程基础及应用
    2.《Python编程基础及应用实验教程》, 陈波,熊心志,张全和,刘慧君,赵恒军,高等教育出版社Python编程基础及应用实验教程
    3. 《简明C及C++语言教程》,陈波,待出版书稿。免费授课视频

    在这里插入图片描述
    表演者显然没有"读心术", 他依赖于观众关于数字在不在卡片上的6个回答来计算答案。解题思路与二进制有关。一个6位的二进制数,其可以表达的最大数字是26 - 1 = 63。所以,任意60以内的整数,都可以用不超过6位的二进制数来表达。比如,41,其二进制值如下图所示:
    在这里插入图片描述
    我们以十进制整数(4321)₁₀来说明表3.3中的位号、位值及位权。位值1、2、3、4从低到高,分别处于位号1(个位)到位号4(千位)。而(4321)₁₀ = 4 ⅹ10³ + 3ⅹ10²+2ⅹ10¹+1ⅹ10⁰,这里的10³为位号4的位权,10⁰为位号1的位权。同理,(41)₁₀=(101001)₂中,位号6处的位值为1,其对应的位权为2⁵=32;位号2处的位值为0,其对应的位权为2¹=2。

    每一个60以内的整数,均可转换成一个6位二进制数。如果对应的二进制数的第1位(最低位)为1,该数包括在卡片1中,同理,二进制第2位为1的数包括在卡片2中,… 二进制第6位为1的数包括在卡片6中。上述数字41,其二进制的第1, 4, 6位为1。读者可以看到,41只出现在卡片1,4,6中,卡片2,3,5里没有41。所以,观众每回答一个按顺序给出的问题,其实就告诉了表演者该数字6位二进制数中的其中一位是0还是1。

    我们用数字58来模拟一下。卡片1,3里没有58,卡片2,4,5,6里有58。所以表演者从观众那里得到的回答从1到6依次是:无,有,无,有,有 ,有。将上述回答换成二进制就是111010。按照对应的位权把0b111010换成十进制就是32+16+8+2 = 58。

    现在我们知道表演者是如何表演的了。他一直在做加法,从0值开始。如果卡片1的回答是有,加1,卡片2的回答是有,加2,卡片3有,加4,… , 卡片6有,加32。最后直接报出和数即可。

    读者可以运行下述程序才模拟执行上述游戏过程:心里先默想一个数,然后运行程序,通过输入y或者n来回答6个问题。看看计算机能否猜出你默想的数,是否跟你有心灵感应。

    #nummagic.py
    card1 = """Card 1:
        1 11 21 31 41 51
        3 13 23 33 43 53
        5 15 25 35 45 55
        7 17 27 37 47 57
        9 19 29 39 49 59"""
    ...
    
    card6 = """Card 6:
       32 37 42 47 52 57
       33 38 43 48 53 58
       34 39 44 49 54 59
       35 40 45 50 55 60
       36 41 46 51 56 *"""
    
    sQuestion = "\nIs your number in this card? y for yes, n for no:"
    b1 = 1 if input(card1+sQuestion).lower().strip() == 'y' else 0
    b2 = 1 if input(card2+sQuestion).lower().strip() == 'y' else 0
    b3 = 1 if input(card3+sQuestion).lower().strip() == 'y' else 0
    b4 = 1 if input(card4+sQuestion).lower().strip() == 'y' else 0
    b5 = 1 if input(card5+sQuestion).lower().strip() == 'y' else 0
    b6 = 1 if input(card6+sQuestion).lower().strip() == 'y' else 0
    
    print("Binary answer:",b6,b5,b4,b3,b2,b1)
    print("The number is:", b6*32 + b5*16 + b4*8 + b3*4 + b2*2 + b1*1)
    
    • 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

    执行结果(输入依次为y,y,y,y,n,y):

    ...
    Card 6:
       32 37 42 47 52 57
       33 38 43 48 53 58
       34 39 44 49 54 59
       35 40 45 50 55 60
       36 41 46 51 56 *
    Is your number in this card? y for yes, n for no:y
    Binary answer: 1 0 1 1 1 1
    The number is: 47
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    代码说明

    • 变量card1-6是6个用"““包裹起来的多行字符串;””"除了用于多行注释外,也可以用于表达一个多行字符串。

    • input().lower().strip()涉及三个函数,input()函数提示操作者输入并返回输入的字符串;该字符串对象的lower()成员函数返回一个新字符串,其为原字符串的小写形式;最后执行lower()函数返回字符串的strip()成员函数,去除其前后空格。

    • b1 = 1 if input(card1+sQuestion).lower().strip() == ‘y’ else 0称之为条件语句,我们将在后续6.2节中正式讨论。如果输入是"y"或者"Y",b1为1,否则为0。

    • b6,b5,b4,b3,b2,b1分别对应数字的6个二进制位,倒数第二行使用print()将数字的二进制形式打印出来。

    • 将每个二进制位乘以对应的位权,然后相加,即得猜测数。

    为了帮助更多的年轻朋友们学好编程,作者在B站上开了两门免费的网课,一门零基础讲Python,一门零基础C和C++一起学,拿走不谢!

    简洁的C及C++
    由编程界擅长教书,教书界特能编程的海洋饼干叔叔打造
    Python编程基础及应用
    由编程界擅长教书,教书界特能编程的海洋饼干叔叔打造

    如果你觉得纸质书看起来更顺手,目前Python有两本,C和C++在出版过程中。

    Python编程基础及应用

    Python编程基础及应用实验教程
    在这里插入图片描述

  • 相关阅读:
    MySQL:索引
    ORB-SLAM2 ---- Frame::ComputeBoW函数
    【爬虫】get 和 post 的区别
    strstr/strtok /strerror /字符分类(转换)函数
    大数据:Sqoop 简介与安装
    CANoe/CAPL ,钉钉群助手消息通知
    VMware Fusion 13+Ubuntu ARM Server 22.04.3在M2芯片的Mac上共享文件夹
    如何改变胆小怕事的性格?
    数据库系统原理与应用教程(003)—— MySQL 安装与配置:手工配置 MySQL(windows 环境)
    分享一个 SpringCloud Feign 中所埋藏的坑
  • 原文地址:https://blog.csdn.net/SeaBiscuitUncle/article/details/126576332