เห็นภาพคณะกรรมการนิ่มเหมือนผู้เชี่ยวชาญ


10

พื้นหลัง

ในเกมของ Nimผู้เล่นเลือกที่จะลบ "หิน" จาก "กอง": ในแต่ละเทิร์นผู้เล่นจะต้องลบระหว่างหนึ่งและหินทั้งหมดจากกองเดียว เป้าหมายของ Nim คือการเอาหินก้อนสุดท้ายออกมาหรือในตัวแปรที่ผิดประเภทเพื่อบังคับให้คู่ต่อสู้ทำเช่นนั้น - อย่างไรก็ตามมันกลับกลายเป็นว่ากลยุทธ์นั้นเหมือนกันเกือบทั้งหมด

นิ่มทำให้เกมบาร์สนุก คุณสามารถใช้ไม้ขีดไฟหรือเหรียญสำหรับ "หิน" และ "กอง" โดยทั่วไปจะจัดเรียงเป็นเส้น ด้านล่างเป็นการตั้งค่าแบบคลาสสิกที่มี 1, 3, 5 และ 7:

นิ่มด้วยไม้ขีดไฟ

หากคุณไม่เคยเล่น Nim มาก่อนคุณอาจลองใช้มือลองดูก่อนที่จะลองทำสิ่งนี้ ต่อไปนี้เป็นรุ่นที่เรียกว่า "ไข่มุกก่อนสุกร"

กลยุทธ์

กลยุทธ์ที่ดีที่สุดในนิ่มก็พอหากินที่วางคนส่วนใหญ่สูญเสียอย่างต่อเนื่องกับผู้เชี่ยวชาญ แต่ง่ายที่จะอธิบายกับเลขคณิตไบนารี

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

มีสามขั้นตอนเท่านั้น:

  1. จัดกลุ่ม "ก้อนหิน" ทางจิตใจในแต่ละบรรทัดเป็นกลุ่มย่อยที่มีขนาดเป็นพลังของ 2 เริ่มต้นด้วยขนาดที่ใหญ่ที่สุดที่เป็นไปได้: 8, 4, 2 และ 1 เพียงพอสำหรับเกมส่วนใหญ่
  2. ลองจับคู่แต่ละกลุ่มกับคู่ในบรรทัดอื่นเพื่อให้ทุกกลุ่มมีคู่
  3. หากไม่สามารถทำได้ให้ลบ "หิน" ที่ไม่ได้รับการจับคู่ออกจากบรรทัดเดียว (สิ่งนี้จะเป็นไปได้เสมอ - ดูที่ลิงค์ Wikipedia สำหรับสาเหตุ) เพื่อให้ขั้นตอนที่ 2 เป็นไปได้

หรือกล่าวอีกวิธีหนึ่งว่า: "เอาหินบางอันออกจากกองเดียวเช่นถ้าคุณจัดกลุ่มกองไว้เป็น 2 กลุ่มทุกกลุ่มอาจถูกจับคู่กับกลุ่มในกองอื่น" ด้วยข้อแม้ที่คุณไม่สามารถแยกพลังที่ใหญ่กว่าของ 2 เป็นอันที่เล็กลงได้ - เช่นคุณไม่สามารถจัดกลุ่มบรรทัดที่มี 8 ก้อนหินเป็นสองกลุ่ม 4 กลุ่ม

ตัวอย่างเช่นนี่คือวิธีที่คุณเห็นภาพกระดานด้านบน:

ไม้ขีดไฟที่สมดุล

กระดานนี้มีความสมดุลอย่างสมบูรณ์แบบดังนั้นคุณต้องการให้คู่ต่อสู้ของคุณเคลื่อนที่ก่อน

ความท้าทาย

รับรายการจำนวนเต็มบวกที่แทนขนาดของ "กอง" ของ Nim แล้วส่งคืนการสร้างภาพข้อความธรรมดาของคณะกรรมการ Nim ตามที่ผู้เชี่ยวชาญเห็น

ตัวอย่างที่อธิบายว่าการสร้างภาพข้อมูลที่ถูกต้องดีที่สุดอย่างไร แต่คุณต้อง:

  1. กำหนดอักขระที่แตกต่างให้กับแต่ละกลุ่มย่อย "power-of-2" และคู่ของมัน (กลุ่มย่อยที่ไม่ได้เข้าคู่จะไม่มีคุณสมบัติ) และใช้อักขระนั้นเพื่อเป็นตัวแทนของ "สโตน" ในทั้งกลุ่มย่อยและคู่
  2. แทน unpaired "หิน" ใด ๆ (เช่นคนที่มีความเชี่ยวชาญจะเอาเมื่อเล่นปกติ - ไม่ misere - สะเดา) -โดยใช้ยัติภังค์:

จะมีหลายวิธีในการสร้างภาพข้อมูลที่ถูกต้องและทั้งหมดนั้นถูกต้อง มาทำงานในกรณีทดสอบบ้าง:

กรณีทดสอบ

อินพุต: 1, 3, 5, 7

เอาต์พุตที่เป็นไปได้ 1:

A
BBA
CCCCD
CCCCBBD

คุณอาจเลือกที่จะรวมช่องว่างระหว่างตัวละครเช่นเดียวกับบรรทัดว่างระหว่างแถว:

เอาต์พุตที่เป็นไปได้ 2:

A

B B A

C C C C D

C C C C B B D

อินพุต: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

ลำดับและตัวเลือกของตัวละครอาจเป็นสิ่งที่คุณต้องการ:

เอาต์พุตที่เป็นไปได้ 1:

G
E E
E E G
C C C C
C C C C F
B B B B D D
B B B B D D F
H H I - - - - -
A A A A A A A A I
A A A A A A A A H H

สัญลักษณ์ Unicode ก็โอเคเช่นกัน:

เอาต์พุตที่เป็นไปได้ 2:

◎
◈  ◈
◈  ◈  ◎
△  △  △  △
△  △  △  △  ◉
◐  ◐  ◐  ◐  ◀  ◀
◐  ◐  ◐  ◐  ◀  ◀  ◉
▽  ▽  ◒  -  -  -  -  -
▥  ▥  ▥  ▥  ▥  ▥  ▥  ▥  ◒ 
▥  ▥  ▥  ▥  ▥  ▥  ▥  ▥  ▽  ▽  

อินพุต: 7

จากกฏจะเป็นไปตามที่ "กองเดียว" จะต้องถูกลบออก

เอาต์พุตที่เป็นไปได้ 1:

-------

เอาต์พุตที่เป็นไปได้ 2:

- - - - - - -

อินพุต: 5, 5

เอาต์พุตที่เป็นไปได้:

A A A A B
A A A A B

กฎเพิ่มเติม

  • นี่คือรหัสกอล์ฟที่มีกฎมาตรฐาน รหัสที่สั้นที่สุดชนะ
  • การป้อนข้อมูลมีความยืดหยุ่นและอาจถูกนำมาใช้ในรูปแบบ list-ish ที่สะดวกสำหรับคุณ
  • เอาต์พุตก็มีความยืดหยุ่นเช่นกันดังตัวอย่างด้านบน รูปแบบที่เหมาะสมที่สุดจะได้รับอนุญาต ถามว่าคุณไม่แน่ใจเกี่ยวกับบางสิ่ง

1
มีการ จำกัด จำนวนกองหินแต่ละกองหรือไม่หรือจำเป็นต้องใช้อักขระที่แตกต่างกันจำนวนมากในการสร้างภาพข้อมูล? (ในกรณีที่สุดขีดตัวอย่างเช่นถ้าต้องการจำนวนอักขระ ASCII ที่พิมพ์ได้มากกว่าจำนวนที่ต้องการหรือมากกว่า 255 อักขระที่แตกต่างกัน)
Doorknob

@Doorknob คุณสามารถสันนิษฐานได้ว่าจะไม่เกิดขึ้น คุณสามารถสันนิษฐานได้ว่าตัวอักษรของตัวอักษรจะเพียงพอสำหรับการป้อนข้อมูลใด ๆ
Jonah

@Jonah นี้จะเป็นผลลัพธ์ที่ถูกต้องสำหรับกรณีทดสอบที่สอง? ["H","EE","EEH","CCCC","CCCCI","DDDDFF","DDDDFFI","AAAAAAAA","AAAAAAAA-","----------"]
ngn

1
@ Οurousฉันคิดว่าคำตอบง่ายๆใช่ ในทางเทคนิคAAAABBBBแล้วมันไม่ถูกต้องและABBไม่ใช่ - แต่มันทำให้อ่านง่ายกว่าดังนั้นฉันคิดว่าการลดลงภายในบรรทัดเป็นกฎที่ชัดเจนที่สุด
Jonah

1
@JanathanAllan ใช่ฉันพึ่งตรรกะที่ทั้ง 3 ขั้นตอนจะต้องเกิดขึ้นพร้อมกัน ดังนั้นถ้าคุณทำตามขั้นตอนที่ 1 และ 2 แต่ไม่สามารถทำตามขั้นตอนที่ 3 ได้คุณจะต้องปรับเปลี่ยนโซลูชันของคุณเป็นขั้นตอนที่ 1 และ 2 ซึ่งฉันเห็นว่าสับสน ฉันได้เพิ่มคำอธิบายของคุณด้านล่าง
Jonah

คำตอบ:


2

ทับทิม, 169 164 148 ไบต์

->a{s=eval a*?^
c=?@
m={}
a.map{|x|z=x-(x^s);[$><<?-*z,x-=z,s=0]if z>0
n=1
eval'x&1>0?[$><<(m[n]||c.next!)*n,m[n]=!m[n]&&c*1]:0;n*=2;x/=2;'*x
puts}}

ลองออนไลน์!

อันดับแรกเราเริ่มต้น

  • nim-sum ด้วยs=eval a*?^(ซึ่งสั้นกว่าa.reduce:^)
  • ตัวแปรcซึ่งเก็บอักขระเฉพาะที่ไม่ได้ใช้แรก
  • แผนที่mที่แม็พความยาวของกำลังสองกับอักขระที่ใช้เพื่อแสดง

จากนั้นวนรอบแต่ละกองเราเรียกใช้สิ่งต่อไปนี้:

z=x-(x^s);[$><<?-*z,x-=z,s=0]if z>0

ตามกลยุทธ์ของวิกิพีเดียหากกอง XORน้อยกว่ากองเราควรลบก้อนหินออกจากเสานั้น โดยการเก็บความแตกต่างในตัวแปรzเราสามารถทดสอบเพื่อดูว่าความแตกต่างนี้เป็นค่าบวกหรือไม่และถ้าเป็นเช่นนั้น 1. ) พิมพ์เครื่องหมายขีดกลางจำนวนมาก 2) ลบออกจากกองและ 3) ตั้งค่าตัวแปร nim-sum เป็น ศูนย์เพื่อป้องกันการกำจัดหินเพิ่มเติม

n=1
eval'[...];n*=2;x/=2;'*x

ตอนนี้เรา "ห่วง" มากกว่ากันบิตและติดตามค่าของพวกเขาด้วยซ้ำหารxโดย2และคูณสะสมโดยn 2จริง ๆ แล้วการวนรอบนั้นเป็นสตริงที่ประเมินxเวลาซึ่งมีค่ามากกว่าlog2(x)เวลาที่จำเป็น แต่ไม่มีอันตรายใด ๆ (นอกเหนือจากความไร้ประสิทธิภาพ) สำหรับแต่ละบิตเราเรียกใช้สิ่งต่อไปนี้ถ้าบิตเป็น 1 ( x&1>0):

$><<(m[n]||c.next!)*n

พิมพ์ตัวละครnครั้ง หากเราพิมพ์กลุ่มของหินจำนวนมากที่ไม่มีคู่นี้ให้ใช้ตัวละครนั้น มิฉะนั้นให้ใช้อักขระที่ไม่ได้ใช้งานถัดไป (เลื่อนcตำแหน่งเนื่องจาก!)

m[n]=!m[n]&&c*1

หากm[n]มีอยู่ (เช่นเราเพิ่งทำคู่เสร็จ) m[n]จะถูกรีเซ็ต มิฉะนั้นเราเพิ่งเริ่มคู่ใหม่ดังนั้นตั้งค่าm[n]เป็นตัวละครที่เราใช้ ( *1เป็นวิธีสั้น ๆ ในการทำสำเนาc)


4

Python 2 , 150 196 206 ไบต์

def f(p):
 c=48;s=[l*'.'for l in p];m=2**len(bin(l))
 while m:
  if sum(m*'.'in l for l in s)>1:
   for i,l in enumerate(s):s[i]=l.replace('.'*m,chr(c)*m,`s`.count(chr(c)*m)<2)
   c+=1
  else:m/=2
 return s

ลองออนไลน์!


4, 9, 10ฉันไม่คิดว่างานนี้สำหรับ
Neil

@Neil จับที่ดีควรได้รับการแก้ไขในขณะนี้
TFeld

1
14, 21, 35ขออภัยฉันจัดการเพื่อหลอกอีกครั้งคราวนี้ด้วย
Neil

นอกจากนี้ยังล้มเหลวสำหรับ [1, 3, 4, 5] ซึ่งควรลบกองที่สองทั้งหมด
Doorknob

@Doorknob นั้นจำเป็นไหม? กฎบอกว่าThere will be multiple ways to achieve a valid visualization, and all are valid
TFeld

1

JavaScript (ES6), 215 ไบต์

f=
(a,c=0,x=eval(a.join`^`),i=a.findIndex(e=>(e^x)<e),b=a.map(_=>``),g=e=>(d=e&-e)&&a.map((e,i)=>e&d&&(a[i]-=d,b[i]=(c++>>1).toString(36).repeat(d)+b[i]))&&g(e-d))=>g(eval(a.join`|`),b[i]='-'.repeat(a[i]-(a[i]^=x)))||b
<textarea oninput=o.textContent=/\d/.test(this.value)?f(this.value.match(/\d+/g)).join`\n`:``></textarea><pre id=o>

มองเห็นเฉพาะอักขระที่แตกต่างกันสูงสุด 36 ตัว 1, 3, 4, 5ฉันรู้สึกโล่งใจงานนี้


ดีจริงๆ. มันสนุกที่จะเล่นกับมันในเวลาจริง
Jonah

1

ทำความสะอาด 454 ไบต์

ยังคงเล่นกอล์ฟ

import StdEnv,Text,Data.List
$p=join"\n"[{#toChar c+'-'\\c<-e}\\e<-[take i(e++[0,0..])\\e<-r[[~c\\c<-reverse e,_<-[1..c]]\\e<-hd[q\\q<-foldr(\h t=[[a:b]\\a<-h,b<-t])[[]][[c\\c<-subsequences(takeWhile((>=)k)(iterate((*)2)1))|sum c<=k]\\k<-p]|sum[1\\a<-q&b<-p|sum a<>b]<2&&foldr(bitxor)0(flatten q)==0]]1&i<-p]]
r[]_=[]
r[h:t]n|all((<)0)h=[h:r t n]
#[m:_]=removeDup[e\\e<-h|e<0]
#(a,[x:b])=span(all((<>)m))t
=r([[if(e==m)n e\\e<-k]\\k<-[h:a]++[x]]++b)(n+1)

ลองออนไลน์!

กำหนดฟังก์ชั่น$ :: [Int] -> Stringการขนาดกองและกลับมาสตริงที่-หินแสดงว่าจะถูกลบออกและกลุ่มโดยมีตัวแทนอักขระ ASCII -ขึ้นจาก หากจำเป็นต้องมีกลุ่มมากพออักขระจะถูกล้อมรอบในที่สุดและเนื่องจากfoldrต้องการหน่วยความจำมากกว่ากิกะไบต์เพื่อเรียกใช้กรณีทดสอบที่สอง

เว้าแหว่งรุ่นยักษ์เข้าใจ:

$p=join"\n"[
    {#
        toChar c+'-'
        \\c<-j
    }
    \\j<-[
        take i(e++[0,0..])
        \\e<-r[
            [
                ~c
                \\c<-reverse e
                ,_<-[1..c]
            ]
            \\e<-hd[
                q
                \\q<-foldr(\h t=[
                    [a:b]
                    \\a<-h
                    ,b<-t
                ])[[]][
                    [
                        c
                        \\c<-subsequences(takeWhile((>=)k)(iterate((*)2)1))
                        |sum c<=k
                    ]
                    \\k<-p
                ]
                |sum[
                    1
                    \\a<-q
                    &b<-p
                    |sum a<>b
                ]<2&&foldr(bitxor)0(flatten q)==0
            ]
        ]1
        &i<-p
    ]
]

แค่อยากรู้อยากเห็น Clean ดูเหมือนคล้ายกับ haskell ... อะไรคือข้อดีของ Haskell
Jonah

1
@ Jonah มันค่อนข้างคล้ายกันใช่ ด้านบนของหัวของฉันมันมีการจัดการประเภทระดับล่าง, อินไลน์ IL / Assembly และการทำงานร่วมกันกับ C ทั้งหมดทำได้ง่ายกว่าด้วย Haskell อย่างไรก็ตามสำหรับการใช้งานจริงเนื่องจากความสับสนและลักษณะการทดลอง / เชิงวิชาการของ Clean ฉันจะแนะนำ Haskell (ซึ่งมีการสนับสนุนเพิ่มเติมในแง่ของห้องสมุดและข้อมูลอ้างอิง) ฉันเพิ่งเกิดขึ้นเช่นเดียวกับคลีนคือทั้งหมด
Junurous
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.