鱼C论坛

 找回密码
 立即注册
查看: 2719|回复: 13

[技术交流] 小练习:20161023 这个英语词列表里共有多少个三角形词?

[复制链接]
发表于 2016-10-24 10:00:00 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 冬雪雪冬 于 2016-10-31 12:50 编辑

从现在开始我们要开展一批欧拉计划的习题练习。
其实在我们论坛中已有欧拉计划的板块,可能有些鱼油还没注意到。
什么是欧拉计划:http://bbs.fishc.com/thread-60405-1-1.html
我们欧拉板块现已给出了81道题,这批练习将从欧拉计划中选题。其实用python语言完成有很多的优势,可以更简洁更方便的实现。
如果大家有兴趣也可浏览欧拉的英文网站:https://projecteuler.net/archives
这里已经有了500余题。


                               
登录/注册后可看大图

好了言归正传,我们开始做小练习。




题目要求:
以python语言完成,如果是python2请注明。
程序以代码文字格式发帖。
注重程序效率和创意。
答题在一周内完成,即10.24 10:00之前,其后将公开大家的答案,并评比成绩。

另程序和答案可以在网上搜到,希望大家独立完成。

----回帖需写明解题思路,鼓励在程序中加上注释-----
----除列出程序外,请给出输出的结果。----



题目:

三角形数序列中第 n 项的定义是:

                               
登录/注册后可看大图
;此前十个三角形数是:

1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...

通过将一个单词中每个字母在字母表中的位置值加起来:我们可以将一个单词转换为一个数。例如,单词 SKY 的值为

                               
登录/注册后可看大图
如果单词的值是一个三角形数,我们称这个单词为三角形单词。

p042_words.txt (15.96 KB, 下载次数: 24) (右键另存为)是一个 16K 的文本文件,包含将近两千个常用英语单词。在这个文件中,一共有多少个三角形词?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-10-24 10:52:50 | 显示全部楼层
这题也不难,思路很简单,先把文件读进python,再分割成单词,按照每个单词计算值,判断是否是三角数,若是三角数计数1,最后显示一共多少个。
答案:
162
[Finished in 0.1s]

Python 2.7写的代码
  1. f=open("p042_words.txt")
  2. string = f.read()
  3. f.close()

  4. def w(word):    #用asc码转换,很方便
  5.         return ord(word)-64

  6. def tri(n):
  7.         trilist = []
  8.         for i in range(1,n+1):
  9.                 trilist.append(int(0.5*i*(i+1)))
  10.         return trilist

  11. trilist = tri(20)   #三角数列表长度需按照单词最大长度来判断,在本题中20就够了。
  12. count = 0
  13. for words in string.split(','):
  14.         words = words.strip('"')  #这里有个坑,要去除单词两边引号,不然计算结果会不正确。
  15.         s = 0
  16.         for word in words:
  17.                 s+=w(word)
  18.         if s in trilist:
  19.                 count += 1
  20. print count
复制代码

评分

参与人数 1荣誉 +10 鱼币 +10 收起 理由
冬雪雪冬 + 10 + 10 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-10-24 11:43:04 | 显示全部楼层
思路:
1、把文件单词读入列表
2、根据单词的字母生成字母对应的数字和(此步考虑到字典比列表的效率更高,所以采用字典来存储,但存储时考虑到单词可能会有重复的,所以采用“单词+单词在列表中的位置”来作为字典的key)。
3、找到字典所有值中的最大值
4、根据最大的数字和生成三角形数的列表
5、判断每个单词的数字和是否在第4步中生成的三角形数字和中
6、输出结果

  1. # -*- coding:Utf-8 -*-
  2. import time
  3. start = time.clock()

  4. def count_triangle_number(str_word):
  5. # 计算单词的值并返回
  6.     s = 0
  7.     for each in str_word:
  8.         s = s + ord(each) - 64
  9.     return s

  10. # 读入文件,并将单词存入list_all_word
  11. with open('p042_words.txt','r') as f:
  12.     str_all_word=f.read()
  13.     list_all_word=(str_all_word.replace('"','')).split(',')

  14. dict_word={}
  15. # 将单词与计算出的值存入字典dict_word
  16. for j in range(0,len(list_all_word)):
  17.     dict_word[list_all_word[j]+'_'+str(j)]=count_triangle_number(list_all_word[j])

  18. # 将dict_word中最大的值赋给int_max_value
  19. int_max_value = dict_word[max(dict_word, key=dict_word.get)]

  20. #生成三角形数的数列,最大值不能大于int_max_value
  21. list_triangle=[]
  22. i=1
  23. while 1:
  24.     a=int((i**2+i)/2)
  25.     if a>int_max_value:
  26.         break
  27.     else:
  28.         list_triangle.append(a)
  29.         i+=1

  30. # 计算字典中三角形单词个数
  31. count_num=0
  32. for each in dict_word:
  33.     if dict_word[each] in list_triangle:
  34.         count_num+=1
  35. print(count_num)

  36. end = time.clock()
  37. print ("read: %f s" % (end - start))
复制代码


计算结果:
  1. 162
  2. read: 0.005940 s
复制代码

评分

参与人数 1荣誉 +10 鱼币 +10 收起 理由
冬雪雪冬 + 10 + 10

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-10-24 14:17:30 | 显示全部楼层
本帖最后由 lovesword 于 2016-10-25 12:03 编辑
  1. #! usr/bin/python
  2. # -*- coding:utf-8 -*-
  3. #python 2.7

  4. import string
  5. dict_char ={v:i+1 for i,v in enumerate(list((string.ascii_uppercase)))}
  6. f = open('p042_words.txt')
  7. for i in eval('['+f.read()+']'):
  8.     tmp = (8*sum(map(lambda x:dict_char[x],i))+1)**0.5-1
  9.     if tmp == int(tmp) and tmp/2.0 == int(tmp/2.0):
  10.         print i,
  11. f.close()
复制代码

评分

参与人数 1荣誉 +10 鱼币 +10 收起 理由
冬雪雪冬 + 10 + 10 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-10-24 16:23:15 | 显示全部楼层
  1. #求单词中每一个字母的和
  2. def he(word):
  3.     a=0
  4.     for i in word:
  5.        a+=(ord(i)-64)
  6.     return a

  7. #定义三角形数生成器,一般单词最长不可能超过10个,即单词对应的数最大不可能大于260
  8. def Tri():
  9.     for i in range(1,25):
  10.         b=i*(i+1)/2
  11.         yield b
  12.         
  13. with open(r'D:\Program Files\Python\p042_words.txt') as f:
  14.     n=0
  15.     word=''
  16.     for i in f.read():
  17.         if i!= ',':
  18.             word+=i
  19.         else:
  20.             word=word.strip('"')
  21.             if he(word) in Tri():
  22.                 n+=1
  23.             word=''
  24.     #判断最后一个单词
  25.     word=word.strip('"')  
  26.     if he(word) in Tri():
  27.         n+=1
  28.    
  29.     print('文件中共有%d个三角形单词' % n)
复制代码


结果:
   文件中共有162个三角形单词

评分

参与人数 1荣誉 +10 鱼币 +10 收起 理由
冬雪雪冬 + 10 + 10 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-10-24 18:03:32 | 显示全部楼层
本帖最后由 玄天宗 于 2016-10-27 12:41 编辑

版本:python 3.3.2
思路:将文本中的单词转化为ASCII码 每个字母的ASCII码减去64就是每个单词的位置,将三角形数依次存入到一个列表中(存多少需要做一个判断),最后验证单词的位置数和(tn)是否在三角形数列表中,如果在说明就是三角形数咯。。。
  1. import time
  2. start=time.clock()
  3. #第一步将文本中的单词存入L列表中
  4. f=open('C:\\Users\\admin\\Desktop\\p042_words.txt')
  5. s=f.read()
  6. f.close()
  7. s=s.replace('"','')
  8. L=s.split(',')
  9. #第二步将每个单词的字母转化为ASCII码病减去64 得到的就是每个单词的位置
  10. #(如,‘A’的ASCII码65 65-64=1就是位置1)利用sum()求和 得到单词的tn值存入d中

  11. d=[]
  12. for each in L:
  13.     l=list(map(ord,each))
  14.     d.append(sum(l)-64*len(each))
  15. #列表C用来存放 tn=n(n+1)/2 的值 当C中的最大值大于max(d)时,说明C中的数据够用了
  16. c=[]
  17. i=1
  18. while True:
  19.     c.append(i*(i+1)/2)
  20.     i +=1
  21.     if max(c)>max(d):break
  22. #最后一步判断d中各个单词值是否在C中(判断是否是三角形数)N为计数器,统计一共有几个这种单词   
  23. N=0
  24. for each in d:
  25.     if each in c:N +=1

  26. print('该文本中共有三角形单词%d个!' % N)   

  27. end=time.clock()
  28. print(end-start)
复制代码


代码有点烂。。。也不知对否!


答案:
  1. 该文本中共有三角形单词162个!
  2. 0.023366400257038435
复制代码

评分

参与人数 1荣誉 +10 鱼币 +10 收起 理由
冬雪雪冬 + 10 + 10 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-10-24 19:00:46 | 显示全部楼层
本帖最后由 wangzhenas 于 2016-10-28 17:48 编辑

答案:162
思路是首先读取文本文件,再按逗号分割为一个比如["APPLE","B",.....]的列表
[1:-1]去除头尾冒号
lambda函数的作用是返回每个字母的(ascii-65)即A返回1,B返回2....,结合map,sum函数算出每个单词的特征值
while循环生成最大值约为单词特征值最大值的三角数列表
最后用filter函数统计属于三角数的数然后计算长度


  1. from time import time
  2. t = time()

  3. word_l = list(map(lambda s:sum(map(lambda c:ord(c)-64,s[1:-1])),open("p042_words.txt").read().split(',')))
  4. triangle_l,i,maximum = [1],2,max(word_l)

  5. while triangle_l[-1] <= maximum:
  6.     triangle_l.append(i + triangle_l[-1])
  7.     i += 1

  8. triangle_s = set(triangle_l)
  9. print(len(list(filter(lambda num: num in triangle_s, word_l))),time()-t)
复制代码

评分

参与人数 1荣誉 +10 鱼币 +10 收起 理由
冬雪雪冬 + 10 + 10 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-10-25 18:49:21 | 显示全部楼层
  1. count = 0 #用于记数
  2. num = lambda s: sum(int(ord(i))-64 for i in s) #计算每个单词的值
  3. set0 = set([0.5*i*(i+1) for i in range(100)]) #生成一个三角数的list
  4. with open("p042_words.txt","r") as f:
  5.     text = f.read()
  6. for x in text.replace(""","").split(","): #对文本处理,生成单词列表
  7.     if num(x) in set0:
  8.         count += 1
  9. print(count)
复制代码


答案:162

评分

参与人数 1荣誉 +10 鱼币 +10 收起 理由
冬雪雪冬 + 10 + 10 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-10-26 11:21:07 | 显示全部楼层
本帖最后由 富友郑鹏展 于 2016-10-26 11:45 编辑

  1. # coding=utf-8

  2. import time
  3. import math as m


  4. #读取单词文件并做转换
  5. def load_file():
  6.     with open(r'e:\p042_words.txt') as f:
  7.         return ''.join([i for i in f]).replace('"', '')


  8. #计时装饰器
  9. def timeit(func):
  10.     def t():
  11.         start = time.time()
  12.         print func()
  13.         return 'use time: %f s' % (time.time()-start)
  14.     return t


  15. # 把单词转换成数字
  16. def wton():
  17.     words_list = load_file().split(',')
  18.     letter = {'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5, 'F': 6, 'G': 7, 'H': 8, 'I': 9, 'J': 10, 'K': 11, 'L': 12, 'M': 13, 'N': 14, 'O': 15, 'P': 16, 'Q': 17, 'R': 18, 'S': 19, 'T': 20, 'U': 21, 'V': 22, 'W': 23, 'X': 24, 'Y': 25, 'Z': 26}
  19.     num = 0
  20.     num_list = []
  21.     for each_word in words_list:
  22.         for each in each_word:
  23.             num += letter[each]
  24.         num_list.append(num)
  25.         num = 0
  26.     return num_list



  27. # 判断一个数是否是三角形数
  28. def istriangles_num(num):
  29.     n = (m.sqrt(1+8*num)-1)/2
  30.     n = str(n)
  31.     if n == n[:n.index(".")] + '.0':
  32.         return True
  33.     else:
  34.         return False



  35. # 判断文件中有多少个三角形单词
  36. @timeit
  37. def main():
  38.     n = len([i for i in wton() if istriangles_num(i) is True])
  39.     return '文件中总共有%s个三角形单词' % n

  40. print main()
复制代码


结果:
QQ截图20161026114525.png

评分

参与人数 1荣誉 +10 鱼币 +10 收起 理由
冬雪雪冬 + 10 + 10 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-10-26 11:35:30 | 显示全部楼层
用列表存放三角数,因为不知道最大的数字是多少,所以在遇到大的数字时添加三角数

  1. from time import time
  2. #三角数列表  第matri个三角数  时间  符合的字符串的个数
  3. triangle,matri,time1,tristring=[1],1,time(),0
  4. #向三角数列表中加入三角数
  5. def add_triangle():
  6.        global matri
  7.        matri+=1
  8.        triangle.append(matri*(matri+1)//2)
  9. #字符串转为数字
  10. def sum_string(string):
  11.        zer=ord('A')-1
  12.        return sum(map(lambda x:ord(x),string))-len(string)*zer

  13. with open('20161026.txt','r') as file:
  14.        #读入字符串存放在列表中
  15.        exec('fi=[%s]'%file.read())
  16.        for i in fi:
  17.               num=sum_string(i)
  18.               #列表中的最大元素小于num时 添加三角数
  19.               while(triangle[-1]<num):
  20.                      add_triangle()
  21.               if num in triangle:
  22.                      tristring+=1
  23.                      
  24. time2=time()
  25. print(tristring,time2-time1)
复制代码

  1. 162 0.031253814697265625
复制代码

评分

参与人数 1荣誉 +10 鱼币 +10 收起 理由
冬雪雪冬 + 10 + 10 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-10-26 18:52:19 | 显示全部楼层
  1. sanjiaoshu = []
  2. for i in range(0,41):
  3.     temp_sanjiao = int(0.5 * i * (i + 1))
  4.     sanjiaoshu.append(temp_sanjiao)
  5. data_zd = {'A' : 1,
  6.            'B' : 2,
  7.            'C' : 3,
  8.            'D' : 4,
  9.            'E' : 5,
  10.            'F' : 6,
  11.            'G' : 7,
  12.            'H' : 8,
  13.            'I' : 9,
  14.            'J' : 10,
  15.            'K' : 11,
  16.            'L' : 12,
  17.            'M' : 13,
  18.            'N' : 14,
  19.            'O' : 15,
  20.            'P' : 16,
  21.            'Q' : 17,
  22.            'R' : 18,
  23.            'S' : 19,
  24.            'T' : 20,
  25.            'U' : 21,
  26.            'V' : 22,
  27.            'W' : 23,
  28.            'X' : 24,
  29.            'Y' : 25,
  30.            'Z' : 26,
  31.            ',' : 0,
  32.            '\'': 0,
  33.            '"' : 0}
  34. result_list = []

  35. file_1 = open('p042_words.txt')
  36. all_file = file_1.read()
  37. list_file1 = str(all_file)
  38. ycl_file = list_file1.split(',')

  39. try:
  40.         for each_word in ycl_file:
  41.                 list_word = list(each_word)
  42.                 word_lenth = len(list_word)
  43.                 jsjg = 0
  44.                 for i in range(0,word_lenth):
  45.                         jsjg += data_zd[list_word[i]]
  46.                 if (jsjg in sanjiaoshu):
  47.                     temp1 = list(each_word)
  48.                     temp1.remove('"')
  49.                     temp1.remove('"')
  50.                     each_word = ('').join(temp1)
  51.                     result_list.append(each_word)
  52. finally:
  53.         file_1.close()
  54. print('该文件中包含的三角形词如下:',result_list)
  55. print('共有三角形词',len(result_list),'个')
复制代码


尝试着做了一下,也不知道对错,请大家多提意见!
说一下思路。
首先根据要求构造出三角数列表以及字母对应数值的字典,然后从文件中读取单词,并利用list()函数将单词拆分以便后续求和。将拆分后的单词字母对照字典取值并求和,若和值为三角数,则保存该单词。
在整个处理过程外加上了try/finally语句,以保证文件可以安全的关闭。

评分

参与人数 1荣誉 +10 鱼币 +10 收起 理由
冬雪雪冬 + 10 + 10 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-10-30 08:00:08 | 显示全部楼层
本帖最后由 bacon6581 于 2016-10-30 11:48 编辑

前期工作:
       检查并确定每个单词都是不一样的
       检查并确定每个单词都是大写字母
---------------------------------------------------
1-2行     获取当前时间
4-6行     读取txt文档的内容
8行         讲读取的内容打断,并存入列表
9-10行   详见:http://bbs.fishc.com/thread-72805-2-1.html,第27楼
12-17     将每个单词转变成数,并存入列表
19行      求出最大数
20-25    求n个三角形数,并存入集合(当n项三角形数>最大数时,就不求了)
27-30    把列表里每个数,和集合对比。记下有多少数相同的。
32-33    输出结果
  1. from time import time
  2. start=time()

  3. f=open('p042_words.txt')
  4. st=f.read()
  5. f.close()

  6. word=st.split('","')
  7. word[0]=word[0][1:]
  8. word[-1]=word[-1][:-1]

  9. nt=[]
  10. for i in word:
  11.     sm=0
  12.     for j in i:
  13.         sm+=ord(j)-64
  14.     nt.append(sm)
  15.    
  16. mx=max(nt)
  17. sjx=set()
  18. for k in range(1,10000):
  19.     x=k*(k+1)/2
  20.     if x>mx:
  21.         break
  22.     sjx.add(x)

  23. result=0
  24. for m in nt:
  25.     if m in sjx:
  26.         result+=1
  27.         
  28. print(result)
  29. print(time()-start)
复制代码

  1. >>> ================================ RESTART ================================
  2. >>>
  3. 162
  4. 0.1628732681274414
  5. >>>
复制代码

评分

参与人数 1荣誉 +10 鱼币 +10 收起 理由
冬雪雪冬 + 10 + 10 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-10-30 10:45:50 | 显示全部楼层
我的程序如下,为了取巧,我直接忽略了判断是否为三角数的过程,而只是通过查表法决定
#-*- coding:utf-8 -*-
import math

check_data=[1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 66, 78, 91, 105, 120,
            136, 153, 171, 190, 210, 231, 253, 276, 300, 325, 351, 378, 406,
            435, 465, 496, 528, 561, 595, 630, 666, 703, 741, 780, 820, 861,
            903, 946, 990, 1035, 1081, 1128, 1176, 1225, 1275, 1326, 1378, 1431,
            1485, 1540, 1596, 1653, 1711, 1770, 1830, 1891, 1953, 2016, 2080,
            2145, 2211, 2278, 2346, 2415, 2485, 2556, 2628, 2701, 2775, 2850,
            2926, 3003, 3081, 3160, 3240, 3321, 3403, 3486, 3570, 3655, 3741,
            3828, 3916, 4005, 4095, 4186, 4278, 4371, 4465, 4560, 4656, 4753,
            4851, 4950]

def open_file():    #打开文件
    file = open('p042_words.txt','r')
    for item in file.readlines():
        line =  item.split(',')
    file.close()
    return line


def process_data():   #数据处理
    data = open_file()
    for item in range(len(data)):   #将字符串转化为列表
        print data[item]
        word = data[item]    #经过转换之后的字符串
        if check(word):
            print word+'is a trial'
        else:
            continue


def check(word):
    sum = 0
    for charator in word:
        sum +=ord(charator)+1-ord('A')   #将字符转化为整数,并计算在字符表中的位置
    sum +=60   #计算时将“”也计算了,将其去除
    if sum in check_data:
        return True
    else:
        return False
process_data()

评分

参与人数 1荣誉 +10 鱼币 +10 收起 理由
冬雪雪冬 + 10 + 10 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-3-1 13:44:42 | 显示全部楼层
jerryxjr1220 发表于 2016-10-24 10:52
这题也不难,思路很简单,先把文件读进python,再分割成单词,按照每个单词计算值,判断是否是三角数,若是 ...
  1. ##  这么多小练习里难得有一个会做的。

  2. def isTriAngleNumber(n):
  3.     p = (-1+(1+8*n)**0.5)/2
  4.     return p == int(p)

  5. def countTriAngleWord(filename = 'p042_words.txt'):
  6.     count = 0
  7.     s = 'abcdefghijklmnopqrstuvwxyz'
  8.     with open(filename, 'r') as f:
  9.         allWords = f.read().split(',')
  10.     for word in allWords:
  11.         a = sum([s.index(char)+1 for char in word.lower().strip('"')])
  12.         if isTriAngleNumber(a):
  13.             count += 1
  14.     return count

  15. print(countTriAngleWord())
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-19 18:36

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表