On Day 18 we need to avoid traps. Our input looks like this:

```
..^^.
```

This is just the first row of a room. Dot character represents a safe tile and ^ character represents a trap. The next row can be generated from the previous one using some rules. The new tile is a trap in the following situations:

- Its left and center tiles are traps, but its right tile is not.
- Its center and right tiles are traps, but its left tile is not.
- Only its left tile is a trap.
- Only its right tile is a trap.

Our task is to tell how many safe tiles there are for a given number of rows and the first row as input.

Here is the full solution:

```
row = File.read("18.txt").strip
def generate_row(row)
new_row = []
0.upto(row.size - 1) do |index|
traps = [index > 0 ? row[index - 1] : ".", row[index], row[index + 1] || "."].join
value = if traps == "^^." || traps == ".^^" || traps == "^.." || traps == "..^"
"^"
else
"."
end
new_row.push(value)
end
new_row.join
end
def get_safe_tiles(row)
row.chars.select { |tile| tile == "." }.size
end
safe = 0
400000.times do |i|
safe += get_safe_tiles(row)
row = generate_row(row)
puts i if i % 1000 == 0
end
puts safe
```

So in first part we have 40 rows and 400000 in second part. The above solution is not ideal. It takes some time to compute, but it is not that bad. Around 25 seconds.