Python Challenge 10의 url은 다음과 같다.

Python challenge 10 : http://www.pythonchallenge.com/pc/return/bull.html


구성

화면에는 성의 없는 글자가 있다.

 

len(a[30])

 

다른 말로하면

 

"야 내가 a라는 배열을 어디 숨겼는데 그거 찾아서 30번째 인덱스 항목의 길이 좀 가져와바"

 

이다 허허... 싹수없는 새 X가

소머리를 누르면 sequence.txt라는 페이지로 이동한다.

 수열도 답이 없어 보이는데... 규칙을 찾아보자


해결 아이디어

개미 수열이라는 수열이 있다, 아래를 참고하자

https://ko.wikipedia.org/wiki/%EC%9D%BD%EA%B3%A0_%EB%A7%90%ED%95%98%EA%B8%B0_%EC%88%98%EC%97%B4

 

읽고 말하기 수열 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 이 선들은 23 (빨강), 1 (파랑), 13 (보라), 312 (초록)으로 시작하는 읽고 말하기 수열의 자릿수를 나타낸다. 이 선은 (로그 수직 척도로 나타냈을 때) 기울기가 콘웨

ko.wikipedia.org

즉 다음과 같은 규칙을 가진다.

이지하다 이제 다음의 아이디어를 구현하자

### 10.py

if __name__ == "__main__" :
    a = ["1"]
    
    while(len(a)<31) :
        base = a[-1][0]
        cnt = 1
        next_val = ""
        for i in range(1,len(a[-1])) :
            if(a[-1][i] != base) :
                next_val += str(cnt)+str(base)
                base = a[-1][i]
                cnt = 1
            else :
                cnt +=1
        next_val += str(cnt)+str(base)
        a.append(next_val)
    
            
    print(len(a[30]))

출력은 다음과 같다.

5808

찾았다.

Answer Url : http://www.pythonchallenge.com/pc/return/5808.html


여담인데, 이 개미 수열은 신기하게도 다음 원소를 분자로 하고 현재 원소를 분모로 하는 경우 콘웨이 상수라는(약 1.3) 곳에 수렴한다고 한다. 

Python Challenge 9의 url은 다음과 같다.

Python challenge 9 : http://www.pythonchallenge.com/pc/return/good.html


구성

홈페이지에는 good.jpg라는 파일 하나가 들어있다. 별다른 상호작용이 보이지 않으니 주석을 확인해보자

 

아래 주석에 first와 second라는 알 수 없는 숫자가 들어있다. 범위가 255를 넘어가는 것을 보니 평범한 1byte짜리 색상 표현 정수 등은 아닌 듯하다. first+second=?라는 문자도 의미심장하다. 길이가 다른 매열을 어떻게 더한다는 것일까?


해결 아이디어

저번시간에 사용한 PIL의 ImageDraw라는 함수가 있다. 이는 배열을 홀짝인덱스로 튜플을 생성하여 선을 그려준다. 즉 first+second라는 의미는 각각의 배열을 다른 선으로 그려서 한 그림에 합쳐보라는 의미이다.

https://pillow.readthedocs.io/en/stable/reference/ImageDraw.html

 

ImageDraw Module — Pillow (PIL Fork) 8.2.0 documentation

Coordinates The graphics interface uses the same coordinate system as PIL itself, with (0, 0) in the upper left corner. Any pixels drawn outside of the image bounds will be discarded. Colors To specify colors, you can use numbers or tuples just as you woul

pillow.readthedocs.io

다운로드받은 good.jpg에 위의 함수를 이용해서 그림을 그려보자

### 9.py

from PIL import Image, ImageDraw

if __name__ == "__main__" :

    first = [146,399,163,403,170,393,169,391,166,386,170,381,170,371,170,355,169,346,167,335,170,329,170,320,170,\
            310,171,301,173,290,178,289,182,287,188,286,190,286,192,291,194,296,195,305,194,307,191,312,190,316,\
            190,321,192,331,193,338,196,341,197,346,199,352,198,360,197,366,197,373,196,380,197,383,196,387,192,\
            389,191,392,190,396,189,400,194,401,201,402,208,403,213,402,216,401,219,397,219,393,216,390,215,385,\
            215,379,213,373,213,365,212,360,210,353,210,347,212,338,213,329,214,319,215,311,215,306,216,296,218,\
            290,221,283,225,282,233,284,238,287,243,290,250,291,255,294,261,293,265,291,271,291,273,289,278,287,\
            279,285,281,280,284,278,284,276,287,277,289,283,291,286,294,291,296,295,299,300,301,304,304,320,305,\
            327,306,332,307,341,306,349,303,354,301,364,301,371,297,375,292,384,291,386,302,393,324,391,333,387,\
            328,375,329,367,329,353,330,341,331,328,336,319,338,310,341,304,341,285,341,278,343,269,344,262,346,\
            259,346,251,349,259,349,264,349,273,349,280,349,288,349,295,349,298,354,293,356,286,354,279,352,268,\
            352,257,351,249,350,234,351,211,352,197,354,185,353,171,351,154,348,147,342,137,339,132,330,122,327,\
            120,314,116,304,117,293,118,284,118,281,122,275,128,265,129,257,131,244,133,239,134,228,136,221,137,\
            214,138,209,135,201,132,192,130,184,131,175,129,170,131,159,134,157,134,160,130,170,125,176,114,176,\
            102,173,103,172,108,171,111,163,115,156,116,149,117,142,116,136,115,129,115,124,115,120,115,115,117,\
            113,120,109,122,102,122,100,121,95,121,89,115,87,110,82,109,84,118,89,123,93,129,100,130,108,132,110,\
            133,110,136,107,138,105,140,95,138,86,141,79,149,77,155,81,162,90,165,97,167,99,171,109,171,107,161,\
            111,156,113,170,115,185,118,208,117,223,121,239,128,251,133,259,136,266,139,276,143,290,148,310,151,\
            332,155,348,156,353,153,366,149,379,147,394,146,399]

    second = [156,141,165,135,169,131,176,130,187,134,191,140,191,146,186,150,179,155,175,157,168,157,163,157,159,\
            157,158,164,159,175,159,181,157,191,154,197,153,205,153,210,152,212,147,215,146,218,143,220,132,220,\
            125,217,119,209,116,196,115,185,114,172,114,167,112,161,109,165,107,170,99,171,97,167,89,164,81,162,\
            77,155,81,148,87,140,96,138,105,141,110,136,111,126,113,129,118,117,128,114,137,115,146,114,155,115,\
            158,121,157,128,156,134,157,136,156,136]
    
    with Image.open("good.jpg") as img :
        dr = ImageDraw.Draw(img)
        dr.line(first,fill=(255,0,0),width=3)
        dr.line(second,fill=(0,255,0),width=3)
        img.save("good_line.jpg")
        

그러면 다음과 같은 그림이 나온다.

어.... 소같이 생겼는데, 정답이 cow인가? 

Answer Url? : http://www.pythonchallenge.com/pc/return/cow.html 

아니 숫놈이라고 한다. bull인가 보다 찾았다.

Answer Url : http://www.pythonchallenge.com/pc/return/bull.html

Python Challenge 8의 url은 다음과 같다.

Python challenge 8 : http://www.pythonchallenge.com/pc/def/integrity.html

 

working hard?

 

www.pythonchallenge.com


구성

귀여운 야 울고 있는 꿀벌이 있다. 글자는 다음과 같다.

 

사라진 링크는 어디에 있는가?

 

꿀벌의 테두리를 누르면 클릭할 수 있다. 페이지로 이동해 보자

자격증명을 물어보는 화면이 나온다. 유의미한 정보는 없으니, 꿀벌 페이지의 주석을 확인해 보자

가장 아래쪽의 주석에 un / pw가 있다(un은 username약어인가? 어느 동네가 저렇게 쓴다는 말인가)

꿀벌 테두리가 Clickable 한건 area 태그 coord로 그린거다. 문제 출제자의 정성에 경의를 표하며 해결 방법을 알아보자


해결 아이디어

우선 un / pw를 복구할 필요가 있어 보인다. BZh로 시작하는 헤더는 bzip2 파일들이다. 이를 이용해서 헥스로 변환 후 압축을 해제하면 될 듯했으나, 우리 으-썸한 파이선은 bz2라는 모듈을 지원한다. 아래를 참조하자

https://docs.python.org/ko/3/library/bz2.html

 

bz2 — bzip2 압축 지원 — Python 3.9.5 문서

bz2 — bzip2 압축 지원 소스 코드: Lib/bz2.py 이 모듈은 bzip2 압축 알고리즘을 사용하여 데이터 압축과 압축 해제를 위한 포괄적인 인터페이스를 제공합니다. bz2 모듈에는 다음이 포함됩니다: 이 모

docs.python.org

간단한 걸 보니까 모듈 소개 시간에 정리해놔야겠다. 아래는 bz2.decompress를 이용해서 un / pw를 압축 해제하는 코드이다.(바이트가 반환되어서 decode로 str 변환했다.)

import bz2

if __name__=="__main__" :
    un = b'BZh91AY&SYA\xaf\x82\r\x00\x00\x01\x01\x80\x02\xc0\x02\x00 \x00!\x9ah3M\x07<]\xc9\x14\xe1BA\x06\xbe\x084'
    pw = b'BZh91AY&SY\x94$|\x0e\x00\x00\x00\x81\x00\x03$ \x00!\x9ah3M\x13<]\xc9\x14\xe1BBP\x91\xf08'

    un = bz2.decompress(un)
    pw = bz2.decompress(pw)

    print("un : ",un.decode())
    print("pw : ",pw.decode())

출력 결과는 다음과 같다.

un :  huge
pw :  file

자격증명에 입력해보면 해결할 수 있다. 찾았다

Answer Un : huge

Answer pw : file

'Python > Python Challenge' 카테고리의 다른 글

[Python Challenge 10] 뚠뚠  (0) 2021.05.19
[Python Challenge 9] 소?난다  (0) 2021.05.19
[Python Challenge 7] 그림분석하기  (0) 2021.05.19
[Python Challenge 6] ZIP과 놀기  (0) 2021.05.18
[Python Challenge 5] 삐끌  (0) 2021.05.16

Python Challenge 7의 url은 다음과 같다.

Python challenge 7 : http://www.pythonchallenge.com/pc/def/oxygen.html

 

smarty

 

www.pythonchallenge.com


구성

사진 하나 있다. 가운데 무슨 바코드 같이 White~Black의 그림이 있는 게 특징인 거 같다.


해결 아이디어

White~Black의 색깔은 특징적으로 (R, G, B)값이 모두 같은 (N, N, N)을 가지고 있다는 특징이 있다.

아마 일렬로 있는 저 긴 사각형의 정사각형으로 나뉜 N들의 ASCII변환값에 힌트가 있지 않을까? 우선 해당 아이디어를 코딩해보았다.

### 7.py

from PIL import Image
import numpy

if __name__=="__main__" :

  with Image.open("oxygen.png","r") as img :
    pix = numpy.array(img)
    y = img.height//2
    ans = ""
    
    ### 단위사격각형 가로 크기가 7인건 그림판으로 쟀다
    for x in range(0,img.width,7) :
      ans += chr(pix[y][x][1])

    print(ans)

출력결과는 다음과 같다.

smart guy, you made it. the next level is [105, 110, 116, 101, 103, 114, 105, 116, 121]n\S

 

잘 찾은거 같으니 나온 배열을 다시 ASCII화 해보자

### 7_1.py

if __name__=="__main__" :
    base = [105, 110, 116, 101, 103, 114, 105, 116, 121]
    ans = ''.join([chr(x) for x in base])
    print(ans)

출력은 다음과 같다.

integrity

찾았다.

Answer Url : http://www.pythonchallenge.com/pc/def/integrity.html

Python Challenge 6의 url은 다음과 같다.

Python challenge 6 : http://www.pythonchallenge.com/pc/def/channel.html

 

now there are pairs

 

www.pythonchallenge.com

* zipline을 활용한 해결방법을 기술하고 있지 않습니다.


구성

으흠 화면에는 PayPal로 연결되는 그림 하나밖에 없다. href 걸려있는 것도 실제로 PayPal로 이동하는 링크이다. 주석을 보자

아래 주석으로 돈을 보내달라는 이야기 인데, 거짓말일 거다. 설마 풀리는 그것도 웃기는 경우니까 ㅋ 맨 윗줄에 zip이라는 주석이 있다. channel.html이라는 소스를 channel.zip으로 변경하면 압축파일을 다운로드할 수 있다.

 

압축파일에는 약910개정도의 텍스트 파일이 있다. 예시로 하나 열어보면 linkedlist문제 때와 같은 Next nothing is XXXX라는 문자열이 있다. 제일 아래를 보면 다음과 같이 readme가 있다. 

readme.txt를 open하면 다음과 같은 안내문이 있다.

welcome to my zipped list.

hint1: start from 90052
hint2: answer is inside the zip

글쿠만 90052로 부터 시작하는 코드를 작성하자

### 코드 6.py

import re

if __name__=="__main__" :

  nothing = 90052

  while(True) :
    try :
      with open("./channel/"+str(nothing)+".txt","r") as f:
        data = f.read()
        nothing = re.findall("Next nothing is (\d+)",data)[-1]
        print(nothing)
    except Exception as e:
      print(data) 
      break

머지않아 다음과 같은 결과를 만날 수 있다.

...
91038
44221
992
8700
45100
68628
67824
46145
Collect the comments.

응? 이게 무슨 소리인지? comments를 모으라고 한다. comments가 의견/주석처럼 쓰이는 단어인데, txt 파일에 comment가 있단 말인가? 힌트는 readme.txt에 있는 hint2 answer is ininside the zip에 있다.

 

해결 아이디어

zip파일의 헤더 구조를 일단 읽고 오자

https://en.wikipedia.org/wiki/ZIP_(file_format) 

 

ZIP (file format) - Wikipedia

From Wikipedia, the free encyclopedia Jump to navigation Jump to search Family of archive file formats ZIP is an archive file format that supports lossless data compression. A ZIP file may contain one or more files or directories that may have been compres

en.wikipedia.org

이번 문제를 풀기위한 설명만을 하자면 ZIP 파일의 구조는 504 b0304~ (로컬 파일 헤더)  + (데이터 디스크립터) + 504 b0102~ (센트럴 딕셔너리 file header)로 이루어져 있다. 모든 파일에 대해서 위와 같은 파일 형식이 들어가는데, 우리가 집중해야 되는 곳은 504b0102로 시작하는 센트럴 딕셔너리 file header이다.

이곳의 offset+len(file_name)+len(Extra_file)가 file_comment 인다. 우리 문제에서는 다행히도 comment는 한 글자로 표현되어있기 때문에, 다음과 같이 파싱 해 보았다.

### 코드 6_1.py

if __name__=="__main__" :
  plz_answer = list()
  avoid_list = [0,32,42]

  with open("channel.zip","rb") as f:
    data = f.read()
    for i in range(len(data)) :
      if(data[i:i+4] == b"\x50\x4b\01\02" and data[i-1] not in avoid_list) :
        plz_answer.append(chr(data[i-1]))
        

  print("".join(plz_answer))

특수문자인 *, 공백(" "), 줄바꿈이 나오길래 이들은 제외하고 출력한 결과를 보고 싶었다. 다음과 같다.

EYEYONYE
OG
YGEYENGGOXEEXGEYOOGXEXOEE
NXGENNGXEXYXNOOOGGOOGYYNYX
GNN
XYEYONXEX
OX
NX
GOYNXNYXEEENGYEOOGOOO
XYGEEYXNYOOXXGNYXOOGONG
ENYEOENEY
NYEXOYGNYGOO
EYGYXGEOOEXEOGY
OONXXXEGXEXGOYEOYEYNYGGXNEOXOYXEYOOXXXXO
EEGYG

??? 아무의미가 없는 문자열이었다. 문득 스쳐 지나간 생각은

 

"순서에 맞게 풀면 ASCII Art가 나오나?"

 

였다. 아래는 위의 아이디어를 구현하기 위해 사용한 코드이다.

### 코드 6_2.py

import re

if __name__=="__main__" :
  struct = dict()

  ### ZIP 파일의 센트럴 딕셔너리를 파싱하는영역 
  ### 결과로 sturct를 만든다. struct는 확장자를 제외한 파일명을 key로 하고
  ### comment를 value로 하는 딕셔너리
  with open("channel.zip","rb") as f:
    data = f.read()
    for i in range(len(data)) :
      if(data[i:i+4] == b"\x50\x4b\01\02") :
        number = list()
        
        ### 파일이름등에 따라 comment의 위치가 변하기 때문에 44~100으로 범위를 설정하고
        ### .txt를 만나면 멈추도록 해두었다.
        for j in range(44,100) :
          if(data[i+j] >=48 and data[i+j]<= 57) :
            number.append(chr(data[i+j]))
          if(data[i+j:i+j+4] == b"\x2e\x74\x78\x74") :
            break
        if(len(number)!=0) :
          number = "".join(number)
          struct[int(number)] = chr(data[i+50+len(number)])

  ### 생성된 struct에서 정답을 찾는다.
  nothing = 90052
  answer = struct[nothing]
  while(True) :
    try :
      with open("./channel/"+str(nothing)+".txt","r") as f:
        nothing = re.findall("Next nothing is (\d+)",f.read())[-1]
        answer += struct[int(nothing)]
    except Exception as e:
      print(answer)
      break

* 필자는 구현할때 offset을 정수 값으로 때려 넣었는데, 나중에 Doc을 보니까 file name와 extra file의 길이가 offset 22부터 해서 저장되더라 제기랄 그거 볼걸 풀었으니 귀찮게 하지 말고 넘어가자

 

다음과 같은 출력결과를 얻을 수 있었다.

찾았다

Answer Url? : http://www.pythonchallenge.com/pc/def/hockey.html 

 

어? 다음과 같은 안내문이 있다.

공기 중에 있다고 한다. 글자를 보라는 안내문에 따라 HOCKEY를 이루고 있는 글자인 oxygen이 답인 듯하다

 Answer Url : http://www.pythonchallenge.com/pc/def/oxygen.html


여담으로 이 문제를 쉽게 해결하는 방법은 모듈 zipline을 이용하는 것이다. zipline을 활용하면 필자가 수동으로 했던 헤더 분석 및 추출 등을 보다 쉽게 할 수 있다. (필자는 왜 수동으로 허튼짓을 헷냐고? 내 맘이다 절대 늦게 봐서가 아니다)

Python Challenge 5의 url은 다음과 같다.

Python challenge 5 : http://www.pythonchallenge.com/pc/def/peak.html

 

peak hell

 

www.pythonchallenge.com


구성

무슨 사진이 떡하니 있다. 이번엔 특별한 상호작용도 없는 거 같다. 사진을 다운로드하여보면 사진 이름이 peakhell.jpg 이라는 점이 특이한 상황인 거 같다. 번역은 다음과 같다.

 

발음해봐

 

ㅋㅋㅋㅋ발음했다 포스팅 재목에


해결 아이디어

peakhell을 발음하면 피-켈이다. pickle이라는 모듈을 모듈 소개시간에 소개한 적이 있는데, 모르는 사람은 읽고 오기를 추천한다.

2021.04.11 - [분류 전체보기] - [Python] - 모듈탐구 pickle - 자료구조의 저장과 불러오기

 

[Python] - 모듈탐구 pickle - 자료구조의 저장과 불러오기

컴퓨터 세계에서 자주 사용되는 json이라는 표준이다. json은 Python을 자주 사용하는 사람이라면 아는 dictionary이라는 자료구조와 유사하게 생겼는데, 광범위하게 데이터 오브젝트를 인간이 읽을

tutoreducto.tistory.com

pickle은 파이선전용으로 자료를 직렬화 하기 위해 만들어진 모듈이다. 소스파일에 처음 보는 html 태그가 있다. 바로 <peakhell> 이라는 태그인데, src프로퍼티에 banner.p가 있다. 아마 이 banner.p에 우리 문제의 해결 key가 들어 있을 듯하다 다운로드하여 코딩 시간이다.

import pickle

if __name__=="__main__" :
  with open("banner.p","rb") as f :
    ans = pickle.load(f)

  print(ans)

출력 결과는 다음과 같다.

[[(' ', 95)], [(' ', 14), ('#', 5), (' ', 70), ('#', 5), (' ', 1)], 
[(' ', 15), ('#', 4), (' ', 71), ('#', 4), (' ', 1)], [(' ', 15), 
('#', 4), (' ', 71), ('#', 4), (' ', 1)], [(' ', 15), ('#', 4), 
(' ', 71), ('#', 4), (' ', 1)], [(' ', 15), ('#', 4), (' ', 71), 
('#', 4), (' ', 1)], [(' ', 15), ('#', 4), (' ', 71), ('#', 4), 
(' ', 1)], [(' ', 15), ('#', 4), (' ', 71), ('#', 4), (' ', 1)],
[(' ', 15), ('#', 4), (' ', 71), ('#', 4), (' ', 1)], [(' ', 6), 
('#', 3), (' ', 6), ('#', 4), (' ', 3), ('#', 3), (' ', 9), ('#', 3), 
(' ', 7), ('#', 5), (' ', 3), ('#', 3), (' ', 4), ('#', 5), (' ', 3), 
('#', 3), (' ', 10), ('#', 3), (' ', 7), ('#', 4), (' ', 1)], [(' ', 3), 
('#', 3), (' ', 3), ('#', 2), (' ', 4), ('#', 4), (' ', 1), ('#', 7),
(' ', 5), ('#', 2), (' ', 2), ('#', 3), (' ', 6), ('#', 4), (' ', 1),
('#', 7), (' ', 3), ('#', 4), (' ', 1), ('#', 7), (' ', 5), ('#', 3), 
(' ', 2), ('#', 3), (' ', 5), ('#', 4), (' ', 1)], [(' ', 2), ('#', 3), 
(' ', 5), ('#', 3), (' ', 2), ('#', 5), (' ', 4), ('#', 4), (' ', 3),
('#', 3), (' ', 3), ('#', 4), (' ', 4), ('#', 5), (' ', 4), ('#', 4),
(' ', 2), ('#', 5), (' ', 4), ('#', 4), (' ', 3), ('#', 3), (' ', 5),
('#', 3), (' ', 3), ('#', 4), (' ', 1)], [(' ', 1), ('#', 3), (' ', 11),
('#', 4), (' ', 5), ('#', 4), (' ', 3), ('#', 3), (' ', 4), ('#', 3), 
(' ', 4), ('#', 4), (' ', 5), ('#', 4), (' ', 2), ('#', 4), (' ', 5),
('#', 4), (' ', 2), ('#', 3), (' ', 6), ('#', 4), (' ', 2), ('#', 4),
(' ', 1)], [(' ', 1), ('#', 3), (' ', 11), ('#', 4), (' ', 5), ('#', 4),
(' ', 10), ('#', 3), (' ', 4), ('#', 4), (' ', 5), ('#', 4), (' ', 2), 
('#', 4), (' ', 5), ('#', 4), (' ', 2), ('#', 3), (' ', 7), ('#', 3), 
(' ', 2), ('#', 4), (' ', 1)], [('#', 4), (' ', 11), ('#', 4), (' ', 5),
('#', 4), (' ', 5), ('#', 2), (' ', 3), ('#', 3), (' ', 4), ('#', 4), 
(' ', 5), ('#', 4), (' ', 2), ('#', 4), (' ', 5), ('#', 4), (' ', 1), 
('#', 4), (' ', 7), ('#', 3), (' ', 2), ('#', 4), (' ', 1)], [('#', 4),
(' ', 11), ('#', 4), (' ', 5), ('#', 4), (' ', 3), ('#', 10), (' ', 4),
('#', 4), (' ', 5), ('#', 4), (' ', 2), ('#', 4), (' ', 5), ('#', 4), 
(' ', 1), ('#', 14), (' ', 2), ('#', 4), (' ', 1)], [('#', 4), (' ', 11),
('#', 4), (' ', 5), ('#', 4), (' ', 2), ('#', 3), (' ', 4), ('#', 4),
(' ', 4), ('#', 4), (' ', 5), ('#', 4), (' ', 2), ('#', 4), (' ', 5), 
('#', 4), (' ', 1), ('#', 4), (' ', 12), ('#', 4), (' ', 1)], [('#', 4), 
(' ', 11), ('#', 4), (' ', 5), ('#', 4), (' ', 1), ('#', 4), (' ', 5),
('#', 3), (' ', 4), ('#', 4), (' ', 5), ('#', 4), (' ', 2), ('#', 4),
(' ', 5), ('#', 4), (' ', 1), ('#', 4), (' ', 12), ('#', 4), (' ', 1)],
[(' ', 1), ('#', 3), (' ', 11), ('#', 4), (' ', 5), ('#', 4), (' ', 1), 
('#', 4), (' ', 5), ('#', 3), (' ', 4), ('#', 4), (' ', 5), ('#', 4), 
(' ', 2), ('#', 4), (' ', 5), ('#', 4), (' ', 2), ('#', 3), (' ', 12), 
('#', 4), (' ', 1)], [(' ', 2), ('#', 3), (' ', 6), ('#', 2), (' ', 2), 
('#', 4), (' ', 5), ('#', 4), (' ', 2), ('#', 3), (' ', 4), ('#', 4),
(' ', 4), ('#', 4), (' ', 5), ('#', 4), (' ', 2), ('#', 4), (' ', 5),
('#', 4), (' ', 3), ('#', 3), (' ', 6), ('#', 2), (' ', 3), ('#', 4), 
(' ', 1)], [(' ', 3), ('#', 3), (' ', 4), ('#', 2), (' ', 3), ('#', 4),
(' ', 5), ('#', 4), (' ', 3), ('#', 11), (' ', 3), ('#', 4), (' ', 5), 
('#', 4), (' ', 2), ('#', 4), (' ', 5), ('#', 4), (' ', 4), ('#', 3),
(' ', 4), ('#', 2), (' ', 4), ('#', 4), (' ', 1)], [(' ', 6), ('#', 3), 
(' ', 5), ('#', 6), (' ', 4), ('#', 5), (' ', 4), ('#', 2), (' ', 4),
('#', 4), (' ', 1), ('#', 6), (' ', 4), ('#', 11), (' ', 4), ('#', 5),
(' ', 6), ('#', 3), (' ', 6), ('#', 6)], [(' ', 95)]]

SHIT! 진정하자. 파일 이름이 banner임을 기억하자. " "와 "#"로 이루어진 것을 보면 이는 ASCII art일 가능성이 농후하다. 그도 그럴 것이 2차원 배열로 이루어진 이 자료구조 원소들의 1번째 인덱스의 합은 전부 95로 동일하다. 같은 길이의 행이라는 것을 암시하는 것이다. 코딩 타임이다.

import pickle

if __name__=="__main__" :
  with open("banner.p","rb") as f :
    ans = pickle.load(f)

  for i in range(len(ans)) :
    for j in range(len(ans[i])) :
      print(ans[i][j][0]*ans[i][j][1],end="")
    print("")

출력 결과는 다음과 같다. 잘려서 사진으로 올린다.

찾았다.

Answer Url : http://www.pythonchallenge.com/pc/def/channel.html

+ Recent posts