ความเท่าเทียมกันของนายกรัฐมนตรี


44

จุดประสงค์ของการท้าทายนี้คือการอธิบายการเดินบนเครื่องบินที่ทิศทางของแต่ละขั้นตอนkถูกกำหนดโดยความเป็นอันดับแรกของและความเท่าเทียมกันของการขยายตัวแบบไบนารี โดยเฉพาะอย่างยิ่งk

  • ทิศทางเริ่มต้นคงที่แล้วพูดทิศเหนือ
  • ทุกขั้นตอนมีความยาวเท่ากัน
  • ทิศทางของขั้นตอนสามารถเป็นนอร์ทเวสต์, เซาท์หรือตะวันออกกลางและถูกกำหนดดังต่อไปนี้: k
    • หากไม่เป็นเอกสิทธิ์ทิศทางจะไม่เปลี่ยนk
    • หากเป็นจำนวนเฉพาะและการขยายตัวแบบไบนารีของมีจำนวนเท่ากันให้เลี้ยวขวาkk
    • หากเป็นจำนวนเฉพาะและการขยายตัวแบบไบนารีของมีจำนวนคี่ให้เลี้ยวซ้ายkk

เป็นตัวอย่างที่ทำงานสมมติว่าทิศทางเริ่มต้นคือทิศเหนือ ขั้นตอนแรกคือ:

  • k=1ไม่สำคัญ ดังนั้นเราจึงเคลื่อนที่ไปหนึ่งก้าวในทิศทางปัจจุบันซึ่งก็คือทิศเหนือ
  • k=2เป็นจำนวนเฉพาะและส่วนขยายไบนารี10มีและจำนวนคี่ ดังนั้นเราเลี้ยวซ้ายและตอนนี้หันหน้าไปทางทิศตะวันตก เราเคลื่อนที่ไปหนึ่งก้าวในทิศทางนั้น
  • k=3เป็นจำนวนเฉพาะและการขยายฐานสองของมัน11มีและจำนวนคู่ ดังนั้นเราเลี้ยวขวาและตอนนี้หันหน้าไปทางทิศเหนือ เราเคลื่อนที่ไปหนึ่งก้าวในทิศทางนั้น
  • k=4ไม่สำคัญ ดังนั้นเราจึงเคลื่อนที่ไปหนึ่งก้าวในทิศทางปัจจุบันซึ่งก็คือทิศเหนือ

ความท้าทาย

การป้อนข้อมูล : บวกจำนวนเต็มNN

เอาต์พุต : พล็อตของการเดิน -step ตามที่กำหนดไว้ด้านบนN

กฎเพิ่มเติม

  • ทิศทางเริ่มต้นที่สามารถเลือกได้อย่างอิสระ (ไม่จำเป็นต้องเหนือ) แต่ควรจะเหมือนกันทุกNN
  • กฎการเปลี่ยนอาจจะตรงข้ามกับที่อธิบายไว้ข้างต้นนั่นคือเลี้ยวขวาเท่าเทียมกันคี่และซ้ายสำหรับแม้แต่; แต่มันจะต้องมีเหมือนกันทุกNN
  • ผลลัพธ์จะต้องเป็นภาพกราฟิกของการเดิน ตัวอย่างเช่น
    • การเดินสามารถวาดด้วยส่วนของเส้น
    • จุดที่เยี่ยมชมสามารถแสดงด้วยเครื่องหมายเช่นจุด; มีหรือไม่มีการเชื่อมต่อส่วนของเส้น
    • สามารถให้ภาพแรสเตอร์สองสีโดยมีหนึ่งสีที่ตรงกับจุดเข้าชมและอีกภาพหนึ่งสำหรับผู้ที่ไม่ได้เข้าชม
  • ตาชั่งของแกนนอนและแนวตั้งไม่จำเป็นต้องเหมือนกัน นอกจากนี้ฉลากแกนและองค์ประกอบที่คล้ายกันก็เป็นทางเลือก ตราบใดที่สามารถมองเห็นการเดินได้ชัดเจน
  • โปรดทราบว่าบางจุดมีการเยี่ยมชมมากกว่าหนึ่งครั้ง เนื้อเรื่องไม่ไวต่อสิ่งนี้ ตัวอย่างเช่นหากมีการแสดงส่วนของเส้นในพล็อตแต่ละส่วนของหน่วยจะแสดงเหมือนกันไม่ว่าจะผ่านเส้นทางไปกี่ครั้งก็ตาม
  • รหัสควรใช้ได้กับNทรัพยากรที่ไม่ จำกัด เป็นที่ยอมรับได้หากในทางปฏิบัติมันล้มเหลวเป็นจำนวนมากNเนื่องจากข้อ จำกัด ด้านเวลาหน่วยความจำหรือชนิดข้อมูล
  • อินพุตและเอาต์พุตยืดหยุ่นตามปกติ โดยเฉพาะอย่างยิ่งวิธีการมาตรฐานใด ๆสำหรับการส่งภาพสามารถนำมาใช้ได้
  • รหัสที่สั้นที่สุดในหน่วยไบต์ชนะ

กรณีทดสอบ

แปลงต่อไปนี้ใช้ทิศเหนือเป็นทิศทางเริ่มต้น แม้แต่พาริตี้เลี้ยวขวา และทางเดินนั้นมีส่วนของเส้นตรง

N = 7:

ป้อนคำอธิบายรูปภาพที่นี่

N = 3000:

ป้อนคำอธิบายรูปภาพที่นี่

N = 20000:

ป้อนคำอธิบายรูปภาพที่นี่

N = 159000:

ป้อนคำอธิบายรูปภาพที่นี่

N = 1200000:

ป้อนคำอธิบายรูปภาพที่นี่

N = 11000000:

ป้อนคำอธิบายรูปภาพที่นี่


1
มีเหตุผล[graphical-output]อนุญาตเท่านั้นหรือไม่ มีเหตุผลใดที่ทำให้ไม่อนุญาตให้ใช้เอาต์พุต ASCII เช่นคำตอบ Charcoal ที่ฉันได้ลบไปแล้วตอนนี้?
Kevin Cruijssen

2
@ เควินฉันได้รับคำแนะนำครั้งหนึ่งไม่ให้ผสมทั้งสองอย่างในความท้าทายเดียวกัน ... คนอื่น ๆ คิดอย่างไร?
Luis Mendo

1
ฉันสามารถเข้าใจเหตุผลที่อยู่เบื้องหลังคำแนะนำนั้นเนื่องจากผลลัพธ์เป็นภาพ / กราฟกับศิลปะ ASCII นั้นแตกต่างกันอย่างสิ้นเชิงในบางภาษา จากนั้นอีกครั้งฉันเห็นกราฟผลลัพธ์ที่ได้รับจำนวน upvotes ในความท้าทายศิลปะ ASCII และในทางกลับกันดังนั้นฉันเดาว่าทุกคนไม่เห็นด้วย โดยส่วนตัวแล้วฉันคิดว่ามันขึ้นอยู่กับความท้าทาย ในกรณีนี้ฉันไม่เห็นอันตรายใด ๆ เลยที่อนุญาตให้ทั้งคู่อยู่ในการท้าทายเดียวกัน แต่บางทีฉันมีอคติเนื่องจากคำตอบที่ถูกลบไปแล้วในตอนนี้ ดังนั้นฉันจะถามคำถามเดียวกันกับคุณ: " คนอื่นคิดอย่างไร? " @Arnauld บางทีคุณควรโพสต์คนขับแท็กซี่ ASCII ของคุณหลังจากนั้น;)
Kevin Cruijssen

1
จะน่าสนใจที่จะเห็นการวิ่งครั้งนี้ในลำดับของ OEIS (จริง ๆ แล้วบางคนอาจเดินเป็นเส้นตรงหรือวิ่งเป็นวงกลม
Draco18s

16
ที่ N = 11000000 ดูเหมือนว่าจะใกล้เคียงกับแผนที่ของยุโรป
Digital Trauma

คำตอบ:


12

Sledgehammer 0.4 , 22 20 bytes

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

บีบอัดลงในฟังก์ชันภาษา Wolfram นี้:

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

Ungolfed

ก่อนอื่นเรากำหนดฟังก์ชั่นที่คืนค่ามุมให้หันในแต่ละขั้นตอน:

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

ThueMorseคือความเท่าเทียมกันของผลรวมของเลขฐานสอง เราใช้-1^(...)มากกว่า2*...-1ด้วยเหตุผลที่ซับซ้อนเล็กน้อย: Wolfram ภาษาอัตโนมัติแปลงนิพจน์ทางคณิตศาสตร์ในแหล่งที่เป็นรูปแบบที่เป็นที่ยอมรับดังนั้นการแสดงออกชอบจะถูกเก็บเป็น2/x Times[2, Power[x, -1]]ทำให้ความถี่Powerสูงมากและทำการบีบอัดราคาถูกมาก

(การคูณโดยBoole@PrimeQ@จะนานกว่าเล็กน้อยและBooleการคัดเลือกโดยนัยของ Booleans ไม่ได้ถูกนำมาใช้ในช่วงเวลาของการท้าทาย)

จากที่นี่ Mathematica AnglePathและListPlotทำสิ่งที่เราต้องการ:

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

ในแอพแบบโต้ตอบเอาต์พุตเป็นวัตถุกราฟิกแบบเวกเตอร์ที่ปรับขนาดได้

ป้อนคำอธิบายรูปภาพที่นี่


เย็น! ฉันเพิ่มเป็น 77 ไบต์ด้วยการรวมโซลูชันของเรา ไชโย!
Roman

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

ลองออนไลน์!

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

ลองออนไลน์!

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

เอาต์พุตครอบตัดสำหรับ 20,000:

เอาต์พุตที่ครอบตัดสำหรับ 20,000

ทั้งสองเวอร์ชันเริ่มต้นด้วยทิศตะวันตกและเลี้ยวขวาที่คี่ซ้ายบน

ฉันลองทดสอบที่มีขนาดใหญ่กว่าโดยไม่ใช้พวกมันเนื่องจากเอาต์พุตที่มี 20,000 คือ ~ 1.5 GB และ 150000 จะเป็น ~ 90GB ทั้งหมดนี้ถูกเก็บไว้ในหน่วยความจำในขณะที่โปรแกรมทำงาน

คำอธิบายของส่วนบน:

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)
Doorknob

3
ฉันตีความสิ่งนี้โดยบอกว่าฉันคาดหวังได้ว่าจะได้รับการจัดสรร นี่เป็นรูปแบบที่ใช้ในฟังก์ชันไลบรารีมาตรฐานจำนวนมากเช่น sprintf
สูญเสีย

อ่าโอเคคุณพูดถูก
Doorknob


8

ภาษา Wolfram (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 สำหรับช่วงเวลาคู่และไบนารีช่วงเวลาคี่ไบนารี ThueMorse@#แทนที่โซลูชันก่อนหน้าTotal[#~IntegerDigits~2](ซึ่งเหมือนกัน modulo 2)

  • Array[Pi/2*%,#]ทำรายการฟังก์ชันนี้โดยดัชนีเริ่มจาก 1 ถึงอาร์กิวเมนต์ของฟังก์ชัน (ในตัวอย่าง 20000) และคูณทุกองค์ประกอบด้วยπ / 2 เพื่อทำให้เป็นมุมเปลี่ยนทิศทาง (เรเดียน) ตอนนี้เรามี 0 สำหรับ non-primes, -π / 2 สำหรับ Even-binary primes และ + π / 2 สำหรับจำนวนคี่ - binary

  • 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 !! 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 = 20,000:

เส้นทางสำหรับ N = 20,000


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)และเอาท์พุทคือ stdout ในรูปแบบ netpbm

ตัวอย่างเอาต์พุตสำหรับ n = 1,000:

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

การทดสอบที่สำคัญเป็นหลักหนึ่งที่ใช้ในการตอบของลินน์จะเป็นความท้าทายที่แตกต่างกันซึ่งอาศัยทฤษฎีบทของวิลสัน

การทดสอบความเท่าเทียมกันใช้การปรับตัวของวิธีบิตนับ Kernighan ของ

เนื่องจากการทดสอบที่สำคัญนั้นช้ามากและอัลกอริทึมจะเรียกใช้ฟังก์ชั่นการสร้างพา ธ ทั้งหมดใหม่สำหรับแต่ละพิกเซลที่วาดดังนั้นอินพุตใด ๆ จึงสูงกว่า 1,000 เท่าของ TIO



4

โลโก้, 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 Bytes Code ตีกอล์ฟให้น้อยกว่าครึ่ง เกือบมากกว่าหนึ่งในสามของมัน อย่าลังเลที่จะเล่นกอล์ฟต่อ จำนวนไบต์ด้วย: เครื่องมือนี้

หลักการ:
วาดลงบนผืนผ้าใบขนาดคงที่ที่มี N และความยาวของเส้นขีดตัวแปรเป็นอินพุต

การแก้ไข:

-07 Bytes - ลบที่ไม่ได้รับถ้า
-08 Bytes - เปลี่ยน switch เป็น if / else
-28 Bytes - เปลี่ยนเป็น tenary if / else
-76 Bytes - การทดสอบ Prime Prime ที่สั้นกว่า (runtime / 3)
-22 Bytes - ใช้ฟังก์ชันเฉพาะนี้ (runtime * 4)

รหัส 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}

โค้ดที่ไม่ถูกฟอล์กพร้อมช่องว่าง:

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 = 20,000 - ความยาว = 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

ฉันไม่ได้เปลี่ยนสไตล์การลากเส้นนี่ควรเป็นค่าเริ่มต้นสีดำที่ไม่มีรูปแบบหรือความโปร่งใส พบที่นี่ เหตุใดจึงอาจมีการเปลี่ยนแปลงสีอาจเกี่ยวข้องกับความกว้างของเส้นขีดที่ฉันตั้งไว้ในพารามิเตอร์ที่สองที่ฟังก์ชั่นของฉันกำลังรับ @val ขออภัยที่ทำให้คุณผิดหวัง
pixma140

3

สีแดง , 515 480 471 ไบต์

-1 ไบต์ต้องขอบคุณ 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]]]]]

ส่วนสำคัญของรหัส (~ 160 ไบต์) เกี่ยวกับการปรับพิกัดให้เป็นมาตรฐานเพื่อให้ภาพกราฟิกพอดีกับพื้นที่ทั้งหมดโดยไม่คำนึงถึงขนาดของอินพุต

ทิศทางเริ่มต้น: ใต้

นี่คือผลลัพธ์สำหรับ n = 3000

3000 การวนซ้ำ

n = 20000

20000


1
จากความอยากรู้ว่าทำไมไม่ได้มีช่องว่างใด ๆ ที่จำเป็นสำหรับการ modulos ที่if j%(k + 1)และif j% 2 = 1แต่มีช่องว่างที่จำเป็นสำหรับส่วนใหญ่ของผู้ประกอบการอื่น ๆ ( +, /ฯลฯ ) สามารถลบพื้นที่ออกที่โมดูโลได้pick[-90 90]s% 2หรือไม่ ที่จริงแล้วทำไมยังไม่ได้มีช่องว่างใด ๆ จำเป็นต้องใช้as-pair k/1 - t * c k/2 - v * cสำหรับ/?
Kevin Cruijssen

1
@KevinCruijssen ใช่พื้นที่สามารถลบออกs% 2ได้ขอบคุณ! ฉันไม่รู้ว่าทำไม แต่โมดูโล่%เป็นผู้ให้บริการเพียงรายเดียวที่สามารถลดพื้นที่ในด้านหน้าได้ถ้านำหน้าด้วยคำ (ตัวแปร) ในas-pair k/1 - t * c k/2 - v * cทับ/ตอบสนองวัตถุประสงค์ที่แตกต่างกันอย่างสิ้นเชิง - พวกเขามีpaths kคือpairและk/1เป็นองค์ประกอบแรก (สามารถเลือกได้ด้วยk/xหรือpick k 1) ต้องการช่องว่างเกือบทุกที่ข้อยกเว้นอยู่ใกล้()[]{}เพราะไม่มีความกำกวม
Galen Ivanov

@KevinCruijssen สัญลักษณ์ส่วนใหญ่สามารถใช้ในwordชื่อ ( Redไม่มีvariablesทุกอย่างเป็นwordค่าหรือ (หรือบล็อกไวยากรณ์บางอย่างเช่น[...]หรือ(...)) ดังนั้น: a*4: 45-> คำa*4ถูกกำหนดค่า 45. %ใช้เป็นเครื่องหมายสำหรับfile!ประเภทข้อมูล และนั่นอาจเป็นเหตุผลว่าทำไมจึงไม่สามารถใช้ในwordชื่อ แต่สามารถทำลายกฎสำหรับตัวดำเนินการทางคณิตศาสตร์อื่น ๆ ได้
Galen Ivanov

1
อ่านั่นเป็นเหตุผลว่า/มีจุดประสงค์ที่แตกต่างกันและสามารถใช้สัญลักษณ์ได้โดยไม่มีช่องว่างในตัวแปร (หรือwordsตามที่เรียกว่า Red) ขอบคุณสำหรับคำอธิบาย :) และดีใจที่ฉันจะทำได้ (ส่วนใหญ่ตั้งใจ) s% 2บันทึกไบต์สำหรับที่ :)
Kevin Cruijssen

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

อาจไม่เห็นผลที่ชัดเจน

เดิน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.