ปัญหาการจำนำที่หายไป


14

ปัญหาการจำนำที่หายไป

หลังจากเกมหมากรุกสิ้นสุดลงเบี้ยที่รอดตายก็ถูกทิ้งไว้เบื้องหลังแนวศัตรู มาช่วยเขาหาทางกลับบ้านให้เร็วที่สุด

ปัญหาเดิมอธิบายกระดาน "หมากรุก" nXn และฟังก์ชั่นf: {1,..,n-1}X{1,..,n}X{-1,0,1} => R+ของน้ำหนัก เป้าหมายคือการหาเส้นทางที่ดีที่สุดจากบางช่องในแนว buttom ไปยัง square อื่น ๆ ใน top line ซึ่งการเคลื่อนไหวที่เป็นไปได้คือ: left-up, up, right-up และคุณไม่สามารถออกจากกระดานได้

ปัญหาค่อนข้างง่ายในการแก้ปัญหาใน O (n ^ 2) โดยใช้การเขียนโปรแกรมแบบไดนามิก แต่นี่คือ codegolf และเราไม่สนใจสิ่งที่ไร้ประโยชน์เช่นความซับซ้อนของเวลาทำงาน ...

ปัญหา

อินพุต:อาร์เรย์ 3 มิติ (หรือคอลเลกชันอื่น ๆ ที่คุณเลือกได้รับผ่าน stdin หรือเป็นอาร์กิวเมนต์ของฟังก์ชัน) สอดคล้องกับกระดานหมากรุกทั่วไปขนาด: 7X8X3 (#linePasses X #rowSize X #movePerPass) จำนวนเต็มไม่เป็นลบ การย้ายค่าใช้จ่ายจากบางตำแหน่ง(i,j)ที่iเป็นดัชนีแถวและjเป็นดัชนีคอลัมน์คือ:

  • a[i][j][0]สำหรับค่าใช้จ่ายในการเดินทางขึ้นไปทางซ้ายไปที่ตารางหรือกราฟิก:(i+1,j-1)\
  • a[i][j][1]สำหรับค่าใช้จ่ายในการเดินทางขึ้นไปที่ตารางหรือกราฟิก:(i+1,j)|
  • a[i][j][2]สำหรับค่าใช้จ่ายในการเดินทางขึ้นทางขวาไปที่ตารางหรือกราฟิก:(i+1,j+1)/

MAX_INTคุณอาจคิดว่ามันจะไม่ประกอบด้วยเส้นทางที่จำนวนเงินที่มากกว่า

เอาต์พุต: เอาต์พุต 8X8 ascii แสดงเส้นทางที่ดีที่สุด (สั้นที่สุดคือผลรวมของน้ำหนักขั้นต่ำ) (หากมีผลลัพธ์ที่เหมาะสมมากกว่า 1 รายการคุณอาจแสดงเส้นทางที่คุณเลือกเอง) เส้นทางถูกวาดจากล่างขึ้นบนซึ่งในแต่ละบรรทัดอักขระที่สอดคล้องกับตำแหน่งของจำนำในเส้นทางเป็นสิ่งที่มันกำลังจะทำ เช่นหากตัวจำนำกำลังจะเลื่อนขึ้น - ซ้ายจากคอลัมน์ 3 (ไปยังคอลัมน์ 2) คุณควรวาด:

#?######
##\#####

ตำแหน่งที่?ควรถูกแทนที่ด้วยการย้ายครั้งต่อไป Xตำแหน่งสุดท้ายจะต้องมีการวาดเป็น

ตัวอย่าง

การป้อนข้อมูล:

[
  [[1,1,1],[1,1,1],[0,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,0,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,1,0],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,1,1],[1,1,0],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,1,1],[1,1,1],[1,0,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,1,1],[1,1,1],[1,0,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,1,1],[1,1,1],[0,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]]
]

เอาท์พุท:

##X#####
###\####
###|####
###|####
##/#####
#/######
#|######
##\#####

การป้อนข้อมูล:

[
  [[41,27,38],[12,83,32],[50,53,35],[46,32,26],[55,89,82],[75,30,87],[2,11,64],[8,55,22]],
  [[56,21,0],[83,25,38],[43,75,63],[56,60,77],[68,55,89],[99,48,67],[94,30,9],[62,62,58]],
  [[23,18,40],[24,47,61],[96,45,72],[71,6,48],[75,63,98],[93,56,51],[23,31,30],[49,34,99]],
  [[20,47,42],[62,79,72],[32,28,44],[68,61,55],[62,39,57],[4,17,49],[97,85,6],[91,18,12]],
  [[51,50,11],[32,39,56],[12,82,23],[33,88,87],[60,55,22],[29,78,14],[70,11,42],[63,94,67]],
  [[75,64,60],[27,79,86],[70,72,56],[55,45,32],[95,67,12],[87,93,98],[81,36,53],[38,22,93]],
  [[31,80,50],[77,71,22],[59,46,86],[64,71,53],[41,19,95],[62,71,22],[92,80,41],[26,74,29]]
]

เอาท์พุท:

######X#
#####/##
####/###
#####\##
#####|##
######\#
######|#
#######\

นี่คือดังนั้นรหัสที่สั้นที่สุดชนะ

เล่นอย่างยุติธรรม. ไม่มีช่องโหว่ ...

แก้ไข:

Iv'e เขียนคำตอบตรงๆที่ไม่ตีกอล์ฟในสกาล่าคุณสามารถดูได้ นอกจากนี้ยังมีไซต์ที่คุณสามารถเล่นด้วยโค้ดสกาล่าออนไลน์: scalakata (เพียงแค่คัดลอกและวางส่วนสำคัญไปยัง scalakata และกดปุ่มเล่น)

คำตอบ:


5

ถาม: 199 ไบต์

f:{m::x;n::{@/[+/-1 0 1_\:/:(x;m[y;;|!3]);0 2;(0W,),{x,0W}]};i:*<*|r:{&/n[x;y]}\[8#0;!7];  s:{-1+{*<x}'+n[y;z]}\[();(,8#0),-1_r;!7];j:i,{x+y x}\[i;|s];-1(@[8#"#";;:;]'[j;"X","/|\\"1+s'[|!7;-1_j]]);}

หมายเหตุ

  • ล่าม Q (kx.com) ฟรีสำหรับการใช้ที่ไม่ใช่เชิงพาณิชย์ (เวอร์ชั่นสำหรับ Windows, Linux, Mac)
  • วิธีการแก้ปัญหานี้ใช้แกนในของ Q (ชื่อภายใน k4) ดังนั้นเราจึงจำเป็นต้องมีไฟล์สคริปต์ที่มีนามสกุล k หรือล่ามแบบโต้ตอบในโหมด k (คำสั่งที่พร้อมท์แรก) ในทางตรงกันข้ามภาษา 'verbose' (อ่านง่าย) ต้องใช้สคริปต์ที่มีส่วนขยาย q และเป็นโหมดเริ่มต้นที่ล่ามแบบโต้ตอบ

ทดสอบ

f ((1 1 1; 1 1 1; 0 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 0 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 1 0; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 1 1; 1 1 0; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 1 1; 1 1 1; 1 0 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 1 1; 1 1 1; 1 0 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 1 1; 1 1 1; 0 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1))

##X#####
###\####
###|####
###|####
##/#####
#/######
#|######
##\#####

f ((41 27 38; 12 83 32; 50 53 35; 46 32 26; 55 89 82; 75 30 87;  2 11 64;  8 55 22)
   (56 21  0; 83 25 38; 43 75 63; 56 60 77; 68 55 89; 99 48 67; 94 30  9; 62 62 58)
   (23 18 40; 24 47 61; 96 45 72; 71  6 48; 75 63 98; 93 56 51; 23 31 30; 49 34 99)
   (20 47 42; 62 79 72; 32 28 44; 68 61 55; 62 39 57;  4 17 49; 97 85  6; 91 18 12)
   (51 50 11; 32 39 56; 12 82 23; 33 88 87; 60 55 22; 29 78 14; 70 11 42; 63 94 67)
   (75 64 60; 27 79 86; 70 72 56; 55 45 32; 95 67 12; 87 93 98; 81 36 53; 38 22 93)
   (31 80 50; 77 71 22; 59 46 86; 64 71 53; 41 19 95; 62 71 22; 92 80 41; 26 74 29))

######X#
#####/##
####/###
#####\##
######\#
######|#
######|#
#######\

คำอธิบาย

เพื่อวัตถุประสงค์ที่ไม่ดีเราจะทำการทดสอบครั้งที่สอง (เมทริกซ์ ((41 27 38; 12 83 32; .... ))

เราเปลี่ยนเมทริกซ์ดั้งเดิม (m ที่ระดับรหัส): แทน orginimal matriz ด้วย triplet สำหรับแต่ละพิกัดเรากำหนดเมทริกซ์สำหรับการเลื่อนขึ้นซ้ายขึ้นและขวา เมทริกซ์ด้านซ้ายมีค่า 7x7 (เราเลื่อนคอลัมน์แรก) ขึ้นเมทริกซ์ 7x8 และเมทริกซ์ด้านขวา 7x7 (เรา frop คอลัมน์สุดท้าย)

left                           up                         right
12 50 46 55 75 2  8       27 83 53 32 89 30 11 55     38 32 35 26 82 87 64
83 43 56 68 99 94 62      21 25 75 60 55 48 30 62     0  38 63 77 89 67 9 
24 96 71 75 93 23 49      18 47 45 6  63 56 31 34     40 61 72 48 98 51 30
62 32 68 62 4  97 91      47 79 28 61 39 17 85 18     42 72 44 55 57 49 6 
32 12 33 60 29 70 63      50 39 82 88 55 78 11 94     11 56 23 87 22 14 42
27 70 55 95 87 81 38      64 79 72 45 67 93 36 22     60 86 56 32 12 98 53
77 59 64 41 62 92 26      80 71 46 71 19 71 80 74     50 22 86 53 95 22 41

ในการคำนวณตำแหน่งสุดท้ายเราจำเป็นต้องประเมินเส้นทางต้นทุนต่ำสุด เราคิดค่าใช้จ่ายเริ่มต้น 0 0 0 0 0 0 0 0 (ค่าใช้จ่ายที่จะมาถึงในแต่ละแถวของแถวแรก) และทำซ้ำกับแต่ละแถวถัดไป ในแต่ละคอลัมน์ i เราจะคำนวณค่าสามค่า:

  • ค่าใช้จ่ายของค่า i + 1 ก่อนหน้าบวกค่าทางซ้าย [i + 1] เราวางองค์ประกอบแรกของต้นทุน (กะและกำหนดคอลัมน์เพื่อเพิ่ม) และรวมองค์ประกอบกับส่วนประกอบ

  • ค่าใช้จ่ายของค่า i ก่อนหน้าบวกขึ้น [i] เรารวมองค์ประกอบกับส่วนประกอบ

  • ค่าใช้จ่ายของค่า i-1 ก่อนหน้าบวกค่า [i-1] เราวางองค์ประกอบสุดท้ายของต้นทุน (กะและกำหนดคอลัมน์เพื่อเพิ่ม) และรวมองค์ประกอบกับส่วนประกอบ

ในการคำนวณขั้นต่ำเราดำเนินการต้นทุนด้านซ้ายให้เสร็จสิ้นโดยไม่ จำกัด และเพิ่มต้นทุนต่อท้ายแบบไม่มีที่สิ้นสุด: ด้วย 3 เวกเตอร์ของแปดองค์ประกอบให้คำนวณส่วนประกอบขั้นต่ำไปยังส่วนประกอบ ค่าผลลัพธ์คือต้นทุนพื้นฐานสำหรับการวนซ้ำใหม่

สำหรับการคำนวณซ้ำครั้งแรกเราจะได้ค่า (0W ไม่มีที่สิ้นสุดใน Q)

0W 12 50 46 55 75 2  8
27 83 53 32 89 30 11 55
38 32 35 26 82 87 64 0W

และคำนวณขั้นต่ำของแต่ละคอลัมน์

27 12 35 26 55 30 2 8

หลังจากการทำซ้ำทั้งหมดเรามีค่าใช้จ่ายขั้นต่ำที่จะมาถึงแต่ละตาราง (สมมติว่าแถว 0 อยู่ด้านบนสุด 7 ที่ด้านล่าง) เราสนใจเฉพาะคอลัมน์สุดท้าย แต่ฉันวาดผลลัพธ์ระดับกลางทั้งหมดเพื่อวัตถุประสงค์เชิงลบ

0   0   0   0   0   0   0   0
27  12  35  26  55  30  2   8
27  37  78  82  110 78  11  70
45  61  123 88  173 129 34  104
87  123 151 143 212 133 40  122
98  155 163 176 234 147 51  185
158 182 219 208 246 234 87  207
208 204 265 261 265 256 128 233

ตอนนี้เราพบค่าต่ำสุดที่แถวสุดท้าย (128, ที่คอลัมน์ 6) นั่นคือจุดสิ้นสุดของเส้นทาง (อักขระ X เป็น ouput)

เราทำการคำนวณต้นทุนซ้ำอีกครั้ง แต่ตอนนี้เราเพิ่มคำอธิบายทิศทางจากที่เราได้รับแต่ละค่าต่ำสุด (ซึ่งมี 3 ค่าที่ใช้ในการคำนวณขั้นต่ำคือค่าที่เลือก)

\|/|\///
\\\\\/|/
\\\|//|/
\\|\//|/
\\|//|\/
\\//|\|/
\|/|/|\/

เราย้อนกลับแถววาง 'X' ที่ pos 6 และเก็บรักษาเฉพาะเส้นทางที่สิ้นสุดที่คอลัมน์ 6 (ส่วนที่เหลือถูกแทนที่ด้วย #)

######X#
#####/##
####/###
#####\##
######\#
######|#
######|#
#######\

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