График *** ameoba **** - это тип дерева , все узлы которого имеют значения от 0 до некоторого неотрицательного целого числа N, и любой конкретный узел со значением x <N соединяется с x + 1 различными узлами со значениями x + 1.
Граф Амеоба для N = 3: (обозначается A 3 )
Обратите внимание, что 2 не имеют права делиться любым из 3; ровно три 3 должны «принадлежать» каждому 2.
Вызов
Ваша задача состоит в том, чтобы индуктивно «вырастить» эти графы амебы в двумерной сетке, жадно минимизируя расстояние Манхэттена между узлами:
- Базовый случай: 0 просто график
0
. - Индуктивный шаг: N + 1 , генерируется путем итеративного размещения нового N + 1 оцененных узлов как можно ближе к значениям узлов N в существующем N структуре. (Это может быть только как можно ближе, так как ближайшие места уже могут быть заполнены.)
Для индуктивного шага вы должны следовать общей процедуре:
for each existing node P with value N:
for each new N+1 valued node Q you need to connect to P: //this loops N+1 times
find the set of vacant spots that are minimally distant from P //by Manhattan distance
place Q in any of these vacant spots
(Различная процедура с неразличимым выводом подойдет.)
Пример роста для A 4 :
A0 is always the same:
0
For A1 I happen to put the 1 to the right of the 0 (it has to go on one of the 4 open sides):
01
For A2 I happen to put the two 2's above and to the right of the 1:
2
012
For A3 I find that one of the six 3's I must place cannot be directly next to a 2, so I put in one of the next closest places:
3
323
0123
33 <-- this 3 is distance two away from its 2
The process continues in A4. Note that I'm iterating over each 3 and placing four 4's next to it or as close as possible, then moving to the next 3 (the order of 3's does not matter):
444
443444
4323444
4012344
44334
4444
44
Always keep in mind that nodes cannot be "shared".
программа
Программа, которую вы пишете, должна принимать число от 0 до 8 (включительно) и выводить ее действительный график амебы, используя схему индуктивного роста, описанную выше.
То, что происходит после 8, не имеет значения.
(A 8 содержит 46234 узлов , который толкают его. Все , что за A 8 будет слишком далеко. Благодаря Мартин Büttner для заметив это.)
Входные данные должны поступать из stdin или из командной строки, а выходные данные - из stdout или файла.
Примеры (взяты непосредственно сверху)
Input: 0
Output:
0
Input: 1
Output:
01
Input: 2
Output:
2
012
Input: 3
Output:
3
323
0123
33
Input: 4
Output:
444
443444
4323444
4012344
44334
4444
44
* Эти типы графиков могут уже иметь имя. Я признаю, что только что сделал их. ;)
Ответы:
Mathematica,
353288285275 байтUngolfed:
Вот пример вывода для
n = 5
:Ввод
8
занимает около 4,5 минут.Для быстрой разбивки моего алгоритма:
Я использую две справочные таблицы,
f
иg
. Первая - это просто разреженная карта, содержащая непустые ячейки. Последний представляет собой список, содержащий все пары координат для каждого значения ячейки (я думаю, мне даже не нужно отслеживать старые здесь). Я перебираю координаты,g
чтобы расширить каждую ячейку с последней итерации. Для этого я перебираю манхэттенские расстояния, создавая все возможные векторы для каждого расстояния и проверяя, пуста ли получающаяся ячейка (в этом случае я ее заполняю). Повторяйте, пока не будет создано достаточно новых клеток.Когда я закончу, я нахожу минимальную и максимальную координаты
g
и создаю соответствующую сетку, которая заполняется поиском ячеекf
. Остальное просто объединяет все в одну строку с переносами строк.источник
C -
309 305 301275 байтовМех, слишком долго ... если бы только один мог печатать
#D
или что-то вместо этого#define
, то C был бы действительно великолепен. Конечно,-D
флаги компилятора возможны, но мне кажется, что это обман, чтобы иметь символы, отличные от символов в исходном файле.Инструкция по эксплуатации:
Быть осторожен! Первая клавиша, которую вы нажимаете после запуска программы, представляет собой ввод. После ввода символа, отличного от '0' до '8', который знает, какие неопределенные вещи произойдут.
Ungolfed (но уже думает о будущем игре в гольф) версия:
Редактировать: я понял, что, поскольку я переместил объявления за пределы main (), массивы больше не могут быть размещены в стеке, поэтому я могу свободно использовать память без риска переполнения.
источник
Рубин - 296
Слегка разгульный.
источник
APL (Дьялог) (121)
Характеристики производительности: это O (n!). В моей системе до n = 5 это происходит мгновенно; n = 6 занимает секунду, n = 7 занимает минуту, а n = 8 занимает час.
Версия без гольфа
Тест:
Объяснение:
{
...}⎕
: прочитать строку с клавиатуры, оценить ее и передать результат функции.0::0
: если другой код вызывает ошибку, вернуть один0
. Это связано с тем, что математика завершается неудачно при попытке вычислить размер для графа с 0 узлами, что является случаем, когда вывод должен быть0
. (В предыдущей версии было⍵=0:0
(если входные данные0
возвращаются, в0
противном случае создайте график), но0::0
(просто попробуйте и верните0
случае неудачи) короче.)M←⌈4×.5*⍨3÷⍨+/!⍳⍵
: предполагая, что на выходе получился грубый круг (это работает), сложите факториалы от1
до⍵
(= область вывода), разделите на 3 (достаточно близко к пи), возьмите квадратный корень (давая радиус вывода), умножьте на 4, и возьми потолок. Это дает вдвое больший диаметр круга, поэтому выход соответствует размеру места. Сохраните это вM
.V←,⍳⍴Z←' '⍴⍨2/M
: создайте матрицу M-by-M пространств и сохраните ее вZ
. Это будет держать вывод. Сохраните список координат всех элементов вV
.Z[G;G←⌈M÷2]←'0'
: установите средний элементZ
в0
.Z⊢{
...}¨⍳⍵
: возвращениеZ
после применения следующей функции для чисел1
в⍵
:⍵∘{
...}V/,Z=⍕⍵-1
: для каждого элемента вZ
со значением предыдущего узла:⍵∘{
...}⍺/⍺
: для текущего узла, N раз,⊃F[⍋+/¨|(F←V/⍨,Z=' ')-⊂⍺]
: получить свободное место ближе к текущему узлу,(
...⌷Z)←⍕⍵
: и установите это пространство вZ
значение текущего узла.источник