PROGRAMMING CHALLENGE 02/23 - CLOCK WISE

PROGRAMMING CHALLENGE 02/23 - CLOCK WISE

john.uhden
Mentor Mentor
1,060 Views
22 Replies
Message 1 of 23

PROGRAMMING CHALLENGE 02/23 - CLOCK WISE

john.uhden
Mentor
Mentor

This challenge is to use AutoLisp only to create a list of strings representing the times (HH:MM:SS) when the hour hand, minute hand, and second hand of an analog clock are all pointing in the same direction (angle) in one (1) rotation of the hour hand (12 hours).
I imagine it will require a few simple but clever formulas, and may even a (while) loop to converge on the solutions.  I have done nothing as yet.
Yes, you may use a fuzz factor of 0.4 seconds or 2e-06 radians (if I converted that correctly).

Of course you should work on this only in your spare TIME.  🙂

John F. Uhden

0 Likes
1,061 Views
22 Replies
Replies (22)
Message 2 of 23

CodeDing
Advisor
Advisor

**Edit: Nevermind, I think my first attempt was wrong, gonna keep working on it**

0 Likes
Message 3 of 23

Kent1Cooper
Consultant
Consultant

If by 0.4 seconds fuzz factor you mean the angle swept by 0.4 seconds on the clock, that's 2.4° or 2°24' or 0.0491 radians.  With that as fuzz factor, it may be possible to achieve what you're looking for.

 

If you really meant your 0.4 seconds as equivalent to 2e-6 radians, that [more precisely 1.94e-6] is equal to 0.4 arc-seconds -- 0°0'0.4" -- in which case it's not possible to get coincidence of all three hands within that fuzz factor.

 

The first occurrence of the hour and minute hands coinciding is when the hour hand has gone 1/11 of all the way around, which is at 5.4545... minutes past 1:00.  That's 5 minutes and 27.2727... seconds, so the second hand aims in quite a different direction than the other two.  Back that off until the second hand hits where the other two were when they coincided, and the minute hand will back off by 2.1822727...°, far outside the 0.4 arc-seconds tolerance.  But not quite outside a tolerance of 0.4 clock-seconds.

Kent Cooper, AIA
0 Likes
Message 4 of 23

CodeDing
Advisor
Advisor

Ok, I think I got it this time!

 

Since it seems the desired output is to know that at any given second, whether or not the hands overlap (within 0.4 seconds of tolerance).. I think my function performs that task.

 

(defun c:CLOCK-WISE ( / Overlapp h m s timeList)
  (defun Overlapp (h m s / radCircle andSec angMin angHour fuzz)
    (setq
      s (atof (itoa s))
      m (+ (atof (itoa m)) (/ s 60.0))
      h (+ (atof (itoa h)) (/ m 60.0))
    );setq
    (setq radCircle (* 2.0 pi))
    (setq angSec (* radCircle (/ s 60.0)))
    (setq angMin (* radCircle (/ m 60.0)))
    (setq angHour (* radCircle (/ h 12.0)))
    (setq fuzz (* radcircle (/ 0.4 60.0))) ;;<--- 0.4 sec tolerance
    (and (equal angSec angMin fuzz) (equal angSec angHour fuzz) (equal angMin angHour fuzz))
  );defun
  (setq h 0)
  (while (<= h 12)
    (setq m 0)
    (while (<= m 60)
      (setq s 0)
      (while (< s 60)
        (if (Overlapp h m s)
          (setq timeList (cons (strcat (itoa h) ":" (itoa m) ":" (itoa s)) timeList))
        );if
        (setq s (1+ s))
      );while
      (setq m (1+ m))
    );while
    (setq h (1+ h))
  );while
  (prompt "\nOverlap Times:")
  (foreach time (reverse timeList)
    (terpri) (prompt time)
  );foreach
  (prompt "\nCLOCK-WISE Complete.")
  (princ)
);defun

 

Outputs:

 

Overlap Times:
0:0:0
2:11:11
3:16:16
8:43:44
9:48:49

 

Best,

~DD

0 Likes
Message 5 of 23

john.uhden
Mentor
Mentor

@Kent1Cooper ,

Many thanks.  We probably all needed that.

Yes, I did mean time seconds = 1/60 minute = 1/3600 hour.

(And to think I scored 728 on the math SAT somewhere near the middle of the last century.

Ah, but I wore a younger man's clothes.)

John F. Uhden

0 Likes
Message 6 of 23

john.uhden
Mentor
Mentor

@CodeDing ,

Pretty good, but I had surmised there would be 12 answers, one for each hour.

I guess that's because of the fuzz factor, as Kent reported, maybe?

John F. Uhden

0 Likes
Message 7 of 23

CodeDing
Advisor
Advisor

😅clocks are weird.. And I should probably check my work a little better?

 

Here are the 11 overlap times (according to chatGPT).

12:00:00.000
1:05:27.273
2:10:54.545
3:16:21.818
4:21:49.091
5:27:16.364
6:32:43.636
7:38:10.909
8:43:38.182
9:49:05.455
10:54:32.727

But that doesn't mean that 1 minute later, they still WOULDN'T be in tolerance. So idk the EXACT answer yet to be within 0.4 seconds of tolerance.

0 Likes
Message 8 of 23

Kent1Cooper
Consultant
Consultant

@CodeDing wrote:

.... Here are the 11 overlap times .....


Those are the overlap times of the hour hand and the minute hand.  The second hand doesn't coincide with those two at any of those times, though at two of them it's only about 5 seconds away, so when it coincides with one of them, all three could be within the fuzz factor of each other.

Kent Cooper, AIA
0 Likes
Message 9 of 23

rgrainer
Collaborator
Collaborator

Both you and the piano man, probably.

 

"but I wore a younger man's clothes."


 

0 Likes
Message 10 of 23

Sea-Haven
Mentor
Mentor

We may have a winner, look carefully at the image for the Author name ! Another great one by him.

SeaHaven_0-1697951124659.png

 

Current time day etc.

 

0 Likes
Message 11 of 23

komondormrex
Mentor
Mentor

 

 

@john.uhden

(defun c:min_hour_overlap ()
	(setq min_start '(0 0)
	      min_end '(3600 60)
	      hour_start '(0 0)
	      hour_end '(3600 5)
	      hour -1
	)
	(repeat 12
	  	(setq _min (cadr (inters min_start min_end hour_start hour_end))
	  	      min_start (mapcar '+ min_start '(3600 0))
		      min_end (mapcar '+ min_end '(3600 0))
		      hour_start (mapcar '+ hour_start '(3600 5))
		      hour_end (mapcar '+ hour_end '(3600 5))
	        )
	  	(princ (setq hour (1+ hour)))
	  	(princ ":")
	  	(princ (fix _min))
	  	(princ ":")
	  	(princ (* 60 (- _min (fix _min))))
	  	(princ "\n")
	)
  (princ)
) 

 

0 Likes
Message 12 of 23

CodeDing
Advisor
Advisor

@komondormrex ,

 

You got the same answers as Chat GPT (my reply in Message 7). But as we can tell by looking at the "seconds" hand of those times, they are incorrect. Kent also pointed out this flaw in Message 8!

 

Best,

~DD

0 Likes
Message 13 of 23

komondormrex
Mentor
Mentor

sure. you may notice that my command is called min_hour_overlap. no second thou. 

0 Likes
Message 14 of 23

hak_vz
Advisor
Advisor

Purely mathematical solution for "ideal mechanical clock":

 

 

(defun c:timeoverlaps (/ test_hours )
	(defun to_hms (secs / hrs rem1 mins rem2 secs test_hours delseconds i overlaps)
		(setq
			hrs (/ secs 3600.0)
			rem1 (rem secs 3600.0)
			mins (/ rem1 60.0)
			rem2 (rem mins 1.0)
			secs (* rem2 60.0)
		)
		(strcat (rtos hrs 2 0) ":" (rtos mins 2 0) ":" (rtos secs 2 2))
	)
	(setq test_hours 12  delseconds (+ (* 65 60) (* (/ 5.0 11) 60)) i -1 )
	(while (< (setq i (1+ i)) test_hours)(setq overlaps (cons (* i delseconds) overlaps)))	
	(mapcar 'princ (mapcar '(lambda (x)(strcat "\n" x)) (mapcar 'to_hms (reverse overlaps))))
	(princ)
)
1:5:27.27
2:11:54.55
3:16:21.82
4:22:49.09
5:27:16.36
7:33:43.64
8:38:10.91
9:44:38.18
10:49:5.45
11:55:32.73
12:0:0

 

 

If we look at this clock hands overlaps we can see that seconds are actually wrong for every but last result.

Since we know that seconds hand is 60 times faster than minutes hand and 720 times faster than hours hand, seconds are irrelevant to final solution since at overlap times all three hand will stay on a mechanical watch within assumed angular tolerance.  So correct clock hands overlap times are:

 

 

 

(defun c:timeoverlaps2 (/ test_hours )
	(defun to_hms (secs / hrs rem1 mins rem2 secs test_hours delseconds i overlaps)
		(setq
			hrs (/ secs 3600.0)
			rem1 (rem secs 3600.0)
			mins (/ rem1 60.0)
			rem2 (rem mins 1.0)
			secs (* rem2 60.0)
		)
		(strcat (rtos hrs 2 0) ":" (rtos mins 2 0) ":" (rtos mins 2 0))
	)
	(setq test_hours 12  delseconds (+ (* 65 60) (* (/ 5.0 11) 60)) i -1 )
	(while (< (setq i (1+ i)) test_hours)(setq overlaps (cons (* i delseconds) overlaps)))	
	(mapcar 'princ (mapcar '(lambda (x)(strcat "\n" x)) (mapcar 'to_hms (reverse overlaps))))
	(princ)
)
1:5:5
2:11:11
3:16:16
4:22:22
5:27:27
7:33:33
8:38:38
9:44:44
10:49:49
11:55:55
12:0:0

 

 

 

 

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
Message 15 of 23

Kent1Cooper
Consultant
Consultant

Those can't all be correct, for example, there can't be one between 11:00 and 12:00 just as there can't be one between 12:00 and 1:00, and there has to be one [hour-&-minute-hands, at least] between 6:00 and 7:00.  But even for those that agree with Message 7, they have the same problem described in Message 8.

Kent Cooper, AIA
0 Likes
Message 16 of 23

hak_vz
Advisor
Advisor

@Kent1Cooper  Check my edited post above

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
0 Likes
Message 17 of 23

komondormrex
Mentor
Mentor

but surely John's challenge can be solved by finding 10 times where the hour and minute hands are 0.4 seconds away from the second hand. something like this.

 

01:05:15.2683812

02:11:3.5487138

03:16:18.8170956

04:21:34.0854768

05:27:22.3658094

06:32:37.6341906

07:38:25.9145232

08:43:41.1829044

09:48:56.4512862

10:54:44.7316188

0 Likes
Message 18 of 23

Kent1Cooper
Consultant
Consultant

Something is still not right.  Surely they won't coincide at 11:55:55.  The last one before 12:00 would have to be exactly as far before 12:00 as the first one is after it.

Kent Cooper, AIA
0 Likes
Message 19 of 23

john.uhden
Mentor
Mentor

@EVERYONE

Here is my very verbose attempt at solving the challenge:

 

 

(defun c:CLOCK-WISE-JU (/ *error* vars vals HMS2ang ang2HMS pad format fuzz H H^ M S a1 a2 HMS)
  ;; v 1.0 (10-23-2023)
  ;; Program by John F. Uhden in response to Challenge 2-23
  ;;   to report the times of a 12-hour analog clock
  ;;   when the hour, minute, and second hands are all pointing in the same direction
  ;;   within a tolerance of 0.41 seconds (clock time).
  ;;   !! IF THE RESULTS ARE WRONG, PLEASE LET ME KNOW !!
  (defun *error* (err)
    (if err (print (strcat "ERROR: " err)))
    (mapcar 'setvar vars vals)
    (princ)
  )
  (setq vars '("angbase" "angdir" "cmdecho" "dimzin"))
  (setq vals (mapcar 'getvar vals))
  (mapcar 'setvar vars '(90 1 0 0))
  (command "_.expert" (getvar "expert")) ; dummy command
  (defun HMS2ang (HMS / H M S ang)
    ; where HMS is a list such as '(1 12 12)
    (setq H (rem (car HMS) 12) M (cadr HMS) S (last HMS))
    (setq ang (+ (* pi (/ H 6.0)) (* pi (/ M 6.0 60)) (* pi (/ S 6.0 3600))))
  )
  (defun ang2HMS (ang / a H M S)
    (setq H (fix (* (/ ang (* 2 pi)) 12.0)))
    (if (= H 0)(setq H 12))
    (setq M (* (/ ang (* 2 pi)) 60.0))
    (setq S (fix (* (- M (fix M)) 60)))
    (setq M (fix M))
    (list H M S)
  )
  (defun pad (str)
    (if (< (strlen str) 2)(strcat "0" str) str)
  )
  (defun format (HMS)
    (setq HMS (mapcar 'itoa HMS))
    (strcat (car HMS) ":" (pad (cadr HMS)) ":" (pad (last HMS)))
  )
  (setq fuzz 2e-006) ; = 0.41 sec.
  (foreach H '(1 2 3 4 5 6 7 8 9 10 11 12)
    (setq H^ (rem H 12))
    (setq M (* H^ 5) S 10) ; seed value based on 5 minutes
       ; being the same deflection as 1 hour.
    (setq a1 (hms2ang (list H^ M S)))
    (while (not (equal a1 a2 fuzz))
      (setq a2 (HMS2ang (ang2hms a1)))
      ; (princ "\n")(princ (angtos a1 1 6))(princ "  ")(princ (angtos a2 1 6))
      (setq a1 (/ (+ a1 a2) 2))
    )
    (print (format (ang2hms a2)))
  ) ;; foreach
  (*error* nil)
)
;|
BTW, I had tried to use the symbol name H', but look what happens...

Command: (setq H' 3)
3

Command: (princ H')
; error: extra right paren on input

Command: (itoa H')
; error: extra right paren on input
|;

 

John F. Uhden

0 Likes
Message 20 of 23

john.uhden
Mentor
Mentor

@hak_vz ,

Your code is amazingly succint, but my answers are slightly different.

That's probably due to some false assumption on my part.

John F. Uhden

0 Likes