Checking if 2 intervals overlap in Scheme - scheme

So basically I've been given a question to this language which I've been reading the documentation on since early last night. I don't know a thing yet so I figured I'd give this website a try.
Basically what question here is this:
I've been given several structures for calendar dates and an interval in scheme:
(define-struct cal (month day))
(define-struct interval (start end))
However I'm being asked to check if 2 different intervals overlap each other. An example to this:
If I have dates March 12th - March 14th in my first interval,
but in my second interval I have the dates March 13th - March 2th
(overlap? int1 int2) would return true.
However if I have dates March 12th - March 14th in my first interval,
but I have March 15th - March 18th in my second interval
(overlap? int1 int2) would return false.
I don't know where to start with this. If anyone can clear this up for me so I can finish this problem I would be grateful. Thanks a lot!

A good approach in general when writing programs is to break a problem down into more manageable ones. So, before tackling the problem of comparing two intervals, try tackling the simpler problem of comparing two calendar dates. Given two dates a and b, try to write a function that returns true if a is before b, and false otherwise. So,
; date1 is January 5, date2 is February 6
(before? date1 date2) ; returns true
; date1 is January 5, date2 is January 2
(before? date1 date2) ; return false
Next, think about how you might use before? to construct overlap?. In particular, consider this: if two intervals do not overlap, then the end date of one comes before the start date of the other.
Finally, consider the edge cases - what do you want your program to do if given, for example, (January 4 to March 6) and (March 6 to December 3) ? Do these intervals overlap or not?
Happy coding!
PS - if you need more help, don't be afraid to ask. I'm being deliberately vague because I thought that giving you hints would be better than just plopping a solution down in front of you - that way you wouldn't learn anything.

To add to Ord's excellent advice, if you're looking for more basic information: what does define-struct mean? How do I write a function that uses dates?--then I would suggest you take a look at the (free, online) textbook How To Design Programs, version 2e. It looks like you're interested in Section 2.5, "Adding Structure", but it may be hard to understand this section without reading earlier ones, as well.
Good luck!

Related

Simple algorithm to alternate days

I need to alternate between 2 tasks every day, and I need a simple algorithm to know which task I need to do.
I need to be able to run this algorithm by head, using simple general knowledge (like day of week, day of month, etc), and it must not rely of which task has been done the previous day (because I have a crappy memory).
I have tried checking for parity in a combination of day of week / day of month / # of month, etc, but couldn't find a suitable system: day of week have 2 consecutive odd numbers, same goes for day of month every so often.
I am afraid that this is impossible: if you can't remember what you did the day before, any other procedure will require more mnemonic effort.
remember what you did on January first (or another date),
remember the parities of the cumulated months: oeoeoeooeoe or ooeoeoeeoeo for a leap year,
add the cumulated parity of the month before* to the parity of the day,
add that to the parity of the first task.
E.g. if A on January 1st 2022, then on March 17, 2022: e + o = o gives B.
*In January, use even.
You can also state the month parity rule as: until August inclusive, use the co-parity of the month number; then use the parity. But for a leap year, change that parity after February (excluded).
I need to be able to run this algorithm by head
So, you don't need to take help of Computer science. You can use cognitive human ability to map a thing to another thing.
Note: This need not make sense to everybody though, if you are thinking out of the box.
Map task 1 as God's day.
Map task 2 as Devil's day in your brain.
This should be simple just like day and night.
Now, remember that devil's evil karma is always burnt by God the next day and that devil never learns his lesson. So this way, alternating would be easy.
Friends Episode snippet on Youtube
Just count the number of days in between your date and a given "zero" one...then use parity.
Take number of seconds (or milli, or whatever) since EPOCH (common zero for date and time), divide (integer division) by 60x60x24 (or 1000x60x60x24, or what is appropriate), you then get the number of days since EPOCH.
----EDIT----
Example: Got 1653910695 seconds since EPOCH (at the time of my experience). Dividing it by 60x60x24 give 19142 days. To morrow it will give 19143, etc.
<?php
$day = Date('j');
$previous_day = date('j', strtotime("-1 days"));
if($day%2==0 OR $previous_day%2!=0)
echo "Task 1";
}else{
echo "Task 2";
}
?>

How to add a simple calendar to my windows store app

I'm working on a Universal windows store app and I want to add a simple calendar so that users can add birthdays of their friends and save them and some other stuff. Is there any simple way to do this?
PS: Using Visual Studio 2013
What I do understand about Calendars, is there are fourteen of them in total that are possible - seven for each day of the week a normal year begins on, and seven more for leap years. You may have to create all fourteen and put them in somehow. There is instead a formula for working out what day of the year anyone was born on by their date of birth, and formulae can be programmed into r or other programmes using perhaps the for loop, or if command. This formula is :
{4(d+y)+x-4c}/28, where d is what number day of the year it is - so Jan 1st, d=1, and so on, but for Leap Years it gets different from Feb 29, y is the year in question, x the closest year before y divisible by four, and c an era constant. For modern dates, c=0, so no worries, but if You go back before September, 1752, it changes, as this is when the British went from the Julian to the Gregorian, while in Catholic Europe it was October, 1582, but these are only a concern if You are into such historical dates. For those, c=1, but may have different values much earlier - if You want to know more, reply to this, and I will get out what I have written on it.
For example, if one was born on 17th May, 1979, you would go :
{4(137+1979)+1976-4 times zero}/28, which equals 372 plus six sevenths - you ignore the whole number, and look at how many sevenths there are. Six means Thursday, and thus the 17th May, 1979 was a Thursday. This is it in short - for more details, if this interests, feel free.
The simple way is in use third-party controls like Telerik Calendar or something free like this one.

How to handle recurring times?

First off, I marked this question as language agnostic, but I'm using PHP and MySQL. It shouldn't affect the question itself very much tho.
I'm creating an application which shows times of certain shows throughout the week. Every single show is recurring (on weekly basis) and there might be shows which are airing through 2 days - eg. starting on Sunday at 23:30, ending on Monday at 00:30. I'm storing start of the show (day of the week - Monday, Tuesday... - it's never exact date; time) and duration. There are never shows that would take more than 24 hours.
My problem is with validation if newly added shows aren't overlapping some old ones. Especially if it comes to Sunday-Monday shows.
How are such recurring events usually handled on both DB side and server side?
tl;dr version with stuff I considered
My first idea was to create some custom validation algorithm, but it seemed too cumbersome and complicated. Not that I'd whine about complicated hand-made solutions, but I'm interested if there isn't something more basic that I'm missing.
Other alternative that came to mind was to change table structure to use datetime (instead of "day of week" and "time"), and use a fake fixed date range to store the data. For example all Mondays would be set to 5th Jan 1970, Sundays would use 11th Jan 1970. There would be one exception to this rule - if there would be some show which starts on Sunday and ends on Monday, it would be stored as 12th Jan 1970. This solution would allow more flexible quering of the DB than the original one, and it would also simplify queries for shows which overlap between individual weeks (since we can do the comparison directly in the query). There are some disadvantages to this solution as well (for one, using fake dates might make it confusing).
Both solutions smell of wrong algorithms to me and would love to hear some opinions from more experienced fellow developers.
Sounds like you could just store the starting minute of each show as an integer number of minutes since the start of the week (10,080 possible values).
Then a show starting at minute $a with duration $dur_a will overlap $b if and only if
(10080 + $b - $a) % 10080 < $dur_a
For example consider a show starting at 11pm Sunday and another starting at 12.30am Monday. Here $a == 10020 and $dur_a == 120 and $b == 30. (10080 + $b - $a) % 10080 == 90. This is less than $dur_a and hence the shows overlap.
This problem could be simplified by converting the data into a format that is amenable to the calculations that are required. I recommend creating a type that represents the start times as the number of minutes from Sunday at midnight. Then simple integer range comparisons could be used to find overlapping shows.
The internal representation must, of course, be hidden and abstracted. You may, at some point, want to change the representation from minutes to seconds, for example.
I would opt for a custom validation algorithm:
For each show, compute all showing intervals [start1, end1], [start2, end2], ... [startN, endN], where N is the number of recurrence of the show.
For a new show, also compute these intervals.
Now check if any of these new intervals intersect any old intervals. This is the case if the start or the end of one interval is contained in the other.

Question about pseudocode for HW

I have the following question, and what I'm most confused on, is how to do the logic for determining if a check is one month late or not.
Question is:
"Write pseudocode for a program that calculates the service charge of a customer owes for writing a bad check. The program accepts a customer's name, the date the check was written (year, month and day), the current date (year, month and day), and the amount of the check in dollars and cents. The program continues until an eof value is encountered. The service charge is $20 plus 2 percent of the amount of the check, plus $5 for every month that has passed since the check was written. A check is one month late as soon as a new month starts-so a bad check written on September 30 is one month overdue on October 1."
So far what I have write now is:
Start
string Name
num AmountOwed
num DateCheckWritten
num CurrentDate
num CheckAmount
get Name, DateCheckWritten, CurrentDate, CheckAmount
while eof
Since you don't have to deal with days, the algorithm is very straightforward:
MonthsLate = (CurrentDate.Year - DateCheckWritten.Year) * 12
+ (CurrentDate.Month - DateCheckWritten.Month)
Good luck with the rest of the problem!
I'm not sure where your problem lies, but I think you have two issues to deal with:
What is the definition of late?
How many months late is this check?
So in my pseudocode, I would have a step that determines how late a check is, and then another step to calculate the fee. Inside the first step, you could just subtract the days and divide. But the directions say as soon as a new month comes along, it is one month late. So all you really have to do is subtract months.
Not sure what else you are asking, but it appears you are asking for guidance, not code. Hope this helps.
I'm going to assume this is homework, and as such I'll try to just point you in the right direction.
If you assign numbers to each month (Jan = 1, Feb = 2, etc) then the number of months between two dates is easy to determine - how many months are there between September (= 9) and May (= 5)?
The other thing to take into account is the year - for each year the check is late, you'll also have to add another twelve months. This works the same as for months.
Need any extra detail, feel free to let me know.
Simplify, hit the main points and then break it down more and more, write it how you would tell your grandma it worked.
you might start out with something like
Start
While there are more bad checks
get the service charge
add the service charge to the account
record the updates
get the service charge
charge starts at $20
add to the charge $5 multiplied by number of months

Efficient algorithm for determining if a date is in DST

I'm looking for a better than O(n) algorithm to determine if a date in the future will have daylight savings time applied (and how much). Given a year, month, day, hour, minute and time zone (and a copy of the Olsen Time Zone database) how does one efficiently determine if that date will be in DST? I'm looking for the algorithm, not a library function to call.
Thank you.
FURTHER EXPLANATION: The date library I'm using is very slow when you create an object with a date in the future and a time zone. It turns out its doing a linear calculation to calculate if the date is in daylight savings time. Not only that, its doing this at object creation time. Obviously it could wait until asked, but it should also be more efficient.
Sure, DST rules change and a date library can't predict the future, but the alternative is to put an arbitrary upper limit on localized dates.
Everybody's already commented on the problems with always-changing DSTs. But I can accept the premise that we just pretend the currently known rules will apply forever.
To get your DST information, the first thing to do is to calculate the year/month/day for your future date (if it isn't in that form already). Then you look up your time zone and pull out the variation against UTC, the DST on/off rule and offset. There could be several different rules depending on which year, you want to be sure to grab the right one for your "target" year. For reasons explained below, it may be handy to also be aware of the rules for the preceding year.
The on/off rules will have a funny spec like "Oct lastSun": That means the switch occurs in the night of the last Sunday in October.
What you need to do is gather up all of these tersely formatted "rules" and develop a bit of code for each to determine the last date indicated by that rule. It's currently December, so given a couple of rules like "Mar lastSun" and "Oct lastSun" for my time zone, those dates would be March 29, 2009 and October 25, 2009. Which of these dates is more recent? October. October is associated with an "off", so we must currently have NO DST.
You can calculate the DST on/off dates for the current (i.e. target) year regardless of whether the target date is before or after those dates; if the on/off date is in the future of your target date, then simply do the rule calculation again for the previous year. Note that the rules may have changed during the interval, so be sure to apply the correct one for the year you're looking at.
Worst case for this calculation is, you have to repeat your two rule calculations for the previous year. But there's no searching going on otherwise, so it's strictly O(1).
I found a Local/DST/Tz calculator here: http://home-4.tiscali.nl/~t876506/WhatDay.html and as it's a JavaScript applet you should be able to simply crib the code. It doesn't handle all rules, though, so you will need to add some code for the remaining rules.
Update: I just noticed you have an hour and minute in your time as well. That complicates matters just a little. If your date is not on a "switch" date then the instructions I gave above will do you fine. Otherwise, you need to consider the time. I guess the cleanest thing to do would be to include the time in your determination of "most recent". I.e. if your target time is 00:30 UTC and switch time for the given zone is 01:00, then the target year's switch time is still in the future and you have to use the previous year's switch time instead. For practical purposes, this will mean that the "other" switch time was the most recent, and its on/off status applies.
Your number one problem is daylight savings rules that are set by the local authorities. The latter can pass almost any law at any time and therefore change the rules in a way you can't possibly predict.
As far as I know DST changes that are known start and end on a fixed day each year (first weekend in april, last weekend in october, stuff like that). So you could ese the Doomsday Algorithm to find the days of the week for the given year and calculate the conversion dates from that. Then you can determine if DST is in effect in source and/or destination locale. The converion itself is simply a matter of adding and/or subtracting an hour to compensate for DST and then factor in the timezone difference.
Hmm, as I see the problematic point is to determine weekday for a given day, far in the future.
For that, I suggest something like that:
after every 400 years, the complete system turns around, so first divide the number of years with 400, take the integral part. In 400 years, there are 99 leap years and 301 simple ones. If an arbitrary day is Monday, then the same day 400 years later will be 301+2x99 = 499 (mod 7) ---> Monday+2 ---> Wednesday. So you have to say something like that:
wday = (ref_day + 2 * (int)((target_year - ref_year) / 400)) mod 7
then you can do further optimizations, but I guess you can go year-by-year, that will do it. At most you make 399 simple operations, if (leap_year) then ++ else +=2, mod 7.
After you have the weekday for Jan 1 that year, you can calculate DST switching dates, as Carl Smotricz has written.

Resources