코드 출현 2020 - 3일차

13142 단어
연휴(및 프로그래밍) 정신으로 Advent of Code 2020 퍼즐에 대한 솔루션을 여기에 게시할 예정입니다. 게시된 후 적어도 하루 후에 여기에 게시할 예정입니다(스포일러 없음!). R로 솔루션을 구현할 것입니다. 왜냐하면 그게 제가 좋아하는 것이기 때문입니다! 내가 하지 않을 일은 실제 답변을 게시하는 것입니다.

또한 일반적으로 퍼즐에 다운로드 가능한 입력이 있을 때마다 input.txt라는 파일에 저장합니다.

3일차 - 터보건 궤적



문제 설명을 찾습니다HERE.

파트 1 - 미끄러운 슬로프



이 문제는 아주 재미있을 것 같습니다! 기본적으로 문자의 2차원 배열(여기서 .은 빈 공간을 나타내고 #는 나무를 나타냄), 시작 위치 및 지도를 가로지르는 방향이 주어지면 여행하는 동안 얼마나 많은 나무에 착지하는지 계산해야 합니다. 지도 아래로. 추가 '트위스트'는 가로로 반복되는 맵의 가장 왼쪽 부분만 제공된다는 것입니다. 땀 없습니다! 사실 이것은 R 행렬을 사용하는 완벽한 변명입니다.

# Helper function, converts a character map to a matrix, where each character
# is held in a corresponding matrix index
trees_map <- function(pattern) {
  pattern_no_whitespace <- str_remove_all(pattern, '[\\t]')
  lines <- str_split(pattern_no_whitespace, '\n', simplify = T)
  line_vecs <- str_split(lines, '')
  mmap <- reduce(line_vecs, rbind)
  row.names(mmap) <- seq(nrow(mmap))

  mmap
}

# The main function, traverses the map and counts the number of trees 
# encountered given a matrix of `.`s and `#`s (tmap) and a vector containing
# the number of rows to move down and the number of columns to move right with
# each iteration (slope)
trees_encountered <- function(tmap, slope) {
  cursor <- c(row = 1, col = 1)
  trees <- list()
  map_h <- nrow(tmap) # Initial matrix dimensions
  map_w <- ncol(tmap) # Initial matrix dimensions

  while(cursor['row'] <= nrow(tmap)) {
    # If the cursor is on the right edge of the map, extend the map by
    # adding a copy of the original to the right
    if (cursor['col'] > ncol(tmap)) {
      tmap <- cbind(tmap, tmap[1:map_h, 1:map_w])
    }

    # If the cursor is on a tree, add the tree to the list
    if (tmap[cursor['row'], cursor['col']] == '#') {
      trees[[length(trees) + 1]] <- cursor
    }

    # Move the cursor according to the current slope
    cursor <- cursor + slope
  }

  trees # Return a list coordinates for trees encountered (row, col)
}

tmap <- trees_map(input)
found_trees <- trees_encountered(tmap, c(1, 3)) # The test slope
answer = length(found_trees)



이제 "커서가 행렬의 오른쪽에 도달했을 때 커서를 가로로 감싸는 것이 더 효율적이지 않을까요?"라고 생각할 수 있습니다. 대답은 이렇습니다. 예, 물론입니다. 하지만 이 달콤한 애니메이션을 만들 수는 없었습니다!



이것은 기울기가 c(1, 3)인 테스트 맵을 순회하는 알고리즘을 보여줍니다. 행렬 좌표는 [x, y] 또는 [column, row]의 데카르트 형식과 반대인 [행, 열] 형식임을 기억하십시오.

2부 - 시지프 썰매



여행이 목적지가 아니라 중요한 부분이었던 것 같습니다. 문제의 두 번째 부분은 개념적으로 언덕을 다시 오르고 다른 경사를 따라 다시 내려오면서 답을 찾기 위해 각 여행의 나무 수를 곱하는 것입니다. . 불행히도 우리는 이미 상당히 일반적인 방법으로 경사를 횡단하는 방법을 알아냈으므로 이 부분에 대한 해결책은 우리 함수를 다시 사용하는 것입니다.

# All the slopes we need to traverse
slopes <- list(c(1, 1), c(1, 3), c(1, 5), c(1, 7), c(2, 1))

# Traverse each slope and identify the trees
all_trees <- sapply(slopes, trees_encountered, tmap = trees_map(input))
answer <- prod(lengths(all_trees)) 



나는 '불행히도'라고 말하지만, 이것은 더 큰 데이터 세트에 대한 반복 작업 작업을 단순화함으로써 R이 정말 빛나는 곳 중 하나입니다.

마무리



3일차는 함수를 반복해서 쉽게 적용할 수 있게 해주는 기본 2차원 데이터 구조와 함수를 사용하여 R에서 구현하는 것이 거의 불공평하다고 느꼈습니다(I'm looking at you, apply family). 반면에 나는 일상 업무에서 행렬을 많이 사용하지 않기 때문에 행렬 수학과 인덱싱의 안팎을 연습할 변명을 갖는 것은 아마도 지적으로 말하면 야채를 먹는 것으로 간주될 것입니다. 다른 솔루션을 찾았거나 내 솔루션 중 하나에서 실수를 발견한 경우 저에게 연락해 주세요!

좋은 웹페이지 즐겨찾기