Design a logger system that receives a stream of messages along with their timestamps. Each unique message should only be printed at most every 10 seconds (i.e. a message printed at timestamp t
will prevent other identical messages from being printed until timestamp t + 10
).
All messages will come in chronological order. Several messages may arrive at the same timestamp.
Implement the Logger
class:
Logger()
Initializes the logger
object.bool shouldPrintMessage(int timestamp, string message)
Returns true
if the message
should be printed in the given timestamp
, otherwise returns false
.Example 1:
Input [ "Logger ", "shouldPrintMessage ", "shouldPrintMessage ", "shouldPrintMessage ", "shouldPrintMessage ", "shouldPrintMessage ", "shouldPrintMessage "] [[], [1, "foo "], [2, "bar "], [3, "foo "], [8, "bar "], [10, "foo "], [11, "foo "]] Output [null, true, true, false, false, false, true]
Explanation Logger logger = new Logger(); logger.shouldPrintMessage(1, "foo "); // return true, next allowed timestamp for "foo " is 1 + 10 = 11 logger.shouldPrintMessage(2, "bar "); // return true, next allowed timestamp for "bar " is 2 + 10 = 12 logger.shouldPrintMessage(3, "foo "); // 3 < 11, return false logger.shouldPrintMessage(8, "bar "); // 8 < 12, return false logger.shouldPrintMessage(10, "foo "); // 10 < 11, return false logger.shouldPrintMessage(11, "foo "); // 11 >= 11, return true, next allowed timestamp for "foo " is 11 + 10 = 21
Constraints:
0 <= timestamp <= 109
timestamp
will be passed in non-decreasing order (chronological order).1 <= message.length <= 30
104
calls will be made to shouldPrintMessage
.program main
use Logger_mod
implicit none
type(Logger) :: logger
integer :: i
character(len=30) :: message
integer :: timestamp
! Example 1
call logger%shouldPrintMessage(1, "foo ")
call logger%shouldPrintMessage(2, "bar ")
call logger%shouldPrintMessage(3, "foo ")
call logger%shouldPrintMessage(8, "bar ")
call logger%shouldPrintMessage(10, "foo ")
call logger%shouldPrintMessage(11, "foo ")
! Example 2
do i = 1, 5
call logger%shouldPrintMessage(i, "bar ")
end do
! Example 3
do i = 1, 5
call logger%shouldPrintMessage(i, "foo ")
end do
! Example 4
do i = 1, 5
call logger%shouldPrintMessage(i, "bar ")
end do
! Example 5
do i = 1, 5
call logger%shouldPrintMessage(i, "foo ")
end do
contains
subroutine print_result(result)
logical, intent(in) :: result
write(*, '(L1)') result
end subroutine print_result
end program main
module Logger_mod
implicit none
private
public :: Logger
type :: Logger
private
integer :: last_printed_timestamp = -1
character(len=30), allocatable :: last_printed_message(:)
contains
procedure :: shouldPrintMessage
end type Logger
contains
logical function shouldPrintMessage(self, timestamp, message) result(should_print)
class(Logger), intent(inout) :: self
integer, intent(in) :: timestamp
character(len=*), intent(in) :: message
integer :: i
should_print = .false.
if (timestamp > self%last_printed_timestamp + 10) then
self%last_printed_timestamp = timestamp
allocate(self%last_printed_message(1))
self%last_printed_message(1) = message
should_print = .true.
else
do i = 1, size(self%last_printed_message)
if (self%last_printed_message(i) == message) then
exit
end if
end do
if (i > size(self%last_printed_message)) then
self%last_printed_message = [self%last_printed_message, message]
should_print = .true.
end if
end if
end function shouldPrintMessage
end module Logger_mod
temp.f95:2:9: 2 | use Logger_mod | 1 Fatal Error: Cannot open module file ‘logger_mod.mod’ for reading at (1): No such file or directory compilation terminated.
module Logger
implicit none
type :: Logger
integer :: lastTimestamp = 0
character(len=30) :: lastMessage = ""
contains
procedure :: shouldPrintMessage
end type Logger
contains
function shouldPrintMessage(self, timestamp, message) result(shouldPrint)
class(Logger), intent(inout) :: self
integer, intent(in) :: timestamp
character(len=*), intent(in) :: message
logical :: shouldPrint
if (timestamp < self%lastTimestamp) then
shouldPrint = .false.
else if (timestamp == self%lastTimestamp .and. message == self%lastMessage) then
shouldPrint = .false.
else
self%lastTimestamp = timestamp
self%lastMessage = message
shouldPrint = .true.
end if
end function shouldPrintMessage
end module Logger
program main
use Logger
implicit none
type(Logger) :: logger
integer :: timestamp, i
character(len=30) :: message
! Examples
call logger%shouldPrintMessage(1, "foo")
call logger%shouldPrintMessage(2, "bar")
call logger%shouldPrintMessage(3, "foo")
call logger%shouldPrintMessage(8, "bar")
call logger%shouldPrintMessage(10, "foo")
call logger%shouldPrintMessage(11, "foo")
! Test cases
do i = 1, 10
timestamp = i * 10
message = "message " // char(ichar('0') + i)
call logger%shouldPrintMessage(timestamp, message)
end do
! Print the results
do i = 1, 10
write (*,*) logger%shouldPrintMessage(i * 10, "message " // char(ichar('0') + i))
end do
end program main
temp.f95:4:18: 4 | type :: Logger | 1 Error: MODULE attribute of ‘logger’ conflicts with PROCEDURE attribute at (1) temp.f95:9:7: 9 | end type Logger | 1 Error: Expecting END MODULE statement at (1) temp.f95:11:8: 11 | contains | 1 Error: Unexpected CONTAINS statement in CONTAINS section at (1) temp.f95:14:22: 1 | module Logger | 2 ...... 14 | class(Logger), intent(inout) :: self | 1 Error: Type name ‘logger’ at (1) conflicts with previously declared entity at (2), which has the same name temp.f95:19:30: 19 | if (timestamp < self%lastTimestamp) then | 1 Error: Symbol ‘self’ at (1) has no IMPLICIT type temp.f95:21:36: 21 | else if (timestamp == self%lastTimestamp .and. message == self%lastMessage) then | 1 Error: Symbol ‘self’ at (1) has no IMPLICIT type temp.f95:23:12: 23 | else | 1 Error: Unexpected ELSE statement at (1) temp.f95:24:18: 24 | self%lastTimestamp = timestamp | 1 Error: Symbol ‘self’ at (1) has no IMPLICIT type temp.f95:25:18: 25 | self%lastMessage = message | 1 Error: Symbol ‘self’ at (1) has no IMPLICIT type temp.f95:27:11: 27 | end if | 1 Error: Expecting END FUNCTION statement at (1) temp.f95:13:36: 13 | function shouldPrintMessage(self, timestamp, message) result(shouldPrint) | 1 Error: Symbol ‘self’ at (1) has no IMPLICIT type temp.f95:32:9: 32 | use Logger | 1 Fatal Error: Cannot open module file ‘logger.mod’ for reading at (1): No such file or directory compilation terminated.
class Logger:
def __init__(self):
self.message_timestamps = {}
def shouldPrintMessage(self, timestamp: int, message: str) -> bool:
if message not in self.message_timestamps or timestamp - self.message_timestamps[message] >= 10:
self.message_timestamps[message] = timestamp
return True
return False
The algorithm initializes an empty map to store message timestamps. The shouldPrintMessage
function takes input parameters timestamp
and message
. It checks if the message is in the map or not. If the message is not in the map or the difference between the given timestamp and the message's timestamp is greater than or equal to 10, it updates the message's timestamp in the map with the given timestamp, and the function returns true
. If the difference is less than 10, the function returns false
. This ensures that messages will only be printed at most every 10 seconds.
#include <unordered_map>
#include <string>
using namespace std;
class Logger {
public:
unordered_map<string, int> message_timestamps;
Logger() {
}
bool shouldPrintMessage(int timestamp, string message) {
if (!message_timestamps.count(message) || timestamp - message_timestamps[message] >= 10) {
message_timestamps[message] = timestamp;
return true;
}
return false;
}
};
The algorithm initializes an empty map to store message timestamps. The shouldPrintMessage
function takes input parameters timestamp
and message
. It checks if the message is in the map or not. If the message is not in the map or the difference between the given timestamp and the message's timestamp is greater than or equal to 10, it updates the message's timestamp in the map with the given timestamp, and the function returns true
. If the difference is less than 10, the function returns false
. This ensures that messages will only be printed at most every 10 seconds.