Peregrinazione di parità primaria


44

Lo scopo di questa sfida è di rappresentare graficamente una camminata sul piano, in cui la direzione di ogni passo k è determinata dalla primalità di e dalla parità della sua espansione binaria. In particolare,k

  • La direzione iniziale è fissa, ad esempio Nord.
  • Tutti i passaggi hanno la stessa lunghezza .
  • La direzione del passaggio può essere Nord, Ovest, Sud o Est ed è determinata come segue: k
    • Se non è primo, la direzione non cambia.k
    • Se è primo e l'espansione binaria di ha un numero pari, girare a destra.kk
    • Se è primo e l'espansione binaria di ha un numero dispari di quelli, girare a sinistra.kk

Ad esempio , supponiamo che la direzione iniziale sia Nord. I primi passi sono:

  • k=1 non è un numero primo. Quindi facciamo un passo nella direzione attuale, che è il Nord.
  • k=2 è primo e la sua espansione binaria 10ha un numero dispari di quelli. Quindi giriamo a sinistra e ora siamo rivolti a ovest. Facciamo un passo in quella direzione.
  • k=3 è primo, e la sua espansione binaria 11, ha e un numero pari di quelli. Quindi giriamo a destra e ora siamo rivolti a nord. Facciamo un passo in quella direzione.
  • k=4 non è un numero primo. Quindi facciamo un passo nella direzione attuale, che è il Nord.

La sfida

Ingresso : intero positivo .N

Output : diagramma della camminata -passo come definito sopra.N

Regole aggiuntive

  • La direzione iniziale può essere scelto liberamente (non necessariamente Nord), ma dovrebbe essere la stessa per tutti .N
  • La regola di svolta può essere l'opposto di quella sopra descritta, ovvero girare a destra per parità dispari e a sinistra per pari; ma deve essere la stessa per tutti .N
  • L'output deve essere una rappresentazione grafica della camminata. Per esempio:
    • La passeggiata può essere tracciata con segmenti di linea.
    • I punti visitati possono essere mostrati con un pennarello, come un punto; con o senza segmenti di linea di collegamento.
    • È possibile fornire un'immagine raster a due colori, con un colore corrispondente ai punti visitati e un altro per i non visitati.
  • Le scale degli assi orizzontale e verticale non devono necessariamente essere le stesse. Anche le etichette degli assi e gli elementi simili sono opzionali. Finché la passeggiata può essere vista chiaramente, la trama è valida.
  • Si noti che alcuni punti vengono visitati più di una volta. La trama non è sensibile a questo. Ad esempio, se i segmenti di linea vengono visualizzati nel grafico, ogni segmento di unità viene visualizzato allo stesso modo, indipendentemente da quante volte è stato attraversato.
  • Il codice dovrebbe funzionare per qualsiasi Ndata risorsa illimitata. È accettabile se in pratica fallisce a Ncausa di limiti di tempo, memoria o tipo di dati.
  • Ingresso e uscita sono flessibili come al solito. In particolare, è possibile utilizzare uno qualsiasi dei mezzi standard per produrre immagini.
  • Vince il codice più breve in byte.

Casi test

I seguenti grafici usano Nord come direzione iniziale; anche la parità gira a destra; e la passeggiata è raffigurata con segmenti di linea.

N = 7:

inserisci qui la descrizione dell'immagine

N = 3000:

inserisci qui la descrizione dell'immagine

N = 20000:

inserisci qui la descrizione dell'immagine

N = 159000:

inserisci qui la descrizione dell'immagine

N = 1200000:

inserisci qui la descrizione dell'immagine

N = 11000000:

inserisci qui la descrizione dell'immagine


1
C'è un motivo solo [graphical-output]è permesso? Qualche motivo in particolare per impedire l'output ASCII, come la mia risposta Charcoal ora cancellata?
Kevin Cruijssen,

2
@Kevin Una volta mi è stato consigliato di non mescolare entrambi nella stessa sfida ... Cosa ne pensano gli altri?
Luis Mendo,

1
Bene, posso capire il ragionamento alla base di quel consiglio, dato che l'output come immagine / grafico rispetto all'arte ASCII è completamente diverso in alcune lingue. Poi di nuovo, ho visto gli output dei grafici ottenere un sacco di voti nelle sfide dell'arte ASCII e viceversa, quindi immagino che non tutti siano d'accordo. Personalmente penso che dipenda davvero dalla sfida. In questo caso personalmente non vedo alcun danno nel consentire entrambi nella stessa sfida, ma forse sono di parte a causa della mia risposta ora cancellata. Quindi ti farò la stessa domanda: " Cosa ne pensano gli altri? " @Arnauld Forse dovresti pubblicare il tuo tassista ASCII dopo tutto;)
Kevin Cruijssen,

1
Sarebbe interessante vedere questa corsa su varie sequenze di OEIS (vero, alcuni camminerebbero semplicemente in linea retta o girerebbero in cerchio, ma alcuni potrebbero essere piuttosto qualcosa).
Draco18s

16
A N = 11000000, sembra avvicinarsi alla mappa dell'Europa.
Digital Trauma,

Risposte:


12

Mazza 0.4 , 22 20 byte

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

Si decomprime in questa funzione del linguaggio Wolfram:

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

Ungolfed

Per prima cosa definiamo una funzione che restituisce l'angolo da ruotare ad ogni passo:

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

ThueMorseè la parità della somma delle cifre binarie. Usiamo -1^(...)piuttosto che 2*...-1per un motivo leggermente complicato: Wolfram Language converte automaticamente le espressioni aritmetiche nella fonte in una forma canonica, quindi le espressioni come 2/xsono memorizzate come Times[2, Power[x, -1]]. Questo rende la frequenza Powermolto alta, e quindi comprimendola molto a buon mercato.

(Moltiplicare per Boole@PrimeQ@è leggermente più lungo e il Boolelancio implicito di booleani non era stato implementato al momento della sfida.)

Da qui, Mathematica AnglePathe ListPlotfa esattamente ciò di cui abbiamo bisogno:

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

Nell'app interattiva, l'output è un oggetto grafico vettoriale riscalabile.

inserisci qui la descrizione dell'immagine


Freddo! Sono arrivato a 77 byte unendo le nostre soluzioni. Saluti!
Roman

14

MATL , 25 24 21 byte

Q:qJyZpbB!sEq*^YpYsXG

Provalo su MATL online

Grazie @LuisMendo per una bella sessione di golf in chat che alla fine ha portato a questa versione da 21 byte, suggerendo Eq*^

Spiegazione

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

Esempio per : k=12345inserisci qui la descrizione dell'immagine


8

C (gcc) , 179 byte

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;}

Provalo online!

Una funzione. Il primo argomento è N, il secondo argomento è un buffer allocato di dimensioni di almeno byte. Un'immagine quadrata viene scritta in questo buffer, la sua lunghezza laterale viene restituita. Nell'immagine, è un pixel bianco, è un pixel nero.4n2+4n+101

C (gcc) , 219 byte

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;}}

Provalo online!

Una funzione. Il primo argomento è N, il secondo argomento è un buffer allocato di dimensioni almeno byte. Un'immagine quadrata in formato PBM viene scritta nel buffer.4n2+4n+2×log10(2n+1)+9

Uscita ritagliata per 20000:

uscita ritagliata per 20000

Entrambe le versioni iniziano con ovest e girano a destra su dispari, a sinistra su pari.

Ho provato i testcase più grandi senza nessuno dei due, poiché l'uscita con 20000 era ~ 1,5 GB e 150000 sarebbero stati ~ 90 GB. Tutto questo è archiviato in memoria durante l'esecuzione del programma.

Spiegazione di quello superiore:

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
Non penso che sia richiesto che venga fornito un buffer allocato come argomento - è consentito un criterio aggiuntivo per ogni meta policy (che interpreterei per indicare un 0puntatore medio o nullo nel caso di C).
Maniglia della porta

3
Sto interpretando questa come dicendo posso invitare per essere assegnato. Questo è anche uno schema usato in molte funzioni di libreria standard, come sprintf.
wastl

Ah va bene, hai ragione, ha senso.
Maniglia della porta


8

Wolfram Language (Mathematica) , 98 96 91 77 76 63 byte

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

-14 byte: grazie a @lirtosiast per avermi mostrato come usareAnglePath ...

-13 byte: ... e ThueMorse!

esempio di utilizzo:

%[20000]

inserisci qui la descrizione dell'immagine

Spiegazione dettagliata:

  • If[PrimeQ@#, 2 ThueMorse@# - 1, 0] &è una funzione che accetta l'indice del passo e restituisce 0 per i numeri primi non binari, -1 per i numeri primi binari pari e +1 per i numeri primi binari dispari. ThueMorse@#sostituisce la soluzione precedente Total[#~IntegerDigits~2](che è la stessa, modulo 2).

  • Array[Pi/2*%,#]crea un elenco di questa funzione con l'indice che va da 1 all'argomento della funzione (20000 nell'esempio) e moltiplica ogni elemento per π / 2 per trasformarlo in un angolo di cambio di direzione (radianti). Ora abbiamo 0 per i numeri primi non primari, -π / 2 per i numeri primi binari pari e + π / 2 per i numeri primi binari dispari.

  • AnglePath[%]converte questo elenco di angoli di cambio di direzione in un percorso. Questa istruzione sostituisce il doppio uso della soluzione precedente Accumulate.

  • ListPlot[%]converte l'elenco delle posizioni in un diagramma a punti XY. Se si preferisce una linea, utilizzare ListLinePlotinvece. Queste funzioni di stampa hanno molte opzioni per migliorare l'aspetto dei grafici.


1
Grazie @lirtosiast! È come imparare una lingua straniera: nuovo vocabolario ogni giorno.
Roman

7

MATL, 31 30 28 26 byte

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

3 byte salvati grazie a @LuisMendo

2 byte salvati grazie a @Sanchises

Provalo su MATL Online

Spiegazione

Questa soluzione utilizza numeri complessi per rappresentare i componenti X e Y del piano 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]

A questo punto, abbiamo quattro punti ( (0, 1), (-1, 0), (0, -1), (1, 0)) in una matrice rappresentata da numeri complessi. Queste sono le quattro direzioni cardinali. Ora vogliamo usarli per "camminare".

Fondamentalmente il modo in cui funziona è che iniziamo a dirigerci nella direzione zero (l'elemento 0 dell'array che è (-1, 0)). Per ogni passaggio, dobbiamo determinare la modifica in questa intestazione. Useremo numeri interi per tenere traccia di questa modifica. Se vogliamo girare "a destra", incrementiamo questo numero intero di 1 (facendo riferimento all'elemento successivo nella matrice a 4 punti) e se vogliamo andare "a sinistra", diminuiamo questo numero intero di 1 (facendo riferimento all'elemento precedente nella Array a 4 punti). Se vogliamo continuare il nostro percorso, manteniamo costante il valore intero (facendo riferimento allo stesso elemento nell'array a 4 punti).

Questa parte del codice crea un array di tutti coloro 0, -1e 1valori.

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

Ora abbiamo una matrice delle differenze tra numeri interi successivi in ​​modo da poter calcolare la somma cumulativa di quelli fino a ottenere gli indici che possiamo quindi usare per cercare la direzione in ogni fase dell'array originale a 4 elementi.

Convenientemente, MATL ha un sistema di indicizzazione avvolgente tale che l'indice si 5avvolge all'inizio di un array di 4 elementi. Possiamo usarlo a nostro vantaggio in modo da poter incrementare e decrementare questo numero intero senza preoccuparci del fatto che l'array della direzione di riferimento sia composto solo da 4 elementi.

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

Ora abbiamo una serie di direzioni di passaggi, quindi possiamo calcolare la somma cumulativa di queste direzioni per tracciare il percorso che è stato preso.

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

5

Perl 6 , 213 182 byte

{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)}

Provalo online!

(Sono davvero riuscito a abbattere questo!)

Questa funzione viene emessa in formato SVG.

  • { -{ .is-prime * .base(2).comb(~1) R** -1 || i }(++$)i } ... *è una sequenza infinita di cambi di direzione per ogni passaggio, sotto forma di numeri complessi, dove 1mezzi "continua nella stessa direzione", isignifica "svolta a sinistra" e -isignifica "svolta a destra".
  • [^$_] limita tale sequenza al numero di passaggi forniti come argomento della funzione.
  • [\*] esegue la scansione di quella sequenza con moltiplicazione (complessa), trasformando l'elenco dei cambi di direzione relativi in ​​un elenco di direzioni assolute.
  • [\+]scansiona quella sequenza con aggiunta (complessa), producendo un elenco delle coordinate visitate.
  • ».reals converte quell'elenco di numeri complessi in elenchi a due elementi delle sue parti reali e immaginarie.

L'immagine SVG è solo un singolo pathelemento.

Uscita (convertita in PNG) per N = 20000:

percorso per N = 20000


4

C, 321 byte

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);}

Provalo online!

Ho iniziato a lavorare su questo prima che l'altra risposta C fosse pubblicata, ma ho pensato che avrei potuto pubblicare anche la mia. Questo è molto più lungo, ma ritaglia automaticamente l'immagine di output fino alle dimensioni del risultato automaticamente.

La funzione si chiama as f(n)e l'output è stdout nel formato netpbm.

Esempio di output per 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

Il test principale è essenzialmente quello utilizzato nella risposta di Lynn a una diversa sfida , che si basa sul teorema di Wilson .

Il test di parità utilizza un adattamento del metodo di conteggio dei bit di Kernighan .

Poiché il test primo è molto lento e l'algoritmo esegue nuovamente l'intera funzione di generazione del percorso per ciascun pixel disegnato, qualsiasi input molto superiore a 1000 volte in uscita su TIO.



4

LOGO, 177 171 byte

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

Ad uso, fare qualcosa di simile questo :

reset
pu
fw 100
pd
g 3000

Spiacenti, ma non sono stato in grado di acquisire l'output di esempio. Spiegazione:

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

Questa è una procedura ricorsiva che ruota di 180 ° per ogni bit impostato nel suo parametro, che calcola efficacemente la parità della sua espansione binaria.

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

Questo è un test di primalità molto semplice. Dopo il caso speciale 1, la procedura torna presto se viene trovato un fattore. Se tuttavia il valore corrente viene rilevato come primo, gira a destra e quindi utilizza la procedura sopra descritta per cambiarlo in una svolta a sinistra, come appropriato.

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

Questo è solo un semplice ciclo per testare tutti i numeri fino alla nprimalità e per spostare due pixel dopo ognuno.


4

Gelatina , 41 byte

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

Provalo online!

N

N=3000

Uscita per 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 byte

La prima volta qui su CodeGolf, inizialmente iniziato con ~ 1500 byte di codice. Lo ha golfato a meno della metà di quasi un terzo di esso. Sentiti libero di continuare a giocare a golf. Byte conteggiati con: questo strumento

Principio:
disegna su tela di dimensioni fisse con N e lunghezza del tratto variabile come input.

modifiche:

-07 byte - rimuove i mancati if
-08 byte - cambia l'opzione in if / else
-28 byte - cambia in tenary if / else
-76 byte - test primo più breve (runtime / 3)
-22 byte - usa questa funzione primaria (runtime * 4)

Codice Golfed:

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}

Codice non golfato con spazi bianchi:

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
}

Esempi:

N = 7 - Lunghezza = 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 - Lunghezza = 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 - Lunghezza = 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 - Lunghezza = 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"/> 


Il colore dipende dalla quantità di linee sovrapposte? Freddo!
val

Non ho cambiato lo stile del tratto, questo dovrebbe essere il nero predefinito senza motivo o trasparenza. Trovato qui . Perché potrebbe accadere che un cambio di colore possa essere correlato alla larghezza della corsa impostata nel secondo parametro, la mia funzione sta prendendo @val. Mi dispiace forse deluderti.
pixma140,

3

Rosso , 515 480 471 byte

-1 byte grazie a Kevin Cruijssen!

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]]]]]

Una parte significativa del codice (~ 160 byte) riguarda la normalizzazione delle coordinate in modo che la grafica si adatti interamente alla tela indipendentemente dalle dimensioni dell'input.

Direzione iniziale: sud.

Ecco il risultato per n = 3000

3000 iterazioni

n = 20000

20000


1
Per curiosità, perché non ci sono gli spazi necessari per i rollover a if j%(k + 1)e if j% 2 = 1, ma ci sono gli spazi necessari per la maggior parte degli altri operatori ( +, /, ecc). Lo spazio può essere rimosso anche nel modulo di pick[-90 90]s% 2? In realtà, perché anche non ci sono spazi richiesti as-pair k/1 - t * c k/2 - v * cper il /?
Kevin Cruijssen, il

1
@KevinCruijssen Sì, lo spazio può essere rimosso per s% 2, grazie! Non so perché, ma modulo %è l'unico operatore per il quale è possibile eliminare lo spazio davanti ad esso, se preceduto da una parola (variabile). Nelle as-pair k/1 - t * c k/2 - v * cbarre /servono scopi completamente diversi: sono paths. kè un paired k/1è il primo elemento (può essere selezionato anche da k/x, o pick k 1). Gli spazi sono necessari quasi ovunque, le eccezioni sono in giro ()[]{}, perché non c'è ambiguità.
Galen Ivanov,

@KevinCruijssen La maggior parte dei simboli può essere utilizzata nei wordnomi ( Rednon ha variables, tutto è o un wordvalore (o alcuni blocchi di sintassi come [...]o (...)). Quindi: a*4: 45-> a una parola a*4viene assegnato un valore 45. %viene utilizzato come marcatore per il file!tipo di dati e forse è per questo che non può essere usato nei wordnomi ma può infrangere le regole per gli altri operatori aritmetici.
Galen Ivanov,

1
Ah ok, ha senso che /hanno uno scopo diverso lì e che i simboli possono essere usati senza spazi nelle variabili (o wordscome sono apparentemente chiamati per il Rosso). Grazie per la spiegazione. :) E felice di aver (per lo più accidentalmente) salvato un byte per il s% 2. :)
Kevin Cruijssen il

1

Elaborazione, oltre 140 byte

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;);}

Potrebbe non soddisfare chiaramente visto

camminare

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.