สกาลา , 764 ไบต์
object B{
def main(a: Array[String]):Unit={
val v=false
val (m,l,k,r,n)=(()=>print("\033[H\033[2J\n"),a(0)toInt,a(1)toInt,scala.util.Random,print _)
val e=Seq.fill(k, l)(v)
m()
(0 to (l*k)/2-(l*k+1)%2).foldLeft(e){(q,_)=>
val a=q.zipWithIndex.map(r => r._1.zipWithIndex.filter(c=>
if(((r._2 % 2) + c._2)%2==0)!c._1 else v)).zipWithIndex.filter(_._1.length > 0)
val f=r.nextInt(a.length)
val s=r.nextInt(a(f)._1.length)
val i=(a(f)._2,a(f)._1(s)._2)
Thread.sleep(1000)
m()
val b=q.updated(i._1, q(i._1).updated(i._2, !v))
b.zipWithIndex.map{r=>
r._1.zipWithIndex.map(c=>if(c._1)n("X")else if(((r._2 % 2)+c._2)%2==0)n("O")else n("_"))
n("\n")
}
b
}
}
}
มันทำงานอย่างไร
อัลกอริทึมแรกเติมลำดับ 2D ด้วยค่าเท็จ มันกำหนดจำนวนซ้ำ (กล่องเปิด) อยู่บนพื้นฐานของอาร์กิวเมนต์บรรทัดคำสั่งใส่มันจะสร้างเท่าที่มีค่านี้เป็นขอบเขตบน ค่าจำนวนเต็มของการพับนั้นใช้โดยนัยเป็นวิธีการนับจำนวนการวนซ้ำที่อัลกอริทึมควรใช้ ลำดับที่เราเติมไว้ก่อนหน้านี้คือลำดับเริ่มต้นของการพับ สิ่งนี้ใช้ในการสร้างลำดับ 2 มิติใหม่ของค่าเท็จด้วยดัชนีที่ไม่สอดคล้องกัน
ตัวอย่างเช่น,
[[false, true],
[true, false],
[true, true]]
จะกลายเป็น
[[(false, 0)], [(false, 1)]]
โปรดทราบว่ารายการทั้งหมดที่เป็นจริงอย่างสมบูรณ์ (มีความยาวเท่ากับ 0) จะถูกตัดออกจากรายการผลลัพธ์ อัลกอริทึมจะใช้รายการนี้และเลือกรายการสุ่มในรายการนอกสุด รายการแบบสุ่มถูกเลือกให้เป็นแถวแบบสุ่มที่เราเลือก จากแถวสุ่มนั้นเราจะพบตัวเลขสุ่มดัชนีคอลัมน์อีกครั้ง เมื่อเราพบดัชนีสุ่มสองตัวนี้แล้วเราจะนอนด้ายที่เราใช้เป็นเวลา 1,000 มิลลิวินาที
หลังจากที่เรานอนหลับเสร็จแล้วเราจะล้างหน้าจอและสร้างบอร์ดใหม่ที่มีtrue
ค่าอัปเดตในดัชนีสุ่มที่เราสร้าง
ในการพิมพ์ออกมาอย่างถูกต้องเราใช้map
และ zip ด้วยดัชนีของแผนที่เพื่อให้เรามีในบริบทของเรา เราใช้ค่าความจริงของลำดับเป็นไปได้ว่าเราควรจะพิมพ์X
หรืออย่างใดอย่างหนึ่งหรือO
_
ในการเลือกหลังเราใช้ค่าดัชนีเป็นแนวทางของเรา
สิ่งที่น่าสนใจที่ควรทราบ
คิดว่ามันควรจะพิมพ์O
หรือ_
, เงื่อนไข((r._2 % 2) + c._2) % 2 == 0
ถูกนำมาใช้ r._2
อ้างถึงดัชนีแถวปัจจุบันในขณะที่c._2
อ้างอิงถึงคอลัมน์ปัจจุบัน หากมีใครอยู่ในแถวคี่r._2 % 2
จะเป็น 1 ดังนั้นจึงชดเชยc._2
ด้วยหนึ่งในเงื่อนไข สิ่งนี้ทำให้มั่นใจได้ว่าในแถวคี่คอลัมน์จะถูกย้ายไป 1 ตามที่ตั้งใจไว้
การพิมพ์สตริง"\033[H\033[2J\n"
ตามคำตอบ Stackoverflow บางคำตอบที่ฉันอ่านจะล้างหน้าจอ มันเขียนไบต์ไปยังเทอร์มินัลและทำสิ่งที่ขี้ขลาดฉันไม่เข้าใจจริงๆ แต่ฉันพบว่ามันเป็นวิธีที่ง่ายที่สุดที่จะไปเกี่ยวกับเรื่องนี้ แม้ว่ามันจะไม่ทำงานกับโปรแกรมจำลองคอนโซลของ Intellij IDEA คุณจะต้องเปิดใช้งานโดยใช้เครื่องธรรมดา
(l * k) / 2 - (l * k + 1) % 2
สมการอีกคนหนึ่งอาจพบว่าแปลกที่จะเห็นในตอนแรกที่กำลังมองหาที่รหัสนี้ ก่อนอื่นเรามาทำความเข้าใจให้ชัดเจนถึงชื่อตัวแปร l
อ้างถึงอาร์กิวเมนต์แรกที่ส่งเข้าสู่โปรแกรมในขณะที่k
อ้างอิงถึงอาร์กิวเมนต์ที่สอง แปลมัน, (first * second) / 2 - (first * second + 1) % 2
. เป้าหมายของสมการนี้คือหาจำนวนที่แน่นอนของการวนซ้ำที่จำเป็นเพื่อให้ได้ลำดับของ X ทั้งหมด ครั้งแรกที่ฉันทำสิ่งนี้ฉันทำ(first * second) / 2
ตามที่สมเหตุสมผล สำหรับทุกn
องค์ประกอบในแต่ละรายการย่อยมีn / 2
ฟองอากาศที่เราสามารถป๊อปได้ อย่างไรก็ตามสิ่งนี้จะแตกเมื่อจัดการกับอินพุตเช่น(11 13)
. เราต้องคำนวณผลคูณของตัวเลขสองตัวทำให้มันแปลกถ้ามันเป็นเลขคู่และแม้ว่ามันจะเป็นเลขคี่และจากนั้นก็หาค่า mod ของมันด้วย 2 มันใช้ได้เพราะแถวและคอลัมน์ที่คี่จะต้องใช้การวนซ้ำน้อยกว่า เพื่อรับผลสุดท้าย
map
ถูกใช้แทน a forEach
เนื่องจากมีอักขระน้อยกว่า
สิ่งที่อาจปรับปรุงได้
zipWithIndex
สิ่งหนึ่งที่เป็นโรคจิตจริงๆฉันเกี่ยวกับการแก้ปัญหานี้คือการใช้บ่อย มันใช้ตัวละครมากมาย ฉันพยายามที่จะทำให้มันเพื่อที่ฉันจะสามารถกำหนดฟังก์ชั่นตัวละครตัวหนึ่งของตัวเองที่จะดำเนินการzipWithIndex
กับค่าที่ส่งผ่านแต่ปรากฎว่า Scala ไม่อนุญาตให้ฟังก์ชั่นที่ไม่ระบุชื่อมีพารามิเตอร์ประเภท อาจมีวิธีอื่นในการทำสิ่งที่ฉันทำโดยไม่ใช้zipWithIndex
แต่ฉันไม่ได้คิดมากเกี่ยวกับวิธีที่ชาญฉลาดในการทำ
ขณะนี้รหัสทำงานในสองรอบ บอร์ดแรกสร้างบอร์ดใหม่ในขณะที่พาสที่สองพิมพ์ออกมา ฉันคิดว่าหากมีการรวมสองผ่านเหล่านี้เป็นหนึ่งผ่านที่จะบันทึกสองสามไบต์
นี่เป็นกอล์ฟรหัสแรกที่ฉันได้ทำดังนั้นฉันมั่นใจว่ามีพื้นที่มากมายสำหรับการปรับปรุง หากคุณต้องการที่จะเห็นรหัสก่อนที่ฉันจะเพิ่มประสิทธิภาพสำหรับไบต์ให้มากที่สุดที่นี่เป็น
1
และ0
แทนO
และได้X
หรือไม่