พิมพ์จุดยอดของลูกบาศก์และสามเหลี่ยมครอบคลุม


9

พิกัดเอาต์พุตของจุดยอดของลูกบาศก์ จากนั้นออกรายการสามเหลี่ยม 12 อันที่จะครอบคลุมลูกบาศก์แต่ละสามเหลี่ยมเป็นรายการจุดยอดสามดัชนี เอาต์พุตต้องเป็นสตริง ASCII ของตัวเลขทศนิยมที่แตกต่างกัน กอล์ฟนี้ไม่มีอินพุท ผู้ชนะคือตัวละครที่น้อยที่สุดโดยที่ชุดอักขระคือ Unicode

ตัวอย่างเช่นพิจารณาลูกบาศก์ 1x1x1 ที่มุมเป็น 0,0,0 แปดจุดยอดของลูกบาศก์สามารถอธิบายได้โดยพิกัด xyz ต่อไปนี้บนตารางคาร์ทีเซียน 3d:

x y z = (0,0,1) (1,0,1) (1,1,1) (0,1,1) (0,0,0) (1,0,0) (1,1,0) (0,1,0)

แต่ละจุดสุดยอดจะได้รับดัชนี: x y z->index: 0 0 1->0, 1 0 1->1, 1 1 1->2, 0 1 1->3, 0 0 0->4, 1 0 0->5, 1 1 0->6, 0 1 0->7

ตอนนี้พิจารณาใบหน้าด้านบนจุดสุดยอดที่ทำดัชนีเป็นศูนย์ถึงสาม สามเหลี่ยมสองรูปสามารถอธิบายได้ด้วยสามดัชนีแต่ละอัน:

[0,1,2] [2,3,0]

นี่คือภาพใบหน้าด้านบนนี้ซึ่งมองจากด้านบนของลูกบาศก์:

 3_____2
 |    /| 
 |   / |                  
 |  /  |
 | /   |
 0_____1                

และนี่คือมุมมองจากมุมหนึ่ง

    3____2
   / __-/|
 0/_`__1 |
  |    | /6
  |____|/
 4     5

สังเกตการวางแนวหรือ 'ไขลาน' ของรูปสามเหลี่ยมทั้งสองนี้คือ 'ทวนเข็มนาฬิกา' เมื่อมองจาก 'นอก' ลูกบาศก์มองดูใบหน้าที่เป็นปัญหาโดยตรง (ลองจินตนาการการเยี่ยมชมแต่ละจุดยอดตามที่ระบุไว้มันจะหมุนทวนเข็มนาฬิกา) ทีนี้ลองจินตนาการว่าสิ่งนี้ทำกับทั้งหกด้านของลูกบาศก์

vertices: (0,0,1) (1,0,1) (1,1,1) (0,1,1) (0,0,0) (1,0,0) (1,1,0) (0,1,0)
triangles as indices: [0,1,2], [2,3,0], [6,5,4], [4,7,6], 
  [5,2,1], [2,5,6], [0,3,4], [4,3,7], [2,6,3], [3,6,7], [0,4,1], [1,4,5]

คุณสามารถส่งออกลูกบาศก์ขนาดใดก็ได้ที่พิกัดใด ๆ คุณสามารถกำหนดจำนวนและสั่งพิกัดของจุดสุดยอดได้ตามที่คุณต้องการ ดัชนีสามารถเป็น 0 หรือ 1 ได้ การวางแนวของสามเหลี่ยมสามารถเป็นได้ทั้งตามเข็มนาฬิกาหรือทวนเข็มนาฬิกาเมื่อมองจากนอกลูกบาศก์ตราบเท่าที่มันสอดคล้องกันสำหรับสามเหลี่ยมทุกรูป

เอาต์พุตสามารถจัดรูปแบบได้ตามที่คุณต้องการตราบใดที่เลขทศนิยม ASCII แต่ละตัวถูกคั่นด้วยอักขระ ASCII ที่ไม่ใช่ตัวเลขอย่างน้อยหนึ่งตัว ตัวอย่างเช่นตัวอย่างข้างต้นยังสามารถส่งออกได้ดังนี้:

0 0 1 1 0 1 1 1 1 0 1 1 0 0 0 1 0 0 1 1 0 0 1 0 
0 1 2 2 3 0 6 5 4 4 7 6 5 2 1 2 5 6 0 3 4 4 3 7 2 6 3 3 6 7 0 4 1 1 4 5

กอล์ฟนี้ได้รับแรงบันดาลใจจากระบบกราฟิก 3 มิติและรูปแบบต่าง ๆ รวมถึง OpenGL, OBJ, OFF, AMF, CGAL และอื่น ๆ กอล์ฟนี้คล้ายกับกอล์ฟโดยงานอดิเรกของ Calvin ที่ชื่อว่าOutput a Face on a Numbered Cubeซึ่งแตกต่างอย่างมาก เพื่อส่งออกพิกัด xyz ของจุดยอดด้วยตนเองและดัชนีสามเหลี่ยมออก ขอบคุณที่อ่าน.

ต่อแรงบันดาลใจของผู้ใช้ที่นี่คือโปรแกรมตรวจสอบ "ผู้ช่วย" ใน python2 (ไม่ใช่กอล์ฟ) ที่จะพิมพ์ 'ok' หรือ 'ไม่ตกลง' สำหรับทดสอบข้อมูลผลลัพธ์ในตัวแปร vertstr และ idxstr มันไม่ทำงานอย่างสมบูรณ์แบบ ... แต่มันสามารถจับข้อผิดพลาดบางอย่าง

แก้ไข: พิมพ์ผิดในตัวอย่างและข้อบกพร่องในรหัสตรวจสอบ

    

#vertstr = '0 0 0 0 0 1 1 1 0 0 1 1 1 0 0 1 1 1 1 1 0 0 1 1 1'
#idxstr = '1 2 0 2 1 3 7 5 6 4 6 5 2 4 0 4 2 6 7 3 5 1 5 3 4 1 0 1 4 5 7 6 3 2 3 6'
vertstr = '0 0 1 1 0 1 1 1 1 0 1 1 0 0 0 1 1 0 0 1 1 0 0 1 0'
idxstr = '0 1 2 2 3 0 6 5 4 4 7 6 5 2 1 2 5 6 0 3 4 4 7 7 6 6 3 3 6 7 0 4 1 1 4 5'

คลาสเวกเตอร์:
    def __init __ (ตัวเอง, v):
        self.x, self.y, self.z v = [0], โวลต์ [1], โวลต์ [2]
    def __ เพิ่ม __ (self, v):
        return เวกเตอร์ ([self.x + vx, self.y + vy, self.z + vz])
    def __sub __ (ตัวเอง, v):
        ส่งคืนเวกเตอร์ ([self.xv.x, self.yv.y, self.zv.z])
    def __str __ (ตัวเอง):
        return str (self.x) + ',' + str (self.y) + ',' + str (self.z)

def cross (v1, v2):
    x = v1.y * v2.z-v2.y * v1.z
    z = v1.x * v2.y-v2.x * v1.y
    y = v1.z * v2.x-v2.z * v1.x
    กลับเวกเตอร์ ([x, y, z])

# http://mathforum.org/library/drmath/view/55343.html & http://sympy.org
def winding (v1, v2, v3, obs):
    x1, y1, Z1, x2, y2, Z2, x3, y3, Z3, x4, y4, z4 = v1.x, v1.y, v1.z, v2.x, v2.y, v2.z, v3 x, v3.y, v3.z, obs.x, obs.y, obs.z
    d = x1 * (y2 * z3 - y2 * z4 - y3 * z2 + y3 * z4 + y4 * z2 - y4 * z3) 
    d = d + y1 * (- x2 * z3 + x2 * z4 + x3 * z2 - x3 * z4 - x4 * z2 + x4 * z3) 
    d = d + z1 * (x2 * y3 - x2 * y4 - x3 * y2 + x3 * y4 + x4 * y2 - x4 * y3)
    d = d - x2 * y3 * z4 + x2 * y4 * z3 + x3 * y2 * z4 - x3 * y4 * z2 - x4 * y2 * z3 + x4 * y3 * z2 
    กลับ d

def normals (v1, v2, v3):
    va = v2-v1
    vb = v3-v2
    vc = v1-v3
    n1 = cross (va, vb)
    n2 = cross (vb, vc)
    n3 = cross (vc, va)
    ส่งคืน [n1, n2, n3]


def เพิ่มเป็นสามเท่า (str):
    nums อเนกประสงค์ = [] []
    สำหรับ num ใน str.split (''): nums + = [int (num)]
    สำหรับฉันอยู่ในช่วง (0, len (จำนวน), 3):
        triples + = [[nums [i], nums [i + 1], nums [i + 2]]
    กลับอเนกประสงค์

verts = เพิ่มเป็นสามเท่า (vertstr)
ดัชนี = triplify (idxstr)
nsum = เวกเตอร์ ([0,0,0])
windsum = 0
XS, ys, ZS = [] [] []
สำหรับ v ใน verts:
    XS + = [วี [0]]
    ys + = [วี [1]]
    ZS + = [วี [2]]
#print xs, ys, zs, len (xs)
ศูนย์ = เวกเตอร์ ([ลอย (ผลรวม (XS)) / len (XS) ลอย (ผลรวม (ys)) / len (ys) ลอย (ผลรวม (ZS)) / len (ZS)])
สำหรับสามเหลี่ยมในดัชนี:
    v1 = เวกเตอร์ (verts [สามเหลี่ยม [0]])
    v2 = เวกเตอร์ (verts [สามเหลี่ยม [1]])
    v3 = เวกเตอร์ (verts [สามเหลี่ยม [2]])
    norms = normals (v1, v2, v3)
    พิมพ์ v1, v2, v3, บรรทัดฐาน [0], บรรทัดฐาน [1], บรรทัดฐาน [2]
    สำหรับ n ในบรรทัดฐาน:
        nsum + = n
    w = ไขลาน (v1, v2, v3, กึ่งกลาง)
    พิมพ์ 'winding', w
    ถ้า w <0: windsum- = 1
    elif w> 0: windsum + = 1
ถ้า abs (windsum) == 12: พิมพ์ 'winding ok'
อื่น ๆ : พิมพ์ 'ม้วนไม่ได้'
if (nsum.x == 0 และ nsum.y == 0 และ nsum.z == 0): พิมพ์ 'sum sum ปกติ'
อื่น ๆ : พิมพ์ 'ผลรวมปกติไม่ตกลง'

1
ชัดเจนจากตัวอย่าง แต่เพื่อให้ชัดเจนอย่างสมบูรณ์คุณอาจต้องการพูดถึงว่าดัชนีนั้นเป็นแบบ 0 นี่ไม่ใช่สิ่งที่กำหนดเนื่องจากอย่างน้อยหนึ่งรูปแบบที่คุณแสดงรายการเป็นตัวอย่าง (OBJ) ใช้ดัชนีที่อิง 1
Reto Koradi

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

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

ตกลงฉันเพิ่มโปรแกรมการตรวจสอบที่รวดเร็วและสกปรกมากซึ่งใช้ผลิตภัณฑ์ของเวกเตอร์แต่ละคู่ในแต่ละสามเหลี่ยมเพิ่มพวกเขาทั้งหมดและถ้า 0 บอกว่า 'ตกลง'
ดอนสดใส

คำตอบ:


1

Pyth, 18 ตัวอักษร

j`CM"⭧勛囃勦⾽仵ᶌﻘꚱ쥎➡˻ì

แนวคิดเดียวกันกับคำตอบของ Haskell พิมพ์:

[
1
1
1
1
1
,

2
1
2
1
1
...

ฉันชอบที่คุณใช้สตริงยูนิโค้ดเดียวกันใน 3 ภาษา
ดอนสดใส

1
เวทมนตร์ยูนิโคดคืออะไร?
RK

2

CJam, 35 ไบต์

YZm*`3{[XY4]m<)\0+_:+1$f-+_@f+W%}%`

ลองออนไลน์

ผลลัพธ์คือ:

[[0 0 0] [0 0 1] [0 1 0] [0 1 1] [1 0 0] [1 0 1] [1 1 0] [1 1 1]] [[1 2 0 2 1 3] ] [7 5 6 4 6 5] [2 4 0 4 2 6] [7 3 5 1 5 3] [4 1 0 1 4 5] [7 6 3 2 3 6]

การวางแนวสามเหลี่ยมตามเข็มนาฬิกาจากด้านนอก ฉันตรวจสอบสิ่งนี้ด้วยตนเองและมันถูกต้องสำหรับฉัน

คำอธิบาย:

YZ      Push 2 and 3 on stack.
m*      Cartesian power, creates the coordinates of the 8 vertices.
`       Convert to string for output. Done with vertices.
3{      Start loop over 3 coordinate directions.
  [XY4]   Push [1 2 4], which are the vertex index offsets for the 3 directions.
  m<      Rotate by loop counter. So the remaining loop body will be executed once
          with [1 2 4], once with [2 4 1], once with [4 1 2].
  )       Pop off last offset. Will use this as index offset between the two
          parallel faces.
  \       Swap pair of remaining two offsets to top. These are the index offsets
          within the face.
  0+      Add a 0 to the list. These 3 indices define the first triangle.
  _:+     Calculate the sum. This is the vertex index of the opposite corner.
  1$      Copy first triangle to the top.
  f-      Subtract all indices from the index of the opposite corner, producing
          the second triangle of the face.
  +       Concatenate the indices of the two triangles, resulting in a list with
          the 6 vertex indices for the face.
  _       Copy the list.
  @       Bring the offset between the two faces to the top.
  f+      Add the offset to each index in the copied list.
  W%      Revert the order, resulting in the properly oriented list of the 6 vertex
          indices for the parallel face.
}%      End of loop over 3 coordinate directions.
`       Convert to string for output. Done with triangles.

มันเจ๋งจริงๆ . . รักความสมมาตร ...
ดอน

นี่เป็นคำตอบที่สนุกที่สุดอย่างชัดเจน แต่ฉันทำให้คำจำกัดความปัญหาของฉันมีคำอธิบายแบบคงที่และ "ไม่ป้อนข้อมูล" ดังนั้นฉันต้องรักษาข้อตกลงและให้รางวัลตัวละครที่มีจำนวนต่ำที่สุดด้านล่าง (ซึ่งเป็นคำตอบที่สนุก วิธีที่แตกต่างกัน) เครื่องหมายถูกคำตอบ ขอบคุณสำหรับการเข้าร่วม
ดอนสดใส

1

JavaScript (ES6) 78

alert([...'1010011100101110111:120213756465240426735153410145763236'].join` `)

ขออภัย แต่ฉันไม่เข้าใจความท้าทายเหล่านี้โดยไม่มีการป้อนข้อมูล


ขออภัยมันเป็นคำถามกอล์ฟครั้งแรกของฉัน ฉันเดาว่ามันจะสายเกินไปที่จะเปลี่ยนมันตอนนี้ ...
don bright

ดีกว่าในครั้งต่อไป คุณมีคะแนนของฉันต่อไป
edc65

1

ทับทิม, 98 106

แก้ไขข้อผิดพลาดที่พบโดย Reto Koradi

s=sprintf'%024b',342391
6.times{|i|t='15462315'[i,3];t+=t.reverse;t[1+i%2*3]='07'[i%2];s+=t}
p s.split(//)

เนื่องจากจำเป็นต้องใช้พิกัดชุดรูปแบบหมายเลขมุมเท่านั้นที่ทำให้ความรู้สึกดูเหมือนจะเป็นที่ที่แต่ละมุมเป็นตัวแทนไบนารีของพิกัดของมัน มันค่อนข้างแตกต่างจากคำถามที่เชื่อมโยงซึ่งมีการลองใช้รูปแบบการนับที่แตกต่างกัน ในที่สุดฉันก็ตัดสินใจที่จะพิมพ์พิกัดด้วย hardcode สกปรก: sเริ่มต้นเป็นรุ่นสตริงจำนวน 24 บิต000001010011100101110111ซึ่งเป็นตัวแทนทศนิยม 342391 จริง ๆ แล้วด้วยวิธีการพิมพ์พิกัดนี้จำนวนของจุดยอดมีความยืดหยุ่นดังนั้นฉันอาจ ทำคำตอบอื่น

เมื่อไปรอบเส้นศูนย์สูตรของลูกบาศก์เราจะพบจุดยอด 1,5,4,6,2,3 และเราสามารถกำหนดหนึ่งรูปสามเหลี่ยมสำหรับแต่ละหน้าจากตัวเลข 3 หมายเลขติดต่อกันในรายการนี้ (ย้อนกลับไปที่จุดเริ่มต้นในตอนท้าย ) รูปสามเหลี่ยมอื่น ๆ ในแต่ละหน้าถูกกำหนดโดยการย้อนกลับของตัวเลขและแทนที่ตัวเลขกลางด้วย 0 หรือ 7 ตามความเหมาะสม

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

["0", "0", "0", "0", "0", "1", "0", "1", "0", "0", "1", "1", "1", "0", "0",
 "1", "0", "1", "1", "1", "0", "1", "1", "1", "1", "0", "4", "4", "5", "1",
 "5", "4", "6", "6", "7", "5", "4", "0", "2", "2", "6", "4", "6", "2", "3",
 "3", "7", "6", "2", "0", "1", "1", "3", "2", "3", "1", "5", "5", "7", "3"]

คุณแน่ใจหรือไม่ว่าคำสั่งที่คดเคี้ยวนั้นสอดคล้องกัน? ตามร่างของฉัน1, 5, 4คือ CCW 5, 4, 6คือ CW
Reto Koradi

@RetoKoradi คงที่ที่ราคา 8 ไบต์ ขอบคุณ นอกจากนี้ฉันยังตระหนักว่าฉันอาจทำได้ดีกว่าด้วยรูปแบบการกำหนดหมายเลขที่แตกต่างกัน
เลเวลริเวอร์เซนต์

1

Haskell, 38 ตัวอักษร

f=mapM(mapM print.show)"⭧勛囃勦⾽仵ᶌﻘꚱ쥎➡˻ì"

พิมพ์ตัวเลขที่ถูกต้องคั่นด้วยขยะจำนวนมาก:

'\''
'\\'
'1'
'1'
'1'
'1'
'1'
'\''
'\''
'\\'
'2'
'1'
'2'
'1'
'1'
...

เส้นทแยงมุมของลูกบาศก์มาจาก (1, 1, 1) ถึง (2, 2, 2)


1

CJam, 20 ตัวอักษร

"⭧勛囃勦⾽仵ᶌﻘꚱ쥎➡˻ì":isS*

แนวคิดเดียวกันกับคำตอบของ Haskell พิมพ์:

1 1 1 1 1 2 1 2 1 1 2 2 2 1 1 2 1 2 2 2 1 2 2 2 1 2 0 2 1 3 7 5 6 4 6 5 2 4 0 4 2 6 7 3 5 1 5 3 4 1 0 1 4 5 7 6 3 2 3 6

1

Ruby, Rev 1 62

29.downto(0){|c|p c>5?73888640>>c&1:[c,c^1,c|6,c|6,(c+3)%6,c]}

กำจัดc-6โดยการคูณเลขเวทย์ด้วย 64

การกำหนดพิกัดอยู่ด้านล่าง มันแปลกที่ฉันกำหนดให้100กับหมายเลข 1 ฉันสามารถบันทึก byte ใน rev 0 โดยการแลกเปลี่ยนแกนและกำหนดให้001กับหมายเลข 1 เหตุผลที่เป็นเช่นนั้นเป็นเพราะเดิมทีฉันมีการนับในลูปซึ่งหมายความว่าฉัน ต้องใส่ทุกอย่างในสิ่งที่ตรงกันข้ามในสายเวทย์มนตร์ อย่างไรก็ตามด้วยการเปลี่ยนแปลงที่ฉันทำตอนนี้ไม่มีการบันทึกเพิ่มเติมที่จะทำดังนั้นฉันจะออกจากพิกัดตามที่พวกเขาเป็น

Cube rotated with 0163 face at back
Top layer from above
01   000 100
74   010 110    
Bottom layer from above
36   001 101   
25   011 111

Ruby, Rev 0 63

29.downto(0){|c|p c>5?1154510>>c-6&1:[c,c^1,c|6,c|6,(c+3)%6,c]}

ใช้ hardcoding ของข้อมูลพิกัดเพื่อให้เกิดความยืดหยุ่นในการเลือกมุม มี 54 ตัวเลขในผลลัพธ์หมายความว่าโซลูชันไร้เดียงสาจะมีรหัส 63-54 = 9 ไบต์ เนื่องจากฉันไม่สามารถคิดวิธีแทรกช่องว่างในขนาด 9 ไบต์ได้ฉันเชื่อว่านี่จะสั้นกว่าโซลูชันที่ไร้เดียงสา

รูปแบบการกำหนดหมายเลข (ดัดแปลงมาจากคำตอบ Ruby ของฉันกับคำถามที่เชื่อมโยงhttps://codegolf.stackexchange.com/a/48867/15599 )

4---7
|  /|
| / |
|/  |
1---0---7
|  /|  /|
| / | / |
|/  |/  |
6---3---2---7
    |  /|  /|
    | / | / |
    |/  |/  |
    6---5---4
        |  /|
        | / |
        |/  |
        6---1

เอาท์พุต

0
0
0
1
0
0
0
1
1
0
0
1
1
1
0
1
1
1
0
0
1
1
1
0
[5, 4, 7, 7, 2, 5]
[4, 5, 6, 6, 1, 4]
[3, 2, 7, 7, 0, 3]
[2, 3, 6, 6, 5, 2]
[1, 0, 7, 7, 4, 1]
[0, 1, 6, 6, 3, 0]

ฉันชอบการรวมตัวกันของวิธีการของ @ Runer112
ดอนสดใส

@donbright ฉันเป็นคนแรกที่คิดถึงการวาง 6 จุดแรกบนเส้นศูนย์สูตรและ 2 อันสุดท้ายบนเสาในคำถามก่อนหน้านั้นซึ่งเป็นสาเหตุที่คำตอบ C ของฉันเป็นคำตอบที่ได้รับความนิยมมากที่สุด ฉันมีจุดยอด 6 จุดตามลำดับ Runer112 สมควรได้รับเครดิตบางส่วนสำหรับการจัดลำดับใหม่ของ 6 ยอดเขาบนเส้นศูนย์สูตร ฉันต้องแก้ไขลำดับใบหน้าสำหรับ Ruby ในคำถามก่อนหน้านี้ แต่ลำดับยอดแน่นอนเหมือนกับ Runer112 การเรียงลำดับทางเลือกของ Phinotphi ของ 6 จุดยอดในเส้นศูนย์สูตรจะทำให้ฉันมีความยาวเท่ากันในคำถามก่อนหน้านี้ แต่จะนานกว่านี้ใน
ระดับ

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