처음에 페이지 소스 보기를 해도 아무런 것이 안보여서 저 줄에서 문제가 있을 거라 생각을했다. 보게되면 일정한 규칙으로 색이 변하는 것을 볼 수 있다.

어떤 rgb인지 확인하기 위해 pillow 이미지 편집 라이브러리를 사용하여 아래와 같이 해당 부분만 편집하여 데이터를 저장후 각 픽셀이 가진 rgb를 찾았다.

아래는 위 이미지 처리 및 rgb를 검출해 내는 코드이다. rgb를 보니 ascii 코드와 유사하다 생각하여 chr를 이용하여 문자열로 변환하였다.

from msilib.schema import Feature
from PIL import Image
img = Image.open("C:\\Users\\Jeong\\Desktop\\oxygen.png")
# 629,95
crop_img = img.crop((0,43,608,52)).convert('RGB')
img.crop((0,43,608,52)).show()
rgb_data = ""
for i in range(0,608,7):
    r,g,b = crop_img.getpixel((i,0))
    rgb_data += chr(r)            
    

print(rgb_data)

# -----------------------------------------------------
rgb_data 내용


last_data= ""
list = [105, 110, 116, 101, 103, 114, 105, 116, 121]
for i in list:
    last_data += chr(i)
    

print(last_data)

출력 : smart guy, you made it. the next level is [105, 110, 116, 101, 103, 114, 105, 116, 121]

와 같이 나왔고 is 뒤 문장을 다시 ascii 코드로 변환하면 답이 나오게 된다.

 

 

 

 

++ 맨처음 간격을 정하지 않고 1의 간격으로 잘라서 만약 전 rgb 데이터와 일치하지 않는 경우만 if문으로 잡아내 데이터를 집어넣었더니 중복된 데이터의 경우 검출하지 않는 문제가 발생하였다. 예를들면 110 같은 경우 1을 중복데이터라 보고 10을 치환해주는 것이다. 이런것도 잘 고려하여 코드를 작성해야할 필요성이 있다.

 

문제 풀때 참고한 사이트

https://coding-kindergarten.tistory.com/158

 

[Python/Pillow] 파이썬 이미징 라이브러리(PIL)_2편.이미지 크기 변경(resize), 자르기(crop), 회전(rotate),

안녕하세요, 왕초보 코린이를 위한 코딩유치원에 오신 것을 환영합니다. 코딩유치원에서는 파이썬 기초부터 사무자동화, 웹크롤링, 데이터 분석 등의 다양한 패키지까지 초보자도 알기 쉽도

coding-kindergarten.tistory.com

 

다음 Level 8 주소

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

TypeScript란 범용성이 넓은 자바스크립트 특성상 문법적인 허용범위가 너무 넓어서 코드가 정상적으로 컴파일 되더라도 실행에 문제가 생기는 경우가 많았다. 이것을 해결하기위해 문법적인 부분을 추가한 것이 Typescript라 보면되겠다. 거의 똑같다.

 

우선

https://nodejs.org/ko/

 

Node.js

Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

nodejs.org

node -v
npm -v

yarn 설치

보통 npm을 명령어로 설치하지만 페이스북이 만든 자바스크립트 패키지 매니저로 yarn이 더 안정성과 보안성이 뛰어나다고 알려져있다.

npm install yarn -g
//작업 폴더 만들기
yarn init -y

//타입스크립트를 글로벌 전역으로 설치한다.
yarn install -g typescript

// 환경설정 파일 설치
 tsc --init
 
 //만약 tsc --init 작동안할시
 
 tsc -watch 입력후 실행

tsc --init 문제가 초기에 해결이 안됐는데 아래와 같은 문구를 출력하였다. 이는 tsc -watch를 실행한 후에는 정상적으로 작동하였다.

error TS6231: Could not resolve the path '—init' with the extensions: '.ts', '.tsx', '.d.ts', '.cts', '.d.cts', '.mts', '.d.mts'.
  The file is in the program because:
    Root file specified for compilation

그러면 아래와 같이 파일이 생성되게 된다.

 

//Typescrpt를 node에서 실행가능하도록 런타임 설치
//ts를 js로 컴파일하여 js로 실행하도록 해준다.

yarn i ts-node --save-dev

 

yarn create next-app --typescript 프로젝트명

프로젝트명에는 대문자 x 


//아래 문구를 실행할때에는 무조건 행 프로젝트 디렉토리에서 실행해야한다.
yarn dev



//Eslin는 정해진 코드 포멧을 따르지 않을경우 에러를 표시해주는것으로 .eslintrc.json파일 안에 규칙을 정의한다.
yarn add -D @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-config-next eslint-config-prettier
.eslintrc.json 파일이 있을텐데 다 지우고 아래를 복붙



{
  "env": {
    "browser": true,
    "es6": true,
    "node": true
  },
  "parser": "@typescript-eslint/parser",
  "plugins": ["@typescript-eslint"],
  "extends": [
    "next/core-web-vitals",
    "plugin:@typescript-eslint/recommended",
    "prettier"
  ],
  "rules": {
    "@typescript-eslint/no-unused-vars": "error", // 사용되지 않는 변수를 에러로 인식
    "@typescript-eslint/no-explicit-any": "error" // any 타입 정의를 에러로 인식
  }
}
yarn add -D prettier



.prettierrc.json 해당 프로젝트 경로에 생성
//일반적인 .prettierrc.json 규칙 아래와 같이 정의
{
  "semi": false,
  "trailingComma": "es5",
  "singleQuote": true,
  "tabWidth": 2,
  "useTabs": false
}

Default formatter를 아래와 같이 설정

format on save 도 설정

페이팔이 적혀있길래 페이팔에 힌트가 있는줄 알았다.. 하지만 후원을 부탁하는 링크였고...

핵심은 아래 사진과 같이 zip이라는 주석을 볼 수 있다. 이를 통해 zip이라는 파일이 존재한다고 생각하여

http://www.pythonchallenge.com/pc/def/channel.zip 이라는링크를 들어간 결과 하나의 압축파일이 저장되었다.

해당 파일을 열어본 결과 저번 문제풀이와 동일하게 해당 파일을 열어 다음 경로로 이동하는 txt 파일이존재하였다. 또한 readme.txt 파일이 있어서 열어본 결과 아래 내용이 있었다. zip 파일을 이용할 것이고 번호의 시작은 90052이다.

------------------------------------------

welcome to my zipped list.

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

------------------------------------------

이를 처음에 해석하기 위해 압축파일을 풀어서 open을 txt로 지정하여 문제를 푼 결과

Collect the comments.

라는 문구가 출력되었다.

comment가 뭐지? 라고 검색한 결과 zip 파일안에 각각에 파일에는 코멘트가 존재하는데 이것을 읽어서 출력하라는 것이였다.

이를 위해

zip 파일 자체를 불러와 각각의 파일을 내부에 적혀있는 순서대로 넣고 각 comment는 더하여 아래와 같이 출력되도록 하였다.

 

import re
import zipfile

zip_data = zipfile.ZipFile("C:\\Users\\JH\\Desktop\\channel.zip", "r")

def zip_read(txt):
	zip_comment = zip_data.read(str(txt)+".txt").decode('utf-8')
	next_txt = re.sub(r'[^0-9]', '', zip_comment)
	return next_txt

txt = 90052
comment = ""
while True:
    try:
        txt_end = txt
        txt = str(zip_read(txt))
        if txt == "":
            print('end')
            print(txt_end)
            answer = 	zip_comment = zip_data.read(txt_end+".txt").decode('utf-8')
            print("답 : " + answer)
            break
        else:
            comment += zip_data.getinfo(txt+".txt").comment.decode('utf-8')
            next
    except:
        print("why Error")
        break    
    
print(comment)

comment 출력 결과

해당 주소로 들어갔는데 아래와 같은 글이 출력되었다. 여기가 아니니 다시 내용을 보라는 것이였는데

보게되면 oxygen 이라는 알파벳으로 각 단어가 작성된 것을 볼 수 있다.

다음 링크는 oxyzen이다.

 

아래코드는 txt 파일을 순차적으로 읽어오는 코드이다. 작성은 했는데 해당 문제를 풀 때는 필요가 없었다. 하지만 혹시몰라 적어놓는다.

import re

def txt_read(txt):
    txt_data = open('C:\\Users\\JH\\Desktop\\channel\\'+str(txt)+'.txt',"r",encoding = 'utf-8').read()
    next_txt = re.sub(r'[^0-9]', '', txt_data)
    return next_txt

txt = 90052 
while True:
    try:
        txt_end = txt
        txt = txt_read(txt)
        if str(txt) == "":
            print('end')
            print(str(txt_end))
            answer = open('C:\\Users\\JH\\Desktop\\channel\\'+str(txt_end)+'.txt',"r",encoding = 'utf-8').read()
            print("답 : " + answer)
            break
        else:
            next
    except:
        print("why Error")
        break

다음 주소 링크

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

이 문제의 경우도 page 소스 보기를 했을 때  아래와 같이 나왔다. banner.p 라는 파일을 이용하라는 것 같아 확장자명을 해 본 결과 해당 파일은 pickle 라는 라이브러리가 저장하는 파일이였다.

pickle이란 파일을 객체 상태로 저장하여 나중에 읽을 때 조금 더 손쉽게 데이터에 접근하기 위해 저장하는 방식이다.

<html>
<head>
  <title>peak hell</title>
  <link rel="stylesheet" type="text/css" href="../style.css">
</head>
<body>
<center>
<img src="peakhell.jpg"/>
<br><font color="#c0c0ff">
pronounce it
<br>
<peakhell src="banner.p"/>
</body>
</html>

<!-- peak hell sounds familiar ? -->

처음 데이터를 불러왔을 때 아래와 같이 되어 있었는데 특수문자와 공백 그리고 그 뒤에 숫자가 오는 것으로 보아 특정한 규칙으로 그림 형식을 만드는 것이라 생각했다

리스트 안에 튜플이 있는 구조

그래서 아래와 같이 첫번째 값을 가져와 튜플의 값을 곱한뒤 result 에 저장 후 반복하여 그림을 출력하였다.

import pickle, urllib.request
url_data = urllib.request.urlopen('http://www.pythonchallenge.com/pc/def/banner.p')
data = pickle.load(url_data)
url_data.close()
result = ""
for list_data in data:
        print(result)
        result = ""
        for tuple_data in list_data:
            result += (''.join(tuple_data[0]) * tuple_data[1])

 

Level 4를 들어가니 이상한 그림이 나왔다. 이전 Level 과 동일하게 페이지 소스 보기를 하니 아래와 같은 소스가 나왔다.

주석 내용은 urllib를 사용하는 것이 도움이 될 것이고 끝날때 까지 계속 시도하라 400번이 넘는 것이 필요할 것이다.

라고 적혀 있다.

그리고 href로 다음 링크로 안내해주는 코드가 있었다.

<html>
<head>
  <title>follow the chain</title>
  <link rel="stylesheet" type="text/css" href="../style.css">
</head>
<body>
<!-- urllib may help. DON'T TRY ALL NOTHINGS, since it will never 
end. 400 times is more than enough. -->
<center>
<a href="linkedlist.php?nothing=12345"><img src="chainsaw.jpg" border="0"/></a>
<br><br><font color="gold"></center>
Solutions to previous levels: <a href="http://wiki.pythonchallenge.com/"/>Python Challenge wiki</a>.
<br><br>
IRC: irc.freenode.net #pythonchallenge
</body>
</html>

 

해당 링크로 들어가니 아래와 같이 다음 44827를 대입해서 다음으로 넘어가라는 코드가 있다.

이는 계속 반복되고 끝날때 까지 돌아갈 것이다. 

문제는 400번 이상의 횟수를 반복해야하기 때문에 코드로 작성해야한다는 것이다.

파이썬 코드로 아래를 작성해 보았다.

from urllib.request import urlopen
import re

def url_read(url):
    url_data = urlopen('http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing='+str(url)).read().decode('utf-8')
    next_url = re.sub(r'[^0-9]', '', url_data)
    return next_url

url = 12345

while True:
    try:
        url_end = url
        url = url_read(url)
        print(url)
        if str(url) == "":
            print('end')
            print(url_end)
            print(urlopen('http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing='+str(url_end)).read().decode('utf-8'))
            break
    except:
        print(url)

작동하다가 멈춰서 내용을 보니 아래와 같은 문구가 떠서 해당 url을 다시 반으로 나누고 코드를 실행하니 

다음 Level 5 url

http://www.pythonchallenge.com/pc/def/peak.html

 

처음에 "One small letter, surrounded by EXACTLY three big bodyguards on each of its sides." 이것이 무슨의미인지 몰라서 계속 해맸다. 

그래서 AAAcDDD 이런 글자를 도출하는 코드를 작성하였는데 값이 너무 많이나와서 생각해보니 주변에 3개의 대문자라는 것은 4개의 대문자가 오면 안되는 것이였다.

그래서 양쪽에 aDDDaCCCa 이런식으로 와야하는 것이다.

이를 if 문으로 작성하긴 했는데 너무 비효율적이다. 나머지 하나는 친구가 작성한것데 이게 훨 나은거 같기도.

더보기
import re

 

data = open('pc.txt', 'r').read()



a = False
b = 0
c = 0
x = ""
find = ""
for i in data:
    # 소문자일 때 들어가는 if문
    if(a == False and c != 3):
        if(i.islower() == True):
            a = True
            c += 1  # 소문자를 새는 곳
            x += i
            if(c == 3):
                find += x
                find += ","
                x = ""
                a = False
                c = 0
        elif(i.islower() == False):
            a = False
            b = 0
            c = 0
            x = ""
    elif(a == True and i.islower() == True):
        if(c == 1 or c == 2 or c == 3):
            a = True
            b = 0
            c = 1
            x = i

 

    # 대문자일 때 들어가는 if 문
    elif(a == True and b != 3):
        if(i.isupper() == True):
            b += 1
            x += i
            if(b == 3 and c == 1):
                a = False
                b = 0

 

            elif(b == 3 and c == 2):
                a = False
                b = 0
        else:  # 영문을 제외한 특수문자 및 수자를 처리해야할 곳
            a = False
            b = 0
            c = 0
            x = ""
 
result = ""
find_list = find.split(',')
find_list = list(filter(None, find_list))
for i in find_list:
    result += i[4]
print(result)

 

 

이건 친구가 만든 코드에 내가 수정을 하여 더 보기 쉽게 해놓았다.

 

더보기
chall_data = open("pc.txt", 'r', encoding='UTF-8')
find_data = chall_data.read()

 

new_string = find_data.replace("\n", "")

 

check_data = []
data = []

 

for i in range(0, len(new_string)-9):
    if new_string[i].isupper() == True:
        if new_string[i+1].isupper() == True:
            if new_string[i+2].isupper() == True:
                if new_string[i+4].isupper() == True:
                    if new_string[i+5].isupper() == True:
                        if new_string[i+6].isupper() == True:
                            if new_string[i+3].isupper() == False and new_string[i-1].isupper() == False and new_string[i+7].isupper() == False:
                                check_data.append(new_string[i-1:i+8])
                                data.append(new_string[i+3])

 

chall_data.close()
result = ""
for i in data:
    result += i
print(check_data)
print(result)

 

다음 Level 4 링크  http://www.pythonchallenge.com/pc/def/linkedlist.php

+ Recent posts