Для изображения N на N найдите набор пикселей, чтобы расстояние между ними не было более одного раза. То есть, если два пикселя разделены расстоянием d , то они являются единственными двумя пикселями, которые разделены ровно d (используя евклидово расстояние ). Обратите внимание, что d не обязательно должно быть целым числом.
Задача состоит в том, чтобы найти такой набор больше, чем кто-либо другой.
Спецификация
Вход не требуется - для этого конкурса N будет зафиксировано на 619.
(Поскольку люди продолжают спрашивать - в числе 619 нет ничего особенного. Оно было выбрано достаточно большим, чтобы сделать оптимальное решение маловероятным, и достаточно маленьким, чтобы изображение N на N отображалось без автоматической стековой замены. Изображения могут быть отображал полный размер до 630 на 630, и я решил пойти с самым большим штрихом, который не превышает это.)
Вывод представляет собой разделенный пробелами список целых чисел.
Каждое целое число в выходных данных представляет один из пикселей, пронумерованных в английском порядке чтения от 0. Например, для N = 3 местоположения будут пронумерованы в следующем порядке:
0 1 2
3 4 5
6 7 8
Вы можете выводить информацию о ходе выполнения во время выполнения, если хотите, при условии, что конечный результат подсчета очков будет легко доступен. Вы можете выводить в STDOUT или в файл, или что-либо другое, что проще всего вставить в Судья Фрагмента стека ниже.
пример
N = 3
Выбранные координаты:
(0,0)
(1,0)
(2,1)
Выход:
0 1 5
выигрыш
Оценка - это количество мест на выходе. Из тех достоверных ответов, которые имеют самый высокий балл, побеждает самый ранний, чтобы опубликовать результат с этим баллом.
Ваш код не должен быть детерминированным. Вы можете опубликовать свой лучший результат.
Смежные области для исследований
(Спасибо Abulafia за ссылки Голомба)
Хотя ни один из них не является тем же, что и эта проблема, они оба похожи по концепции и могут дать вам идеи о том, как подойти к этому:
- Линейка Голомба : одномерный случай.
- Прямоугольник Голомба : двумерное расширение линейки Голомба. Вариант случая NxN (квадрат), известный как массив Костаса, решается для всех N.
Обратите внимание, что точки, необходимые для этого вопроса, не подпадают под те же требования, что и прямоугольник Голомба. Прямоугольник Голомба простирается от одномерного случая, требуя, чтобы вектор от каждой точки друг к другу был уникальным. Это означает, что могут быть две точки, разделенные расстоянием 2 по горизонтали, а также две точки, разделенные расстоянием 2 по вертикали.
В этом вопросе скалярное расстояние должно быть уникальным, поэтому не может быть горизонтального и вертикального разделения на 2. Каждое решение этого вопроса будет прямоугольником Голомба, но не каждый прямоугольник Голомба будет правильным решением этот вопрос.
Верхние границы
Деннис услужливо указал в чате, что 487 является верхней границей на счете, и дал доказательство:
Согласно моему коду CJam (
619,2m*{2f#:+}%_&,
), существует 118800 уникальных чисел, которые могут быть записаны как сумма квадратов двух целых чисел от 0 до 618 (оба включительно). n пикселей требуют n (n-1) / 2 уникальных расстояний между собой. Для n = 488 это дает 118828.
Таким образом, есть 118 800 возможных различных длин между всеми потенциальными пикселями в изображении, и размещение 488 черных пикселей приведет к 118 828 длинам, что делает невозможным их уникальность.
Мне было бы очень интересно узнать, есть ли у кого-нибудь доказательство более низкой верхней границы, чем эта.
Leaderboard
(Лучший ответ от каждого пользователя)
Судья фрагмента стека
источник
Ответы:
Питон 3,
135136137Найдено с использованием жадного алгоритма, который на каждом этапе выбирает действительный пиксель, чей набор расстояний до выбранных пикселей меньше всего перекрывается с набором других пикселей.
В частности, выигрыш
и выбирается пиксель с наименьшей оценкой.
Поиск начинается с точки
10
(то есть(0, 10)
). Эта часть является настраиваемой, поэтому начало с разных пикселей может привести к лучшим или худшим результатам.Это довольно медленный алгоритм, поэтому я пытаюсь добавить оптимизацию / эвристику и, возможно, некоторый откат назад. PyPy рекомендуется для скорости.
Любой, кто пытается придумать алгоритм, должен пройти тестирование
N = 10
, для которого у меня есть 9 (но это заняло много изменений и пробовал разные начальные точки):Код
источник
N=10
и есть много разных раскладов с 9 очками, но это лучшее, что вы можете сделать.SWI-Пролог, оценка 131
Едва лучше, чем первоначальный ответ, но я думаю, что это заставит все начаться немного больше. Алгоритм такой же, как и у ответа Python, за исключением того, что он пробует пиксели альтернативным способом, начиная с верхнего левого пикселя (пиксель 0), затем нижнего правого пикселя (пиксель 383160), затем пикселя 1, затем пикселя 383159 , так далее.
Входные данные:
a(A).
Выход:
Изображение из фрагмента стека
источник
Хаскель -
115130131135136Моим вдохновением было «Сито Эратосфена» и, в частности, «Подлинное сито Эратосфена» , статья Мелиссы Э. О'Нил из колледжа Харви Мадда. Моя оригинальная версия (в которой учитывались баллы в порядке индекса) набирала баллы очень быстро, по какой-то причине, которую я не могу вспомнить, я решила перетасовать баллы, прежде чем «просеивать» их в этой версии (я думаю, только для того, чтобы упростить создание разных ответов с помощью новое семя в генераторе случайных чисел). Поскольку баллы уже не в каком-либо порядке, на самом деле просеивание больше не происходит, и в результате требуется всего несколько минут, чтобы получить этот единственный ответ из 115 баллов. Нокаут
Vector
, вероятно, будет лучшим выбором сейчас.Таким образом, с этой версией в качестве контрольной точки я вижу две ветви: возвращение к алгоритму «Genuine Sieve» и использование монады List для выбора или замена
Set
операций на их эквивалентыVector
.Редактировать: Таким образом, для рабочей версии второй я повернул назад к алгоритму сита, улучшив генерацию «кратных» (выбивая индексы, находя точки по целочисленным координатам на окружностях с радиусом, равным расстоянию между любыми двумя точками, сродни генерации простых кратных) ) и несколько улучшений по времени, избегая ненужного пересчета.
По какой-то причине я не могу перекомпилировать с включенным профилированием, но я считаю, что основным узким местом является возврат. Я думаю, что изучение параллелизма и параллелизма приведет к линейному ускорению, но исчерпание памяти, вероятно, ограничит меня в 2 раза.
Редактировать: Версия 3 немного запуталась, я сначала поэкспериментировал с эвристикой, взяв следующие индексы (после просеивания из более ранних выборов) и выбрав тот, который дал следующий минимальный выбивающий набор. Это оказалось слишком медленным, поэтому я вернулся к методу грубой силы всего пространства поиска. Идея упорядочить точки по расстоянию от какого-либо источника пришла ко мне и привела к улучшению на одну единицу (за то время, что мое терпение длилось). Эта версия выбирает индекс 0 как начало координат, возможно, стоит попробовать центральную точку плоскости.
Изменить: я поднял 4 балла, изменив порядок поиска, чтобы расставить приоритеты для самых отдаленных точек от центра. Если вы тестируете мой код,
135136 на самом делевторойтретьим найденным решением. Быстрое редактирование: эта версия, скорее всего, продолжит работать, если останется запущенной. Я подозреваю, что могу связать в 137, а затем хватит терпения в ожидании 138.Одна вещь, которую я заметил (это может кому-то пригодиться), это то, что если вы установите порядок точек из центра плоскости (то есть удалите
(d*d -)
изoriginDistance
), то сформированное изображение будет немного похоже на редкую простую спираль.Выход
источник
d
минимизирует количество других точек, исключенных из рассмотрения путем трассировки окружностей радиусаd
с центрами обеих выбранных точек, где периметр касается только трех других целочисленных координат (при поворотах на 90, 180 и 270 градусов вокруг круг) и перпендикулярная биссектриса, не пересекающая целочисленные координаты. Таким образом, каждая новая точкаn+1
будет исключать6n
другие точки из рассмотрения (с оптимальным выбором).Python 3, оценка 129
Это пример ответа, чтобы начать работу.
Просто наивный подход, проходящий через пиксели по порядку и выбирающий первый пиксель, который не вызывает дублирования расстояния до тех пор, пока пиксели не закончатся.
Код
Выход
Изображение из фрагмента стека
источник
Питон 3, 130
Для сравнения, вот рекурсивная реализация backtracker:
Он быстро находит следующее 130-пиксельное решение, прежде чем начинает задыхаться:
Что еще более важно, я использую это, чтобы проверить решения для маленьких случаев. Для
N <= 8
, оптимальными являются:В скобках указаны первые лексикографические оптимумы.
неподтвержденный:
источник
Скала, 132
Сканирует слева направо и сверху вниз, как наивное решение, но пытается начать в разных местах пикселей.
Выход
источник
Питон, 134
132Вот простой, который случайным образом отбирает часть пространства поиска, чтобы охватить большую область. Итерирует точки на расстоянии от исходного порядка. Он пропускает точки, которые находятся на одинаковом расстоянии от источника, и заблаговременно, если не может улучшить в лучшую сторону. Это работает бесконечно.
Он быстро находит решения с 134 баллами:
3097 3098 2477 4333 3101 5576 1247 9 8666 8058 12381 1257 6209 15488 6837 21674 19212 26000 24783 1281 29728 33436 6863 37767 26665 14297 4402 43363 50144 52624 18651 9996 58840 42792 6295 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 бы 5 бы бывала бы бывали бы вы бы хотели, чтобы вы смогли сделать это. 113313 88637 122569 11956 36098 79401 61471 135610 31796 4570 150418 57797 4581 125201 151128 115936 165898 127697 162290 33091 20098 189414 187620 186440 91290 206766 35619 69033 351 186511 129058 223 625 226 226 226 227 226 226 226 226 226 226 226 226 216 226 226 226 226 226 226 226 226 226 216 226 226 226 226 226 226 5326 5326 236 6366 236 226 226 226 226 226 226 226 226 226 226 236 6366 177 625 такого строительного сословия 249115 21544 95185 231226 54354 104483 280665 518 147181 318363 1793 248609 82260 52568 365227 361603 346849 331462 69310 90988 341446 229599 277828 382837 339014 323612 365040 269883 302598 372 286 287 282 282 276 276 296 286 376 287 286 262 632 932 9329 249115 21544 95185 231226
Для любопытных вот несколько маленьких N:
источник
Fantom 96
Я использовал алгоритм эволюции, в основном добавляя k случайных точек за раз, делаю это для j различных случайных наборов, затем выбираю лучший и повторяю. Довольно ужасный ответ прямо сейчас, но он работает только с 2 детьми на поколение ради скорости, что почти случайно. Я собираюсь немного поиграть с параметрами, чтобы посмотреть, как все пойдет, и мне, вероятно, нужна лучшая функция подсчета очков, чем количество оставшихся свободных мест.
Выход
источник
Питон 3, 119
Я больше не помню, почему я назвал эту функцию
mc_usp
, хотя подозреваю, что она как-то связана с цепями Маркова. Здесь я публикую свой код, который я запускал с PyPy около 7 часов. Программа пытается создать 100 различных наборов пикселей путем случайного выбора пикселей до тех пор, пока не проверит каждый пиксель изображения и не вернет один из лучших наборов.С другой стороны, в какой-то момент мы действительно должны попытаться найти верхнюю границу,
N=619
которая лучше, чем 488, потому что, судя по ответам здесь, это число слишком велико. Комментарий Роуэн Блэш о том, что каждая новая точкаn+1
может потенциально удалять6*n
точки с оптимальным выбором, показался хорошей идеей. К сожалению, после проверки формулыa(1) = 1; a(n+1) = a(n) + 6*n + 1
, гдеa(n)
указано количество точек, удаленных после добавленияn
точек в наш набор, эта идея может оказаться не самой подходящей. Проверка, когдаa(n)
больше чемN**2
,a(200)
быть больше, чем619**2
кажется многообещающим, ноa(n)
больше, чем10**2
есть,a(7)
и мы доказали, что 9 - это фактическая верхняя граница дляN=10
, Я буду держать вас в курсе, как я пытаюсь выглядеть лучше верхней границы, но любые предложения приветствуются.На мой ответ. Во-первых, мой набор из 119 пикселей.
Во-вторых, мой код, который случайным образом выбирает начальную точку из октанта квадрата 619x619 (поскольку начальная точка в противном случае равна при вращении и отражении), а затем через любую другую точку из остальной части квадрата.
источник