Prime Parity Peregrination

44

Der Zweck dieser Herausforderung besteht darin, einen Gang in der Ebene grafisch darzustellen, wobei die Richtung jedes Schritts durch die Primalität von und die Parität seiner binären Expansion bestimmt wird. Speziell,kk

  • Die anfängliche Richtung ist festgelegt, etwa nach Norden.
  • Alle Stufen haben die gleiche Länge .
  • Die Richtung von Schritt kann Nord, West, Süd oder Ost sein und wird wie folgt bestimmt: k
    • Wenn nicht prim ist, ändert sich die Richtung nicht.k
    • Wenn eine Primzahl ist und die binäre Expansion von eine gerade Anzahl von Einsen hat, biege nach rechts ab.kk
    • Wenn eine Primzahl ist und die binäre Expansion von eine ungerade Anzahl von Einsen hat, biege links ab.kk

Nehmen Sie als Beispiel an , dass die Anfangsrichtung Nord ist. Die ersten Schritte sind:

  • k=1 ist keine Primzahl. Wir bewegen uns also einen Schritt in Richtung Norden.
  • k=2 ist eine Primzahl, und ihre binäre Expansion 10hat eine ungerade Anzahl von Einsen. Also biegen wir links ab und sind jetzt nach Westen ausgerichtet. Wir gehen einen Schritt in diese Richtung.
  • k=3 ist eine Primzahl, und ihre binäre Expansion 11hat eine gerade Anzahl von Einsen. Wir biegen also rechts ab und sind jetzt nach Norden ausgerichtet. Wir gehen einen Schritt in diese Richtung.
  • k=4 ist keine Primzahl. Wir bewegen uns also einen Schritt in Richtung Norden.

Die Herausforderung

Input : positive ganze Zahl .N

Ausgabe : Darstellung des oben definierten Schritt-Wegs.N

Zusätzliche Regeln

  • Die Anfangsrichtung kann frei gewählt werden (nicht unbedingt Nord), sollte aber für alle .N
  • Die Wende-Regel kann der oben beschriebenen entgegengesetzt sein, dh für ungerade Parität nach rechts und für gerade nach links drehen; aber es muss für alle .N
  • Die Ausgabe muss eine grafische Darstellung des Weges sein. Zum Beispiel:
    • Der Weg kann mit Liniensegmenten gezeichnet werden.
    • Die besuchten Punkte können mit einer Markierung angezeigt werden, z. B. einem Punkt. mit oder ohne Verbindungsliniensegmente.
    • Es kann ein zweifarbiges Rasterbild bereitgestellt werden, wobei eine Farbe besuchten Punkten und eine andere Farbe nicht besuchten Punkten entspricht.
  • Die Maßstäbe der horizontalen und vertikalen Achse müssen nicht identisch sein. Auch Achsenbeschriftungen und ähnliche Elemente sind optional. Solange der Weg gut sichtbar ist, ist die Handlung gültig.
  • Beachten Sie, dass einige Punkte mehrmals besucht werden. Die Handlung reagiert darauf nicht. Wenn zum Beispiel Liniensegmente im Plot angezeigt werden, wird jedes Einheitensegment gleich angezeigt, unabhängig davon, wie oft es durchlaufen wurde.
  • Der Code sollte für alle Ngegebenen unbegrenzten Ressourcen funktionieren . Es ist akzeptabel, wenn in der Praxis Naufgrund von Zeit-, Speicher- oder Datentypbeschränkungen ein großer Fehler auftritt.
  • Ein- und Ausgabe sind wie gewohnt flexibel. Insbesondere kann jedes der Standardmittel zum Ausgeben von Bildern verwendet werden.
  • Der kürzeste Code in Bytes gewinnt.

Testfälle

In den folgenden Darstellungen wird Nord als Anfangsrichtung verwendet. gerade Parität geht nach rechts; und der Weg ist mit Liniensegmenten dargestellt.

N = 7:

Bildbeschreibung hier eingeben

N = 3000:

Bildbeschreibung hier eingeben

N = 20000:

Bildbeschreibung hier eingeben

N = 159000:

Bildbeschreibung hier eingeben

N = 1200000:

Bildbeschreibung hier eingeben

N = 11000000:

Bildbeschreibung hier eingeben

Luis Mendo
quelle
1
Gibt es einen Grund, der nur [graphical-output]erlaubt ist? Gibt es einen Grund, wie meine jetzt gelöschte Charcoal-Antwort, die ASCII-Ausgabe zu deaktivieren?
Kevin Cruijssen
2
@ Kevin Mir wurde einmal geraten, nicht beide in der gleichen Herausforderung zu mischen ... Was denken andere?
Luis Mendo
1
Nun, ich kann die Gründe für diesen Rat verstehen, da die Ausgabe als Bild / Grafik im Vergleich zu ASCII-Kunst in einigen Sprachen völlig anders ist. Andererseits habe ich Graphausgaben gesehen, die bei ASCII-Kunst-Herausforderungen eine Menge Upvotes erhalten haben und umgekehrt, also denke ich, dass nicht jeder zustimmt. Persönlich denke ich, dass es wirklich von der Herausforderung abhängt. In diesem Fall sehe ich persönlich keinen Nachteil darin, beide in derselben Herausforderung zuzulassen, aber vielleicht bin ich aufgrund meiner jetzt gelöschten Antwort voreingenommen. Also stelle ich die gleiche Frage wie Sie: " Was denken andere? " @Arnauld Vielleicht sollten Sie doch Ihren ASCII-Taxifahrer
posten
1
Es wäre interessant, diesen Lauf auf verschiedenen OEIS-Sequenzen zu sehen (wahr, einige würden nur in einer geraden Linie laufen oder im Kreis laufen, aber einige könnten etwas ganz Besonderes sein).
Draco18s
16
Bei N = 11000000 scheint es sich um eine Annäherung an die Europakarte zu handeln.
Digitales Trauma

Antworten:

12

Vorschlaghammer 0,4 , 22 20 Bytes

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

Dekomprimiert in diese Wolfram Language-Funktion:

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

Ungolfed

Zuerst definieren wir eine Funktion, die den Drehwinkel bei jedem Schritt zurückgibt:

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

ThueMorseist die Parität der Summe der Binärziffern. Wir verwenden dies -1^(...)nicht 2*...-1aus einem etwas komplizierten Grund: Wolfram Language konvertiert arithmetische Ausdrücke in der Quelle automatisch in eine kanonische Form, sodass Ausdrücke wie 2/xgespeichert werden als Times[2, Power[x, -1]]. Dies macht die Frequenz Powersehr hoch und komprimiert sie daher sehr billig.

(Das Multiplizieren mit Boole@PrimeQ@ist etwas länger und das implizite BooleCasting von Booleanern war zum Zeitpunkt der Challenge noch nicht implementiert.)

Von hier aus Mathematica AnglePathund ListPlottun genau das, was wir brauchen:

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

In der interaktiven App ist die Ausgabe ein skalierbares Vektorgrafikobjekt.

Bildbeschreibung hier eingeben

Lirtosiast
quelle
Cool! Durch die Kombination unserer Lösungen habe ich 77 Byte erreicht. Prost!
Roman
14

MATL , 25 24 21 Bytes

Q:qJyZpbB!sEq*^YpYsXG

Probieren Sie es bei MATL online

Vielen Dank an @LuisMendo für eine nette Golfsitzung im Chat, die letztendlich zu dieser 21-Byte-Version führte, indem sie vorschlug Eq*^

Erläuterung

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=12345Bildbeschreibung hier eingeben

Sanchises
quelle
8

C (gcc) 179 Bytes

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

Probieren Sie es online!

4n2+4n+101

C (gcc) , 219 Bytes

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

Probieren Sie es online!

4n2+4n+2×log10(2n+1)+9

Zugeschnittene Ausgabe für 20000:

abgeschnittene Ausgabe für 20000

Beide Versionen beginnen mit West und biegen rechts ab, ungerade links auf gerade.

Ich habe die größeren Testfälle mit keinem von beiden ausprobiert, da die Ausgabe mit 20000 ~ 1,5 GB betrug und 150000 ~ 90 GB gewesen wären. Dies alles wird gespeichert, während das Programm ausgeführt wird.

Erklärung der oberen:

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 */
}
wastl
quelle
1
Ich glaube nicht, dass die Angabe eines zugewiesenen Puffers als Argument zulässig ist. Pro Metarichtlinie muss jede zusätzliche Eingabe leer sein (was ich 0im Fall von C als Mittelwert oder Nullzeiger interpretieren würde ).
Türklinke
3
Ich interpretiere das so, dass ich damit rechnen kann, dass es zugeteilt wird. Dies ist auch ein Muster, das in vielen Standardbibliotheksfunktionen verwendet wird, z. B. sprintf.
Wastl
Ah okay, du hast recht, das macht Sinn.
Türknauf
162 Bytes
Ceilingcat
8

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

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

-14 Bytes: Vielen Dank an @lirtosiast, der mir gezeigt hat, wie man es benutztAnglePath ...

-13 Bytes: ... und ThueMorse!

Anwendungsbeispiel:

%[20000]

Bildbeschreibung hier eingeben

Schritt für Schritt Erklärung:

  • If[PrimeQ@#, 2 ThueMorse@# - 1, 0] &ist eine Funktion, die den Schrittindex verwendet und 0 für nicht-Primzahlen, -1 für geradzahlige binäre Primzahlen und +1 für ungeradzahlige binäre Primzahlen zurückgibt. ThueMorse@#Ersetzt die vorherige Lösung Total[#~IntegerDigits~2](die gleiche, Modulo 2).

  • Array[Pi/2*%,#]erstellt eine Liste dieser Funktion mit einem Index von 1 bis zum Funktionsargument (im Beispiel 20000) und multipliziert jedes Element mit π / 2, um einen Richtungsänderungswinkel (Bogenmaß) zu erhalten. Wir haben jetzt 0 für Nicht-Primzahlen, -π / 2 für gerade-binäre Primzahlen und + π / 2 für ungerade-binäre Primzahlen.

  • AnglePath[%]konvertiert diese Liste von Richtungsänderungswinkeln in einen Pfad. Diese Anweisung ersetzt die doppelte Verwendung der vorherigen Lösung von Accumulate.

  • ListPlot[%]konvertiert die Liste der Positionen in ein XY-Punktdiagramm. Wenn eine Linie bevorzugt wird, verwenden Sie ListLinePlotstattdessen. Diese Plotfunktionen verfügen über zahlreiche Optionen, um die Darstellung der Plots zu verbessern.

römisch
quelle
1
Vielen Dank @lirtosiast! Es ist, als würde man eine Fremdsprache lernen: Jeden Tag ein neues Vokabular.
Roman
7

MATL, 31 30 28 26 Bytes

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

3 Bytes gespart dank @LuisMendo

2 Bytes gespart dank @Sanchises

Probieren Sie es bei MATL Online aus

Erläuterung

Diese Lösung verwendet komplexe Zahlen, um die X- und Y-Komponenten der 2D-Ebene darzustellen

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]

Zu diesem Zeitpunkt haben wir vier Punkte ( (0, 1), (-1, 0), (0, -1), (1, 0)) in einem Array, das durch komplexe Zahlen dargestellt wird. Dies sind die vier Hauptrichtungen. Jetzt wollen wir diese verwenden, um "zu gehen".

Im Wesentlichen funktioniert dies so, dass wir in die nullte Richtung (das nullte Element des Arrays, das ist (-1, 0)) fahren. Für jeden Schritt müssen wir die Änderung in dieser Überschrift bestimmen. Wir werden ganze Zahlen verwenden, um diese Änderung zu verfolgen. Wenn wir "nach rechts" drehen möchten, erhöhen wir diese Ganzzahl um 1 (wobei auf das nächste Element im 4-Punkt-Array verwiesen wird ), und wenn wir "nach links" gehen möchten, verringern wir diese Ganzzahl um 1 (wobei auf das vorherige Element im Feld verwiesen wird) 4-Punkt-Array). Wenn wir unseren Weg fortsetzen möchten, halten wir den ganzzahligen Wert konstant (wobei auf dasselbe Element im 4-Punkt-Array verwiesen wird ).

Dieser Teil des Codes erzeugt ein Array von all jenen 0, -1und 1Werte.

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

Jetzt haben wir ein Array der Unterschiede zwischen aufeinanderfolgenden ganzen Zahlen, so dass wir die kumulative Summe dieser berechnen können, um die Indizes zu erhalten, die wir dann verwenden können, um die Richtung bei jedem Schritt im ursprünglichen 4-Element-Array nachzuschlagen.

Praktischerweise verfügt MATL über eine Umlaufindizierung, sodass der Index 5am Anfang eines Arrays mit 4 Elementen umläuft. Wir können dies zu unserem Vorteil nutzen, um diese Ganzzahl zu erhöhen und zu verringern, ohne uns Gedanken darüber zu machen, dass das Referenzrichtungs-Array nur aus 4 Elementen besteht.

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

Jetzt haben wir eine Reihe von Richtungen für die Schritte, sodass wir die kumulative Summe dieser Richtungen berechnen können, um den eingeschlagenen Pfad zu verfolgen.

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

Perl 6 , 213 182 Bytes

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

Probieren Sie es online!

(Wirklich geschafft, dieses zu reduzieren!)

Diese Funktion gibt im SVG-Format aus.

  • { -{ .is-prime * .base(2).comb(~1) R** -1 || i }(++$)i } ... *ist eine unendliche Folge von Richtungsänderungen für jeden Schritt in Form von komplexen Zahlen, wobei 1"in die gleiche Richtung weitergehen" ibedeutet, "nach links abbiegen" und -i"nach rechts abbiegen" bedeutet.
  • [^$_] begrenzt diese Sequenz auf die Anzahl der Schritte, die als Argument der Funktion angegeben werden.
  • [\*] Durchsucht diese Sequenz mit (komplexer) Multiplikation und wandelt die Liste der relativen Richtungen in eine Liste der absoluten Richtungen um.
  • [\+]scannt diese Sequenz mit (komplexer) Addition und erstellt eine Liste der besuchten Koordinaten.
  • ».reals wandelt diese Liste komplexer Zahlen in Listen mit zwei Elementen der Real- und Imaginärteile um.

Das SVG-Bild ist nur ein einzelnes pathElement.

Ausgabe (umgerechnet in PNG) für N = 20000:

Pfad für N = 20000

Sean
quelle
4

C 321 Bytes

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

Probieren Sie es online!

Ich fing an, daran zu arbeiten, bevor die andere C-Antwort veröffentlicht wurde, aber ich dachte, ich könnte meine sowieso genauso gut veröffentlichen. Diese ist viel länger, aber sie schneidet das Ausgabebild automatisch auf die Abmessungen des Ergebnisses ab.

Die Funktion wird als aufgerufen f(n)und die Ausgabe erfolgt im Netpbm-Format stdout.

Beispielausgabe für 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

Der Primärtest ist im Wesentlichen derjenige, der in Lynns Antwort auf eine andere Herausforderung verwendet wird , die auf dem Satz von Wilson beruht .

Der Paritätstest verwendet eine Anpassung der Kernighan-Bitzählmethode .

Da der Primetest sehr langsam ist und der Algorithmus die gesamte Pfadgenerierungsfunktion für jedes gezeichnete Pixel erneut ausführt, ist jede Eingabe auf TIO viel höher als das 1000-fache.

Türknauf
quelle
308 Bytes
Ceilingcat
4

LOGO, 177 171 Bytes

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

Gebrauch, so etwas wie dies :

reset
pu
fw 100
pd
g 3000

Es tut mir leid, aber ich konnte keine Beispielausgabe erfassen. Erläuterung:

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

Dies ist eine rekursive Prozedur, die für jedes gesetzte Bit in ihrem Parameter um 180 ° gedreht wird, wodurch die Parität ihrer binären Expansion effektiv berechnet wird.

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

Dies ist ein sehr grundlegender Primalitätstest. Nach Sonderfall 1 kehrt die Prozedur vorzeitig zurück, wenn ein Faktor gefunden wird. Wenn sich jedoch herausstellt, dass der aktuelle Wert eine Primzahl ist, biegt er nach rechts ab und wandelt ihn dann wie oben beschrieben in eine Linkskurve um.

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

Dies ist nur eine einfache Schleife, um alle Zahlen bis auf ihre nUrsprünglichkeit zu testen und zwei Pixel nacheinander zu verschieben.

Neil
quelle
4

Jelly , 41 Bytes

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

Probieren Sie es online!

N

N=3000

Ausgabe für 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
Nick Kennedy
quelle
4

JavaScript - 675 668 660 632 556 534 Bytes

Zum ersten Mal hier auf CodeGolf, zunächst mit ~ 1500 Bytes Code gestartet. Golf es zu weniger als der Hälfte fast mehr als ein Drittel davon. Fühlen Sie sich frei, weiter Golf zu spielen. Bytes Counted with: dieses Tool

Prinzip:
Zeichnet in eine Leinwand mit fester Größe mit N und variabler Strichlänge als Eingabe.

Bearbeitungen:

-07 Bytes - Entfernen von verpassten if
-08 Bytes - Ändern des Schalters auf if / else
-28 Bytes - Ändern auf tenary if / else
-76 Bytes - Kürzere Primzahlprüfung (Laufzeit / 3)
-22 Bytes - Verwenden Sie diese Primzahlfunktion (Laufzeit) * 4)

Golf Code:

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}

Ungolfed Code mit Leerzeichen:

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
}

Beispiele:

N = 7 - Länge = 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 - Länge = 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 - Länge = 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 - Länge = 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"/> 

pixma140
quelle
Die Farbe hängt von der Anzahl der überlappenden Linien ab. Cool!
val
Ich habe den Strichstil nicht geändert. Dies sollte standardmäßig Schwarz ohne Muster oder Transparenz sein. Gefunden hier . Warum es zu einer Farbänderung kommen kann, hängt möglicherweise mit der Strichstärke zusammen, die ich im zweiten Parameter festgelegt habe, den meine Funktion für @val verwendet. Tut mir leid, Sie vielleicht enttäuscht zu haben.
Pixma140
3

Rot , 515 480 471 Bytes

-1 Byte Danke an 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]]]]]

Ein wesentlicher Teil des Codes (~ 160 Byte) befasst sich mit der Normalisierung der Koordinaten, sodass die Grafiken unabhängig von der Größe der Eingabe vollständig in die Zeichenfläche passen.

Anfangsrichtung: Süden.

Hier ist das Ergebnis für n = 3000

3000 Iterationen

n = 20000

20000

Galen Ivanov
quelle
1
Aus Neugier, warum nicht es Räume für die modulos erforderlich an if j%(k + 1)und if j% 2 = 1, aber es gibt Räume , die für die meisten anderen Operatoren ( +, /usw.). Kann der Raum auch im Modulo von entfernt werden pick[-90 90]s% 2? Warum braucht man eigentlich auch keine Plätze as-pair k/1 - t * c k/2 - v * cfür die /?
Kevin Cruijssen
1
@ KevinCruijssen Ja, das Leerzeichen kann entfernt werden s% 2, danke! Ich weiß nicht warum, aber modulo %ist der einzige Operator, für den das Leerzeichen davor entfernt werden kann, wenn ein Wort (Variable) vorangestellt wird. In as-pair k/1 - t * c k/2 - v * cden Schrägstrichen /dienen ganz andere Zwecke - sie sind paths. kist ein pairund k/1ist das erste Element (es kann auch mit k/x, oder ausgewählt werden pick k 1). Fast überall werden Leerzeichen benötigt ()[]{}, es gibt Ausnahmen , da es keine Mehrdeutigkeiten gibt.
Galen Ivanov
@KevinCruijssen Die meisten Symbole können in wordNamen verwendet werden ( Redhaben nicht variables, alles ist entweder ein wordoder ein Wert (oder ein Syntaxblock wie [...]oder (...)). Also: a*4: 45-> einem Wort a*4wird ein Wert zugewiesen 45. %wird als Markierung für den file!Datentyp verwendet und vielleicht ist das der Grund, warum es nicht in wordNamen verwendet werden kann, aber die Regeln für die anderen arithmetischen Operatoren brechen kann.
Galen Ivanov
1
Ah ok, das macht Sinn, dass die /dort einen anderen Zweck haben und die Symbole ohne Leerzeichen in Variablen verwendet werden können (oder wordswie sie anscheinend für Rot genannt werden). Danke für die Erklärung. :) Und froh, dass ich (meistens aus Versehen) ein Byte für das speichern konnte s% 2. :)
Kevin Cruijssen
1

Verarbeitung, 140+ Bytes

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

Könnte nicht klar gesehen erfüllen

gehen

PrincePolka
quelle