Симметрия на часах (конкурс)

Симметрия на часах (конкурс)

На рекламных фотографиях часовая и минутная стрелки часов обычно устанавливаются на отметках 10 и 2 часа, таким образом, чтобы они были симметричны по отношению к вертикальной оси.

Реальные часы имеют некоторую дискретность. Например, у конкретной модели часовая стрелка может перемещаться только после окончания очередной минуты. А то и 12 минут.

Будем считать наши часы более совершенными: часовая стрелка перемещается всегда пропорционально минутной, а минутная, в свою очередь, пропорционально секундной. Соответственно, говорить о полной симметрии вряд ли уместно, углы могут незначительно отличаться.

Требуется найти все положения часовой и минутной стрелок, соответственно, с точностью до секунды, когда достигается симметрия и выбрать из них максимально симметричное относительно оси "12-6" часов.

Решений может быть представлено два:

  1. Простой перебор вариантов. В дальнейшем будет использоваться как "скоростемер" (бенчмарк)
  2. В аналитическом виде

Для участия в конкурсе нужно предложить программы для ПМК, описание и результаты расчетов. Никаких ограничения по моделям нет. Язык программирования должен быть основным входным языком для данного устройства. Допускаются также программы для эмуляторов ПМК.

Критерии оценки решения:

  1. Срок публикации (при наличии сокращенной опубликованной ранее программы приоритет получает автор оригинальной версии)
  2. Полнота решения (один или два варианта)
  3. Компактность (число шагов/байтов программы)
  4. Скорость расчета (программы для эмуляторов по этому критерию не оцениваются, необходим прогон на реальном железе)

Пример решения

Для начала мы попробуем предложить более формальную постановку задачи и наиболее простое в алгоритмическом плане решение на МК-61/52/152.

Нетрудно заметить, что за часовая стрелка поворачивается на 30° за 1 час, а минутная и секундная - на 6° за минуту и секунду, соответственно. Если задавать время в виде тройки чисел (h, m, s), где h - часы в диапазоне [0..11], m - минуты [0..59], s - секунды [0..59], тогда углы стрелок можно вычислить следующим образом:
a = 6s
b = 6m + 0,1s
c = 30h + 0,5(m + s/60)
где a, b и c - углы поворота, соответственно, секундной, минутной и часовой стрелок [0..360) относительно оси на 12 часов.

Симметрию можно определить по-разному.

Используя тригонометрию, необходимо найти значения cos b и cos c, отличающиеся на заданную погрешность. При этом sin b и sin с должны иметь разные знаки. Получаем систему уравнений:
|cos b - cos c| <= µ1
sign(sin b) = -sign(sin c)
где µ1 - абсолютная погрешность вычисления, sign() - функция определения знака действительного числа, дающая на выходе -1, 0 или 1.

Арифметическая проверка чуть более длинная:
|360 - max(b,c)| - min(b,c) <= µ2
max(b,c) > 180
min(b,c) < 180
где µ2 - абсолютная погрешность вычисления

Поскольку тригонометрия в общем случае вычисляется медленнее арифметики, то для программы поиска решений методом перебора будем использовать арифметику.

Программа для МК-61/52/152 будет выглядеть следующим образом:

00.Сх	01.1	02.8	03.0	04.П5	05.1	06.1	07.ПО	08.5	09.9
10.П1	11.5	12.9	13.П2	14.ИП2	15.6	16.0	17.:	18.ИП1	19.+
20.2	21.:	22.3	23.0	24.ИП0	25.х	26.+	27.ПС	28.ИП2	29.1
30.0	31.:	32.ИП1	33.6	34.х	35.+	36.ПВ	37.ИПС	38.Кmax	39.ИП5
40.-	41.Fх≥0	42.68	43.ИП5	44.-	45.К|к|	46.ипс	47./-/	48.ИПВ	49./-/
50.Кmax	51./-/	52.XY	53.FO	54.B^	55.ИП5	56.-	57.Fx<0	58.68	59.FO
60.-	61.П4	62.К|к|	63.ип3	64.-	65.Fх<0	66.68	67.С/П	68.КИП2	69.ИП2
70.Fх<0	71.14	72.КИП1	73.ИП1	74.Fх<0	75.11	76.КИП0	77.ИП0	78.Fх<0	79.08
80.С/П														

В регистр П3 заносим µ2. Опытным путем выбрано значение 0,055. Меньшие значения пропускают часть решений, бОльшие дают группы аналогичных результатов с разными погрешностями.

Предостерегаю от запуска программы на старых ПМК. Очевидно, что вычисления и проверки на интервале в 1 секунду будут выполняться медленее, чем эта самая секунда, поэтому счет может затянуться на несколько суток.

Прогон на эмуляторе дает следующие результаты в порядке их вычислений (положение стрелок 0 часов 0 минут 0 секунд не рассматриваем).

# Час (П0) Мин (П1) Сек (П2) Угол час,° (ПС) Угол мин,° (ПВ) Разница,° (П3)
1 11 4 37 332,30833 27,7 -0,00833
2 10 9 14 304,61666 55,4 -0,01666
3 9 13 51 276,925 83,1 -0,025
4 8 18 28 249,23333 110,8 -0,03333
5 7 23 5 221,54166 138,5 -0,04166
6 6 27 42 193,85 166,2 -0,05
7 5 32 18 166,15 193,8 0,05
8 4 36 55 138,45833 221,5 0,04167
9 3 41 32 110,76666 249,2 0,03334
10 2 46 9 83,075 276,9 0,025
11 1 50 46 55,383333 304,6 0,016667
12 0 55 23 27,691666 332,3 0,008334

Что дальше?

Имеются пути оптимизации переборного алгоритма. Например, можно ограничиться перебором положений часовой стрелки, вычислять симметричное положение минутной и искать положение реальной стрелки в окрестностях этого угла. Думаю, такой алгоритм работал бы на порядки быстрее.

Решение, полученое в аналитическом виде (система уравнений и программа поиска корней) потенциально может оказаться наиболее быстрым.

Прикрепленный файлРазмер
Файл программы для эмулятора (ClockSymmetry2.C3)4.58 кб
Оценка: 4 (Голосов 1)

Программа

Программа поиска таких значений для калькулятора Assistant AC-3600:
0→H:Lbl 1:(12-H)×60⌟13→T:Int T→M:Int ((T-M)×60)→S:H◢M◢S◢H+1→H:H<12⇒Goto 1