zoukankan      html  css  js  c++  java
  • 暴力求解Calculator:The Game

    本文详实的记录的我的思考过程,类似流水账....

    目前已经烂尾,我对付不了133关后面的关卡

    这个手机游戏挺不错的,就是有点难,所以要写程序,暴力的通关。

    游戏名字:Calculator:The Game

    编程语言:python

    图标长这个样子

     游戏界面这个样子

    灰色按钮表示对数字的操作

    游戏很简单,在步数限制内,将数字变成“目标数字”

    目前看上去,很容易,for循环+eval函数就可以解决问题

    就算后来出现了乘除 eval函数 也能应付

    s = [ "+2" ,"+3"]
    begin = 0
    end = 8
    for i_0 in s:
        for i_1 in s:
            for i_2 in s:
                num = begin
                num =eval( str(num) +i_0 )
                num =eval( str(num) +i_1 )
                num =eval( str(num) +i_2 )
                if num == end:
                    print(i_0,end = ",")
                    print(i_1,end = ",")
                    print(i_2)

    后来果然出现了乘除

    而且步数限制变成了4,也就是加个for循环的事

    后来解锁了一个新的键 它可以删掉数字的最后一位,例如 4321-->432-->43-->4

    其实,它并不算新运算,它就是“//10”

    >>> s = ["+8","*5","//10"]
    >>> begin = 0
    >>> end = 4
    >>> game_3(s,begin,end)
    +8,*5,//10

    ps:我已经悄悄的包装成函数啦

    后来限制步数变成了5 我不想再添for了

    现在开始思考

    >>> s = ["+2","+3"]
    >>> con = s
    #定义变量con表示所有可能的解法
    #当步数为1时,con就等于s
    >>> con = [ (x,y) for x in con for y in s]
    >>> con
    [('+2', '+2'), ('+2', '+3'), ('+3', '+2'), ('+3', '+3')]
    #当步数为2时,两层遍历就可以啦
    #但是,再遍历一次可不是步数为3的情况
    >>> con_3 = [ (x,y) for x in con for y in s]
    >>> con_3
    [(('+2', '+2'), '+2'), (('+2', '+2'), '+3'), (('+2', '+3'), '+2'), (('+2', '+3'), '+3'), (('+3', '+2'), '+2'), (('+3', '+2'), '+3'), (('+3', '+3'), '+2'), (('+3', '+3'), '+3')]
    #仔细观察(('+2', '+2'), '+2')可不是想要的格式
    #('+2', '+2', '+2')才是
    #所以遍历的时候,需要对x解构
    >>> con = [ (*x,y) for x in con for y in s]
    >>> con
    [('+2', '+2', '+2'), ('+2', '+2', '+3'), ('+2', '+3', '+2'), ('+2', '+3', '+3'), ('+3', '+2', '+2'), ('+3', '+2', '+3'), ('+3', '+3', '+2'), ('+3', '+3', '+3')]
    #这才是正确的做法

    完整的代码

        s = tuple(s)
        con = s
        con = ( (x,y) for x in con for y in s)
        for i in range(step-2):
            con = ( (*x,y) for x in con for y in s)
    
    #列表生成式 改成 生成器
    #为了避免的不必要的麻烦,list改成tuple

    PS:因为这个游戏的特性,步数不可能是1,2(那样就太简单了)

    然后对con遍历,寻找正确的解

    然后整体加上必要的input(),实际使用中发现,输入按钮类型时,输入大量的引号,对此做点优化

    def game():
        begin = int(input("初始数字:"))
        end = int(input("目标数字:"))
        step = int(input("限制步数:"))
        s = []
        n = int(input("按钮数量:"))
        for i in range(n):
            s.append(input("第%d个:"%(i+1)))
        s = tuple(s)
        con = s
        con = ( (x,y) for x in con for y in s)
        for i in range(step-2):
            con = ( (*x,y) for x in con for y in s)
        for i in con :
            num = begin
            for j in i:
                num = eval(str(num) + j)
            if num == end:
                print(i)

    实际的使用情况

    >>> game()
    初始数字:0
    目标数字:404
    限制步数:5
    按钮数量:3
    第1个:+8
    第2个:*10
    第3个:/2
    ('+8', '*10', '*10', '+8', '/2')
    >>> game()
    初始数字:171
    目标数字:23
    限制步数:4
    按钮数量:3
    第1个:*2
    第2个:-9
    第3个://10
    ('-9', '*2', '//10', '-9')
    ('-9', '//10', '*2', '-9')

     出现里新按钮 它可以在数字最后面加一个数字 

    那也没问题这个按钮可以理解为“*10+1”   当然,直接一个1也是可以的

    >>> a = 23
    >>> b = eval(str(a)+'5')
    >>> b
    235
    初始数字:0
    目标数字:56
    限制步数:3
    按钮数量:2
    第1个:1
    第2个:+5
    Traceback (most recent call last):
      File "F:py测试IDEL5-3.py", line 48, in <module>
        game()
      File "F:py测试IDEL5-3.py", line 44, in game
        num = eval(str(num) + j)
      File "<string>", line 1
        01
         ^
    SyntaxError: invalid token

    遭遇了一个错误↑↑↑

    还是老老实实的写成*10+1吧

    26级左右出现了新按钮,其实也没啥, *100+10 就可以啦

    我本以为,我可以靠这点代码打通关的,结果我错了

    好吧对代码进行微调

        for i in con :
            num = begin
            for j in i:
                if "-/" not in j:
                    num = eval(str(num) + j)
                else:
                    num = int(str(num).replace( j[0], j[3]))
            if num == end:
                print(i)

    使用情况

    初始数字:0
    目标数字:93
    限制步数:4
    按钮数量:3
    第1个:+6
    第2个:*7
    第3个:6-/9
    ('+6', '6-/9', '*7', '6-/9')

    完美  φ(>ω<*) 

    32关遭遇bug

    初始数字:11
    目标数字:29
    限制步数:5
    按钮数量:4
    第1个:/2
    第2个:+3
    第3个:1-/2
    第4个:2-/9
    Traceback (most recent call last):
      File "F:py测试IDEL5-3.py", line 52, in games
        game()
      File "F:py测试IDEL5-3.py", line 47, in game
        num = int(str(num).replace( j[0], j[3]))
    ValueError: invalid literal for int() with base 10: '0.6875'

    解决方法 : int改为float

    当初偷得懒,迟早要还的   T^T

        for i in con :
            num = begin
            for j in i:
                if "-/" not in j:
                    num = eval(str(num) + j)
                else:
                    k = j.split('-/')
                    num = float(str(num).replace( *k ))
            if num == end:
                print(i)

    后来出现了负数....-1 *10+5 = -5 对负数而言 应该是*10-5才对

    好吧,再改改

        for i in con :
            num = begin
            for j in i:
                if "-/"  in j:
                    k = j.split('-/')
                    num = float(str(num).replace( *k ))
                elif "++" in j:
                    k =int( j.split('++')[-1] )
                    num = num*10 + k if num >=0 else num*10 - k
                else:
                    num = eval(str(num) + j)  
            if num == end:
                print(i)

    Q:k =int( j.split('++')[-1] )中的[-1]是什么意思

    A:split产生的是列表,而且++前面的空白也被切出来了..所以不是[0]

    >>> '++5'.split('++')
    ['', '5']

    使用情况

    初始数字:0
    目标数字:-85
    限制步数:4
    按钮数量:3
    第1个:+6
    第2个:++5
    第3个:-7
    ('+6', '-7', '-7', '++5')
    ('-7', '+6', '-7', '++5')
    ('-7', '-7', '+6', '++5')

    PS:再也不用打*10+5啦,格式改成++5

    39左右出现新按钮

            for j in i:
                if "-/"  in j:
                    k = j.split('-/')
                    num = float(str(num).replace( *k ))
                elif "++" in j:
                    k =int( j.split('++')[-1] )
                    num = num*10 + k if num >=0 else num*10 - k
                elif "+-" in j :
                    num = -num
                else:
                    num = eval(str(num) + j)  
            if num == end:
                print(i)

    使用情况

    >>>game()
    初始数字:0
    目标数字:-13
    限制步数:4
    按钮数量:3
    第1个:+3
    第2个:-7
    第3个:+-
    ('+3', '+3', '+-', '-7')

     

    看来得加入新东西啦

                if "-/"  in j:
                    k = j.split('-/')
                    num = float(str(num).replace( *k ))
                elif "++" in j:
                    k =int( j.split('++')[-1] )
                    num = num*10 + k if num >=0 else num*10 - k
                elif "+-" in j :
                    num = -num
                elif "00" in j:
                    num = int(str(num)[::-1])
                else:
                    num = eval(str(num) + j)  

    另外,大量使用中发现,基础的数据需要手动录入那没有办法,那只能减少其它不必要的按键

    #原来的
        begin = int(input("初始数字:"))
        end = int(input("目标数字:"))
        step = int(input("限制步数:"))
        s = []
        n = int(input("按钮数量:"))
        for i in range(n):
            s.append(input("第%d个:"%(i+1)))
    
    #改后
        begin ,end, step = map(int,input("始-终-步:").split(" "))
        s = input("按钮们:").split(" ")

    使用效果

    遭遇bug

    >>>game()
    始-终-步:0 58 4
    按钮们:+4 *4 -3 00
    ('+4', '*4', '00', '-3')
    Traceback (most recent call last):
      File "F:py测试IDEL5-3.py", line 65, in games
        game()
      File "F:py测试IDEL5-3.py", line 57, in game
        num = int(str(num)[::-1])
    ValueError: invalid literal for int() with base 10: '2-'

    负数的问题..

    微调下(游戏里面应该不会有“翻转”负数的情况)

                elif "00" in j:
                    if num >= 0:
                        num = int(str(num)[::-1])
                    else:
                        break

    第2个bug

    >>>game()
    始-终-步:6 4 3
    按钮们:++1 /4 00
    Traceback (most recent call last):
      File "F:py测试IDEL5-3.py", line 68, in games
        game()
      File "F:py测试IDEL5-3.py", line 58, in game
        num = int(str(num)[::-1])
    ValueError: invalid literal for int() with base 10: '52.51'

    看来小数也不行

                elif "00" in j:
                    if num >= 0 and num%1 == 0 :
                        num = int(str(num)[::-1])
                    else:
                        break

    又一个bug

    >>>game()
    始-终-步:6 4 3
    按钮们:++1 /4 00
    ('++1', '00', '/4')
    ('/4', '++1', '/4')
    Traceback (most recent call last):
      File "F:py测试IDEL5-3.py", line 68, in games
        game()
      File "F:py测试IDEL5-3.py", line 58, in game
        num = int(str(num)[::-1])
    ValueError: invalid literal for int() with base 10: '0.61'

    浮点数也不行...

                elif "00" in j:
                    if num >= 0 :
                        num = int(str(int(num))[::-1])
                    else:
                        break

    这下应该没问题啦

    62级处,出现无解的情况..

    >>>game()
    始-终-步:0 102 4
    按钮们:++10 *4 +5 00

    原因也找到了,原有的代码,为了兼容负数,结果兼容不了“添加两个数字”啦

    #原有的
                elif "++" in j:
                    k =int( j.split('++')[-1] )
                    num = num*10 + k if num >=0 else num*10 - k
    #更改后
                elif "++" in j:
                    k =  j.split('++')[-1]
                    num = int(str(num)+k)

    PS,必须用int 不能用eval,下面感受下它们的不同

    >>> a = int("010")
    >>> a
    10
    >>> b = eval("010")
    Traceback (most recent call last):
      File "<pyshell#7>", line 1, in <module>
        b = eval("010")
      File "<string>", line 1
        010
          ^
    SyntaxError: invalid token

    OK bug修复

    >>>game()
    始-终-步:0 102 4
    按钮们:++10 *4 +5 00
    ('+5', '*4', '++10', '00')

    打脸了,

    >>>game()
    始-终-步:0 7 4
    按钮们:++2 +1 /3 00
    Traceback (most recent call last):
      File "F:py测试IDEL5-3.py", line 71, in games
        game()
      File "F:py测试IDEL5-3.py", line 53, in game
        num = int(str(num)+k)
    ValueError: invalid literal for int() with base 10: '7.3333333333333332'

    补个int吧

                elif "++" in j:
                    k =  j.split('++')[-1]
                    num = int(str(int(num))+k)

    解决了

    >>>game()
    始-终-步:0 7 4
    按钮们:++2 +1 /3 00
    ('++2', '++2', '/3', '00')
    ('+1', '++2', '00', '/3')

    按第一个解法,结果...

    我发现这个游戏里显示不了小数..

    按第一个解法

    ('++2', '++2', '/3', '00')

    0 --> 2 --> 22 --> 7.1 --> 7

                else:
                    num = eval(str(num) + j)
                if num%1 != 0:
                    break
            if num == end:
                print(i)

    加上些代码,由于监测num是否变成小数,一旦变了,直接终止

    第71级 无解bug

    >>>game()
    始-终-步:0 -43 5
    按钮们:-5 +7 -9 00

    最终原因,游戏里面实验了下,负数可以翻转...-18翻转成-81..

    而我的代码否定了负数的翻转...

    #之前的
                elif "00" in j:
                    if num >= 0 :
                        num = int(str(int(num))[::-1])
                    else:
                        break
    #改正后
                elif "00" in j:
                    if num >= 0 :
                        num = int(str(num)[::-1])
                    else:
                        num = int(str(num)[1:][::-1])*-1

    PS,由于,num不可能是小数,内层的int就去掉了

    >>>game()
    始-终-步:0 -43 5
    按钮们:-5 +7 -9 00
    ('-5', '-9', '00', '+7', '-9')
    ('-5', '-9', '00', '+7', '00')
    ('-5', '-9', '00', '-9', '+7')
    ('-9', '-5', '00', '+7', '-9')
    ('-9', '-5', '00', '+7', '00')
    ('-9', '-5', '00', '-9', '+7')

    ......不知道该说些什么...

    >>>game()
    始-终-步:88 41 4
    按钮们:/4 -4 00
    Traceback (most recent call last):
      File "F:py测试IDEL5-3.py", line 73, in games
        game()
      File "F:py测试IDEL5-3.py", line 61, in game
        num = int(str(num)[::-1])
    ValueError: invalid literal for int() with base 10: '0.41'
    #之前
                if num%1 != 0:
                    break
            if num == end:
                print(i)
    #之后
                if num%1 != 0:
                    break
                else:
                    num = int(num)
            if num == end:
                print(i)

    bug:算出的解,游戏里面没法用

    >>>game()
    始-终-步:50 101 5
    按钮们:1-/10 +50 00 5-/1
    
    ...
    
    ('5-/1', '5-/1', '00', '+50', '+50')

    游戏:  如果没法转换,按了按钮,也不算步数...

    我的代码:  如果没法转换,按了按钮,算步数...

    结果出现了一些偏差.......

            for j in i:
                if "-/"  in j:
                    k = j.split('-/')
                    num = float(str(num).replace( *k ))
    #改为
            for j in i:
                if "-/"  in j:
                    num_0 = num
                    k = j.split('-/')
                    num = float(str(num).replace( *k ))
                    if num_0 == num:
                        break

    89级处出现新按钮

    使用+*+表示吧,PS:尽量使用小键盘

                elif "+*+" in j:
                    num = sum(map(int,str(num)))

    103级

    >>>game()
    始-终-步:9 30 4
    按钮们:-5 *-6 +- +*+
    Traceback (most recent call last):
      File "F:py测试IDEL5-3.py", line 80, in games
        game()
      File "F:py测试IDEL5-3.py", line 68, in game
        num = sum(map(int,str(num)))
    ValueError: invalid literal for int() with base 10: '-'

    经验证 sum可以对负数求和 -54 --> -9 就是去掉符号再求和

                elif "+*+" in j:
                    if num>=0:
                        num = sum(map(int,str(num)))
                    else:
                        num = -num
                        num = sum(map(int,str(num)))
                        num = -num
                else:

     

    举个例子1234-->2341-->3412-->4123(这是向左的,还会有向右的)

               elif "/**" in j :
                    num = str(num)
                    num = int(num[1:]+num[0])
                elif "**/" in j:
                    num = str(num)
                    num = int(num[-1]+num[:-1])

    /*   向左, */  向右

    示例

    >>>game()
    始-终-步:101 121 3
    按钮们:/** **/ +2
    ('*/', '+2', '/*')
    >>>game()
    始-终-步:120 210 5
    按钮们:+1 /** +-
    Traceback (most recent call last):
      File "F:py测试IDEL5-3.py", line 91, in games
        game()
      File "F:py测试IDEL5-3.py", line 76, in game
        num = int(num[1:]+num[0])
    ValueError: invalid literal for int() with base 10: '123-'

    负数..负数是去掉符号再移动

                elif "/*" in j :
                    fh = 1 if num>=0 else -1
                    num = str(abs(num))
                    num = int(num[1:]+num[0])
                    num = num*fh
                elif "*/" in j:
                    fh = 1 if num>=0 else -1
                    num = str(abs(num))
                    num = int(num[-1]+num[:-1])
                    num = num*fh

     

    新按钮,作用 23---> 2332

                elif "---" in j:
                    num = str(num)
                    num = int(num+num[::-1])

    使用

    >>>game()
    始-终-步:91 19 6
    按钮们:+5 --- +*+
    ('+5', '+5', '+5', '---', '+5', '+*+')
    ('+5', '+5', '+5', '---', '+*+', '+5')
    
    ...........

    经验证,游戏里面对负数也可以镜像,老套路,忽略符号....

                elif "---" in j:
                    fh = 1 if num>=0 else -1
                    num = str(abs(num))
                    num = int(num+num[::-1])
                    num = num*fh

    发现新特性,游戏中不能6位以上的数字

                if num%1 != 0 :
                    break
                else:
                    num = int(num)
    #改为
                if num%1 != 0 or num >=10**6 :
                    break
                else:
                    num = int(num)

     最终代码

    def game():
        begin ,end, step = map(int,input("始-终-步:").split(" "))
        s = input("按钮们:").split(" ")
    
        s = tuple(s)
        con = s
        con = ( (x,y) for x in con for y in s)
        for i in range(step-2):
            con = ( (*x,y) for x in con for y in s)
        for i in con :
            num = begin
            for j in i:
                if "-/"  in j:
                    num_0 = num
                    k = j.split('-/')
                    num = float(str(num).replace( *k ))
                    if num_0 == num:
                        break
                elif "++" in j:
                    k =  j.split('++')[-1]
                    num = int(str(num)+k)
                elif "+-" in j :
                    num = -num
                elif "00" in j:
                    if num >= 0 :
                        num = int(str(num)[::-1])
                    else:
                        num = int(str(num)[1:][::-1])*-1
                elif "+*+" in j:
                    if num>=0:
                        num = sum(map(int,str(num)))
                    else:
                        num = -num
                        num = sum(map(int,str(num)))
                        num = -num
                elif "/**" in j :
                    fh = 1 if num>=0 else -1
                    num = str(abs(num))
                    num = int(num[1:]+num[0])
                    num = num*fh
                elif "**/" in j:
                    fh = 1 if num>=0 else -1
                    num = str(abs(num))
                    num = int(num[-1]+num[:-1])
                    num = num*fh
                elif "---" in j:
                    fh = 1 if num>=0 else -1
                    num = str(abs(num))
                    num = int(num+num[::-1])
                    num = num*fh
                else:
                    num = eval(str(num) + j)
                if num%1 != 0 or num >=10**6 :
                    break
                else:
                    num = int(num)
            if num == end:
                print(i)

    烂尾啦

    133级遇到了新按钮,我短时间内找不到解决方法

    #

  • 相关阅读:
    SpringBoot list查询方法
    eclipse创建web项目
    loadrunner获取返回值为乱码
    连接数据库
    lr并发量和迭代的区别
    LoadRunner11.00入门教程出现的问题
    python学习杂记--函数参数的设置
    adb logcat的命令行开启和关闭
    python学习杂记--pycharm控制台输出乱码
    python学习杂记--装饰器
  • 原文地址:https://www.cnblogs.com/ansver/p/8982980.html
Copyright © 2011-2022 走看看