I know that it's a busy time of year, with the end of the school year and whatnot, but I figured an easy golf could be a welcome break from the chaos that is the outside world.

This program should take the on-calc time and return the Unix/Epoch time in Ans (Assuming the on-calc time is UTC). If you don't know what Unix time is, you can glance over the [Wikipedia page], but in short, Unix Time is the number of seconds since midnight on Jan 1, 1970 (UTC) minus leap seconds.

It only needs to output values from between calculator and unix compatible times, which leads to the range of 00:00:00 Jan 1, 1997 (852076800) [calc min] to 03:14:07 Jan 19, 2038 (2147483647) [Unix max] To find out why this is the Unix max, you can read the [Wikipedia page] on the K2k38 problem.

To test different times, I use epochconverter.com.

Examples:
Code:
getDate
{2020,1,1
getTime
{0,0,0
0:prgmU:Ans
1577836800

getDate
{2017,9,2
getTime
{5,10,24
0:prgmU:Ans
1504329024


Requirements:
  • Input: None
  • Freshly reset calc (every variable reset to 0/not defined [except the time, obviously])
  • Valid on-calc time
  • Output: Integer in Ans with the Unix time that corresponds with the on-calc time.
  • The only time-based functions allowed are getTime and getDate (no dbd, startTmr, checkTmr, setDate, or setTime), but I would be happy to see other obscure functions.

Size: The program's size is measured as:

Code:
on-calc-size - 9 - length(name)
Lowest score wins! Good luck!

Don't forget about leap years!

Current Results:
  1. lirtosiast: 63 bytes
  2. LogicalJoe: 68 bytes
  3. Zeroko: 91 bytes
  4. kg583: 103 bytes
  5. Sam: 118 bytes

Other results:
  • PT_: 11 bytes - startTmr monochrome only
  • fghsgh: 12 bytes - startTmr monochrome only
  • mr womp womp: 23 bytes - setDate( and setTime(
  • lirtosiast: 39 bytes - only one time supported
  • fghsgh: 52 bytes - dbd(

Code:
:getDate
:sum(getTime{3600,60,1})+86400dbd(101.7,100Ans(3)+Ans(2)+fPart(.01Ans(1
for a total score of 52
(dbd( is technically not a time-based command as it also existed before calcs with a clock (like the 83+))
EDIT: oh come on I give up in that case

with

Code:
:startTmr+852076800
it could've been 12...
104 bytes, with a bit of costless obfuscation cause why not:


Code:
:not(fPart(4^^-1max(getDate->A
:23+{8,7,8,7,8
:cumSum(augment({-1.1,31,28+A},augment(Ans,Ans
:getDate
:|LA(Ans(2))+Ans(3)-365.25(1970-max(Ans
:86400round(Ans,0)+sum(getTime60^{2,1,0


Implementing dbd( by hand is really annoying... (though I'm sure there is still room for improvement)

EDIT: 103 bytes via Zeroko's substitution


Code:
:not(fPart(4^^-1max(getDate->A
:23+{8,7,8,7,8
:cumSum(augment({-1.1,31,28+A},augment(Ans,Ans
:getDate
:|LA(Ans(2))+Ans(3)-365.25(1970-max(Ans
:5!6!round(Ans,0)+sum(getTime60^{2,1,0
Very Happy


Code:
While min(augment(getDate,getTime)!={2020,1,1,0,0,0
End
1577836800


I haven't written an actual solution, but it feels somewhere around 60-70. Not having to do the full leap year rule really helps.

Edit:

This looks like 80 (could take 81 if I get unlucky with storing the data).


Code:
getDate
sum({365.25,28,1}Ans)+sum(int(4fPart(FGHIJKLrandIntNoRep(1,Ans(2
Ans+int(Ans/1461-XXXXXXX.XXX
86400Ans+sum(getTime{60^^2,60,1
125

Code:
augment(getDate-1,getTime→L₁
L₁(1)-1969→Y
L₁(2→M
3600→H
24H(30M+int((M+1+(M>7))/2)-(1+(fPart((Y+1)/4)≠0))(M>1))+8760HY+24Hint((Y+2)/4)+sum(L₁{0,0,24H,H,60,1

This took me wayyyyy too long, lol. I could easily take 5-10 bytes off but I'm just happy that it works for now.

Edit: 118

Code:
augment(getDate-1,getTime→L₁
L₁(1)-1969→Y
L₁(2→M
60^^2→H
sum(L₁{0,0,24H,H,60,1})+24H(30M+int((M+1+(M>7))/2+int((Y+2)/4)+365Y)-(M>1)(1+(fPart((Y+1)/4)≠0
lirtosiast wrote:

Code:
getDate
sum({365.25,28,1}Ans)+sum(int(4fPart(FGHIJKLrandIntNoRep(1,Ans(2
Ans+int(Ans/1461-XXXXXXX.XXX
86400Ans+sum(getTime{60^^2,60,1
What in tarnation does this do? Do I see a randIntNoRep in there, lol?

Edit: Looking closer, it's clear that this does not properly account for leap days anyway. You can't just put in 365.25 and call it a day, sadly.
Sam wrote:
lirtosiast wrote:

Code:
getDate
sum({365.25,28,1}Ans)+sum(int(4fPart(FGHIJKLrandIntNoRep(1,Ans(2
Ans+int(Ans/1461-XXXXXXX.XXX
86400Ans+sum(getTime{60^^2,60,1
What in tarnation does this do? Do I see a randIntNoRep in there, 0x5?

Edit: Looking closer, it's clear that this does not properly account for leap days anyway. You can't just put in 365.25 and call it a day, sadly.


What does it do? A clever hashing trick to deal with the months, one that's smaller than my attempt which uses cumSum(. Though you are correct to point out that leap years really do make a fuss out of everything since they occur at the end of February.

So, though not technically my own entry (I just found lirto's constants using his own hash generator 0x5), 93 bytes:

Code:
:getDate-1
:sum({365.25,28,1}Ans)-719177+sum(int(4fPart((37747811-5628827not(fPart(4^^-1max(Ans+1))))cosh(cos(randIntNoRep(0,Ans(2
:86400int(Ans)+sum(getTime60^{2,1,0


Sorry if I stole any of your thunder lirto. I just had to fill in those Xs...
Suggestions to deal with leap years are always much appreciated.

Edit: 90 bytes by finding some smaller hashes

Code:
:getDate-1
:int(sum({365.25,28,1}Ans)-719177+sum(int(4fPart((8479662-798066not(fPart(4^^-1max(Ans+1))))cosh(sin(randIntNoRep(0,Ans(2
:86400Ans+sum(getTime60^{2,1,0
Sam wrote:
lirtosiast wrote:

Code:
getDate
sum({365.25,28,1}Ans)+sum(int(4fPart(FGHIJKLrandIntNoRep(1,Ans(2
Ans+int(Ans/1461-XXXXXXX.XXX
86400Ans+sum(getTime{60^^2,60,1
What in tarnation does this do? Do I see a randIntNoRep in there, 0x5?

Edit: Looking closer, it's clear that this does not properly account for leap days anyway. You can't just put in 365.25 and call it a day, sadly.

randIntNoRep is the shortest way to create a list of numbers [1 ... n] if you don't already have a list of length n and you don't care that the numbers aren't in order (in this case, he is taking the sum so it doesn't matter)

This is very cheaty but meets all your requirements (you have to read them like a lawyer though) 23 Bytes Evil or Very Mad

Code:
setDate(2001,9,9
setTime(1,46,40
10^(9
Sam wrote:
lirtosiast wrote:

Code:
getDate
sum({365.25,28,1}Ans)+sum(int(4fPart(FGHIJKLrandIntNoRep(1,Ans(2
Ans+int(Ans/1461-XXXXXXX.XXX
86400Ans+sum(getTime{60^^2,60,1
What in tarnation does this do? Do I see a randIntNoRep in there, 0x5?

Edit: Looking closer, it's clear that this does not properly account for leap days anyway. You can't just put in 365.25 and call it a day, sadly.


The program was broken, but the idea is sound. Without any years divisible by 100 but not 400 in the domain, leap days are just every 4 years; i.e. every 1460 normal days. So we add a day every 1460 days using int(Ans/1460, but need to offset it by .05 of a leap cycle so it happens after February.

This works for 79 bytes.


Code:
getDate->D
int(365max(Ans)+30.5Ans(2)-int(3fPart(35sin(cosh^-1(sqrt(Ans(2
Ans+|LD(3)+int(Ans/1460-719573.05
86400Ans+sum(getTime{60^^2,60,1
91 bytes with correct leap year handling:

Code:
getDate→X
sum(int(2fPart(.43randIntNoRep(1,Ans(2
Ans-int(4⁻¹(2878297+sum(ʟX{1461,5!,4
Ans-(ʟX(2)>2)(2-not(remainder(ʟX(1),4
5!6!Ans+sum(getTime{60²,60,1

EDIT: Oops, lirtosiast already had a smaller correct solution.
Zeroko wrote:
91 bytes with correct leap year handling:

Code:
getDate→X
sum(int(2fPart(.43randIntNoRep(1,Ans(2
Ans-int(4⁻¹(2878297+sum(ʟX{1461,5!,4
Ans-(ʟX(2)>2)(2-not(remainder(ʟX(1),4
5!6!Ans+sum(getTime{60²,60,1

EDIT: Oops, lirtosiast already had a smaller correct solution.


Don't sell yourself short; you're the first to realize that 86400=5!6!, which can put lirto's down to 78 bytes with the substitution. Now I'm left wondering if there's an optimal solution that doesn't require saving getDate to a custom list...
71 bytes; relies on the fact that rand is seeded to 0 when the calculator is reset.


Code:
getDate
365max(Ans)+sum(31-iPart(tanh^-1(fPart(28pitanh^-1(rand(Ans(2
Ans+int(Ans/1460-719574.05+sum(getDate,3
5!6!Ans+sum(getTime{60^^2,60,1
11-byte solution, though technically not valid:


Code:
5!²59172+startTmr
63 bytes. I should have recognized this technique from similar challenges (abuse of vectorization and int/fPart) but I didn't see the structure earlier.

This is probably still not optimal, but I'm done for now.


Code:
getDate
sum(getTime{60^^2,60,1}+6!40int(3Ans-719574.05+max(364.25Ans+sum(30.02-iPart(tanh^-1(fPart(28pitanh^-1(rand(Ans(2
gg lirtosiast.

68 bytes using a similar structure.

Code:
getDate
sum(getTime{60^^2,60,1})+5!6!int(max(365.25Ans-719575+Ans(3)+tanh(5Ans(2))+sum(31-int(atanh(fPart(pi28atanh(rand(Ans(2
I feel that it is important to note that I made this code before I started the thread.

I don't know how you manage to get into my computer each golf when I actually have something good. I know it's difficult because it takes you until the day before I intend to post it. I keep changing my security, but every time you still somehow manage to get through.
lirtosiast wrote:
63 bytes. I should have recognized this technique from similar challenges (abuse of vectorization and int/fPart) but I didn't see the structure earlier.

This is probably still not optimal, but I'm done for now.


Code:
getDate
sum(getTime{60^^2,60,1}+6!40int(3Ans-719574.05+max(364.25Ans+sum(30.02-iPart(tanh^-1(fPart(28pitanh^-1(rand(Ans(2
Would you mind explaining what's happening here? This is really the first time I've tried hardcore optimization so I don't really know all the tricks.
New code golf - secure LJ's computer!
Sam wrote:
lirtosiast wrote:
63 bytes. I should have recognized this technique from similar challenges (abuse of vectorization and int/fPart) but I didn't see the structure earlier.

This is probably still not optimal, but I'm done for now.


Code:
getDate
sum(getTime{60^^2,60,1}+6!40int(3Ans-719574.05+max(364.25Ans+sum(30.02-iPart(tanh^-1(fPart(28pitanh^-1(rand(Ans(2
Would you mind explaining what's happening here? This is really the first time I've tried hardcore optimization so I don't really know all the tricks.


First, let's look at how one would find a program assuming leap years didn't exist. If you realize the result is linear in the number of days and years, and months can fit in a lookup table, a first attempt might look like this, where X is the number of days between "year 0" and year 1970:

Code:
getDate
365Ans(1)+Ans(3)-XXXXXXX+sum({0,31,28,31,30,31,30,31,31,30,31,30},1,Ans(2
86400Ans+sum({3600,60,1}getTime


But lookup tables are always inferior to hashes-- that is, random-looking expressions on a small domain found by brute force. Here, the domain is of size 12, or maybe 11 depending on whether we can offset January for free with X. We really want to compute the month part with a hash, but our required range is numbers between 0 and 334, and for information-theoretic reasons, hashes can only reliably map to a small range as well-- say, N^K < 10^11 where K is the range size and N is the domain size. 334^11 would be way too big! Luckily, for month M, the day number is very close to 30M with a small offset. So we have two options:

* something like 30Ans(2)+ before the hash (+7 bytes)
* Have the hash expression be the sum( of a list, and add 30 to each element of the list for a total of 30M. This requires a different hash that's effectively the DeltaList( of the other one. But assuming the hash expressions are the same length, we only use "sum(30+" (+4 bytes). It turns out to be better to make the output of the hash positive, which means "sum(31-". The range is {0,1,2,3} so we have N^K = 4^11 = 4 * 10^6, much better. My rule of thumb is that hashes have size log_10(N^K), and in fact we find it at 6 bytes:

Code:
sum(31-iPart(tanh^-1(fPart(28pitanh^-1(rand(Ans(2


The full solution would be

Code:
getDate
sum(getTime{60^^2,60,1})+86400(365Ans(1)+Ans(3)-XXXXXXX+sum(31-iPart(tanh^-1(fPart(28pitanh^-1(rand(Ans(2


At this point, you should remember that indexing into a list is an expensive way to access its elements. Ans(1) takes 4 bytes, while max(Ans) is 3. Also noticing that

* sum(Ans) = Ans(1)+Ans(2)+Ans(3)
* 86400=5!6! (I probably wouldn't have found this without Zeroko)
* Ans(1) = max(Ans), because the year is larger than the month or day

we have

Code:
getDate
sum(getTime{60^^2,60,1})+6!5!(364max(Ans)+sum(Ans)-XXXXXXX+sum(30-iPart(tanh^-1(fPart(28pitanh^-1(rand(Ans(2


Now we can abuse vectorization -- instead of adding to the sum, we can add to elements of the list, saving the end-parenthesis after the first sum(. (A heuristic: If your code has any open or close parentheses, with some exceptions, it's probably suboptimal.) Also, multiplication can go inside or outside max(, and that sort of thing. Since we're adding to 3 elements of the list, we have to divide scalars by 3, giving us:

Code:
getDate
sum(getTime{60^^2,60,1}+6!40(3Ans-XXXXXXX+max(364Ans+sum(30-iPart(tanh^-1(fPart(28pitanh^-1(rand(Ans(2


That's the main part of the code. Adding leap years seems daunting, but leap days in this domain are just every 4 years, and we only add one at a time. This screams int(; changing the year coefficient from 364 to 364.25 and rounding down with int( is almost enough. But we need to apply the leap day at the start of March, not the start of the year.


Code:

year 2018 2019 2020 2021 ...
Jan   .50  .75  .00  .25
Feb   .50  .75  .00  .25
Mar   .50  .75  .00  .25
...
// subtracting .05 and adding .02 per month gives
year 2018 2019 2020 2021 ...
Jan   .47  .71  .97  .22 ...
Feb   .49  .74  .99  .24 ...
Mar   .51  .76  .01  .26 ...
...


To recap:

Code:
getDate
sum(getTime{60^^2,60,1}+6!40int(3Ans-719574.05+max(364.25Ans+sum(30.02-iPart(tanh^-1(fPart(28pitanh^-1(rand(Ans(2

getDate
    30.02-        // 31 days/month† - 1 - offset
sum(     -iPart(tanh^-1(fPart(28pitanh^-1(rand(Ans(2
+max(364.25Ans    // 365 days per year - 1
-719574.05        // day number of 1970†
        3Ans      // {day,month,year}
    int(          // add a whole number of leap days
6!40              // 86400 s/day, /3 since everything but the 3Ans
                  // has *3 from vectorization


† adjust for leap year at start of March
//finally, add time
sum(getTime{60^^2,60,1}+


To implement the full leap year rule, I'd probably add a couple more chained int( for 100 and 400 but keep the structure much the same, something like -int(max(Ans%+int(Ans/400. Then the long line would need to be split up because there are two vines (expressions with more than 2-3 open parentheses, which is too many to efficiently close them all). Finding a way to combine vines, as I did from 71 bytes to 63, can be very golfy because all those linebreaks add up-- not to mention storing subexpressions.

LogicalJoe wrote:
I don't know how you manage to get into my computer each golf when I actually have something good. I know it's difficult because it takes you until the day before I intend to post it. I keep changing my security, but every time you still somehow manage to get through.


I think I get a lot out of the 4th or 5th day of thinking about a code-golf problem of this difficulty because I've been golfing for a few years. TI-BASIC is limiting enough that there aren't many clever techniques left to invent, so it's often just about fiddling with the arithmetic and finding the correct structure and doing micro-optimizations, which can take a while. If you can find a problem with structure that BASIC can exploit in some highly nonobvious way (e.g. the "rand" thing for the 8 puzzle), I probably won't find it.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement