Skip to content

Commit

Permalink
add day 3
Browse files Browse the repository at this point in the history
  • Loading branch information
norcalbiostat committed Dec 14, 2024
1 parent 83ebc9f commit dbcccef
Show file tree
Hide file tree
Showing 7 changed files with 213 additions and 6 deletions.
50 changes: 49 additions & 1 deletion 2024/day/2/index.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ categories:
- loops
- tidyr
- NAs
- one_star
draft: false
---

Expand Down Expand Up @@ -88,7 +89,7 @@ exa
```
:::

_The Red-Nosed reactor safety systems can only tolerate levels that are A) either all increasing or all decreasing, or B) Any two adjacent levels differ by at least one and at most three._
> The Red-Nosed reactor safety systems can only tolerate levels that are A) either all increasing or all decreasing, or B) Any two adjacent levels differ by at least one and at most three.
okay, so we need a difference between column j+1 and j. Easiest way would probably be to do a loop.

Expand Down Expand Up @@ -139,6 +140,53 @@ Matches.

## Part 2

> The same rules apply as before, except if removing a single level from an unsafe report would make it safe, the report instead counts as safe.
I was stumped, so I'm trying a tactic idea from [Angel Martinez](https://github.com/Angelmartinez-20/Advent_of_Code/tree/main).

Check between each level for whether or not it was a safe transition.
Then count the number of unsafe levels per row.

```{r, eval=FALSE}
angels.if_safe.fun <- function(i, j){
diff <- abs(exa[i,j] - exa[i,j-1])
flip <- (sign(exa[i,j]) != sign(exa[i,j-1]))
status <- dplyr::case_when(diff == 0 ~ "unsafe",
diff > 3 ~ "unsafe",
flip == TRUE ~ "unsafe",
.default = "safe")
return(status)
}
angels.if_safe.fun(3, 5)
# set an indicator of the number of unsafe levels
is.safe <- rep("safe", NROW(exa))
for(i in 1:NROW(exa)){
J <- length(na.omit(exa[i,])) # number of non-NA entries
err <- 0
for(j in 2:J){
# run the function to check for an unsafe level.
if(angels.if_safe.fun(i, j) == "unsafe"){
# if j is unsafe, and not at J, delete it and put j+1 where j is at
exa[i, j:J-1] <- exa[i, j+1:J]
exa[i, J] <- NA
err <- 1
}
# re-run safe check function on the same j. If another error then flag as unsafe
if(angels.if_safe.fun(i, j) == "unsafe" & err==1){
is.safe[i] <- "unsafe"
}
}
}
(safe.if.remove.1 <- n.unsafe<2)
```

Yea.. this isn't working b/c when j=J, there is no j+1.

##### Session info {.appendix}

<details><summary>Toggle</summary>
Expand Down
135 changes: 135 additions & 0 deletions 2024/day/3/index.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
---
title: "2024: Day 03 Mull it over"
date: 2024-12-13
categories:
draft: false
---

## Setup

[The original challenge](https://adventofcode.com/2024/day/03)

Goal: Multiply numbers using `mul(X,Y)` function.
Except instructions got corrupt and so there are incorrect symbols.

x`mul(2,4)`%&mul[3,7]!@^do_not_`mul(5,5)`+mul(32,64]then(`mul(11,8)``mul(8,5)`)
Only the four highlighted sections are real `mul` instructions. Adding up the result of each instruction produces 161 (2*4 + 5*5 + 11*8 + 8*5).

# Input data

```{r}
library(aochelpers)
indata <- readLines("~/GitHub/AdventOfCode/2024/day/3/input")
```

# TLDR; Solutions

## Part 1 ⭐

```{r}
a <- stringr::str_extract_all(indata, "\\mul\\(\\d+,\\d+\\)") |> unlist()
df <- data.frame(a = a)
df$a1 <- gsub("mul", "", df$a)
df2 <- stringr::str_extract_all(df$a, "\\d+", simplify = TRUE)
df2 <- apply(df2, 2, as.numeric)
df2[,1]%*%df2[,2]
```


## Part 2 ⭐⭐

::: {.callout-danger}
###
:::




# Walkthrough / Explainer

## Part 1
Clearly a regex problem.

:::{.callout-exa icon=true}
**Example Data**

```{r}
exa <- "xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))"
```

:::

```{r}
a <- stringr::str_extract_all(exa, "\\mul\\(\\d+,\\d+\\)") |> unlist()
```

Throw it into a data frame, will automatically separate into rows. Now I can get out the #'s and multiply.
```{r}
df <- data.frame(a = a)
df$a1 <- gsub("mul", "", df$a)
df2 <- stringr::str_extract_all(df$a, "\\d+", simplify = TRUE)
df2 <- apply(df2, 2, as.numeric)
```

Now to do rowwise multiplication and sum it up
```{r}
df2[,1]%*%df2[,2]
```

Well.. the example matches. Time to see how jacked up the actual data is.

```{r}
indata <- readLines("~/GitHub/AdventOfCode/2024/day/3/input")
```

It's reading it in as multiple lines... when I don't think that was the intention. I think that's okay, when I `unlist` it combined it into one vector.

```{r}
a <- stringr::str_extract_all(indata, "\\mul\\(\\d+,\\d+\\)") |> unlist()
df <- data.frame(a = a)
df$a1 <- gsub("mul", "", df$a)
df2 <- stringr::str_extract_all(df$a, "\\d+", simplify = TRUE)
df2 <- apply(df2, 2, as.numeric)
df2[,1]%*%df2[,2]
```

Yep. that worked. Coolio


## Part 2

There are two new instructions

* The do() instruction enables future mul instructions.
- The other mul instructions function normally, including the one at the end that gets re-enabled by a do() instruction.
* The don't() instruction disables future mul instructions.
- mul(5,5) and mul(11,8) instructions are disabled
```{r}
exa2 <- "xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))"
```





##### Session info {.appendix}

<details><summary>Toggle</summary>


```{r}
#| echo: false
sessioninfo::session_info(pkgs = "attached")
```


</details>





Loading

0 comments on commit dbcccef

Please sign in to comment.