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)