ooxx7788 发表于 2017-5-4 18:57:47

Python: 每日一题 38

本帖最后由 ooxx7788 于 2017-5-5 20:18 编辑

有一个车的里程表是以整数方式显示的,但是有个毛病,每到4时会直接跳至5,例如3后面本应该显示4,但是直接显示为5。
那么当显示为13公里的时候,实际上是12公里。(因为4被跳了。)
而当显示为15公里的时候,实际上是13公里。(因为4和14被跳了。)

现在请给出一个函数,当输入显示公里数时,返回实际公里数。

有人表示有答案会影响自己的思路,所以答案将延迟放出(我会告诉你,其实是我没做出来吗?)。

给出测试代码,test.py请在每日一题33,34中查看。
test.assert_equals(faulty_odometer(13), 12)
test.assert_equals(faulty_odometer(15), 13)
test.assert_equals(faulty_odometer(55), 40)
test.assert_equals(faulty_odometer(2005), 1462)
test.assert_equals(faulty_odometer(1500), 1053)
test.assert_equals(faulty_odometer(999999), 531440)
test.assert_equals(faulty_odometer(165826622), 69517865)

更新答案。
**** Hidden Message *****

jerryxjr1220 发表于 2017-5-4 21:50:00

本帖最后由 jerryxjr1220 于 2017-5-4 21:58 编辑

def count(n):
real, show = 0, 0
while show < n:
    real += 1
    show += 1
    while '4' in str(show):
      show += 1
else:
    return real
这个是最偷懒的写法,实际上有更好的算法,比如第几位出现4就跳过多少数,懒得算了,手机随便写写。

ooxx7788 发表于 2017-5-4 22:02:43

jerryxjr1220 发表于 2017-5-4 21:50
这个是最偷懒的写法,实际上有更好的算法,比如第几位出现4就跳过多少数,懒得算了,手机随便写写。

这算法就是模拟实际发生情况,思路上倒是很有意思。
缺陷就是如果n给一个很大的数字,比如千万以上的数字,效率就有点太低了。
不过随便写写,就能写出这样的,很厉害!

jerryxjr1220 发表于 2017-5-4 22:05:00

本帖最后由 jerryxjr1220 于 2017-5-5 06:48 编辑

ooxx7788 发表于 2017-5-4 22:02
这算法就是模拟实际发生情况,思路上倒是很有意思。
缺陷就是如果n给一个很大的数字,比如千万以上的 ...

是的,这就是我说的缺陷。
优化的算法就是根据4出现的位置,直接跳过多少数字,这样效率就会高很多。
个位出现4 就加1, 十位出现4就加10,百位出现4就加100,以此类推。
提供思路,写就不写了,我去看美剧了{:10_256:}

def count(n):
    real, show = 0, 0
    while show<n:
      real += 1
      show += 1
      while '4' in str(show):
            show += 10**list(str(show))[::-1].index('4')
    else:
      return real
只改了1行

jerryxjr1220 发表于 2017-5-5 06:55:55

本帖最后由 jerryxjr1220 于 2017-5-5 07:06 编辑

其实还能继续优化,不需要每次+1,可以每次+10或者+100或者+1000,这样可以更快.
显示的数每次+10,实际数每次+9
显示数每次+100,实际数每次+81,以此类推。

实际上,这样最终优化的结果就是只要根据你输入的数字,比如999,转化为列表【9,9,9】
提取百位的数字9(比4大的要-1),十位数字9(比4大的要-1),个位数字9(比4大的要-1),那么直接可以得到答案 81×(9-1)+ 9×(9-1)+ (9-1) = 728
以此类推,这样就不需要循环了,直接出答案,最快{:10_256:}

ooxx7788 发表于 2017-5-5 20:20:09

jerryxjr1220 发表于 2017-5-5 06:55
其实还能继续优化,不需要每次+1,可以每次+10或者+100或者+1000,这样可以更快.
显示的数每次+10,实际数 ...

是的,我更新的答案里面,其实有人用了更聪明的办法,直接把数字变成9进制。就是你这个想法的延伸了。

18813034116 发表于 2017-5-5 22:12:32

这样对吗
def real_num(num):
    n=4
    i=0
    while num>=n:
      
      print 'num:%s,n:%s'%(num,n)
      n+=10
      i+=1
    return num-i

ooxx7788 发表于 2017-5-5 22:18:43

18813034116 发表于 2017-5-5 22:12
这样对吗

Success!
Success!
Fail!49 not equals 40

Fail!1804 not equals 1462

Fail!1350 not equals 1053

Fail!899999 not equals 531440

Fail!149243960 not equals 69517865

不对哦!

当回首遇上转身 发表于 2017-5-6 02:08:47

本帖最后由 当回首遇上转身 于 2017-5-6 02:23 编辑


楼主,显示路程数不可能有49、1804、149243960出现吧?
应该显示的是59、1805、159253960才对啊

你发这样有悖论可能的调试,我写了代码也不敢发

当回首遇上转身 发表于 2017-5-6 02:35:37

本帖最后由 当回首遇上转身 于 2017-5-6 03:11 编辑

先发个简单的{:10_256:}      Powered by: Python 3.5.2
import os

while 1:
    showGL = int(input("请输入显示公里:"))
    temp, factGL = 0, 0
    while temp < showGL:
      temp += 1
      factGL += 1
      temp =int((str(temp)).replace('4','5'))
    print("实际公里:",factGL)

调试信息:
请输入显示公里:55
实际公里:40
请输入显示公里:2005
实际公里:1462
请输入显示公里:1500
实际公里:1053
请输入显示公里:999999
实际公里:531440
请输入显示公里:165826622
实际公里:69517865

这种递进的坏处就是数位比较大后之后很呵呵{:10_269:}
而且要一直在字符和整型数之间转换也很影响系统效率

ooxx7788 发表于 2017-5-6 07:43:49

当回首遇上转身 发表于 2017-5-6 02:08
楼主,显示路程数不可能有49、1804、149243960出现吧?
应该显示的是59、1805、159253960才对啊



49是他算出来的结果。并不是显示数字。

当回首遇上转身 发表于 2017-5-6 08:58:07

本帖最后由 当回首遇上转身 于 2017-5-6 08:59 编辑

ooxx7788 发表于 2017-5-6 07:43
49是他算出来的结果。并不是显示数字。

fair enough, my mistake

gopythoner 发表于 2017-5-8 10:22:12

很简单啊,直接把包含4的数字的个数减掉不就行了
def getnum(num):
fours =
return num-len(fours)

badaoqingchen 发表于 2017-5-8 16:05:08

def real_num(num):
    count = 0
    for i in range(1,num):
      stl = str(i)
      if '4' in stl:
            count += 1
    print(num - count)
real_num(165826622)

余欲渔 发表于 2017-5-10 09:14:51

其实就是变相的九进制
yz=(0,1,2,3,0,4,5,6,7,8)
def jiu(s):
    s=str(s)
    l=len(s)
    k=0
    for i in range(l):
      k+=yz)]*(9**(l-i-1))
    return k
      
print(jiu(165826622))

余欲渔 发表于 2017-5-10 09:27:32

为什么我为了写九进制稀里哗啦写了这么多,原来还有直接替换和int带第二参数的一条搞定的啊{:10_266:}

ooxx7788 发表于 2017-5-10 09:42:33

余欲渔 发表于 2017-5-10 09:27
为什么我为了写九进制稀里哗啦写了这么多,原来还有直接替换和int带第二参数的一条搞定的啊

{:10_297:}

whsb564308702 发表于 2017-5-10 11:41:18

1

willLin 发表于 2017-5-15 15:08:44

{:10_254:}

ooxx7788 发表于 2017-5-15 16:11:20

willLin 发表于 2017-5-15 15:08


光看,不写是不行的。
页: [1] 2 3
查看完整版本: Python: 每日一题 38