If X = weekday that the month started on (for example, this month would be 4, or Wednesday)
Y = some other day of the month (for example, 21)
Find Z, which is the weekday (1-7) of Y
I thought this would work:
Z = (Y-X) % 7
In the example above Z = (21-4) % 7 = 3, which is correct (Oct. 21st is a Tuesday)
But it fails for November 8th: Z = (8-7) % 7 = 1, incorrect because Nov. 8th is a Saturday (weekday=7).
So what would be a robust formula for this?
Note - I know there are NSDate utilities for finding the weekday of a date, but in this case all I know is X,Y as given above.
It is hard to use modular arithmetic if you don't start counting from zero.
So let's define some new variables:
W = X - 1 = the weekday number, where W = 0 means Sunday
D = Y - 1 = the day of the month, starting with 0
Then W + D is the weekday number (Sunday = 0) of day D, if W + D < 7.
So take (W + D) mod 7 to get the weekday number of day D. Add 1 to convert back to Sunday = 1, so ((W + D) mod 7) + 1.
Substitute the definitions of W and D.
Weekday number of day X (where Sunday = 1) = ((X - 1 + Y - 1) mod 7) + 1 = ((X + Y - 2) mod 7) + 1.
Related
Summary
I would like to add 1 day to given timestamp in lua script.
My try
local creation_date = "2016-01-01 00:00:00.000"
local y, m, d, Hr, Min, Sec, Milli = creation_date:match '(%d+)-(%d+)-(%d+) (%d+):(%d+):(%d+).(%d+)'
local dt = y .. '-' .. m .. '-'..d.. ' '..Hr..':'..Min..'-'..Sec..'.'..Milli
print(dt)
local new_ts = os.time
{ year = y, month = m, day = d,
hour = Hr, min = Min, sec = Sec, mill=Milli } + 1*24*60*60
print(new_ts)
I am getting new_ts = 1452470400
Expected result
2016-01-01 00:01:00.000 (in this format only)
The closest you may be able to get is something like this:
local creation_date = "2016-01-01 00:00:00.000"
local y, m, d, Hr, Min, Sec, Milli = creation_date:match '(%d+)-(%d+)-(%d+) (%d+):(%d+):(%d+).(%d+)'
local dt = y .. '-' .. m .. '-'..d.. ' '..Hr..':'..Min..'-'..Sec..'.'..Milli
print(dt)
local new_ts = os.time { year = y, month = m, day = d, hour = Hr, min = Min, sec = Sec } + 1*24*60*60
print(string.format("%s.%03d", os.date("%Y-%m-%d %H:%M:%S", new_ts), Milli))
The Mill entry in the table that you pass on to os.time() is being ignored, and the resulting value doesn't provide millisecond precision, so there's no point in including it. To get the format you desire, you need os.date() with an appropriate format, and then you can append the milliseconds to that again, manually.
With that, it looks like this:
$ lua script.lua
2016-01-01 00:00-00.000
2016-01-02 00:00:00.000
With the suggestion from #Nifim it can be simplified further, confirmed by the documentation
When the function is called, the values in these fields do not need to be inside their valid ranges. For instance, if sec is -10, it means 10 seconds before the time specified by the other fields; if hour is 1000, it means 1000 hours after the time specified by the other fields. - Lua 5.4 Reference Manual: os.time
local creation_date = "2016-01-31 00:00:00.000"
local y, m, d, Hr, Min, Sec, Milli = creation_date:match '(%d+)-(%d+)-(%d+) (%d+):(%d+):(%d+).(%d+)'
local dt = y .. '-' .. m .. '-'..d.. ' '..Hr..':'..Min..'-'..Sec..'.'..Milli
print(dt)
local new_ts = os.time { year = y, month = m, day = d + 1, hour = Hr, min = Min, sec = Sec }
print(string.format("%s.%03d", os.date("%Y-%m-%d %H:%M:%S", new_ts), Milli))
Output:
$ lua script.lua
2016-01-31 00:00-00.000
2016-02-01 00:00:00.000
I am trying to divide Time in float form (hh.mm) by an integer.
For example 1.30 by 2 must give 00.45.
Is there any simple way to do this?
Using a float to express h.mm is a bit unusual. You would typically use strings for formatting.
However, I'd start by extracting hours and minutes from the float value. To do so, I would convert the float to a string using format:
time = 1.3
time_str = format('%.2f', time)
#=> "1.30"
Then I would split the string at . to get the hour part and minutes part and call to_i to convert them to actual integers: (I'm using map here, you could also call h = h.to_i / m = m.to_i afterwards)
h, m = time_str.split('.').map(&:to_i)
h #=> 1
m #=> 30
Now that we have the numbers 1 and 30 as integers, we can easily calculate the total duration in minutes:
duration = h * 60 + m
#=> 90
I would then divide the duration by 2 (or whatever value):
duration /= 2
#=> 45
and convert it back to hours and minutes using divmod: (it returns both values at once)
h, m = duration.divmod(60)
h #=> 0
m #=> 45
We can format these as a string:
format('%02d.%02d', h, m)
#=> "00.45"
or convert it back to a float:
time = h + m.fdiv(100)
#=> 0.45
Which can be formatted like this:
format('%05.2f', time)
#=> "00.45"
time = 1.3
divisor = 2
hr, min = (time.fdiv(divisor)).divmod(1)
#=> [0, 0.65]
min = (60 * min).round
#=> 39
"%02d.%02d" % [hr, min]
#=> "00.39"
Another example.
time = 1005
divisor = 5
hr, min = (time.fdiv(divisor)).divmod(1)
#=> [201, 0.0]
"%02d.%02d" % [hr, (60 * min).round]
#=> "201.00"
See Integer#fdiv, Float#fdiv, Integer#divmod and Integer#round. divmod is an extremely useful method that, for reasons I don't understand, seems to be under-used.
Maybe you can split into an array an then:
n = 2
[1, 30].then { |h, m| [h / n, (m + h % n * 60) / n]}
#=> [0, 45]
For splitting:
num = 1.3
('%.2f' % num).split('.').map(&:to_i) #=> [1, 30]
You can try the following :
num = 1.3
splitted_values = ('%.2f' % num).split('.').map(&:to_i) => [1, 30]
((splitted_values[0] * 60) / 2) + (splitted_values[1] / 2 ) => 45
I have one program downloaded from internet and need to get each digit printed out from a three digit number. For example:
Input: 123
Expected Output:
1
2
3
I have 598
Need to Get:
5
9
8
I try using this formula but the problem is when number is with decimal function failed:
FIRST_DIGIT = (number mod 1000) / 100
SECOND_DIGIT = (number mod 100) / 10
THIRD_DIGIT = (number mod 10)
Where number is the above example so here is calulation:
FIRST_DIGIT = (598 mod 1000) / 100 = 5,98 <== FAILED...i need to get 5 but my program shows 0 because i have decimal point
SECOND_DIGIT = (598 mod 100) / 10 = 9,8 <== FAILED...i need to get 9 but my program shows 0 because i have decimal point
THIRD_DIGIT = (598 mod 10) = 8 <== CORRECT...i get from program output number 8 and this digit is correct.
So my question is is there sample or more efficient code that get each digit from number without decimal point? I don't want to use round to round nearest number because sometime it fill failed if number is larger that .5.
Thanks
The simplest solution is to use integer division (\) instead of floating point division (/).
If you replace each one of your examples with the backslash (\) instead of forward slash (/) they will return integer values.
FIRST_DIGIT = (598 mod 1000) \ 100 = 5
SECOND_DIGIT = (598 mod 100) \ 10 = 9
THIRD_DIGIT = (598 mod 10) = 8
You don't have to do any fancy integer calculations as long as you pull it apart from a string:
INPUT X
X$ = STR$(X)
FOR Z = 1 TO LEN(X$)
PRINT MID$(X$, Z, 1)
NEXT
Then, for example, you could act upon each string element:
INPUT X
X$ = STR$(X)
FOR Z = 1 TO LEN(X$)
Q = VAL(MID$(X$, Z, 1))
N = N + 1
PRINT "Digit"; N; " equals"; Q
NEXT
Additionally, you could tear apart the string character by character:
INPUT X
X$ = STR$(X)
FOR Z = 1 TO LEN(X$)
SELECT CASE MID$(X$, Z, 1)
CASE " ", ".", "+", "-", "E", "D"
' special char
CASE ELSE
Q = VAL(MID$(X$, Z, 1))
N = N + 1
PRINT "Digit"; N; " equals"; Q
END SELECT
NEXT
I'm no expert in Basic but looks like you have to convert floating point number to Integer. A quick google search told me that you have to use Int(floating_point_number) to convert float to integer.
So
Int((number mod 100)/ 10)
should probably the one you are looking for.
And, finally, all string elements could be parsed:
INPUT X
X$ = STR$(X)
PRINT X$
FOR Z = 1 TO LEN(X$)
SELECT CASE MID$(X$, Z, 1)
CASE " "
' nul
CASE "E", "D"
Exponent = -1
CASE "."
Decimal = -1
CASE "+"
UnaryPlus = -1
CASE "-"
UnaryNegative = -1
CASE ELSE
Q = VAL(MID$(X$, Z, 1))
N = N + 1
PRINT "Digit"; N; " equals"; Q
END SELECT
NEXT
IF Exponent THEN PRINT "There was an exponent."
IF Decimal THEN PRINT "There was a decimal."
IF UnaryPlus THEN PRINT "There was a plus sign."
IF UnaryNegative THEN PRINT "There was a negative sign."
I am trying to write a script that determines stardate using the formula
a = LastLeapYearShort (if year is leap year make 4 years ago)
b = 366 + (365 * ((CurrentYearShort - 1) - LastLeapYearShort)
c = DayOfYear - DayOfMonth
d = DayOfMonth
e = (SecondOfMinute + (MinuteOfHour * 60))/1440
f = 36525
st = ((a + b + c + d + e)/f)*100000
separate x.y into x and y
if the century is greater than 19 add 1- to the beginning of x and get the first to digits of y
date = x.y
however I can't seem to determine a way to get DayOfYear. The Current Script I have is
function isLeapYear(year)
return year%4==0 and (year%100~=0 or year%400==0)
end
function lastLeapYear(year)
if(isLeapYear(year))
result = strsub(year,2,4) - 4
else
year = year - 1
if(isLeapYear(year))
result = strsub(year,2,4)
else
year = year - 1
if(isLeapYear(year))
result = strsub(year,2,4)
else
year = year - 1
if(isLeapYear(year))
result = strsub(year,2,4)
else
result = "Invalid"
end
end
end
end
return result
end
function stardate()
yearf = os.date("%Y")
yearh = os.date("%y")
a = lastLeapYear(yearf)
b = (366 + (365 * (yearh - a)))
c = (!!DayOfYear!! - os.date("%d"))
d = os.date("%d")
e = (os.date("%S") + (os.date("%M") * 60))/1440
f = 36525
st = ((a + b + c + d + e)/f)*100000
!!Separate st into x and y!!
if(strsub(yearf,0,2) > 19)
diff = strsub(yearf,0,2) - 19
lead = diff "-" lead
end
return lead.dec
end
if there are any other errors in my code please point them out as I have very little Lua experience.
The day of year is the value of os.date("*t").yday or os.date("%j").
The first expression gives you a number; the second one gives you a string (which can be converted explicitly to a number with tonumber or implicitly when used in an arithmetic operation).
For any one who can't find the proper format string a more advanced list than that on http://www.lua.org/pil/22.1.html (which is where I was looking) can be found on http://docs.rainmeter.net/manual/measures/time
Now that CodeSprint 3 is over, I've been wondering how to solve this problem. We need to simply calculate nCr mod 142857 for large values of r and n (0<=n<=10^9 ; 0<=r<=n). I used a recursive method which goes through min(r, n-r) iterations to calculate the combination. Turns out this wasn't efficient enough. I've tried a few different methods, but they all seem to not be efficient enough. Any suggestions?
For non-prime mod, factor it (142857 = 3^3 * 11 * 13 * 37) and compute C(n,k) mod p^q for each prime factor of the mod using the general Lucas theorem, and combine them using Chinese remainder theorem.
For example, C(234, 44) mod 142857 = 6084, then
C(234, 44) mod 3^3 = 9
C(234, 44) mod 11 = 1
C(234, 44) mod 13 = 0
C(234, 44) mod 37 = 16
The Chinese Remainder theorem involves finding x such that
x = 9 mod 3^3
x = 1 mod 11
x = 0 mod 13
x = 16 mod 37
The result is x = 6084.
Example
C(234, 44) mod 3^3
First convert n, k, and n-k to base p
n = 234_10 = 22200_3
k = 44_10 = 1122_3
r = n-k = 190_10 = 21001_3
Next find the number of carries
e[i] = number of carries from i to end
e 4 3 2 1 0
1 1
r 2 1 0 0 1
k 1 1 2 2
n 2 2 2 0 0
Now create the factorial function needed for general Lucas
def f(n, p):
r = 1
for i in range(1, n+1):
if i % p != 0:
r *= i
return r
Since q = 3, you will consider only three digits of the base p representation at a time
So
f(222_3, 3)/[f(210_3, 3) * f(011_3, 3)] *
f(220_3, 3)/[f(100_3, 3) * f(112_3, 3)] *
f(200_3, 3)/[f(001_3, 3) * f(122_3, 3)] = 6719344775 / 7
Now
s = 1 if p = 2 and q >= 3 else -1
Then
p^e[0] * s * 6719344775 / 7 mod 3^3
e[0] = 2
p^e[0] = 3^2 = 9
s = -1
p^e[0] * s * 6719344775 = -60474102975
Now you have
-60474102975 / 7 mod 3^3
This is a linear congruence and can be solved with
ModularInverse(7, 3^3) = 4
4 * -60474102975 mod 27 = 9
Hence C(234, 44) mod 3^3 = 9