library(dplyr) asLines <- readLines("d12.txt") height <- length(asLines) width <- nchar(asLines[1]) chars <- strsplit(paste(asLines, collapse = ""), "")[[1]] aCropMatrix <- matrix(chars, nrow = height, byrow = TRUE) aFieldMatrix <- matrix(1:length(chars), nrow = height, byrow = TRUE) priorFieldMatrix <- matrix(rep(1, length(chars)), nrow = height, byrow = TRUE) while (!identical(priorFieldMatrix, aFieldMatrix)) { priorFieldMatrix <- aFieldMatrix for (i in 1:(height)) { for (j in 1:(width)) { if (i < height) { if (aCropMatrix[i, j] == aCropMatrix[i + 1, j]) { aFieldMatrix[aFieldMatrix == aFieldMatrix[i + 1, j]] <- aFieldMatrix[i, j] } } if (j < width) { if (aCropMatrix[i, j] == aCropMatrix[i, j + 1]) { aFieldMatrix[aFieldMatrix == aFieldMatrix[i, j + 1]] <- aFieldMatrix[i, j] } } } } for (i in (height):1) { for (j in (width):1) { if (i > 1) { if (aCropMatrix[i, j] == aCropMatrix[i - 1, j]) { aFieldMatrix[aFieldMatrix == aFieldMatrix[i - 1, j]] <- aFieldMatrix[i, j] } } if (j > 1) { if (aCropMatrix[i, j] == aCropMatrix[i, j - 1]) { aFieldMatrix[aFieldMatrix == aFieldMatrix[i, j - 1]] <- aFieldMatrix[i, j] } } } } } zoning <- function(x, reference = aFieldMatrix) { starting <- as.data.frame(which(reference == x, arr.ind = TRUE)) |> mutate(field = x) return(starting) } zonespace <- bind_rows(lapply(unique(as.vector(aFieldMatrix)), zoning)) areas <- zonespace |> summarise(.by = field, area = n()) |> filter(field != -1) looktosouth <- zonespace |> mutate(adjrow = row, adjcol=col,row=row-1, col=col) looktonorth <- zonespace |> mutate(adjrow = row, adjcol=col,row=row+1, col=col) looktowest <- zonespace |> mutate(adjrow = row, adjcol=col,col=col+1, row=row) looktoeast <- zonespace |> mutate(adjrow = row, adjcol=col,col=col-1, row=row) bufferabove = data.frame(row = 1, col=1:width, field=-1, adjrow=0, adjcol=1:width) bufferleft = data.frame(row = 1:height, col=1, field=-1, adjrow=1:height, adjcol=0) bufferbelow = data.frame(row = height, col=1:width, field=-1, adjrow=height+1, adjcol=1:width) bufferright = data.frame(row = 1:height, col=width, field=-1, adjrow=1:height, adjcol=width+1) neighbour <- bind_rows(looktosouth,looktonorth,looktowest,looktoeast, bufferabove,bufferleft,bufferbelow,bufferright) |> rename(adjacentfield =field) borders <- zonespace |> left_join(neighbour, by=join_by(row,col)) fences <- borders |> summarise(.by = field, fences = sum(field !=adjacentfield)) areas |> inner_join(fences, by="field") |> mutate(costs = area*fences) |> summarise(sum(costs)) # part2 a side is a run length encoded section of fence on the horizontal # and vertical rleish <- function(x, direction, reference=borders){ if(direction == "vertical"){ interest <- reference |> filter(col == x & adjcol==(x-1)) |> arrange(row) |> mutate(isFence = ifelse(field != adjacentfield, field, NA)) rl <- rle(interest$isFence) fencing1 <- rl$values[!is.na(rl$values)] interest <- reference |> filter(col == x & adjcol==(x+1)) |> arrange(row) |> mutate(isFence = ifelse(field != adjacentfield, field, NA)) rl <- rle(interest$isFence) fencing2 <- rl$values[!is.na(rl$values)] output <- c(fencing1,fencing2) } if(direction == "horizontal"){ interest <- reference |> filter(row == x, adjrow==x-1) |> arrange(col) |> mutate(isFence = ifelse(field != adjacentfield, field, NA)) rl <- rle(interest$isFence) fencing1 <- rl$values[!is.na(rl$values)] interest <- reference |> filter(row == x, adjrow==x+1) |> arrange(col) |> mutate(isFence = ifelse(field != adjacentfield, field, NA)) rl <- rle(interest$isFence) fencing2 <- rl$values[!is.na(rl$values)] output <- c(fencing1,fencing2) } return(output) } vfnc <- unlist(lapply(1:width, rleish, direction = "vertical")) hfnc <- unlist(lapply(1:height, rleish, direction = "horizontal")) fencePer <- table(c(vfnc,hfnc)) areas$sides <- fencePer[as.character(areas$field)] sum(areas$area*areas$sides)