Skip to content

Instantly share code, notes, and snippets.

@AndreasH96
Last active January 12, 2021 15:15
Show Gist options
  • Save AndreasH96/b1c3509d809fc4cc83e0e24a9eb7755a to your computer and use it in GitHub Desktop.
Save AndreasH96/b1c3509d809fc4cc83e0e24a9eb7755a to your computer and use it in GitHub Desktop.
AoC day11
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