Leap years not working in Date and Time program in Dlang - date

I haven't been programming very long, so I'm practicing some logic exercises in dlang. Any ideas on what I've done wrong here. When I get to a leap year, my program just keeps looping on the WHILE.
import std.stdio;
void main()
{
bool dead;
string thing;
int phew = 5; //days
int tahr = 1; //months
int tron; //monthsDate
string[7] days = ["Sunday", "Monday", "Tuesday", "Wednesday","Thursday", "Friday", "Saturday"];
int date = 28;
string[12] months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
int year = 1996;
int hours = 11;
int mins = 28;
string ampm = "pm";
bool ly;
int leap = 1996;
int cen = 996;
//writeln("This program is incomplete. Obviously.");
write("Press Enter to Continue.");
readf("%s\n",&thing);
while(!dead)
{
while(hours <= 12)
{
while(mins <= 59)
{
if(mins < 10)
write(date," ",months[tahr],", ",year,". ",days[phew],". ",hours,":0",mins,ampm,": ");
else
write(date," ",months[tahr],", ",year,". ",days[phew],". ",hours,":",mins,ampm,": ");
readf("%s\n",&thing);
mins++;
}
hours++;
if(hours == 12 && ampm == "am")
{
ampm = "pm";
}
else if (hours == 12 && ampm == "pm")
{
ampm = "am";
phew++;
date++;
if(phew > 6)
phew = 0;
if((date == 29 || date == 30) && tahr == 1)
{
while(leap <= year) //this assuming time travel doesn't work
{ //reminder: add time travel
if (leap == year)
{
ly = true;
break;
}
leap+=4;
ly = false;
}
if(!ly || date == 30)
{
date = 31;
leap-=4;
}
}
if(!ly || date == 30)
{
date = 31;
leap-=4;
}
}
if(date == 31 && (tahr == 1 || tahr == 3 || tahr == 5 || tahr == 8 || tahr == 10))
{
date = 1;
tahr++;
}
else if (tahr == 11 && date == 32)
{
tahr = 0;
date = 1;
year++;
cen++;
if(cen == 1000)
{
writeln("Happy Millennium!");
cen = 0;
}
else
writeln("Happy New Year!");
}
else if(date == 32 && (tahr == 0 || tahr == 2 || tahr == 4 || tahr == 6 || tahr == 7 || tahr == 9))
{
date = 1;
tahr++;
}
}
if(hours == 13)
{
hours = 1;
}
mins = 0;
}
}
}
The important part is this:
if((date == 29 || date == 30) && tahr == 1)
{
while(leap <= year) //this assuming time travel doesn't work
{ //reminder: add time travel
if (leap == year)///
{
ly = true;
break;
}
leap+=4;
ly = false;
}
if(!ly || date == 30)
{
date = 31;
leap=-4;
}
}
So, I figured out the issue almost immediately after posting. Basically, I wrote =+ instead of +=. Very simple mistake. That's what I get for typing too fast. So, I've fixed up the code now, if you have any other suggestions, make sure to put them in the comments. Thanks.

Decided to print out leap into the terminal, and I figured out my issue. Leap was continuously equal to 4, because I wrote =+ instead of +=. It was just a case of clicking the wrong button first. That's what I get for typing fast. The program works now, as far as I know. Feel free to correct me on anything else you may notice.

I haven't read it in depth, but I recommend you add lots of debug writelns.
Particularly just inside the block you're THINKING should get run:
if((date == 29 || date == 30) && tahr == 1) {
writefln("Handling leap years...");
while(leap <= year) //this assuming time travel doesn't work
{ //reminder: add time travel
writefln("In loop, Leap <= year? %s", leap <= year);
This will allow you to debug more what is actually happening when your program is run.

Related

Test for scalar function inputs is failing

Despite using isscalar, isinteger... the result after running is still true, I still had this test which is incorrect and in relation with Scalar values.
My program:
function valid = valid_date(year, month, day)
[y1 y2] = size(year);
[m1 m2] = size(month);
[d1 d2] = size(day);
if (mod(year,4)==0 && mod(year,100)~=0) || mod(year,400)==0
is_leap_year = 1;
else
is_leap_year = 0;
end
if ~(y1==y2==d1==d2==m1==m2==1)
valid = false;
elseif any(month == [1, 3, 5, 7, 8, 10, 12])
valid = (day >0 && day <= 31)
elseif any(month == [4, 6, 9, 11])
valid = day >0 && day <= 30;
elseif month == 2 && is_leap_year == 1
valid = (day >0 && day <=29);
elseif month == 2 && is_leap_year == 0
valid = (day >0 && day <=28);
else
valid = false;
end
end
The result after submitting my program, all tests are passed except the one related to scalar values:
Why did my program fail on the non-scalar test?
The way you're checking for scalars is really not well defined.
~(y1==y2==d1==d2==m1==m2==1)
This chained equivalence check is not the same as checking if all of your variables are equal to 1, consider the following counter-example:
1==0==0==1 % Output: 1
In this case none of your comparison variables should be 0, so you might skirt this issue, but it's still best to avoid it. You're also contending with floating point comparisons which are prone to issues.
You should use isscalar, you say you tried it but didn't show how. Something like this should work:
function valid = valid_date(year, month, day)
if ~( isscalar(year) && isscalar(month) && isscalar(day) )
valid = false;
return
end
% ... other code now we know inputs are scalar
end
Thank you so much #Wolfie. The problem is solved.
I used what you told me about and put it at the beginning of my function.
I show you guys the code, in case you had the same error:
function valid = valid_date(year, month, day)
if ~(isscalar(year) && isscalar(month) && isscalar(day))
valid = false;
return
end
if ((mod(year,4)==0 && mod(year,100)~=0) || mod(year,400)==0)
is_leap_year = 1;
else
is_leap_year = 0;
end
if any(month == [1, 3, 5, 7, 8, 10, 12])
valid = (day >0 && day <= 31);
elseif any(month == [4, 6, 9, 11])
valid = day >0 && day <= 30;
elseif (month == 2 && is_leap_year == 1)
valid = (day >0 && day <=29);
elseif (month == 2 && is_leap_year == 0)
valid = (day >0 && day <=28);
else
valid = false;
end
end
Yaaay all the tests are passed lhamdullah!

Programming on the Nintendo DS - issue with collisions

Sorry if this question has already been asked, but I have not managed to find any advice on the internet for my issue. I am currently trying to program a little game on the Nintendo DS, in which the player has to move a sprite (currently a square) until it reaches the exit. For this, I use a sprite I have included using a grit file, and also a background enabled in tiled mode. However, I am having a problem when it comes to checking if the sprite is going to collide with a wall. Here is the code I have both for the background configuration (where I declare the tiles and the map) and also for the sprite movements (I didn't add the condition for all cases yet, as it didn't work well) :
void configureMaze_Sub() {
int row, col;
for (row = 0; row < 24; row ++) {
for (col = 0; col < 32; col ++) {
BG_MAP_RAM_SUB(3)[row * 32 + col] = 1;
if (col == 15 && (row != 12 && row !=4 && row != 19)) {
BG_MAP_RAM_SUB(3)[row * 32 + col] = 0;
}
if ((row == 1 || row == 22) && (col > 2 && col < 29)) {
BG_MAP_RAM_SUB(3)[row * 32 + col] = 0;
}
if ((col == 3 || col == 28) && (row > 1 && row < 22 && row != 12)) {
BG_MAP_RAM_SUB(3)[row * 32 + col] = 0;
}
if ((row == 3 || row == 20) && (col > 4 && col < 27)) {
BG_MAP_RAM_SUB(3)[row * 32 + col] = 0;
}
if ((col == 5 || col == 26) && (row != 9 && row != 15 && row > 3 && row < 20)) {
BG_MAP_RAM_SUB(3)[row * 32 + col] = 0;
}
if (row == 8 && (col > 5 && col < 15)) {
BG_MAP_RAM_SUB(3)[row * 32 + col] = 0;
}
if (row == 16 && (col > 15 && col < 26)) {
BG_MAP_RAM_SUB(3)[row * 32 + col] = 0;
}
if ((row == 12) && (col > 5 && col < 26)) {
BG_MAP_RAM_SUB(3)[row * 32 + col] = 0;
}
}
}
}
void gameplayMaze() {
int x = 103, y = 41, keys;
int maze_success = 0;
while (maze_success == 0) {
scanKeys();
keys = keysHeld();
int xmod = x / 8;
int ymod = x / 8;
if ((keys & KEY_RIGHT) && BG_MAP_RAM_SUB(3)[xmod + 32 * ymod] == 1) {
x++;
printf("%d \n", x);
}
if ((keys & KEY_LEFT) && BG_MAP_RAM_SUB(3)[xmod + 32 * ymod] == 1) {
x--;
}
if (keys & KEY_UP) {
y--;
}
if (keys & KEY_DOWN) {
y++;
}
oamSet(&oamSub,
0,
x, y,
0,
0,
SpriteSize_8x8,
SpriteColorFormat_256Color,
gfxSub,
-1,
false,
false,
false, false,
false
);
swiWaitForVBlank();
oamUpdate(&oamSub);
}
The main problem I have is to try to change from the coordinates of the tiles (which are 8x8) to the ones of the map, as for the coordinates of the sprite (256x192). If any of you have any hint to help me, I would be very grateful! I am still new to programming on the NDS, so I am still struggling to get the hang of it.

Checking if a Date is Valid in MATLAB

So as to not mislead anyone, this is a HW problem that I am attempting to complete and need a little help with. The problem itself is pretty self-explanatory. I have to write a function where I input a string 'Month Day, Year' and have it tell me whether or not it's valid (true or false statements). I have it working for almost everything, except now it doesn't seem to recognize my constraints for possible days.
function[valid] = isValidDate(str)
[date, year] = strtok(str, ','); %Should give me the date and year
[~, year2] = strtok(year, ' ');
[month, day] = strtok(date, ' '); %Should give me month and the day
day = round(day);
if length(date) < 6
valid = false;
elseif month(1) == upper(month(1))
valid = true;
elseif length(date) >= 12
valid = false;
end
if year2 >= 0
valid = true;
else
valid = false;
end
leapyear = mod(year, 400) == 0 | (mod(year, 4) == 0 ~= mod(year, 100) == 0);
switch month
case {'September','April','June','November'}
day <= 30;
valid = true;
case {'February'}
if leapyear
day <= 29;
valid = true;
else
day <= 28;
valid = true;
end
case {'January', 'March', 'May', 'July', 'August', 'October', 'December'}
days <= 31;
valid = true;
otherwise
valid = false;
end
end
So basically
valid4 = isValidDate('December 29.9, -1005.7')
valid = false
Note: There will be no suffix after the day. My only issue now is that my function doesn't realize my constraints on days. it likes to think 'February 30, 2014' is possible
Code
function[valid] = isValidDate(str)
[date1, year1] = strtok(str, ','); %Should give me the date and year
[month1, day1] = strtok(date1, ' '); %Should give me month and the day
%// 1. Take care of bad month strings
all_months = {'January', 'February','March', 'April', 'May','June',...
'July', 'August', 'September','October','November' 'December'} ;
if ~ismember(cellstr(month1),all_months)
valid = false;
return;
end
%// 2. Take care of negative or fraction days
day1 = day1(isstrprop(day1,'digit')); %// Take care of suffixes after day string
num_day = str2double(day1);
if round(num_day)~=num_day || num_day<1
valid = false;
return;
end
%// 3. Take care of fraction or negative years
num_year = str2double(strtok(year1,','));
if round(num_year)~=num_year || num_year<0
valid = false;
return;
end
lpyr =mod(num_year, 400) == 0 | (mod(num_year, 4) == 0 ~= mod(num_year, 100) == 0);
switch month1
case {'September','April','June','November'}
if num_day > 30
valid = false;
return;
end
case {'February'}
if (lpyr && num_day > 29) | (~lpyr && num_day > 28)
valid = false;
return;
end
case {'January', 'March', 'May', 'July', 'August', 'October', 'December'}
if num_day > 31;
valid = false;
return;
end
end
valid = true; %// We made it through!
return;
If you would prefer a compact code -
function valid = isValidDate(str)
[date1, year1] = strtok(str, ','); %Should give me the date and year
[month1, day1] = strtok(date1, ' '); %Should give me month and the day
%// 1. Take care of bad month strings
all_months = {'January', 'February','March', 'April', 'May','June',...
'July', 'August', 'September','October','November' 'December'} ;
valid_month = ismember(cellstr(month1),all_months);
%// 2. Take care of negative or fraction days
day1 = day1(isstrprop(day1,'digit')); %// Take care of suffixes after day string
num_day = str2double(day1);
valid_day = round(num_day)==num_day && num_day>=1;
%// 3. Take care of fraction or negative years
num_year = str2double(strtok(year1,','));
valid_year = round(num_year)==num_year && num_year>=0;
%// 4. Take care of valid days based on leap year and days in a month limits
lpyr = mod(num_year, 400) == 0 | (mod(num_year, 4) == 0 ~= mod(num_year, 100) == 0);
valid_leapyear = true;
switch month1
case {'September','April','June','November'}
valid_leapyear = num_day<=30;
case {'February'}
valid_leapyear = ~((lpyr && num_day>29) || (~lpyr && num_day>28));
case {'January', 'March', 'May', 'July', 'August', 'October', 'December'}
valid_leapyear = num_day<=31;
end
valid = valid_year & valid_month & valid_day & valid_leapyear;
return;
I made some simple function, using the java interface in matlab. Hope it will be useful.
function [valid] = isValidDate(dateStr)
valid = true;
dateFormat = java.text.SimpleDateFormat('MMM dd, yyyy');
dateFormat.setLenient(false);
try
dateFormat.parse(dateStr);
valid = true;
catch err
valid = false;
end
end
Example:
isValidDate('December 21, 1934'); % gives 1
isValidDate('December 29.9, -1005.7'); % gives 0

Comparison operators not functioning as expected

I have a set of checks to perform certain tasks.
// tempDouble is a (double), hour is an int
if (tempDouble > 60.0 && (hour >= 6 || hour <= 17)) { //CLEAR
NSLog(#"CLEAR");
}
else if (tempDouble > 60.0 && (hour < 6 || hour > 17)) { //NIGHT_CLEAR
NSLog(#"NIGHT_CLEAR");
}
else if (tempDouble <= 60.0 && (hour >= 6 || hour <= 17)) { //CLOUDY
NSLog(#"CLOUDY");
}
else if (tempDouble > 60.0 && (hour < 6 || hour > 17)) { //NIGHT_CLOUDY
NSLog(#"NIGHT_CLOUDY");
}
When I have a temp of 76.3 and an hour of 2, for example, I'd expect it to jump to NIGHT_CLEAR, but it actually goes to CLEAR. Did I set up my comparisons wrongly?
Thanks in advance for this simple question!
(hour >= 6 || hour <= 17)
is always true. All real numbers are either greater than or equal to 6 or less than or equal to 17 (some are both). I think you want:
(hour >= 6 && hour <= 17)
The same also applies to CLOUDY.
Some of your ||'s might be better off being &&'s.
Perhaps what you want is...
if (tempDouble > 60.0 && (hour >= 6 && hour <= 17)) { //CLEAR
NSLog(#"CLEAR");
}
else if (tempDouble > 60.0 && (hour < 6 && hour > 17)) { //NIGHT_CLEAR
NSLog(#"NIGHT_CLEAR");
}
else if (tempDouble <= 60.0 && (hour >= 6 || hour <= 17)) { //CLOUDY
NSLog(#"CLOUDY");
}
else if (tempDouble > 60.0 && (hour < 6 || hour > 17)) { //NIGHT_CLOUDY
NSLog(#"NIGHT_CLOUDY");
}

iPhone time comparison

I am trying to figure out how to create an 'if' statement that uses a time value as a condition. For example:
if (time <= 10:00) {
score = 3;
} else if (time <= 20:00) {
score = 5;
} else {
score = 9;
}
I know that a string of "5:23" cannot be compared this way but I don't think I can just turn a string value like that directly into an integer. Any thoughts?
Try this:
NSString *realTimeString = #"10:00";
NSString *someTimeString = [realTimeString stringByReplacingOccurrencesOfString:#":"
withString:#"."];
float time = [someTimeString floatValue];
if (time <= 10.00) {
score = 3;
} else if (time <= 20.00) {
score = 5;
} else {
score = 9;
}