파이썬으로 수학문제 풀기- 프로젝트 오일러(project euler, 22번부터)

프로젝트 오일러 22번문제 - 알파벳-숫자변환

알파벳을 숫자로 변환해서, 특정 연산을 하는 문제입니다.

약 5천개의 영문이름이 있고, 각이름의 알파벳을 A=1,B=2,,, 로 치환해서, 합계를 계산합니다. 그다음, 그이름의 5000개중의 index값을 이전의 합계와 곱해서, 모든 이름의 계산결과를 누적한 값을 계산하는게 문제입니다.

파일을 불러오고, List에 저장해서, sorting 한다음에, 아스키 코드를 이용해서 하나씩 계산을 하면서, 누적하면 되겠네요.

 

파일 불러오기
filename = 'q022_data.txt'
with open(filename) as file_object:
    contents = file_object.read()
print(type(contents))
print(contents)
<class 'str'>
"MARY","PATRICIA","LINDA","BARBARA","ELIZABETH","JENNIFER","MARIA","SUSAN","MARGARET","DOROTHY","LISA","NANCY","KAREN","BETTY","HELEN","SANDRA","DONNA","CAROL","RUTH","SHARON","MICHELLE","LAURA","SARAH","KIMBERLY","DEBORAH","JESSICA","SHIRLEY","CYNTHIA","ANGELA","MELISSA","BRENDA","AMY","ANNA","REBECCA","VIRGINIA","KATHLEEN","PAMELA","MARTHA","DEBRA","AMANDA","STEPHANIE","CAROLYN","CHRISTINE","MARIE","JANET","CATHERINE","FRANCES","ANN","JOYCE","DIANE","ALICE","JULIE","HEATHER","TERESA","DORIS","GLORIA","EVELYN","JEAN","CHERYL","MILDRED","KATHERINE","JOAN","ASHLEY","JUDITH","ROSE","JANICE","KELLY","NICOLE","JUDY","CHRISTINA","KATHY","THERESA","BEVERLY","DENISE","TAMMY","IRENE","JANE","LORI","RACHEL","MARILYN","ANDREA","KATHRYN",,,,,,,,,,,,,

텍스트 안의 따옴표(")는 제거를 해주어야 할것 같고, 컴마(,)를 기준으로 split을 하면 될것 같습니다.

 

불러온 텍스트 처리하기
filename = 'q022_data.txt'
with open(filename) as file_object:
    contents = file_object.read()
contents=contents.replace('"','')  #따옴표 처리
print(contents.isupper())
names=contents.split(',')     #split
print(type(names))
print(names)
True
<class 'list'>
['MARY', 'PATRICIA', 'LINDA', 'BARBARA', 'ELIZABETH', 'JENNIFER', 'MARIA', 'SUSAN', 'MARGARET', 'DOROTHY', 'LISA', 'NANCY', 'KAREN', 'BETTY', 'HELEN', 'SANDRA', 'DONNA', 'CAROL', 'RUTH', 'SHARON', 'MICHELLE', 'LAURA', 'SARAH', 'KIMBERLY', 'DEBORAH', 'JESSICA', 'SHIRLEY', 'CYNTHIA', 'ANGELA', 'MELISSA', 'BRENDA', 'AMY', 'ANNA', 'REBECCA', 'VIRGINIA', 'KATHLEEN', 'PAMELA', 'MARTHA', 'DEBRA', 'AMANDA', 'STEPHANIE', 'CAROLYN', 'CHRISTINE', 'MARIE', 'JANET', 'CATHERINE', 'FRANCES', 'ANN', 'JOYCE', 'DIANE', 'ALICE', 'JULIE', 'HEATHER', 'TERESA', 'DORIS', 'GLORIA', 'EVELYN', 'JEAN', 'CHERYL', 'MILDRED', 'KATHERINE', 'JOAN', 'ASHLEY', 'JUDITH', 'ROSE', 'JANICE', 'KELLY', 'NICOLE', 'JUDY', 'CHRISTINA', 'KATHY', 'THERESA', 'BEVERLY', 'DENISE', 'TAMMY', 'IRENE', 'JANE', 'LORI', 'RACHEL', 'MARILYN', 'ANDREA', 'KATHRYN', 'LOUISE', 'SARA', 'ANNE', 'JACQUELINE', 'WANDA', 'BONNIE', 'JULIA', 'RUBY', 'LOIS', 'TINA', 'PHYLLIS', 'NORMA', 'PAULA', 'DIANA', 'ANNIE', 'LILLIAN', 'EMILY', 'ROBIN', 'PEGGY', 'CRYSTAL', 'GLADYS', 'RITA', 'DAWN',,,,,,,,,

 따옴표는 공백으로 치환을 해주었고, 컴마를 기준으로 split을 했습니다. split을 하고 나면, 데이터형은 List형으로 저장됩니다. 그리고 아스키코드를 사용할 계획인데, 이름에 소문자가 섞여 있는지를 확인하기 위해서, print(contents.isupper()) 라는 명령을 추가해주었습니다.

 

리스트 정렬하기
filename = 'q022_data.txt'
with open(filename) as file_object:
    contents = file_object.read()
contents=contents.replace('"','')
names=contents.split(',')
names.sort()     #list 정렬
for idx,val in enumerate(names):
    print(idx+1,val)
1 AARON
2 ABBEY
3 ABBIE
4 ABBY
5 ABDUL
,,,,,,,,,,,, 
5159 ZORA
5160 ZORAIDA
5161 ZULA
5162 ZULEMA
5163 ZULMA

알파벳순으로 정렬해주고, for문으로 루프를 만들어 주었습니다. for문안에 enumerate()를 사용하게 되면, iter 나 sequence형(str,list,tuple등) 데이타 타입에 index를 자동으로 생성해줍니다. 위 코드에서는 idx에 index가 할당되고, val에 각 names의 값들이 할당됩니다.

 

아스키코드를 이용하여, 이름을 숫자로 변경
filename = 'q022_data.txt'
with open(filename) as file_object:
    contents = file_object.read()
contents=contents.replace('"','')
names=contents.split(',')
names.sort()
for idx,val in enumerate(names):
    print(idx+1,val,end=' ')
    for i in val:
        print(ord(i)-64,end=',')  #아스키코드로 변환
    print()
1 AARON 1,1,18,15,14,
2 ABBEY 1,2,2,5,25,
3 ABBIE 1,2,2,9,5,
4 ABBY 1,2,2,25,
,,,,,,,
5160 ZORAIDA 26,15,18,1,9,4,1,
5161 ZULA 26,21,12,1,
5162 ZULEMA 26,21,12,5,13,1,
5163 ZULMA 26,21,12,13,1,

 ord(i) 명령이 아스키 코드로 바꾸는 명령입니다. 대문자 A가 65번이기 때문에, 64를 빼주면, 1부터 시작하는 연속된 값을 얻을수 있습니다.

 

합계 계산
filename = 'q022_data.txt'
with open(filename) as file_object:
    contents = file_object.read()
contents=contents.replace('"','')
names=contents.split(',')
names.sort()
grand_total =0
for idx,val in enumerate(names):
    print(idx+1,val,end=' ')
    total=0
    for i in val:
        print(ord(i)-64,end=',')
        total=total+ord(i)-64
    print("total:",total,end=',')
    grand_total+=total*(idx+1)  #누적
    print(grand_total)

 

1 AARON 1,1,18,15,14,total: 49,49
2 ABBEY 1,2,2,5,25,total: 35,119
3 ABBIE 1,2,2,9,5,total: 19,176
4 ABBY 1,2,2,25,total: 30,296
5 ABDUL 1,2,4,21,12,total: 40,496
,,,,,,,,,,,
5160 ZORAIDA 26,15,18,1,9,4,1,total: 74,870109087
5161 ZULA 26,21,12,1,total: 60,870418747
5162 ZULEMA 26,21,12,5,13,1,total: 78,870821383
5163 ZULMA 26,21,12,13,1,total: 73,871198282

맨 마지막 합계가 문제의 답입니다.

댓글

댓글 본문
작성자
비밀번호
버전 관리
nomadlife
현재 버전
선택 버전
graphittie 자세히 보기