Перегрин премьер паритет


44

Цель этой задачи состоит в том, чтобы графически изобразить прогулку на плоскости, где направление каждого шага определяется простотой и четностью его двоичного расширения. В частности,kk

  • Начальное направление зафиксировано, скажем, на север.
  • Все шаги имеют одинаковую длину .
  • Направление этапа может быть Север, Запад, Юг и Восток, и определяется следующим образом : k
    • Если не простое, направление не меняется.k
    • Если простое и двоичное разложение имеет четное число единиц, поверните направо.kk
    • Если простое и двоичное разложение имеет нечетное число единиц, поверните налево.kk

В качестве рабочего примера предположим, что начальное направление - север. Первые шаги:

  • k=1 не простое число. Таким образом, мы движемся на один шаг в текущем направлении, которое севернее.
  • k=2 простое, и его двоичное разложение 10, имеет и нечетное число единиц. Итак, мы поворачиваем налево и теперь лицом к западу. Мы продвигаемся на один шаг в этом направлении.
  • k=3 простое, а его двоичное разложение 11, имеет и четное число единиц. Таким образом, мы поворачиваем направо, и теперь лицом к северу. Мы продвигаемся на один шаг в этом направлении.
  • k=4 не простое число. Таким образом, мы движемся на один шаг в текущем направлении, которое севернее.

Соревнование

Входные данные : целое положительное число .N

Вывод : график обхода шага, как определено выше.N

Дополнительные правила

  • Начальное направление может быть свободно выбрано (не обязательно Север), но должна быть одинаковой для всех .N
  • Поворота правило может быть противоположное тому , что было описано выше, то есть, повернуть направо на нечетность и влево для четных; но он должен быть одинаковым для всех .N
  • Выходными данными должно быть графическое изображение прогулки. Например:
    • Прогулка может быть нарисована отрезками.
    • Посещенные точки могут быть показаны с помощью маркера, такого как точка; с или без соединительных отрезков.
    • Может быть предоставлено двухцветное растровое изображение, один цвет которого соответствует посещенным точкам, а другой - непосещенным.
  • Шкалы горизонтальной и вертикальной осей не обязательно должны быть одинаковыми. Также метки оси и подобные элементы являются необязательными. Пока прогулка хорошо видна, сюжет действителен.
  • Обратите внимание, что некоторые пункты посещаются более одного раза. Сюжет не чувствителен к этому. Например, если на графике показаны линейные сегменты, каждый сегмент блока отображается одинаково, независимо от того, сколько раз он был пройден.
  • Код должен работать для любых Nнеограниченных ресурсов. Это допустимо, если на практике это приводит к большим Nсбоям из-за ограничений по времени, памяти или типу данных.
  • Ввод и вывод являются гибкими, как обычно. В частности, может быть использовано любое стандартное средство для вывода изображений.
  • Самый короткий код в байтах побеждает.

Контрольные примеры

Следующие графики используют Север в качестве начального направления; даже паритет поворачивает направо; и прогулка изображена с отрезками.

N = 7:

введите описание изображения здесь

N = 3000:

введите описание изображения здесь

N = 20000:

введите описание изображения здесь

N = 159000:

введите описание изображения здесь

N = 1200000:

введите описание изображения здесь

N = 11000000:

введите описание изображения здесь


1
Есть ли причина только [graphical-output]разрешена? Есть ли какая-либо причина, в частности, запретить вывод ASCII, например мой удаленный ответ на Charcoal?
Кевин Круйссен

2
@Kevin Мне однажды посоветовали не смешивать оба в одном вызове ... Что думают другие?
Луис Мендо

1
Ну, я могу понять причину этого совета, так как вывод в виде изображения / графика и ASCII-графики совершенно отличается в некоторых языках. С другой стороны, я видел, как выходные данные графиков получают массу положительных отзывов в ASCII-искусстве и наоборот, так что, думаю, не все с этим согласны. Лично я думаю, что это действительно зависит от задачи. В этом случае я лично не вижу никакого вреда в том, чтобы разрешить оба в одном и том же вызове, но, возможно, я предвзят, потому что мой теперь удаленный ответ. Поэтому я задам тот же вопрос, что и вы: « Что думают другие? » @Arnauld Может быть, вам все-таки следует опубликовать свой ASCII Taxi Driver;)
Кевин Круйссен

1
Было бы интересно увидеть этот прогон на различных последовательностях OEIS (правда, некоторые просто шли по прямой или бегали кругами, но некоторые могли бы быть чем-то вполне).
Draco18s

16
В N = 11000000, это, кажется, приближается к карте Европы.
Цифровая травма

Ответы:


12

Кувалда 0,4 , 22 20 байт

⢂⡐⠥⡄⠡⢒⣩⣀⣼⡝⢄⡎⣛⠅⡉⣱⡆⢀⡠⣽

Распаковывает в эту функцию Wolfram Language:

ListPlot[AnglePath[Array[If[PrimeQ@#, ArcSin[(-1)^ThueMorse@#], 0] &, #]]]

Ungolfed

Сначала мы определяем функцию, которая возвращает угол поворота на каждом шаге:

If[PrimeQ[#],
    ArcSin[(-1)^ThueMorse@#],
    0
]&

ThueMorseэто соотношение суммы двоичных цифр. Мы используем, -1^(...)а не 2*...-1по несколько сложной причине: Wolfram Language автоматически преобразует арифметические выражения в источнике в каноническую форму, поэтому выражения вроде 2/xсохраняются как Times[2, Power[x, -1]]. Это делает частоту Powerочень высокой и, следовательно, сжимает ее очень дешево.

(Умножение на Boole@PrimeQ@немного длиннее, и неявное Booleприведение логических значений не было реализовано во время вызова.)

Отсюда, Mathematica AnglePathи ListPlotделать именно то, что нам нужно:

ListPlot[AnglePath[Array[%, #]]]&

В интерактивном приложении выводом является перекалиброванный объект векторной графики.

введите описание изображения здесь


Круто! Я сократил до 77 байт, объединив наши решения. Ура!
Роман

14

MATL , 25 24 21 байт

Q:qJyZpbB!sEq*^YpYsXG

Попробуйте это в MATL онлайн

Спасибо @LuisMendo за приятную игру в гольф в чате, которая в конечном итоге привела к этой 21-байтовой версии, предлагая Eq*^

объяснение

Q:q % Push 0:n
J   % Push 1i for later use.
y   % Duplicate 0:n from below
Zp  % Vector result of isprime()
b   % Bubble 0:n from bottom of stack
B!s % Sum of bits in binary representation
Eq  % Double minus one to get an odd number
*   % Multiply by isprime result to get either zero or aforementioned odd number
^   % Exponentiate 1i by an odd number or zero to get -i, 1 or i (corresponding to left turn, straight ahead, right turn).
Yp  % Cumulative product to get a vector of directions
Ys  % Cumulative sum to get vector of positions
XG  % Plot

Пример для : k=12345введите описание изображения здесь


8

C (gcc) , 179 байтов

o;i;d;k;h;f(n,p)char*p;{h=2*n+1;memset(p,0,h*h);p+=h--*n+n;*p=1;for(d=k=0;k++<n;){for(i=1;k%++i%k;);for(o=k;o/2;o=o/2^o&1);i==k?d+=o*2+3:0;p+=(d%2*h+1)*((d&2)-1);*p=1;}return++h;}

Попробуйте онлайн!

Функция. Первый аргумент - это N, второй аргумент - это выделенный буфер размером не менее байт. Квадратное изображение записывается в этот буфер, возвращается длина его стороны. На изображении белый пиксель, черный пиксель.4n2+4n+101

C (gcc) , 219 байтов

o;i;d;k;h;f(n,p)char*p;{h=2*n+1;p+=sprintf(p,"P1 %d %d ",h,h);memset(p,48,h*h);k=h--*n+n;*(p+2*k+1)=0;p+=k;*p=49;for(d=k=0;k++<n;){for(i=1;k%++i%k;);for(o=k;o/2;o=o/2^o&1);i==k?d+=o*2+3:0;p+=(d%2*h+1)*((d&2)-1);*p=49;}}

Попробуйте онлайн!

Функция. Первый аргумент - N, второй аргумент - это выделенный буфер размером не менее байтов. Квадратное изображение в формате PBM записывается в буфер.4n2+4n+2×log10(2n+1)+9

Обрезанный вывод на 20000:

обрезанный вывод на 20000

Обе версии начинаются с запада и поворачиваются направо на нечетное, слева - на четное.

Я пробовал большие тестовые наборы ни с одним из них, так как выход с 20000 был ~ 1,5 ГБ, а 150000 был бы ~ 90 ГБ. Все это сохраняется в памяти во время выполнения программы.

Объяснение верхнего:

o;         /* Temporary variable for calculating parity */
i;         /* Temporary variable for primality test */
d;         /* d % 4 = direction */
k;         /* Step */
h;         /* height/width of image */
f(n,p)char*p;{ /* Function taking int and char pointer */
  h=2*n+1;     /* Image sidelength = 2 * N + 1, so N in each direction */
  memset(p,0,h*h); /* Reset buffer */
  p+=h--*n+n;  /* Position p at image center; decrement h */
  *p=1;        /* Put a dot at center */
  for(d=k=0;   /* Set direction and step to 0 */
    k++<n;){   /* Loop over [1..N] */
    for(i=1;k%++i%k;); /* Primality test */
    for(o=k;o/2;o=o/2^o&1); /* Parity test */
    i==k?d+=o*2+3:0; /* Change direction if necessary */
    p+=(d%2*h+1)*((d&2)-1); /* Move according to direction */
    *p=1; /* Set pixel to black */
  }
  return++h; /* Add 1 back to h and return */
}

1
Я не думаю, что требование предоставления выделенного буфера в качестве аргумента разрешено - для каждой мета-политики любой дополнительный ввод должен быть пустым (который я бы интерпретировал как означающий 0или нулевой указатель в случае C).
Ручка двери

3
Я интерпретирую это как высказывание, что я могу ожидать, что это будет распределено. Это также шаблон, используемый во многих стандартных библиотечных функциях, таких как sprintf.
Wastl

Ах, хорошо, ты прав, это имеет смысл.
Ручка двери


8

Wolfram Language (Mathematica) , 98 96 91 77 76 63 байта

ListPlot@AnglePath@Array[Pi/2If[PrimeQ@#,2ThueMorse@#-1,0]&,#]&

-14 байт: спасибо @lirtosiast за то, что показали мне, как использоватьAnglePath ...

-13 байт: ... и ThueMorse!

пример использования:

%[20000]

введите описание изображения здесь

Пошаговое объяснение:

  • 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вместо этого. Эти функции построения графиков имеют много опций, чтобы сделать графики лучше.


1
Спасибо @lirtosiast! Это как изучение иностранного языка: новый словарный запас каждый день.
Роман

7

MATL, 31 30 28 26 байт

J4:^0i:Zpl_G:B!s^*hYs)YsXG

3 байта сохранены благодаря @LuisMendo

2 байта сохранены благодаря @Sanchises

Попробуйте это на MATL Online

объяснение

Это решение использует комплексные числа для представления X и Y компонентов 2D плоскости

J      % Push the literal complex number 0 + 1j to the stack
4:     % Create the array [1, 2, 3, 4]
^      % Raise 0 + 1j to each power in the array, [1, 2, 3, 4]

На данный момент у нас есть четыре точки ( (0, 1), (-1, 0), (0, -1), (1, 0)) в массиве, представленном комплексными числами. Это четыре основных направления. Теперь мы хотим использовать их, чтобы «ходить».

По сути, способ, которым это работает, заключается в том, что мы начинаем двигаться в нулевом направлении (0-й элемент массива (-1, 0)). Для каждого шага нам нужно определить изменение в этом заголовке. Мы будем использовать целые числа для отслеживания этого изменения. Если мы хотим повернуть «вправо», мы увеличиваем это целое число на 1 (ссылаясь на следующий элемент в 4-точечном массиве), и если мы хотим перейти «влево», мы уменьшаем это целое число на 1 (ссылаясь на предыдущий элемент в 4-х точечный массив). Если мы хотим продолжить наш путь, мы сохраняем целочисленное значение постоянным (ссылаясь на тот же элемент в 4-точечном массиве).

Эта часть кода создает массив всех тех 0, -1и 1ценностей.

0      % Push a literal 0 to the stack (the starting point)
i      % Explicitly grab the input (N)
:      % Create an array from 1...N
Zp     % Determine if each element is a prime (1) or not (0)
l_     % Push the literal -1 to the stack
G      % Explicitly grab the input again (N)
:      % Create an array from 1...N
B      % Convert to binary representation (each row is the binary representation of
       % each element in the vector)
!      % Transpose
s      % Sum down the columns to count number of 1's
^      % Raise the -1 to each element. For odd number of 1's in the
       % binary expansion this yields -1, and even yields 1

*      % Multiply this -1 or 1 by the result of the prime check (element-wise). 
       % For non-primes this yields a 0, for primes with an even number of 1's in 
       % the binary representation this is a 1, and for primes 
       % with an odd number of 1's in

h      % Horizontally concatenate with the initial 0

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

Удобно, что MATL имеет циклическую индексацию, так что индекс 5переносится к началу массива из 4 элементов. Мы можем использовать это в наших интересах, чтобы мы могли увеличивать и уменьшать это целое число, не беспокоясь о том, что массив опорных направлений состоит всего из 4 элементов.

Ys     % Compute the cumulative sum
)      % Use this to modularly index into the original array of four points

Теперь у нас есть массив направлений шагов, поэтому мы можем вычислить совокупную сумму этих направлений, чтобы проследить пройденный путь.

Ys     % Compute the cumulative sum
XG     % Plot as a 2D plot

5

Perl 6 , 213 182 байта

{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 viewBox='{{.min,.min,+$_,+$_}(.minmax)}'><path d='{"L"X~$_}' fill='none' stroke='red'/></svg>"}(([\+] [\*]({-{.is-prime*.base(2).comb(~1)R**-1||i}(++$)i}...*)[^$_])».reals)}

Попробуйте онлайн!

(Действительно удалось сократить это!)

Эта функция выводит в формате SVG.

  • { -{ .is-prime * .base(2).comb(~1) R** -1 || i }(++$)i } ... *представляет собой бесконечную последовательность изменений направления для каждого шага в форме комплексных чисел, где 1означает «продолжить в том же направлении», iозначает «повернуть налево» и -iозначает «повернуть направо».
  • [^$_] ограничивает эту последовательность количеством шагов, предоставляемых в качестве аргумента функции.
  • [\*] сканирует эту последовательность с (сложным) умножением, превращая список относительных направлений в список абсолютных направлений.
  • [\+]сканирует эту последовательность с (сложным) сложением, создавая список посещенных координат.
  • ».reals преобразует этот список комплексных чисел в двухэлементные списки его вещественных и мнимых частей.

Изображение SVG - это всего лишь один pathэлемент.

Выход (преобразованный в PNG) для N = 20000:

путь для N = 20000


4

C, 321 байт

a,b,A,B,k,p,e,i,t,r;g(n,c,d,x,y,X,Y){x=y=Y=r=0;X=1;for(k=0;k++<=n;){r|=x==c&y==d;a=x<a?x:a;A=x>A?x:A;b=y<b?y:b;B=y>B?y:B;for(p=1,i=k;--i;p=p*i*i%k);for(e=1,i=k;i;e=-e)i&=i-1;if(p)t=X,X=-e*Y,Y=e*t;x+=X;y+=Y;}}f(n,x,y){A=a=B=b=0;g(n);printf("P1%d %d ",A-a+1,B-b+1);for(y=b;y<=B;++y)for(x=a;x<=A;++x)g(n,x,y),putchar(48+r);}

Попробуйте онлайн!

Я начал работать над этим до того, как был опубликован другой ответ C, но я решил, что в любом случае мог бы также опубликовать свой. Это намного длиннее, но оно также автоматически обрезает выходное изображение до размеров результата.

Функция вызывается как f(n), а вывод - в стандартный вывод в формате netpbm.

Пример вывода для n = 1000:

a,b,A,B,          // used to store x range [a,A] and y range [b,B]
k,p,e,i,t,        // temp variables used in g
r;g(n,c,d,        // takes n + coordinates, sets r to whether (c,d) is visited
x,y,X,Y){         // temp variables - position (x,y) and velocity (X,Y)
x=y=Y=r=0;X=1;    // initialization
for(k=0;k++<=n;){ // loops k over the step number
r|=x==c&y==d;     // set r to 1 if current coordinate is the requested one
a=x<a?x:a;A=x>A?x:A;b=y<b?y:b;B=y>B?y:B;    // update bounds
for(p=1,i=k;--i;p=p*i*i%k);                 // prime test
for(e=1,i=k;i;e=-e)i&=i-1;                  // parity test
if(p)t=X,X=-e*Y,Y=e*t;                      // if prime, turn accordingly
x+=X;y+=Y;}}      // move position in direction of velocity
f(n,x,y){         // main function; x and y are temp variables
A=a=B=b=0;g(n);   // obtain accurate bounds
printf("P1 %d %d\n",A-a+1,B-b+1);           // output netpbm header
for(y=b;y<=B;++y)for(x=a;x<=A;++x)          // loop through all coordinates
g(n,x,y),putchar(48+r);}                    // output 1 if visited, 0 otherwise

Основной тест - это, по существу, тест, использованный в ответе Линн на другой вопрос , основанный на теореме Уилсона .

Тест на четность использует адаптацию метода подсчета бит Кернигана .

Так как основной тест очень медленный, и алгоритм перезапускает всю функцию генерации пути для каждого нарисованного пикселя, любой вход значительно превышает 1000 раз на TIO.



4

LOGO, 177 171 байт

to d:c
if :c%2[rt 180
make"c:c-1]if:c<1[stop]d:c/2
end
to p
if:c>1[make"f 2
repeat:c-2[if:c%:f<1[stop]make"f:f+1]rt 90
d:c]end
to g:n
make"c 1
repeat:n[p
fw 2
make"c:c+1]end

Чтобы использовать, сделайте что-то вроде этого :

reset
pu
fw 100
pd
g 3000

Извините, но я не смог захватить пример вывода. Объяснение:

to d:c
if :c%2[rt 180
make"c:c-1]if:c<1[stop]d:c/2
end

Это рекурсивная процедура, которая поворачивает 180 ° для каждого установленного бита в своем параметре, который эффективно вычисляет четность его двоичного расширения.

to p
if:c>1[make"f 2
repeat:c-2[if:c%:f<1[stop]make"f:f+1]rt 90
d:c]end

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

to g:n
make"c 1
repeat:n[p
fw 2
make"c:c+1]end

Это просто простой цикл для проверки всех чисел вплоть до nпростоты и для перемещения на два пикселя после каждого.


4

Желе , 41 байт

B§ḂḤ’×ıµ1Ẓ?€×\ÄŻÆiZ_Ṃ$€Z‘ḞŒṬµẈḢ⁾P1,;Lṭ@FK

Попробуйте онлайн!

N

N=3000

Выход для N = 3000

N=300

0000000000000000000000111110000000000
0000000000000000000000100010000000000
0000001110000000000000100010000000000
0000001010000000000000100010000000000
0000001010000000000000100010000000000
0000001010000000000000100010000000000
0000001010000000111111111010000000000
0000001010000000100000101010000000000
0000001111111110100000101010000000000
0000000000100010100000101010000000000
0000000000111111100000101010001111111
0000000000000010000000101010001000001
0000000000000011100010101010001000001
0000000000000000100010101010001000001
0000111111100000100011111111111111111
0100100000100000100010001010001000001
0110100000111111100011111111111000111
0010100000000000000010101010000000101
1111100000000000000010101110000000101
1010000000000000000010100000000000101
1010000000000000000011111111111011101
1010000000000000000000100000001010101
1110000000000000000000111111101111101
0000000000000000000000000000100010101
0000000000000000000000000000100010101
0000000000000000000000000000100010101
0000000000000000000000000000111111111
0000000000000000000000000000000010100
0000000000000000000000000000000010100
0000000000000000000000000000000010100
0000000000000000000000000000000011100

4

JavaScript - 675 668 660 632 556 534 байт

Впервые здесь, на CodeGolf, изначально началось с ~ 1500 байт кода. Гольф это меньше половины, почти треть. Не стесняйтесь продолжать играть в гольф. Байт с этим инструментом

Принцип:
Рисует на холсте фиксированного размера с N и переменной длиной хода в качестве входных данных.

Редактирование:

-07 байт - удалить пропущенные if
-08 байт - изменить переключатель на if / else
-28 байт - изменить на десятичный, если / else
-76 байт - более короткий простой тест (время выполнения / 3)
-22 байта - использовать эту простую функцию (время выполнения * 4)

Гольф-код:

function f(e,r){for(var t=0,n=0,i=950,f=450,o=document.getElementById("d").getContext("2d"),a=1;a<=e;a++){n=iP(a)?iO(a)?1:2:0;var u=i,c=f;t==0?(t=0==n?(c=f-r,0):1==n?(u=i-r,1):(u=i+r,3)):t==1?(t=0==n?(u=i-r,1):1==n?(c=f+r,2):(c=f-r,0)):t==2?(t=0==n?(c=f+r,2):1==n?(u=i+r,3):(u=i-r,1)):(t=0==n?(u=i+r,3):1==n?(c=f-r,0):(c=f+r,2));o.beginPath(),o.moveTo(i,f),o.lineTo(u,c),o.stroke(),i=u,f=c}}function iP(h){for(i=n=h;n%--i;);return(1==i)}function iO(e){for(var r=(e>>>0).toString(2),t=0,n=0;n<r.length;n++)"1"==r[n]&&t++;return t%2!=0}

Разобранный код с пробелами:

function f(e,r){
    for(var t=0,n=0,i=950,f=450,o=document.getElementById("d").getContext("2d"),a=1;a<=e;a++){

        // prime and odd/even check
        n=iP(a)?iO(a)?1:2:0;

        var u=i,c=f;

        t==0?(t=0==n?(c=f-r,0):1==n?(u=i-r,1):(u=i+r,3)):t==1?(t=0==n?(u=i-r,1):1==n?(c=f+r,2):(c=f-r,0)):t==2?(t=0==n?(c=f+r,2):1==n?(u=i+r,3):(u=i-r,1)):(t=0==n?(u=i+r,3):1==n?(c=f-r,0):(c=f+r,2));

        o.beginPath(),o.moveTo(i,f),o.lineTo(u,c),o.stroke(),
        i=u,f=c // renew old cords
    }
}

// check prime
function iP(h){
    for(i=n=h;n%--i;);
    return(1==i)
}

// check binary expression even/odd
function iO(e){
    for(var r=(e>>>0).toString(2),t=0,n=0;n<r.length;n++)
        "1"==r[n]&&t++;
    return t%2!=0
}

Примеры:

N = 7 - длина = 60

f(7, 60);
function f(e,r){for(var t=0,n=0,i=950,f=450,o=document.getElementById("d").getContext("2d"),a=1;a<=e;a++){n=iP(a)?iO(a)?1:2:0;var u=i,c=f;t==0?(t=0==n?(c=f-r,0):1==n?(u=i-r,1):(u=i+r,3)):t==1?(t=0==n?(u=i-r,1):1==n?(c=f+r,2):(c=f-r,0)):t==2?(t=0==n?(c=f+r,2):1==n?(u=i+r,3):(u=i-r,1)):(t=0==n?(u=i+r,3):1==n?(c=f-r,0):(c=f+r,2));o.beginPath(),o.moveTo(i,f),o.lineTo(u,c),o.stroke(),i=u,f=c}}function iP(h){for(i=n=h;n%--i;);return(1==i)}function iO(e){for(var r=(e>>>0).toString(2),t=0,n=0;n<r.length;n++)"1"==r[n]&&t++;return t%2!=0}
<canvas id="d" width="1900" height="900"/> 

N = 3000 - длина = 4

f(3000, 4);
function f(e,r){for(var t=0,n=0,i=950,f=450,o=document.getElementById("d").getContext("2d"),a=1;a<=e;a++){n=iP(a)?iO(a)?1:2:0;var u=i,c=f;t==0?(t=0==n?(c=f-r,0):1==n?(u=i-r,1):(u=i+r,3)):t==1?(t=0==n?(u=i-r,1):1==n?(c=f+r,2):(c=f-r,0)):t==2?(t=0==n?(c=f+r,2):1==n?(u=i+r,3):(u=i-r,1)):(t=0==n?(u=i+r,3):1==n?(c=f-r,0):(c=f+r,2));o.beginPath(),o.moveTo(i,f),o.lineTo(u,c),o.stroke(),i=u,f=c}}function iP(h){for(i=n=h;n%--i;);return(1==i)}function iO(e){for(var r=(e>>>0).toString(2),t=0,n=0;n<r.length;n++)"1"==r[n]&&t++;return t%2!=0}
<canvas id="d" width="1900" height="900"/> 

N = 20000 - длина = 2

f(20000, 2);
function f(e,r){for(var t=0,n=0,i=950,f=450,o=document.getElementById("d").getContext("2d"),a=1;a<=e;a++){n=iP(a)?iO(a)?1:2:0;var u=i,c=f;t==0?(t=0==n?(c=f-r,0):1==n?(u=i-r,1):(u=i+r,3)):t==1?(t=0==n?(u=i-r,1):1==n?(c=f+r,2):(c=f-r,0)):t==2?(t=0==n?(c=f+r,2):1==n?(u=i+r,3):(u=i-r,1)):(t=0==n?(u=i+r,3):1==n?(c=f-r,0):(c=f+r,2));o.beginPath(),o.moveTo(i,f),o.lineTo(u,c),o.stroke(),i=u,f=c}}function iP(h){for(i=n=h;n%--i;);return(1==i)}function iO(e){for(var r=(e>>>0).toString(2),t=0,n=0;n<r.length;n++)"1"==r[n]&&t++;return t%2!=0}
<canvas id="d" width="1900" height="900"/> 

N = 159000 - длина = 1

f(159000, 1);
function f(e,r){for(var t=0,n=0,i=950,f=450,o=document.getElementById("d").getContext("2d"),a=1;a<=e;a++){n=iP(a)?iO(a)?1:2:0;var u=i,c=f;t==0?(t=0==n?(c=f-r,0):1==n?(u=i-r,1):(u=i+r,3)):t==1?(t=0==n?(u=i-r,1):1==n?(c=f+r,2):(c=f-r,0)):t==2?(t=0==n?(c=f+r,2):1==n?(u=i+r,3):(u=i-r,1)):(t=0==n?(u=i+r,3):1==n?(c=f-r,0):(c=f+r,2));o.beginPath(),o.moveTo(i,f),o.lineTo(u,c),o.stroke(),i=u,f=c}}function iP(h){for(i=n=h;n%--i;);return(1==i)}function iO(e){for(var r=(e>>>0).toString(2),t=0,n=0;n<r.length;n++)"1"==r[n]&&t++;return t%2!=0}
<canvas id="d" width="1900" height="900"/> 


Цвет зависит от количества перекрывающихся линий? Круто!
Вэл

Я не изменил стиль обводки, это должен быть черный цвет по умолчанию без рисунка или прозрачности. Нашел здесь . Почему это может произойти, изменение цвета может быть связано с шириной обводки, которую я установил во втором параметре, моя функция принимает @val. Извините, что разочаровал вас.
pixma140

3

Красный , 515 480 471 байт

-1 байт благодаря Кевину Круйссену!

func[n][a: 270 x: t: u: v: w: 0 y: 1
b: copy[line 0x0 0x1]repeat i n - 1[p: on
j: i + 1 repeat k i / 2[if j%(k + 1)= 0[p: off]]if p[s: 0
until[if j% 2 = 1[s: s + 1](j: j / 2)< 1]a: a + pick[-90 90]s% 2 + 1]append b 'line 
append b as-pair x y x: x + cosine a y: y - sine a append b as-pair x y t: min x t
u: max x u v: min y v w: max y w]c: 500 /(max u - t w - v)view[base white 502x500
draw collect[foreach k b[keep either pair? k[as-pair k/1 - t * c k/2 - v * c][k]]]]]

Значительная часть кода (~ 160 байт) имеет дело с нормализацией координат, так что графика полностью помещается на холст, независимо от размера ввода.

Начальное направление: юг.

Вот результат для n = 3000

3000 итераций

n = 20000

20000


1
Из любопытства, почему не требуется пробелов для модулей в if j%(k + 1)и if j% 2 = 1, но есть пробелы, необходимые для большинства других операторов ( +, /и т. Д.). Можно ли убрать пространство по модулю pick[-90 90]s% 2? На самом деле, почему также нет места as-pair k/1 - t * c k/2 - v * cдля /?
Кевин Круйссен

1
@KevinCruijssen Да, место можно удалить s% 2, спасибо! Я не знаю почему, но по модулю %это единственный оператор, для которого пространство перед ним может быть отброшено, если ему предшествует слово (переменная). В as-pair k/1 - t * c k/2 - v * cслешах /служат совершенно иные цели - они и есть path. kявляется pairи k/1является первым элементом (его также можно выбрать с помощью k/xили pick k 1). Пространства нужны почти везде, исключения есть ()[]{}, потому что двусмысленности нет.
Гален Иванов

@KevinCruijssen Большинство символов может использоваться в wordименах ( Redне имеет variables, все является либо wordзначением, либо значением (или некоторым синтаксическим блоком, подобным [...]или (...)). Итак: a*4: 45-> слову a*4присваивается значение 45. %используется в качестве маркера для file!типа данных и, возможно, именно поэтому он не может использоваться в wordименах, но может нарушать правила для других арифметических операторов
Гален Иванов

1
Ах, хорошо, это имеет смысл, что у /них другое назначение, и символы могут использоваться без пробелов в переменных (или, wordsкак они явно называются для красного). Спасибо за объяснение. :) И рад, что мог (в основном случайно) сохранить байт для s% 2. :)
Кевин Круйссен

1

Обработка, 140+ байтов

void f(int N){for(int x,y,i,l,d,k=d=y=x=0;k++<N;d+=i<l?0:Integer.bitCount(k)%2*2-1,d&=3,point(x-=~-d%2,y+=(d-2)%2))for(i=1,l=k;0<l%++i%l;);}

Может не выполнять четко видно

ходить

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.