코드 출현 2015 - 3일차

12539 단어 adventofcodepython
나는 오늘의 퍼즐에 대한 우아한 해결책을 찾기 위해 고군분투했지만 다른 몇몇 사람들은 해냈습니다. 먼저 1부입니다.



우리는 산타가 동서남북으로 이동하면서 그가 얼마나 많은 장소를 방문하는지 기록하도록 요청받았습니다. 2부를 미리 생각하면서 그가 가장 많이 방문한 곳을 찾아야 할 텐데, 오늘은 다른 일을 염두에 두었습니다.

내 접근 방식은 산타의 dictx 좌표의 튜플을 키로 하는 y 를 만드는 것이었습니다. 2부에 뭐가 있는지 누가 알겠어?! 그의 움직임을 기록하는 내 코드는 다른 사람들이 내놓은 Pythonic 솔루션에 비해 약간 서투른 것처럼 보이지만 작동했습니다. 기본 코드와 함께 인라인으로 시작했지만 결국 2부 때문에 자체 함수에 넣었습니다.

def increment_house(x, y, houses):
    if (x, y) in houses:
        houses[(x, y)] += 1
    else:
        houses[(x, y)] = 1

def calc_move(x, y, move):
    if move == '^':
        y += 1
    elif move == 'v':
        y -= 1
    elif move == '>':
        x += 1
    else:
        x -= 1
    return x, y

santaX = 0
santaY = 0
houses = {}
increment_house(santaX, santaY, houses)
for char in data:
    santaX, santaY = calc_move(santaX, santaY, char)
    increment_house(santaX, santaY, houses)
print(len(houses))


많은 코드가 있지만 상당히 읽기 쉽고 작업이 완료되었으므로 이제 2부로 넘어갑니다!



산타의 방문 횟수를 세는 대신 새로운 캐릭터를 소개합니다! 이제 우리는 산타의 로봇도 추적하고 있는데, 이는 제 코드에서 calc_move()가 얼마나 일반적인지 설명합니다. 위의 동일한 두 기능을 사용하여 제 2부 솔루션은 다음과 같습니다.

santaX = 0
santaY = 0
robX = 0
robY = 0
houses = {}
increment_house(santaX, santaY, houses)
increment_house(robX, robY, houses)
moveSanta = True
for char in data:
    if moveSanta:
        santaX, santaY = calc_move(santaX, santaY, char)
        increment_house(santaX, santaY, houses)
        moveSanta = False
    else:
        robX, robY = calc_move(robX, robY, char)
        increment_house(robX, robY, houses)
        moveSanta = True
print(len(houses))


모듈로 나누기를 사용하여 누가 이동하는지 결정하는 몇 가지 예를 보았습니다. 그러면 코드가 원하는 만큼 많은 문자를 추적할 수 있지만 부울은 두 문자에 대해 충분히 잘 작동했습니다.

파이썬에 가까워지기!



megathread에서 다른 사람들의 솔루션을 살펴보면 한 줄의 코드만으로 문자를 이동하는 데 dict를 사용할 수 있음을 발견했습니다.

def calc_move(c, p):
    return { '>': (p[0] + 1, p[1]), '<': (p[0] - 1, p[1]), '^': (p[0], p[1] + 1), 'v': (p[0], p[1] - 1) }[c];


이 코드에서 현재 좌표는 p 튜플로 전달되며 이동 방향은 문자 c 입니다. 이 문자는 동시에 조회되는 사전의 4개 항목에 대한 키이며 그에 따라 좌표가 업데이트됩니다. 나는 이것이 정말 우아하다는 것을 알았습니다. 우아함은 코더가 진정한 Pythonic을 찾는 열쇠 중 하나인 것 같습니다.

진정한 골프!



나는 또한 this Python one-liner을 찾았는데, 나는 그것이 효과가 있다고 추정하고(나는 그것을 테스트하지 않았음) 그것을 응시하고 수많은 커피를 마셨음에도 불구하고 여전히 그것이 무엇을 하는지 이해할 수 없습니다. 그럼에도 불구하고 인상적입니다!

len(set.union(*(set((tuple(map(sum, zip(*({">": (1, 0), "<": (-1, 0), "^": (0, 1), "v": (0, -1)}[v] for v in y[:z])))) for z in range(len(y)))) for y in (data[x::2] for x in [0, 1]))))

set 개체를 사용하여 컬렉션에 각 항목 중 하나만 포함되도록 하는 것 외에 다른 작업을 수행하지 않았으므로 여기서는 set.union()가 수행하는 작업만 추측할 수 있습니다. 마찬가지로 zip()가 많은 Python 코드에서 사용되는 것을 보았지만 실제로 무엇을 하는지 문서를 자세히 살펴보지는 않았습니다.

(* 알고 보니 각 위치를 몇 번이나 방문했는지 일일이 셀 필요가 없었기 때문에 set()houses를 사용하여 약간의 시간을 절약할 수 있었습니다.)

좋은 웹페이지 즐겨찾기