Last active
January 12, 2021 15:15
-
-
Save AndreasH96/b1c3509d809fc4cc83e0e24a9eb7755a to your computer and use it in GitHub Desktop.
AoC day11
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Printf | |
using Test | |
using DSP | |
using ImageFiltering | |
testData = readlines("testinput.txt") | |
realData = readlines("input.txt") | |
# Translates L => 1, . => 0 , # => -1 | |
function parseData(data) | |
replacement = Dict('L' => 1, '.'=>0,'#'=>-1) | |
returnData = reshape(filter(x -> x!= '\n',collect(Iterators.flatten(data))),(length(data),length(data[1]))) | |
returnData = map((x) -> replacement[x] ,returnData) | |
return returnData' | |
end | |
# Updates according to rules set by Website | |
function adapt(current,nextState) | |
change = false | |
# Compares the current state (which holds where empy seats are and floors) | |
# to the next state which holds the information about how many occupied seats each | |
# position has adjecent to it | |
for index in CartesianIndices(current) | |
# If position is floor, no update | |
if getindex(current,index) == 0 | |
setindex!(nextState,0,index) | |
# If position is empty and no adjecent seat is occupied | |
# make seat oppupied | |
elseif getindex(current,index) == 1 | |
if getindex(nextState,index) == 0 | |
setindex!(nextState,-1,index) | |
change = true | |
else | |
setindex!(nextState,1,index) | |
end | |
# If position is occupied and more than 4 adjecent seats are occupied | |
# Make seat empty | |
elseif getindex(current,index) == -1 | |
if getindex(nextState,index) >= 4 | |
setindex!(nextState,1,index) | |
change = true | |
else | |
setindex!(nextState,-1,index) | |
end | |
end | |
end | |
# returns nextState which now holds the correct status for each position | |
# also returns if any change has been made | |
return nextState , change | |
end | |
function solve(data) | |
# Initialize state | |
currentState = parseData(data) | |
# Create kernel for convolution | |
# The idea here is that since occupied seats are -1 then this will count amount of | |
# occupied seats with high efficiency | |
# -1 -1 -1 | |
# -1 0 -1 | |
# -1 -1 -1 | |
kernel = fill(-1,(3,3)) | |
kernel[2,2] = 0 | |
count = 0 | |
currentTakenSeatsAmount = 0 | |
for x in range(1,stop=10000000) | |
count+=1 | |
# Create temporary matrix where free seats are set to 0 | |
# This since the amount of free seats doesn't matter and | |
# We dont want them to affect the amount of taken seats | |
occupiedSeats = map(x -> x == -1 ? -1 : 0 ,currentState) | |
# Perform convolution with border | |
# Since imfilter performs correlation, we have to invert the kernel for it to perform convolution | |
# Also remove padded edges | |
nextStates = conv(occupiedSeats,kernel)[2:end-1,2:end-1] | |
# Create the new state from the convolution result | |
# "change" holds if any changes has been made | |
currentState , change = adapt(currentState,nextStates) | |
# Count amount of taken seats | |
takenSeatAmount = length(findall(x-> x==-1,currentState)) | |
if takenSeatAmount != currentTakenSeatsAmount | |
currentTakenSeatsAmount = takenSeatAmount | |
println(currentTakenSeatsAmount) | |
end | |
if !change | |
break | |
end | |
end | |
return currentTakenSeatsAmount | |
end | |
testResult = solve(testData) #outputs 37, correct | |
result = solve(realData) # toggles between 2129 and 2287 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment