2021 Day 17

Author

Nathan Moore

— Day 17: Trick Shot —

Send a probe into the ocean trench.

Find the initial velocity that causes the probe to reach the highest y position and still eventually be within the target area after any step. What is the highest y position it reaches on this trajectory?

library(tidyverse)

my_file <- here::here("2021", "data-2021-17.txt")
x <- readLines(my_file)

nums = str_extract_all(x, '-?\\d+')

x0 = as.integer(nums[[1]][1])
x1 = as.integer(nums[[1]][2])
y0 = as.integer(nums[[1]][3])
y1 = as.integer(nums[[1]][4])

We can probably try out all options and figure this out. Part two guess: the target area is multiplied by 100 or 1,000,000 and brute force becomes impossible.

# make a function so we can reuse program

cannonball <- function(v) {
    pos = c(0,0)
    max_y = -999
    for (i in 1:1000) {
        # move cannonball
        pos[1] = pos[1] + v[1]
        pos[2] = pos[2] + v[2]
        if (pos[2] > max_y) {
            max_y = pos[2]
        }
        # print for debug
        # print(i)
        # print(pos)
        # print(v)
        # test position
        if (pos[1] >= x0 && pos[1] <= x1) { 
            if (pos[2] >= y0 && pos[2] <= y1) {
                # found a good spot
                break
            }    
        }
        # edit velocity
        # x must always be positive for my target, I think
        if (v[1] > 0) {
            v[1] = v[1] - 1
        } else {
            v[1] = 0
        }
        v[2] = v[2] - 1
    }
    return(c(i, max_y))
}

Use this function and see what we can find

# cannonball(c(14,7))

# has to be larger than 12, otherwise we don't get into the square
# 13: 5, 15; 6, 21; 
# 14: 6, 21; 7, 28; 

# Loop!
for (j in 10:30) {
    max_y = 0
    step = 0
    for (k in 5:1000) { 
        res = cannonball(c(j, k))
        # print(res)
        if (res[1] < 1000) { 
            if (res[2] > max_y) { 
                max_y = res[2]
                step = res[1]
            }
        }
    }
    print(c(j, step, max_y))
}
[1] 10  0  0
[1] 11  0  0
[1] 12  0  0
[1]    13   300 11175
[1]    14   300 11175
[1]    15   300 11175
[1] 16  0  0
[1] 17  0  0
[1] 18  0  0
[1] 19  0  0
[1] 20  0  0
[1] 21  0  0
[1] 22  0  0
[1] 23  0  0
[1] 24  0  0
[1] 25  0  0
[1] 26  0  0
[1] 27  0  0
[1] 28  0  0
[1] 29  0  0
[1] 30  0  0

— Part Two —

How many distinct initial velocity values cause the probe to be within the target area after any step?

all_count = 0

# Loop!
# Negatives!
for (j in 10:140) {
    counter = 0
    for (k in -200:1000) { 
        res = cannonball(c(j, k))
        # print(res)
        if (res[1] < 1000) { 
            counter = counter + 1
        }
    }
    print(c(j, counter))
    all_count = all_count + counter
}
[1] 10  0
[1] 11  0
[1] 12  0
[1]  13 125
[1]  14 128
[1]  15 131
[1] 16 19
[1] 17 16
[1] 18 15
[1] 19 19
[1] 20 16
[1] 21 16
[1] 22 21
[1] 23 21
[1] 24 21
[1] 25 17
[1] 26 17
[1] 27 17
[1] 28 24
[1] 29 24
[1] 30 24
[1] 31 24
[1] 32 24
[1] 33 24
[1] 34 15
[1] 35 15
[1] 36 15
[1] 37 15
[1] 38 15
[1] 39 15
[1] 40 15
[1] 41 36
[1] 42 36
[1] 43 36
[1] 44 36
[1] 45 21
[1] 46 21
[1] 47 21
[1] 48 21
[1] 49 21
[1] 50 21
[1] 51 21
[1] 52 21
[1] 53 21
[1] 54 21
[1] 55 21
[1] 56 21
[1] 57 21
[1] 58 21
[1] 59 21
[1] 60 21
[1] 61 21
[1] 62 21
[1] 63 21
[1] 64 21
[1] 65 21
[1] 66  0
[1] 67  0
[1] 68  0
[1] 69  0
[1] 70  0
[1] 71  0
[1] 72  0
[1] 73  0
[1] 74  0
[1] 75  0
[1] 76  0
[1] 77  0
[1] 78  0
[1] 79  0
[1] 80  0
[1] 81 43
[1] 82 43
[1] 83 43
[1] 84 43
[1] 85 43
[1] 86 43
[1] 87 43
[1] 88 43
[1] 89 43
[1] 90 43
[1] 91 43
[1] 92 43
[1] 93 43
[1] 94 43
[1] 95 43
[1] 96 43
[1] 97 43
[1] 98 43
[1] 99 43
[1] 100  43
[1] 101  43
[1] 102  43
[1] 103  43
[1] 104  43
[1] 105  43
[1] 106  43
[1] 107  43
[1] 108  43
[1] 109  43
[1] 110  43
[1] 111  43
[1] 112  43
[1] 113  43
[1] 114  43
[1] 115  43
[1] 116  43
[1] 117  43
[1] 118  43
[1] 119  43
[1] 120  43
[1] 121  43
[1] 122  43
[1] 123  43
[1] 124  43
[1] 125  43
[1] 126  43
[1] 127  43
[1] 128  43
[1] 129  43
[1] 130   0
[1] 131   0
[1] 132   0
[1] 133   0
[1] 134   0
[1] 135   0
[1] 136   0
[1] 137   0
[1] 138   0
[1] 139   0
[1] 140   0
print(all_count)
[1] 3540