เครื่องกำเนิดบัตร Dobble / SpotIt


15

บทนำ

Dobble / SpotItเป็นเกมไพ่ที่ผู้คนต้องมองเห็นสัญลักษณ์เดียวกันบนการ์ดในเวลาอันสั้นระบุและย้ายไปที่คู่ถัดไป การ์ดแต่ละใบมีหลายสัญลักษณ์ (8 ในรุ่นปกติ) แต่มีหนึ่งสัญลักษณ์ที่เหมือนกันระหว่างการ์ดแต่ละคู่

ตัวอย่างจากเกมจริง: การ์ดที่มีตัวอย่างของคู่

ท้าทาย

เขียนโปรแกรมที่ได้รับชุดของสัญลักษณ์ (ตัวอักษร ASCII เดียว) และจำนวนของสัญลักษณ์บนการ์ดใบเดียวจะผลิตบัตรรายการผลลัพธ์ด้วยสัญลักษณ์สำหรับการ์ดแต่ละใบ เห็นได้ชัดว่ามีชุดค่าผสมที่เทียบเท่าจำนวนมากโปรแกรมของคุณต้องเขียนชุดค่าผสมใด ๆ ที่สร้างการ์ดจำนวนมากที่สุดสำหรับอินพุตที่กำหนด

มันเป็นรหัส - กอล์ฟดังนั้นจึงย่อรหัสได้ดีกว่า

มันจะเป็นการดีถ้าการคำนวณจะเสร็จสิ้นก่อนที่ความร้อนจากจักรวาลจะเสียชีวิตสำหรับกรณีที่ซับซ้อนที่สุด

อินพุต

ข้อโต้แย้งสองข้อสำหรับฟังก์ชัน / stdin (ตัวเลือกของคุณ)

  • อันดับแรกคือการรวบรวมสัญลักษณ์บางอย่างเช่น 'ABCDE "หรือ [' A ',' B ',' C ',' D ',' E '] - รูปแบบที่คุณเลือกไม่ว่าจะเป็นสตริงชุดรายการสตรีม หรืออะไรก็ตามที่เป็นสำนวนสำหรับภาษาที่เลือกตัวละครจะได้รับจากชุดของ [A-Za-z0-9] ไม่มีการซ้ำซ้อน (ดังนั้นขนาดสูงสุดของชุดสัญลักษณ์อินพุตคือ 62) พวกเขาจะไม่ได้รับคำสั่งโดยไม่จำเป็น ( เพื่อให้คุณสามารถรับ "yX4i9A" ได้เช่นกันสำหรับตัวอักษร 6 ตัว)

  • อาร์กิวเมนต์ที่สองคือจำนวนเต็มซึ่งระบุจำนวนสัญลักษณ์บนบัตรเดียว มันจะเป็น <= ขนาดของชุดสัญลักษณ์

เอาท์พุต

พิมพ์หลายบรรทัดคั่นด้วยการขึ้นบรรทัดใหม่แต่ละบรรทัดมีสัญลักษณ์สำหรับการ์ดเดี่ยว

ตัวอย่าง

ABC
2
>>>>
AB
BC
AC

หรือ

ABCDEFG
3
>>>>
ABC
BDE
CEF
BFG
AEG
CDG
ADF

หรือ

ABCDE
4
>>>>
ABCD

คำแนะนำ

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

นี่เป็นความท้าทายครั้งแรกของฉันเกี่ยวกับการเล่นกอล์ฟดังนั้นโปรดให้อภัยปัญหาที่อาจเกิดขึ้นกับการจัดรูปแบบ / สไตล์ - ฉันจะพยายามแก้ไขข้อผิดพลาดหากคุณชี้ไปที่ความคิดเห็น



กรณีทดสอบที่แนะนำ('abcdefghijklmnopqrstu', 5)-> ['abcde', 'afghi', 'ajklm', 'anopq', 'arstu', 'bfjnr', 'bgkpt', 'bhlou', 'bimqs', 'cfkqu', 'cgjos', 'chmpr', 'cilnt', 'dfmot', 'dglqr', 'dhkns', 'dijpu', 'eflps', 'egmnu', 'ehjqt', 'eikor']หรือโซลูชันการทำงานของการ์ด 21 ใบอื่น ๆ (โปรดทราบว่านี่คือระนาบ จำกัด projective ของคำสั่ง 4)
Jonathan Allan

คำตอบ:


5

Python 2 , 192 162 ไบต์

ฉันมีข้อโต้แย้งว่าสิ่งนี้สร้างชุดการ์ดสูงสุดสำหรับทุกสถานการณ์และมันจัดการกับกรณีทดสอบ 3 กรณี

from itertools import*
def m(a,s):
    C=["".join(x)for x in combinations(a,s)]
    while len(C):
        print C[0]
        C=list(set(A for A in C if len(set(A)&set(C[0]))==1<s))

ลองออนไลน์!

ขั้นตอนวิธี

กำหนดตัวอักษรaและขนาดการ์ดsใช้sองค์ประกอบทั้งหมดในaและเรียกมันว่าCจากนั้น:

  • ใช้องค์ประกอบแรกของ Cเรียกว่าC0
  • บันทึก C0
  • ลบองค์ประกอบทั้งหมดจากCที่มีการรวมกับC0ไม่เท่ากับ1
  • ทำซ้ำกับองค์ประกอบที่สองของ C
  • ดำเนินการต่อจนกว่าCจะว่างเปล่า

จากนั้นพิมพ์องค์ประกอบที่บันทึกไว้

การโต้เถียง

บางส่วนย่อยที่ไม่ว่างเปล่าของการเป็นวิธีการแก้สูงสุดของเราC Kเพราะมันมีองค์ประกอบอย่างน้อยหนึ่งและสององค์ประกอบจะแยกไม่ออกเลือกองค์ประกอบโดยพลการC0ของที่จะอยู่ในC Kสำหรับองค์ประกอบใด ๆeในK, ความสำคัญของการeรวมxเป็น 1 สำหรับx != eในK; เพื่อกำจัดองค์ประกอบทั้งหมดในCสหภาพที่มีกับC0ไม่มี cardinallity 1 โดยให้เหตุผลเดียวกันเลือกองค์ประกอบโดยพลการใหม่ในการCเพิ่มไปและลดK Cในที่สุดCคือชุดที่ว่างเปล่าและKจะเป็นทางออกที่สูงสุดเพราะเราไม่ได้เลือกองค์ประกอบที่แตกต่างจากองค์ประกอบอื่น ๆ


กรณีทดสอบ

กรณีทดสอบเหล่านี้เขียนขึ้นก่อนที่ฉันจะรู้ว่าการพิมพ์นั้นเป็นข้อกำหนด

a=["a","b","c"]
b=2
c=3
d=m(a,b)
print d,len(d)==c
>> ['bc', 'ab', 'ac'] True

a=["a","b","c","d","e","f","g"]
b=3
c=7
d=m(a,b)
print d,len(d)==c
>> ['aef', 'abc', 'bde', 'ceg', 'adg', 'cdf', 'bfg'] True

a=["a","b","c","d","e"]
b=4
c=1
d=m(a,b)
print d,len(d)==c
>> ['abcd'] True

ปรับปรุง

  • +9 [16-12-07] พอดีกับข้อกำหนดการพิมพ์
  • -11 [16-12-07] อธิบายRตัวแปรของฉัน
  • -30 [16-12-09] อธิบายKตัวแปรของฉันแล้วขอบคุณ@Leo !

1
คุณจำเป็นต้องลบชุด K จาก C ในทุกขั้นตอนหรือไม่? ฉันคิดว่าการกรองที่คุณทำ ( A for A in C if len(set(A)&set(C[0]))==1) ลบองค์ประกอบที่เลือกไว้แล้วยกเว้น s == 1 (ในกรณีนี้ len (set (C [0]) & set (C [0])) จะเป็น 1) คุณสามารถเล่นกอล์ฟสายที่สองถึงบรรทัดสุดท้ายได้ที่:C=[A for A in C if len(set(A)&set(C[0]))==1<s]
Leo

ฉันกำลังเขียนความท้าทาย Dobble ในกล่องทรายและ Dom Hastings ชี้ให้ฉันเห็นว่าคำถามนี้เป็นล่อลวงที่เป็นไปได้ (ซึ่งอาจเป็นไปได้) แต่สิ่งหนึ่งที่ฉันสังเกตเห็นก็คือมันยากกว่ามากที่จะสร้างสำรับ Dobble เต็มรูปแบบของ N * N + N + 1 การ์ด (และสัญลักษณ์) ที่มี N + 1 สัญลักษณ์ต่อการ์ดโดยที่ N เป็นไพรม์พาวเวอร์ สำหรับ N = 4 = 2 ^ 2 นี่จะเป็นสำรับโดยใช้สัญลักษณ์ 4 * 4 + 4 + 1 = 21 และมีจำนวนไพ่เท่ากัน อย่างไรก็ตามวิธีนี้สร้างสำรับไพ่เพียง13 ใบ - แต่เป็นไปได้ 21ข้อ
Jonathan Allan

@JonathanAllan เพิ่งเพิ่มลิงค์ TIO ฉันวิ่งฟังก์ชั่นด้วยตัวอักษร 21 ตัวอักษรและมี 5 ตัวอักษรต่อบัตร มันออก 21 ใบ ฉันคิดว่ามันถูกต้องเว้นแต่ฉันจะเข้าใจผิด
NonlinearFruit

อืมขอโทษฉันต้องทำผิดพลาดบางอย่างในการใช้งานในพื้นที่แล้ว! ( นั่นคือดาดฟ้าเต็ม Dobble ของการสั่งซื้อ 4. :) )
โจนาธานอัลลัน

2

Haskell, 175 156 ไบต์

การเล่นกอล์ฟครั้งแรกของฉันบอกให้ฉันรู้ว่าฉันทำอะไรผิดพลาด

import Data.List
f 0_=[[]]
f n a=g$c n a
c n a=[a!!i:x|i<-[0..(length a)-1],x<-f(n-1)(drop(i+1)a)]
g[]=[]
g(x:t)=x:g(filter(\z->length(z`intersect`x)<= 1)t)

ลองออนไลน์!

ขอบคุณ@Paul Mutserสำหรับการปรับปรุงและ -19 ไบต์


รุ่นเดิม


1
ยินดีต้อนรับสู่ PPCG! โปรดทราบว่าการนำเข้าจะนับรวมกับคะแนนของคุณ การปรับปรุงที่เป็นไปได้: 156 ไบต์รวมถึงการนำเข้า
Paul Mutser

ขอบคุณสำหรับหัวฉันไม่แน่ใจว่าพวกเขาทำ!
ข้อบกพร่อง

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