94 lines
1.9 KiB
Lua
94 lines
1.9 KiB
Lua
|
-- see if the file exists
|
||
|
local function file_exists(file)
|
||
|
local f = io.open(file, "rb")
|
||
|
if f then
|
||
|
f:close()
|
||
|
end
|
||
|
return f ~= nil
|
||
|
end
|
||
|
|
||
|
-- get all lines from a file, returns an empty
|
||
|
-- list/table if the file does not exist
|
||
|
local function lines_from(file)
|
||
|
if not file_exists(file) then
|
||
|
return {}
|
||
|
end
|
||
|
local lines = {}
|
||
|
for line in io.lines(file) do
|
||
|
lines[#lines + 1] = line
|
||
|
end
|
||
|
return lines
|
||
|
end
|
||
|
|
||
|
local function splitstr(inputstr, sep)
|
||
|
if sep == nil then
|
||
|
sep = "%s"
|
||
|
end
|
||
|
local t = {}
|
||
|
for str in string.gmatch(inputstr, "([^" .. sep .. "]+)") do
|
||
|
t[#t + 1] = str
|
||
|
end
|
||
|
return t
|
||
|
end
|
||
|
|
||
|
-- tests the functions above
|
||
|
local file = "input"
|
||
|
local lines = lines_from(file)
|
||
|
|
||
|
local reports = {}
|
||
|
for _, line in ipairs(lines) do
|
||
|
local raw_report = splitstr(line)
|
||
|
for i, v in ipairs(raw_report) do
|
||
|
raw_report[i] = tonumber(v)
|
||
|
end
|
||
|
|
||
|
reports[#reports + 1] = raw_report
|
||
|
end
|
||
|
|
||
|
-- return the sign of a number
|
||
|
local function sign(number)
|
||
|
if number > 0 then
|
||
|
return 1
|
||
|
elseif number == 0 then
|
||
|
return 0
|
||
|
else
|
||
|
return -1
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local safe_count = 0
|
||
|
for _, report in ipairs(reports) do
|
||
|
local s = nil -- keeps track of the sign over the course of a report
|
||
|
local unsafe = false
|
||
|
for i, v1 in ipairs(report) do
|
||
|
local v2 = report[i + 1]
|
||
|
-- if v2 doesn't exist, we are at the end of the report
|
||
|
if v2 ~= nil then
|
||
|
if s == nil then
|
||
|
-- if we are on the first iteration, we need to set the direction for
|
||
|
-- the rest of the report
|
||
|
s = sign(v1 - v2)
|
||
|
else
|
||
|
-- we check that the sign matches the rest of the report, breaking early if not
|
||
|
if sign(v1 - v2) ~= s then
|
||
|
unsafe = true
|
||
|
break
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- Checking if the rate of change in the report is within acceptable bounds
|
||
|
local distance = math.abs(v1 - v2)
|
||
|
if distance < 1 or distance > 3 then
|
||
|
unsafe = true
|
||
|
break
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if not unsafe then
|
||
|
safe_count = safe_count + 1
|
||
|
end
|
||
|
end
|
||
|
|
||
|
print(safe_count)
|