วาด hexa-glyph แบบสุ่ม


23

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

รูปด้านบนนี้เรียกว่า hexa-glyph Hexa-glyphs เป็นรูปแบบเท่ ๆ ที่ฉันทำขึ้นในขณะที่อยู่ในชั้นเรียน DiffEq นี่คือวิธีการทำ:

  1. พิจารณาชุดของคะแนนต่อไปนี้มีรูปร่างเหมือน hexagram ปกติ รูปหกเหลี่ยมด้านในคือสิ่งที่จะมีสัญลักษณ์สุดท้ายในขณะที่ 6 คะแนนด้านนอกก่อตัวดาวฤกษ์และเราจะเริ่มวาดเส้นของเรา

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

  1. จากจุดนอกหกจุดสุ่มเลือกคู่ เพื่อประสิทธิภาพควรมีจุดอื่นอย่างน้อยหนึ่งจุดระหว่างสองจุดที่เลือก (มิฉะนั้นจะไม่มีผลกระทบกับตัวเลขสุดท้าย) จากนั้นแต่ละจุดให้ทำการฉายแสงไปยังอีกจุดหนึ่ง รังสีนี้ถูกบล็อกโดยบรรทัดก่อนหน้า

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

  1. ทำขั้นตอนนี้ซ้ำจนกระทั่งเกิดขอบทั้ง 9 ด้านดังที่แสดงในภาพต่อไป

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

  1. นี่คือตัวอย่างของรังสีที่ถูกบล็อก ปลายของส่วนรังสียังคงมองเห็นได้ แต่ส่วนตรงกลางจะถูกอุดด้วยสองส่วนแรกที่เราวาด

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

  1. รังสีทั้งสองนี้ยัง "ถูกบล็อก" แต่สิ่งนี้ไม่ได้ทำให้เกิดความแตกต่างที่มองเห็นได้เนื่องจากมันถูกปิดกั้นโดยสายอื่น ๆ

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

  1. การส่งต่ออย่างรวดเร็วจนกว่าจะมีการวาดทั้ง 9 บรรทัด หากคุณต้องการคำอธิบายโดยละเอียดเพิ่มเติมของขั้นตอนที่ข้ามเหล่านี้ฉันสามารถอธิบายได้

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

  1. ในที่สุดลบคะแนนของดาว เพื่อให้ดูสวยขึ้นจุดหนาจะถูกลบออกด้วย

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

ความท้าทาย

คุณท้าทายคือการส่งออกการแสดงภาพของ hexa-glyph สุ่ม นี่คือโค้ดกอล์ฟซึ่งเป็นจำนวนไบต์ที่น้อยที่สุดที่ชนะ

  1. hexa-glyphs ที่เป็นไปได้ทั้งหมดควรปรากฏขึ้นพร้อมกับความน่าจะเป็นเชิงบวก hexa-glyphs ที่แตกต่างกันถูกสร้างขึ้นโดยการเปลี่ยนลำดับการลากเส้นทั้ง 9 ขอบ

  2. นอกจากนี้ภาพทั้งหมดที่ส่งออกโดยโปรแกรมของคุณจะต้องเป็นเลขฐานสิบหกที่ถูกต้อง รูปแบบบางอย่าง (เช่นโครงร่างที่สมบูรณ์ของรูปหกเหลี่ยมด้านใน) อาจไม่ปรากฏเป็นรูปหกเหลี่ยม - และดังนั้นโปรแกรมของคุณจะต้องไม่แสดงผลลัพธ์เหล่านี้

  3. ผลลัพธ์ควรเป็นภาพกราฟิก (พิมพ์ไปที่หน้าจอหรือไฟล์)

  4. รูปหกเหลี่ยมต้องเป็นปกติ แต่สามารถปรากฏในทิศทางใดก็ได้

  5. การสะท้อนกลับ / การหมุนนั้นไม่ถือว่ามีลักษณะเฉพาะ (สิ่งนี้อาจทำให้ความต้องการ 1 ง่ายต่อการติดตาม)


8
I made up while doodling during my DiffEq class. วิธีการค้นพบที่ยิ่งใหญ่เกิดขึ้น ... : P
Rɪᴋᴇʀ

ข้อกำหนดขั้นต่ำสำหรับภาพคืออะไร ขอบเขตของศิลปะ ASCII ต้องเป็นที่จดจำได้ตราบใดที่ขอบแต่ละอันถูกนำเสนอและวางในตำแหน่งที่เหมาะสม
John Dvorak

@JanDvorak ฉันลบตัวเลือกศิลปะ ASCII ของความท้าทาย (เช่นภายใน 2 นาทีของการโพสต์) เนื่องจากโปรแกรมที่สร้าง ASCII-art และเอาต์พุตกราฟิกไม่สามารถเปรียบเทียบได้ง่าย
PhiNotPi

ถ้าเช่นนั้นงานศิลปะพิกเซล ส่วนหัว PPM ไม่หนักเกินไปและหลังจากนั้นความแตกต่างเพียงใช้กับพื้นที่บรรณนิทัศน์แทน'01' ' *'
John Dvorak

@JanDvorak Output จะเป็นไฟล์ภาพที่มีรูปแบบที่ถูกต้องใช่ไหม? จากนั้นฉันก็ไม่เห็นอะไรผิดปกติกับมัน
PhiNotPi

คำตอบ:


18

Mathematica, 273 268 264 242 ไบต์

c=CirclePoints;b@_=k=1>0;Graphics[Line/@Cases[Append[Join@@({c@6,{3^.5/2,-Pi/6}~c~6}),{0,0}][[b@#=!k;#]]&/@TakeWhile[#,t=k;(r=t;t=b@#;r)&]&/@Join@@RandomSample[{#,Reverse@#}&/@Partition[Range@12,3,2,1]~Join~Array[{2#,13,2#+6}&,3]],{_,__}]]

แสดงผลเป็นตัวยกTใน Mathematica และเป็นผู้ประกอบการ postfix transpose

การแยกข้อบกพร่องในเรื่องนี้ใช้เวลาตลอดไป ... ในตอนท้ายฉันแฮ็คบางอย่างเข้าด้วยกันเพื่อให้มันใช้งานได้ ฉันยังสงสัยด้วยว่ามันอาจจะดีกว่าถ้าจะนำ spec ไปใช้อย่างแท้จริงผ่านเส้นตรงข้ามหกเหลี่ยมด้านนอกและให้ฟังก์ชันเรขาคณิตของ Mathematica จัดการกับจุดตัด

โปรดทราบว่านี้เป็นโปรแกรมเต็มรูปแบบและถ้าคุณต้องการที่จะเรียกใช้รหัสหลายครั้งภายในเซสชั่น REPL Clear[b]เดียวที่คุณจะต้องนำหน้าด้วย

นี่คือผลลัพธ์ของการวิ่ง 20 ครั้ง:

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

คำอธิบาย

วิธีนี้ไม่ได้ใช้ประโยชน์จากจุดนอกของดาวเลย แต่มันจะทำงานโดยตรงกับจุดที่เป็นส่วนหนึ่งของ hexaglyph และบรรทัดที่ครอบคลุมสามของพวกเขาในเวลา

ลองติดป้ายคะแนน:

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

1เริ่มต้นที่มุมแปลกเล็กน้อย แต่นี่คือสาเหตุที่ (ยังค่อนข้างแปลก) CirclePointsพฤติกรรมเริ่มต้นของ การเริ่มต้นหกเหลี่ยมจากที่นั่นกลายเป็นถูกที่สุด

ตอนนี้เราต้องการค้นหาเส้นที่เกี่ยวข้องผ่านจุดสามจุดที่สอดคล้องกับจุดเชื่อมต่อของดาวชั้นนอก คนที่อยู่รอบ ๆ รูปหกเหลี่ยมนั้นมีเพียง 3 จุดที่อยู่ติดกัน (modulo 12) โดยเริ่มจากจำนวนคี่ คนที่อยู่ตรงข้ามศูนย์ประกอบด้วยจำนวนnคู่13และn+6.

การเป็นตัวแทนของเส้นเหล่านี้ (ในรูปแบบของรายการสามจุดจะถูกสร้างขึ้นโดยรหัสต่อไปนี้):

Partition[Range@12,3,2,1]~Join~Array[{2#,13,2#+6}&,3]

Partitionสร้างเส้นรอบรูปหกเหลี่ยมและArrayเส้นผ่านศูนย์ ในการประมวลผลคานทั้งสองเราจับคู่ฟังก์ชันนี้กับรายการของเส้น:

{#,Reverse@#}&

ตอนนี้เราสลับเพลงเหล่านี้RandomSampleเพื่อประมวลผลแบบสุ่ม Join @@แบนรายชื่อคู่เพื่อให้เรามีรายการของลำแสง

ระยะสั้น: การติดตามของจุดที่มีอยู่แล้วในบล็อกเราจะใช้ฟังก์ชั่นการค้นหาbซึ่งเป็น initialised ไปสำหรับค่าทั้งหมดโดยTrue b@_=k=1>0;เมื่อทำการประมวลผลลำแสงเราจะเก็บคะแนนทั้งหมดจนถึงจุดแรกที่มีb[n] == False( รวมถึงจุดนั้น):

TakeWhile[#,t=k;(r=t;t=b@#;r)&]&

ฉันรู้สึกว่านี่เป็นส่วนที่สามารถเล่นกอล์ฟได้มากที่สุดในตอนนี้ ... การใช้ตัวแปรชั่วคราวสองตัวในการเล่น Mastermindดูเหมือนว่าจะแพงมาก อย่างไรก็ตามผลของสิ่งนี้ทำให้เราได้คะแนนในบรรทัดที่เราอนุญาตให้วาด ตอนนี้ฟังก์ชั่นนี้จะถูกแมปผ่านจุดเหล่านี้:

Append[Join@@({c@6,{3^.5/2,-Pi/6}~c~6}),{0,0}][[b@#=!k;#]]&

ส่วนแรกสร้างรายการทั้งหมด 13 คะแนนโดยใช้ผลลัพธ์ interleaved ของการเรียกสองครั้งCirclePoints(ด้วยรัศมีที่แตกต่างกันสำหรับศูนย์กลางกึ่งกลางและมุมของหกเหลี่ยม) โปรดสังเกตb@#=!kว่าตอนนี้ตั้งค่าของตารางการค้นหาสำหรับจุดปัจจุบันไปที่จุดใดFalseเพื่อไม่ให้มีลำแสงเพิ่มเติมผ่านได้ ในที่สุดค่าจะถูกใช้เป็นดัชนีในรายการพิกัดเพื่อรับจุด 2D ที่ถูกต้อง

Cases[...,{_,__}]

สิ่งนี้จะยกเลิกรายการองค์ประกอบเดียวทั้งหมดเพราะจะแสดงเป็นจุด (และมองเห็นได้) เป็นรายบุคคล ในที่สุดเราก็แสดงผล:

Graphics[Line/@...]

b@_=1>0=b=1>0&
CalculatorFeline

@CatsAreFluffy ฉันไม่คิดว่าจะใช้งานได้เพราะฉันต้องสามารถเขียนทับค่าแต่ละค่าในภายหลัง
Martin Ender

ใช้ CirclePoint ได้ดี
DavidC

ฉันชื่นชมลิงก์ Youtube
DanTheMan

8

รองเท้า (Ruby) Rev C 184 ไบต์

บันทึก 12 ไบต์โดยการถ่ายโอนความรับผิดชอบในการตรวจสอบว่าควรดึงครึ่งหนึ่งจากโปรแกรมหลักไปยังวิธีการวาด โปรแกรมหลักยังคงต้องตรวจสอบว่าสายทั้งหมดถูกปิดกั้นอย่างสมบูรณ์แม้ว่า

Shoes.app{t=[]
d=->p,q{t[p]&&t[q]||line(p/6*8,p%6*14,q/6*8,q%6*14)}
%w{1I IW WM M5 5' '1 =A P. R,}.shuffle.map{|i|b=i.sum/2
c=b*2-a=i.ord
t[a]&&t[c]||(d[a,b]
d[b,c]
t[a]=t[b]=t[c]=1)}}

รองเท้า (ทับทิม) 205 ... รุ่น B 196 ไบต์

Shoes เป็นเครื่องมือที่ใช้ทับทิมสำหรับการสร้าง GUI เป็นต้นเป็นครั้งแรกที่ฉันใช้มัน mothereff.in/byte-counter นับการส่งของฉันเป็น 196 ไบต์ แต่ด้วยเหตุผลบางอย่างรองเท้านับว่าเป็น 202

นอกจากนี้ทับทิมยังช่วยให้คุณทำสิ่งต่าง ๆ เช่นt[a=i.ord]แต่แปลก ๆ ดูเหมือนว่าจะไม่ทำงานตามที่คาดไว้กับรองเท้า

Shoes.app{t=[]
d=->p,q{line(p/6*8,p%6*14,q/6*8,q%6*14)}
%w{1I IW WM M5 5' '1 =A P. R,}.shuffle.map{|i|b=i.sum/2
c=b*2-a=i.ord
t[a]&&t[c]||(t[a]&&t[b]||d[a,b]
t[b]&&t[c]||d[b,c]
t[a]=t[b]=t[c]=1)}}

คำอธิบาย

ฉันไม่พิจารณาส่วนของเส้นนอกรูปหกเหลี่ยม ฉันวาดส่วนที่ต้องวาดเท่านั้น สิ่งสำคัญคือไม่ว่าเส้นจะตัดกันทางแยก (ถ้าเราวาดเฉพาะส่วนที่ต้องวาดนั่นหมายความว่าพวกมันเริ่มต้น / สิ้นสุดที่ทางแยก)

กฎพื้นฐานคือถ้าทั้งสองปลายทางของบรรทัดได้รับการเยี่ยมชมบรรทัดนั้นถูกบล็อกและไม่ควรวาด เนื่องจากเส้นถูกวาดในสองส่วนเรายังต้องตรวจสอบว่าจุดกึ่งกลางได้รับการเยี่ยมชมเพื่อดูว่าควรจะดึงแต่ละครึ่งหรือไม่

t[]ผมติดตามซึ่งจุดที่ได้รับการเข้าเยี่ยมชมในอาร์เรย์ ซึ่งจะมีรายการสำหรับแต่ละพิกัดทางกายภาพในตารางด้านล่าง ไม่มีโลจิคัลอาร์เรย์ 13 องค์ประกอบที่แยกจากกัน ในตอนท้ายt[]อาจมีองค์ประกอบ 87 รายการ แต่มีเพียง 13 รายการเท่านั้นที่จะมีข้อมูลที่เป็นประโยชน์

ภายในพิกัดของจุดสิ้นสุดของเส้นจะถูกกำหนดโดยหมายเลข z เดียวโดยที่ z% 6 เป็นพิกัด y และ z / 6 คือพิกัด x ในระบบนี้รูปหกเหลี่ยมจะแบน เมื่อเส้นถูกพล็อตค่าสเกล x จะถูกคูณด้วย 8 และสเกล y คูณด้วย 14 ซึ่งเป็นอัตราส่วนที่ใกล้เคียงกับอัตราส่วนที่ถูกต้อง: 14/8 = 1.75 vs sqrt (3) = 1.732

ระบบพิกัดภายในแสดงไว้ด้านล่างโดยมีเอาต์พุตตัวอย่างสองสามตัวอย่าง

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

Ungolfed

Shoes.app{
  t=[]                                          #Empty array for status tracking
  d=->p,q{line(p/6*8,p%6*14,q/6*8,q%6*14)}      #Drawing method. Convert p and q into x,y pairs, scale and draw line.
  %w{1I IW WM M5 5' '1 =A P. R,}.shuffle.map{|i|#take an array of the coordinates of the endpoints of each line, shuffle, then for each line
    b=i.sum/2                                   #b = midpoint of line, convert ASCII sum to number (average of the two coordinates)
    a=i.ord                                     #a = first endpoint of line, convert ASCII to number (no need to write i[0].ord)
    c=b*2-a                                     #c = second endpoint of line (calculating is shorter than writing i[1].ord)
    t[a]&&t[c]||(                               #if both endpoints have already been visited, line is completely blocked, do nothing. ELSE
      t[a]&&t[b]||d[a,b]                        #if first endpoint and midpoint have not both been visited, draw first half of line
      t[b]&&t[c]||d[b,c]                        #if second endpoint and midpoint have not both been visited, draw second half of line
      t[a]=t[b]=t[c]=1                          #mark all three points of the line as visited
    )
  }
}

ตัวอย่างผลลัพธ์เพิ่มเติม

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

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


mothereff.in/byte-counter counts my submission as 196 bytes, but for some reason Shoes counts it as 202.ฉันไม่รู้ 100% ว่าเป็นจริงหรือไม่ แต่ฉันคิดว่าเหตุผลที่ Shoes นับรหัสของคุณเป็น 202 ไบต์แทนที่จะเป็น 196 เป็นเพราะบรรทัดใหม่ของคุณเป็นอักขระสองตัวจริง "\ r \ n" สิ่งนี้ทำให้การขึ้นบรรทัดใหม่ทุกครั้งถูกนับเป็นสองเท่า นี่คือคำตอบสแต็กล้นที่เกี่ยวกับ \ r และ \ n
K Zhang

ฉันไม่สามารถหาชื่อRuby with Shoes XD ได้
Beta Decay

3

Python, 604 591 574 561 538 531 536 534 528 493 483 452 431 420 419 415 388 385 384 ไบต์

ฉันปรับความคิดของLevel River St ในการตรวจสอบว่าบรรทัดนั้นจะถูกบล็อกโดยการตรวจสอบหรือไม่ว่าจุดปลายทั้งสองของสายนั้นเคยไปแล้ว วิธีนี้จะช่วยประหยัด 27 ไบต์ ยินดีต้อนรับคำแนะนำการเล่นกอล์ฟ

แก้ไข: แก้ไขข้อผิดพลาดและการเล่นกอล์ฟเป็นg(p,q)เวลา 3 ไบต์ Golfed Lสำหรับหนึ่งไบต์

from turtle import*
from random import*
R=range
G=goto
*L,=R(9)
shuffle(L)
a=[0]*13
ht()
T=12
c=[(j.imag,j.real)for j in(1j**(i/3)*T*.75**(i%2/2)for i in R(T))]+[(0,0)]
def g(p,q):pu();G(c[p]);a[p]*a[q]or pd();G(c[q])
for m in L:
 p=2*m;x,y,z=R(p,p+3)
 if m<6:
  if a[x]*a[z%T]<1:g(x,y);g(y,z%T);a[x]=a[y]=a[z%T]=1
 else:
  if a[p-11]*a[p-5]<1:g(p-11,T);g(p-5,T);a[p-11]=a[p-5]=a[T]=1

Ungolfing:

from turtle import*
from random import*

def draw_line(points, p_1, p_2):
    penup()
    goto(points[p_1])
    if not (a[p] and a[q]):
        pendown()
    goto(points[p_2])

def draw_glyph():
    ht()
    nine_lines = list(range(9))
    shuffle(nine_lines)
    size = 12
    center = [0,0]

    points = []
    for i in range(12):      # put in a point of a dodecagon
                             # if i is even, keep as hexagon point
                             # else, convert to hexagon midpoint
        d = 1j**(i/3) * 12   # dodecagon point
        if i%2:
            d *= .75**.5     # divide by sqrt(3/4) to get midpoint
        points += (d.imag, d.real)
    points.append(center)

    a = [0]*13
    for m in nine_lines:
        p = 2*m
        if m<6:
            x, y, z = p, p+1, p+2
            if not (a[x] and a[z%12]):
                draw_line(points, x, y)
                draw_line(points, y, z%12)
                a[x] = a[y] = a[z%12] = 1
        else:
            if not (a[p-11] and a[p-5]):
                draw_line(p-11, 12)
                draw_line(p-5, 12)
                a[p-11] = a[p-5] = a[12] = 1

Hexa-glyphs เองนั้นค่อนข้างเล็กเนื่องจากเราใช้รูปหกเหลี่ยม 12 พิกเซลเป็นฐาน (สำหรับเหตุผลในการเล่นกอล์ฟ) นี่คือตัวอย่าง hexa-glyphs (ขอโทษสำหรับการครอบตัดที่ไม่ดี):

ตัวอย่าง hexa-glyph ตัวอย่าง hexa-glyph ตัวอย่าง hexa-glyph ตัวอย่าง hexa-glyph ตัวอย่าง hexa-glyph ตัวอย่าง hexa-glyph


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