Цель этой задачи состоит в том, чтобы графически изобразить прогулку на плоскости, где направление каждого шага определяется простотой и четностью его двоичного расширения. В частности,
- Начальное направление зафиксировано, скажем, на север.
- Все шаги имеют одинаковую длину .
- Направление этапа может быть Север, Запад, Юг и Восток, и определяется следующим образом :
- Если не простое, направление не меняется.
- Если простое и двоичное разложение имеет четное число единиц, поверните направо.
- Если простое и двоичное разложение имеет нечетное число единиц, поверните налево.
В качестве рабочего примера предположим, что начальное направление - север. Первые шаги:
- не простое число. Таким образом, мы движемся на один шаг в текущем направлении, которое севернее.
- простое, и его двоичное разложение
10
, имеет и нечетное число единиц. Итак, мы поворачиваем налево и теперь лицом к западу. Мы продвигаемся на один шаг в этом направлении. - простое, а его двоичное разложение
11
, имеет и четное число единиц. Таким образом, мы поворачиваем направо, и теперь лицом к северу. Мы продвигаемся на один шаг в этом направлении. - не простое число. Таким образом, мы движемся на один шаг в текущем направлении, которое севернее.
Соревнование
Входные данные : целое положительное число .
Вывод : график обхода шага, как определено выше.
Дополнительные правила
- Начальное направление может быть свободно выбрано (не обязательно Север), но должна быть одинаковой для всех .
- Поворота правило может быть противоположное тому , что было описано выше, то есть, повернуть направо на нечетность и влево для четных; но он должен быть одинаковым для всех .
- Выходными данными должно быть графическое изображение прогулки. Например:
- Прогулка может быть нарисована отрезками.
- Посещенные точки могут быть показаны с помощью маркера, такого как точка; с или без соединительных отрезков.
- Может быть предоставлено двухцветное растровое изображение, один цвет которого соответствует посещенным точкам, а другой - непосещенным.
- Шкалы горизонтальной и вертикальной осей не обязательно должны быть одинаковыми. Также метки оси и подобные элементы являются необязательными. Пока прогулка хорошо видна, сюжет действителен.
- Обратите внимание, что некоторые пункты посещаются более одного раза. Сюжет не чувствителен к этому. Например, если на графике показаны линейные сегменты, каждый сегмент блока отображается одинаково, независимо от того, сколько раз он был пройден.
- Код должен работать для любых
N
неограниченных ресурсов. Это допустимо, если на практике это приводит к большимN
сбоям из-за ограничений по времени, памяти или типу данных. - Ввод и вывод являются гибкими, как обычно. В частности, может быть использовано любое стандартное средство для вывода изображений.
- Самый короткий код в байтах побеждает.
Контрольные примеры
Следующие графики используют Север в качестве начального направления; даже паритет поворачивает направо; и прогулка изображена с отрезками.
N = 7
:
N = 3000
:
N = 20000
:
N = 159000
:
N = 1200000
:
N = 11000000
:
code-golf
graphical-output
integer
primes
Луис Мендо
источник
источник
[graphical-output]
разрешена? Есть ли какая-либо причина, в частности, запретить вывод ASCII, например мой удаленный ответ на Charcoal?Ответы:
Кувалда 0,4 ,
2220 байтРаспаковывает в эту функцию Wolfram Language:
Ungolfed
Сначала мы определяем функцию, которая возвращает угол поворота на каждом шаге:
ThueMorse
это соотношение суммы двоичных цифр. Мы используем,-1^(...)
а не2*...-1
по несколько сложной причине: Wolfram Language автоматически преобразует арифметические выражения в источнике в каноническую форму, поэтому выражения вроде2/x
сохраняются какTimes[2, Power[x, -1]]
. Это делает частотуPower
очень высокой и, следовательно, сжимает ее очень дешево.(Умножение на
Boole@PrimeQ@
немного длиннее, и неявноеBoole
приведение логических значений не было реализовано во время вызова.)Отсюда, Mathematica
AnglePath
иListPlot
делать именно то, что нам нужно:В интерактивном приложении выводом является перекалиброванный объект векторной графики.
источник
MATL ,
252421 байтПопробуйте это в MATL онлайн
Спасибо @LuisMendo за приятную игру в гольф в чате, которая в конечном итоге привела к этой 21-байтовой версии, предлагая
Eq*^
объяснение
Пример для :k=12345
источник
C (gcc) , 179 байтов
Попробуйте онлайн!
Функция. Первый аргумент - это N, второй аргумент - это выделенный буфер размером не менее байт. Квадратное изображение записывается в этот буфер, возвращается длина его стороны. На изображении белый пиксель, черный пиксель.4n2+4n+1
0
1
C (gcc) , 219 байтов
Попробуйте онлайн!
Функция. Первый аргумент - N, второй аргумент - это выделенный буфер размером не менее байтов. Квадратное изображение в формате PBM записывается в буфер.4n2+4n+2×⌊log10(2n+1)⌋+9
Обрезанный вывод на 20000:
Обе версии начинаются с запада и поворачиваются направо на нечетное, слева - на четное.
Я пробовал большие тестовые наборы ни с одним из них, так как выход с 20000 был ~ 1,5 ГБ, а 150000 был бы ~ 90 ГБ. Все это сохраняется в памяти во время выполнения программы.
Объяснение верхнего:
источник
0
или нулевой указатель в случае C).Wolfram Language (Mathematica) ,
989691777663 байта-14 байт: спасибо @lirtosiast за то, что показали мне, как использовать
AnglePath
...-13 байт: ... и
ThueMorse
!пример использования:
Пошаговое объяснение:
If[PrimeQ@#, 2 ThueMorse@# - 1, 0] &
это функция, которая принимает индекс шага и возвращает 0 для не простых чисел, -1 для четных двоичных простых чисел и +1 для нечетных простых чисел.ThueMorse@#
заменяет предыдущее решениеTotal[#~IntegerDigits~2]
(то же самое, по модулю 2).Array[Pi/2*%,#]
создает список этой функции с индексом, идущим от 1 до аргумента функции (в примере 20000), и умножает каждый элемент на π / 2, чтобы превратить его в угол изменения направления (радианы). Теперь у нас есть 0 для не простых чисел, -π / 2 для четно-двоичных простых чисел и + π / 2 для нечетно-двоичных простых чисел.AnglePath[%]
преобразует этот список углов изменения направления в траекторию. Эта инструкция заменяет двойное использование предыдущего решенияAccumulate
.ListPlot[%]
преобразует список позиций в точечный график XY. Если строка предпочтительнее, используйтеListLinePlot
вместо этого. Эти функции построения графиков имеют много опций, чтобы сделать графики лучше.источник
MATL,
31302826 байт3 байта сохранены благодаря @LuisMendo
2 байта сохранены благодаря @Sanchises
Попробуйте это на MATL Online
объяснение
Это решение использует комплексные числа для представления X и Y компонентов 2D плоскости
На данный момент у нас есть четыре точки (
(0, 1), (-1, 0), (0, -1), (1, 0)
) в массиве, представленном комплексными числами. Это четыре основных направления. Теперь мы хотим использовать их, чтобы «ходить».По сути, способ, которым это работает, заключается в том, что мы начинаем двигаться в нулевом направлении (0-й элемент массива
(-1, 0)
). Для каждого шага нам нужно определить изменение в этом заголовке. Мы будем использовать целые числа для отслеживания этого изменения. Если мы хотим повернуть «вправо», мы увеличиваем это целое число на 1 (ссылаясь на следующий элемент в 4-точечном массиве), и если мы хотим перейти «влево», мы уменьшаем это целое число на 1 (ссылаясь на предыдущий элемент в 4-х точечный массив). Если мы хотим продолжить наш путь, мы сохраняем целочисленное значение постоянным (ссылаясь на тот же элемент в 4-точечном массиве).Эта часть кода создает массив всех тех
0
,-1
и1
ценностей.Теперь у нас есть массив различий между последовательными целыми числами, поэтому мы можем вычислить их совокупную сумму, чтобы получить индексы, которые мы затем можем использовать для поиска направления на каждом шаге в исходном массиве из 4 элементов.
Удобно, что MATL имеет циклическую индексацию, так что индекс
5
переносится к началу массива из 4 элементов. Мы можем использовать это в наших интересах, чтобы мы могли увеличивать и уменьшать это целое число, не беспокоясь о том, что массив опорных направлений состоит всего из 4 элементов.Теперь у нас есть массив направлений шагов, поэтому мы можем вычислить совокупную сумму этих направлений, чтобы проследить пройденный путь.
источник
Perl 6 ,
213182 байта{my @p = [\ +] [\ *] ({{. is-prime ??. base (2) .comb (~ 1)% 2 ?? i !! - i !! 1 + 0i} (+ + $)} ... *) [^ $ _]; {"<svg viewBox = '{. min xx 2, .elems xx 2}' >>. & {" L {.re} {.im} " }} 'fill =' none 'stroke =' black '/> "} (minmax | @p» .reals)}Попробуйте онлайн!
(Действительно удалось сократить это!)
Эта функция выводит в формате SVG.
{ -{ .is-prime * .base(2).comb(~1) R** -1 || i }(++$)i } ... *
представляет собой бесконечную последовательность изменений направления для каждого шага в форме комплексных чисел, где1
означает «продолжить в том же направлении»,i
означает «повернуть налево» и-i
означает «повернуть направо».[^$_]
ограничивает эту последовательность количеством шагов, предоставляемых в качестве аргумента функции.[\*]
сканирует эту последовательность с (сложным) умножением, превращая список относительных направлений в список абсолютных направлений.[\+]
сканирует эту последовательность с (сложным) сложением, создавая список посещенных координат.».reals
преобразует этот список комплексных чисел в двухэлементные списки его вещественных и мнимых частей.Изображение SVG - это всего лишь один
path
элемент.Выход (преобразованный в PNG) для N = 20000:
источник
C, 321 байт
Попробуйте онлайн!
Я начал работать над этим до того, как был опубликован другой ответ C, но я решил, что в любом случае мог бы также опубликовать свой. Это намного длиннее, но оно также автоматически обрезает выходное изображение до размеров результата.
Функция вызывается как
f(n)
, а вывод - в стандартный вывод в формате netpbm.Пример вывода для n = 1000:
Основной тест - это, по существу, тест, использованный в ответе Линн на другой вопрос , основанный на теореме Уилсона .
Тест на четность использует адаптацию метода подсчета бит Кернигана .
Так как основной тест очень медленный, и алгоритм перезапускает всю функцию генерации пути для каждого нарисованного пикселя, любой вход значительно превышает 1000 раз на TIO.
источник
LOGO,
177171 байтЧтобы использовать, сделайте что-то вроде этого :
Извините, но я не смог захватить пример вывода. Объяснение:
Это рекурсивная процедура, которая поворачивает 180 ° для каждого установленного бита в своем параметре, который эффективно вычисляет четность его двоичного расширения.
Это очень простой тест на первичность. После специального случая 1 процедура возвращается рано, если найден фактор. Однако, если текущее значение оказывается простым, оно поворачивает вправо, а затем использует описанную выше процедуру, чтобы изменить его на левый поворот в зависимости от ситуации.
Это просто простой цикл для проверки всех чисел вплоть до
n
простоты и для перемещения на два пикселя после каждого.источник
Желе , 41 байт
Попробуйте онлайн!
источник
JavaScript -
675668660632556534 байтВпервые здесь, на CodeGolf, изначально началось с ~ 1500 байт кода. Гольф это
меньше половины,почтитреть. Не стесняйтесь продолжать играть в гольф. Байт с этим инструментомПринцип:
Рисует на холсте фиксированного размера с N и переменной длиной хода в качестве входных данных.
Редактирование:
-07 байт - удалить пропущенные if
-08 байт - изменить переключатель на if / else
-28 байт - изменить на десятичный, если / else
-76 байт - более короткий простой тест (время выполнения / 3)
-22 байта - использовать эту простую функцию (время выполнения * 4)
Гольф-код:
Разобранный код с пробелами:
Примеры:
источник
Красный ,
515480471 байт-1 байт благодаря Кевину Круйссену!
Значительная часть кода (~ 160 байт) имеет дело с нормализацией координат, так что графика полностью помещается на холст, независимо от размера ввода.
Начальное направление: юг.
Вот результат для
n = 3000
n = 20000
источник
if j%(k + 1)
иif j% 2 = 1
, но есть пробелы, необходимые для большинства других операторов (+
,/
и т. Д.). Можно ли убрать пространство по модулюpick[-90 90]s% 2
? На самом деле, почему также нет местаas-pair k/1 - t * c k/2 - v * c
для/
?s% 2
, спасибо! Я не знаю почему, но по модулю%
это единственный оператор, для которого пространство перед ним может быть отброшено, если ему предшествует слово (переменная). Вas-pair k/1 - t * c k/2 - v * c
слешах/
служат совершенно иные цели - они и естьpath
.k
являетсяpair
иk/1
является первым элементом (его также можно выбрать с помощьюk/x
илиpick k 1
). Пространства нужны почти везде, исключения есть()[]{}
, потому что двусмысленности нет.word
именах (Red
не имеетvariables
, все является либоword
значением, либо значением (или некоторым синтаксическим блоком, подобным[...]
или(...)
). Итак:a*4: 45
-> словуa*4
присваивается значение 45.%
используется в качестве маркера дляfile!
типа данных и, возможно, именно поэтому он не может использоваться вword
именах, но может нарушать правила для других арифметических операторов/
них другое назначение, и символы могут использоваться без пробелов в переменных (или,words
как они явно называются для красного). Спасибо за объяснение. :) И рад, что мог (в основном случайно) сохранить байт дляs% 2
. :)Обработка, 140+ байтов
Может не выполнять четко видно
источник