λ‚˜μ˜ 이야기/ν¬λž˜ν”„ν†€ μ •κΈ€

ν¬λž˜ν”„ν†€ μ •κΈ€ 1μ£Όμ°¨ WIL

Unused 2025. 3. 20. 16:31
WIL: Weekly I Learned; λ˜λŠ” What I Learned This Week

μ •κΈ€μ˜ μ„€κ²½

κ²¨μšΈμž…λ‹ˆλ‹€. μ‹œκ°„μ΄ 흘러 μ •κΈ€ μΊ νΌμŠ€μ—λ„ 첫눈이 λ‚΄λ ΈμŠ΅λ‹ˆλ‹€.κ°€ μ•„λ‹ˆλΌ 세상에, 3월에 이런 ν•¨λ°•λˆˆμ„ 보게 될 쀄은 λͺ°λžμŠ΅λ‹ˆλ‹€. 이런 광경은 2μ›” μ€‘μˆœμ΄μ—ˆλ˜κ°€, λ§ˆμ§€λ§‰μœΌλ‘œ 봀던 것 같은데, κ·Έλ•Œλ§Œ 해도 이런 λˆˆμ„ λ‹€μ‹œ 보렀면 λ‚΄λ…„κΉŒμ§€ κΈ°λ‹€λ €μ•Όκ² μ§€, ν–ˆμ§€μš”. 또 λ³Ό 쀄이야! λ„ˆλ¬΄λ‚˜ λ°˜κ°€μ› μŠ΅λ‹ˆλ‹€.

μ•Œκ³ λ¦¬μ¦˜ μž…λ¬Έ

ν¬λž˜ν”„ν†€ μ •κΈ€μ˜ μƒˆλ‘œμš΄ μ£Ό(ι€±)의 μ‹œμž‘μ€ 항상 λͺ©μš”μΌμž…λ‹ˆλ‹€. 이전 ν¬μŠ€νŠΈμ—μ„œ μ„€λͺ…ν•œ 0μ£Όμ°¨ λ―Έλ‹ˆ ν”„λ‘œμ νŠΈκ°€ λλ‚˜κ³ , μ €ν¬λŠ” μƒˆλ‘œμš΄ νŒ€μ„ λ°°μ •λ°›κ²Œ λ˜μ—ˆμŠ΅λ‹ˆλ‹€. μ •κΈ€ μ΄μ™Έμ˜ ν”„λ‘œκ·Έλž¨μ—μ„œ κ΅¬ν•˜κΈ° μ–΄λ €μš΄ 것 쀑 ν•˜λ‚˜κ°€ λ°”λ‘œ μ»΄ν“¨νŒ… 이둠에 λŒ€ν•œ λ™λ£Œ ν•™μŠ΅μΌ κ²ƒμž…λ‹ˆλ‹€. 이번 1μ£Όμ°¨μ—μ„œ μ €ν¬λŠ” 3인 1νŒ€μœΌλ‘œ μ»€λ¦¬ν˜λŸΌμ„ 따라가고, 맀일 1회 μ΄μƒμ˜ 'μ½”μ–΄ νƒ€μž„'을 톡해 λ™λ£Œλ“€λΌλ¦¬ 각자 ν•™μŠ΅ν•œ λ‚΄μš©κ³Ό μž‘μ„±ν•œ μ½”λ“œμ˜ 결과물듀을 μ„œλ‘œ κ³΅μœ ν•˜κ³  λ¦¬λ·°ν•˜μ˜€μŠ΅λ‹ˆλ‹€. κ°μ‚¬ν•˜κ²Œλ„, μ΄λ²ˆμ— μƒˆλ‘œμ΄ κ΅¬μ„±λœ νŒ€μ›λ“€ μ—­μ‹œ ν•™μŠ΅μ— λ„ˆλ¬΄λ‚˜λ„ 적극적인 μžμ„Έλ‘œ μ°Έμ—¬ν•΄μ£Όμ…¨μŠ΅λ‹ˆλ‹€.

이번 1μ£Όμ°¨λŠ” μ•Œκ³ λ¦¬μ¦˜μ— μž…λ¬Έν•˜λŠ” μ‹œκ°„μ΄μ—ˆμŠ΅λ‹ˆλ‹€. μ •κΈ€μ—μ„œ μ œκ°€ κ°€μž₯ κΈ°λŒ€ν–ˆλ˜ 것 쀑 ν•˜λ‚˜μž…λ‹ˆλ‹€. 컴퓨터 κ΄€λ ¨ν•˜μ—¬ 독학할 λ•Œ 개인적으둜 κ°€μž₯ νž˜λ“€μ—ˆλ˜ 것이 λ°”λ‘œ μ•Œκ³ λ¦¬μ¦˜κ³Ό μžλ£Œκ΅¬μ‘°μ˜€λŠ”λ°, μ •κΈ€μ—μ„œλŠ” λͺ°μž…κ³Ό λ™λ£Œ ν•™μŠ΅μ„ 톡해 Python의 κΈ°λ³Έ 문법과 λ°˜λ³΅λ¬Έμ„ μ΄μš©ν•œ κ΅¬ν˜„μœΌλ‘œλΆ€ν„° μ‹œμž‘ν•˜μ—¬ μž¬κ·€, μ •λ ¬, μ™„μ „νƒμƒ‰κΉŒμ§€ νŒŒν—€μΉ  수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

λ™λ£Œ ν•™μŠ΅

ꡬ체적으둜 λ°±μ€€ 9663번 N Queen 문제λ₯Ό λ“€ 수 μžˆκ² μŠ΅λ‹ˆλ‹€. μ–΄μ°Œμ €μ°Œ 문제의 νƒ€λ‹Ήν•œ 접근법은 κΉ¨μš°μ³€μ§€λ§Œ, μ•Œκ³ λ¦¬μ¦˜μ˜ A도 λͺ¨λ₯΄λ˜ μ œκ°€ μž¬κ·€μ˜ ν•„μš”μ„±μ— λŒ€ν•΄μ„œ 이해할 턱이 μ—†μ—ˆμŠ΅λ‹ˆλ‹€. κ·Έλž˜μ„œ λ‚˜μ˜¨ 첫 번째 결과물은 μ•„λž˜μ™€ κ°™μ•˜μŠ΅λ‹ˆλ‹€. (μ°Έκ³ : μ•ˆ λŒμ•„κ°‘λ‹ˆλ‹€ - λ°±νŠΈλž˜ν‚Ή μ μš©ν•˜λ‹€κ°€ μ‹€νŒ¨)

def pi_board():
    for b in board:
        print(b)
    input()
    
init_size = int(input())
board = [[False for _ in range(init_size)] for _ in range(init_size)]

# 각 rowλ§ˆλ‹€ 반볡
row = 0
prev_col = []
# 이전 column κΈ°μ–΅
while True:
    # Q 놓기 - λͺ¨λ“  row, col, λŒ€κ°μ„ μœΌλ‘œλ„
    col=0
    while True:
        # 놓을 수 μ—†μœΌλ©΄ μƒλž΅
        if board[row][col] == True: continue
        
        # 이 row의 λͺ¨λ“  col이 Trueλ©΄ 포기, 1 row 후퇴, 1 col μƒλž΅
        gave_up = True
        for col in board[row]:
            if board[row][col] == False: gave_up = False
        if gave_up == True: 
            board[row-1][prev_col.pop()] = True
            row = row-1
            continue;

        # 놓기 핡심 - 일단 ν˜„μž¬ col κΈ°μ–΅
        prev_col.append(col)

        # row 전체
        board[row] = [True]*init_size
        # col 전체
        for i in range(init_size):
            board[i][col] = True
        # λŒ€κ°μ„  전체
        for i in range(init_size):
            pi_board()
            # μš°ν•˜ν–₯ λŒ€κ°μ„ 
            # i 증가
            if not( (row+i) > (init_size-1) or (col+i) > (init_size-1) ): 
                print(f"i b{row+i} {col+i}")
                board[row+i][col+i] = True
            # i κ°μ†Œ
            if not( (row-i) < 0 or (col-i) < 0 ): 
                board[row-i][col-i] = True

            # μš°μƒν–₯ λŒ€κ°μ„ 
            # 증,감
            if not( (row+i) > (init_size-1) or (col-i) < 0) : 
                board[row+i][col-i] = True
            # 감,증
            if not( (row-i) < 0 or (col+i) > (init_size-1)) : 
                board[row-i][col+i] = True
        input("COL DONE")
        col +=1
        if col >= init_size: break

    row +=1
    if row >= init_size: break
print(board)

μ €λŸ° 60쀄이 λ„˜μ–΄κ°€λŠ” 3쀑 λ°˜λ³΅λ¬Έμ„ μ§œλ‹€κ°€ PTSDκ°€ λ„μ‘ŒμŠ΅λ‹ˆλ‹€. λ°”λ‘œ μ œκ°€ μ‹ μž… μ±„μš© μ½”λ”©ν…ŒμŠ€νŠΈλ₯Ό 보던 λ•Œκ°€ λ”± μ €λž¬κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€. 보톡 3λ¬Έμ œμ”© μΆœμ œλ˜λŠ”λ° 1λ²ˆμ€ μ›¬λ§Œν•˜λ©΄ λ‹¨μˆœ κ΅¬ν˜„μ΄λΌ μ λ‹Ήνžˆ 짜쑌고, 2λ²ˆμ„ ν’€ λ•Œ μ €λŸ° μ‹μ΄μ—ˆμŠ΅λ‹ˆλ‹€. μ €λ ‡κ²Œ 60쀄 100쀄씩 λ„˜μ–΄κ°€λŠ” (엉망진창인) μ½”λ“œ λ§Œλ“ λ‹€κ³  2μ‹œκ°„μ”© μŸμ•„λΆ“λ‹€κ°€, 운 μ’‹κ²Œ λŒμ•„κ°€λ©΄ κ·ΈλŒ€λ‘œ μ œμΆœν•˜λŠ” κ±°κ³ , λ‚˜μ˜λ©΄ κ·Έλƒ₯ ν¬κΈ°ν•˜κ³  λ§ˆλŠ” κ²ƒμž…λ‹ˆλ‹€. 3번 λ¬Έμ œλŠ” μ•„μ˜ˆ μ‹œλ„μ‘°μ°¨ λͺ»ν•˜λŠ” κ²½μš°κ°€ λŒ€λΆ€λΆ„μ΄μ—ˆμŠ΅λ‹ˆλ‹€.

ν•˜μ§€λ§Œ μ €λŠ” 이번 λ™λ£Œ ν•™μŠ΅μ„ 톡해 λ¬Έμ œμ— λŒ€ν•œ λ‹€λ₯Έ μ ‘κ·Ό 방식을 터득할 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€. λ°”λ‘œ, μ €λŸ° λ¬Έμ œμ— λŒ€ν•΄μ„œλŠ” λ°˜λ³΅λ¬Έμ„ μ§€μ–‘ν•˜κ³  μž¬κ·€λ₯Ό 톡해 문제λ₯Ό ν‘ΈλŠ” κ²ƒμž…λ‹ˆλ‹€. νŒ€μ›λ“€μ€ 각자 본인듀이 μž‘μ„±ν•œ μž¬κ·€λ₯Ό ν†΅ν•œ 접근법을 μ„€λͺ…ν•΄μ£Όμ…¨κ³ , κ·Έμ œμ„œμ•Ό μ €λŠ” μ•Œκ³ λ¦¬μ¦˜μ— λŒ€ν•œ μƒˆλ‘œμš΄ 관점을 터득할 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€. μž¬κ·€. μž¬κ·€κ°€ λ°”λ‘œ 첫 λ΄‰μš°λ¦¬μ˜€μŠ΅λ‹ˆλ‹€. λ‹¨μˆœνžˆ 문제의 λ‚΄μš©μ„ κΈ°κ³„μ²˜λŸΌ κ΅¬ν˜„ν•˜λ € λ“œλŠ” 것이 μ•„λ‹ˆλΌ, λ¬Έμ œλ‘œλΆ€ν„° νŒ¨ν„΄μ„ κ°„νŒŒν•΄μ•Ό 이λ₯Ό 기반으둜 μˆ˜λ„μ½”λ“œ(λ˜λŠ” 점화식)λ₯Ό λ„μΆœν•  수 있고, 이것이 μžˆμ–΄μ•Όλ§Œ λΉ„λ‘œμ†Œ μ œλŒ€λ‘œ 된 해결법을 μž‘μ„±ν•  수 μžˆμ—ˆλ˜ κ²ƒμž…λ‹ˆλ‹€. 개인적으둜 이것을 κΉ¨λ‹«κΈ°κΉŒμ§€ λ„˜μ–΄μ•Ό ν–ˆλ˜ λ΄‰μš°λ¦¬κ°€ λ°”λ‘œ μž¬κ·€μ˜€μŠ΅λ‹ˆλ‹€. λ™λ£Œ ν•™μŠ΅μ΄ μ—†μ—ˆλ‹€λ©΄ μ–»μ§€ λͺ»ν–ˆμ„ μΈμ‚¬μ΄νŠΈμΌ κ²ƒμž…λ‹ˆλ‹€.

μœ„ N Queen λ¬Έμ œλŠ” μ–΄λ–»κ²Œ λ˜μ—ˆμ„κΉŒμš”.

input_n = int(input().strip())

count = 0 # κ²°κ³Ό
col = [0] * input_n  # 각 ν–‰μ˜ ν€Έμ˜ μ—΄ 번호의 리슀트

# is_safeλŠ” μ§€κΈˆ 퀸을 놓을 후보 ν–‰(=row)κ³Ό 컬럼(=c)λ₯Ό λ°›μ•„, 이전에 놓은 퀸듀을 ν•˜λ‚˜ν•˜λ‚˜ μˆœνšŒν•˜λ©° μ•ˆμ „ν•œμ§€ 검사
def is_safe(row, c):
    result = True
    for i in range(row): # 이전 ν–‰λ“€μ˜ ν€Έλ“€κ³Ό μΆ©λŒν•˜λŠ”κ°€? 좩돌 μ¦‰μ‹œ False
        if col[i] == c or abs(col[i] - c) == row - i: # abs(col[i]-c)==row-i ==> 이전 ν€Έκ³Ό, λ†“μœΌλ €λŠ” μƒˆ ν€Έμ˜, ν–‰ 차이 == 컬럼 차이
            return False
    return result

def backtrack(row):
    global count
    if row == input_n: # 베이슀 쑰건 - λͺ¨λ“  행에 퀸을 λ†“μ•˜μœΌλ―€λ‘œ
        count += 1
        return
    for c in range(input_n): # c: ν˜„μž¬ 행에 놓을 후보 컬럼 번호
        if is_safe(row, c): # is_safe()κ°€ λͺ¨λ“  μ»¬λŸΌμ—μ„œ Falseλ©΄ backtrack()이 ν˜ΈμΆœλ˜μ§€ μ•ŠμŒ ==> μžμ—°μŠ€λŸ½κ²Œ λ‹€μŒμœΌλ‘œ λ„˜μ–΄κ°
            col[row] = c
            backtrack(row + 1)

backtrack(0) # 0번째 rowλΆ€ν„° μ‹œμž‘
print(count)

μž¬κ·€λ‘œ μ ‘κ·Όν•˜λ‹ˆ, κ΅¬ν˜„ν•˜λ‹€κ°€ 만 λ°±νŠΈλž˜ν‚ΉκΉŒμ§€ μ €λ ‡κ²Œ κ°„λ‹¨ν•˜κ²Œ λλ‚¬μŠ΅λ‹ˆλ‹€. 2차원 λ³΄λ“œλ₯Ό 1μ°¨μ›μœΌλ‘œ 쀄인 것은 λ€μž…λ‹ˆλ‹€.

갈 길은 λ©€λ‹€

ν¬λ‚˜ν° κΉ¨λ‹¬μŒμ„ μ£ΌλŠ” ν•œ μ£Όμ˜€μ§€λ§Œ μ΄λŠ” κ·Έμ € μ‹œμž‘μΌ 뿐, μ €λŠ” μ—¬μ „νžˆ λ³‘μ•„λ¦¬μž…λ‹ˆλ‹€. κ²Œμž„μœΌλ‘œ 치자면 마치 νŠœν† λ¦¬μ–Όμ„ 끝낸 레벨 1짜리 λ‰΄λΉ„λ‚˜ λ‹€λ¦„μ—†μŠ΅λ‹ˆλ‹€. μ•žμœΌλ‘œλ„ 이뢄탐색, 뢄할정볡, κ·Έλž˜ν”„, DFS(깊이 μš°μ„  탐색), BFS(λ„ˆλΉ„ μš°μ„  탐색), μœ„μƒμ •λ ¬(λ°©ν–₯ κ·Έλž˜ν”„μ—μ„œ λ…Έλ“œ μ •λ ¬ν•˜κΈ°), λ‹€μ΄λ‚˜λ―Ή ν”„λ‘œκ·Έλž˜λ°(κΈ°μ–΅μ‹œν‚€λ©° ν’€κΈ°), 그리디 μ•Œκ³ λ¦¬μ¦˜(λ§€μˆœκ°„ μ΅œμ ν•΄λ‘œμ¨ ν•΄κ²°ν•˜κΈ°)κ³Ό 같은 κ·Έλƒ₯ 읽기만 해도 λ¬΄μ‹œλ¬΄μ‹œν•œ 것듀이 μ €λ₯Ό λ§ˆμ£Όν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. 이외에도 μ €λ₯Ό κΈ°λ‹€λ¦¬λŠ” C 기반 자료ꡬ쑰 κ΅¬ν˜„, λ ˆλ“œ-λΈ”λž™ 트리, 말둝(malloc) 랩, PintOS와 같은 것듀 λͺ¨λ‘, μ œκ°€ μ»΄ν“¨ν„°κ³Όν•™μœΌλ‘œλΆ€ν„° ν•œ 발짝 λΉ„μΌœλ‚˜ μžˆμ„ λ•Œ 제 μΉœκ΅¬λ“€μ΄ ν•™λΆ€μ—μ„œ λΉ„λͺ…을 μ§€λ₯΄λ©° μˆ˜ν–‰ν–ˆλ˜ κ³Όμ œλ“€μž…λ‹ˆλ‹€. ν”Όν•˜κ³  μ‹Άμ—ˆμ§€λ§Œ, κ·Έλž˜μ„œ μ—¬νƒœκΉŒμ§€ ν”Όν•΄μ™”μ§€λ§Œ, ν”Όν•  수 μ—†μ—ˆμŠ΅λ‹ˆλ‹€. μ œκ°€ κΏˆκΎΈμ—ˆλ˜ λͺ¨λ“  컀리어 νŒ¨μŠ€λŠ” 이λ₯Ό μš”κ΅¬ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. 이제 더 이상 λ¬ΌλŸ¬λ‚  곳은 μ—†μŠ΅λ‹ˆλ‹€.

μ–΄μ œ μ•Œκ³ λ¦¬μ¦˜ νŠΉκ°•μ„ ν•΄μ£Όμ‹ , κ²Œμž„λž© μ½”μΉ˜λ‹˜κ»˜μ„œλŠ” μ•Œκ³ λ¦¬μ¦˜ 문제 팁으둜 μ•„λž˜μ™€ 같이 λ§μ”€ν•˜μ…¨μŠ΅λ‹ˆλ‹€.

  • 문제의 μ‚¬μ΄μ¦ˆλ₯Ό 쀄여라. 예: n개 => 3개둜 쀄이기, λ‹¨μˆœν™”μ‹œν‚€κΈ°.
  • 점화식은 μž‘μ€ λ¬Έμ œλ“€μ΄ λͺ¨μ—¬ 큰 문제λ₯Ό μ΄λ£¨λŠ” 것.

인생도 μ–΄μ©Œλ©΄ 이와 λ‹€λ₯΄μ§€ μ•Šμ„ 수 μžˆκ² μŠ΅λ‹ˆλ‹€. μ»€λ‹€λž€ λ¬Έμ œλ“€μ΄ 산적해 μžˆλŠ” 것은 μ •κΈ€λΏλ§Œ μ•„λ‹ˆλΌ μš°λ¦¬λ„€ 인생도 λ§ˆμ°¬κ°€μ§€μ΄λ©°, 이것이 λͺ¨μ—¬ μ‚¬νšŒλ‘œ μ΄μ–΄μ§‘λ‹ˆλ‹€. κ·Έλ ‡μ§€λ§Œ, 그럴수둝, μ œκ°€ ν’€ 수 μžˆλŠ” κ·Έ μž‘μ€ 쑰각뢀터 μ°Ύμ•„λ‚΄μ–΄ ν•΄κ²°ν•΄λ΄…λ‹ˆλ‹€. κ·Έμ € λ¬Έμ œκ°€ ν•˜λ‚˜ν•˜λ‚˜ 풀릴 λ•Œλ§ˆλ‹€ λŠκ»΄μ§€λŠ” μœ ν¬λ¦¬μ•„λ§Œμ΄ μ €λ₯Ό μ•žμœΌλ‘œ λ‚˜μ•„κ°€κ²Œ ν•  λΏμž…λ‹ˆλ‹€.