Bạn có thể bỏ bùa không?


22

Trong Magic: the Gathering, các pháp sư (được gọi là "máy bay chiến đấu") chiến đấu với nhau bằng cách sử dụng phép thuật. Phép thuật tốn mana. Năm màu của mana tồn tại: Trắng, Xanh lam, Đen, Đỏ và Xanh lục, tương ứng là {W}, {U}, {B}, {R} và {G}.

Chi phí của một câu thần chú phức tạp hơn một chút. Chi phí có thể là bất kỳ sự kết hợp nào sau đây:

  • Một hoặc nhiều màu
  • Một hoặc nhiều màu không màu, được biểu thị là {X}, trong đó X là số nguyên dương
  • Một hoặc nhiều giống lai, được biểu thị là {Y / Z}, trong đó Y và Z là một màu (được biểu thị bằng một trong năm chữ cái) hoặc không màu, được biểu thị bằng một số nguyên dương

Các quy tắc sau được áp dụng khi cố gắng sử dụng một câu thần chú:

  • Một màu trong chi phí phải được thỏa mãn bởi một mana của màu đó
  • Chi phí không màu {X} có thể được thỏa mãn bởi X mana của bất kỳ màu nào
  • Một chi phí lai {Y / Z} có thể được thỏa mãn bằng cách thỏa mãn Y hoặc Z
    • Lưu ý rằng niềng răng không được lồng
    • Y và Z không lai

Viết chương trình hoặc hàm, được cung cấp một nhóm mana và chi phí, in hoặc trả về giá trị đúng (hoặc một số giá trị trung thực) nếu và chỉ khi mana trong nhóm đó có thể thỏa mãn chi phí, nếu không sai (hoặc một số giá trị giả).

Nhóm mana là một chuỗi không có định dạng:

Color1,Color2,Color3,...,Colorn-1,Colorn

Chi phí là một chuỗi không trống của định dạng:

Cost1,Cost2,Cost3,...,Costn-1,Costn

Ví dụ

Trong định dạng Pool Cost -> ExpectedOutput(có khoảng cách giữa Pool và Chi phí):

{R},{R},{G},{B},{R} {4},{R} -> True
{G},{G},{G},{G},{W},{W},{W} {2/W},{2/U},{2/B},{2/R},{2/G} -> False
{G},{G},{R} {R/G},{G/B},{B/R} -> True
{R},{R},{R},{G} {1},{G},{2/G}-> True
{R} {R},{R},{R},{R},{R} -> False
{W},{R},{R} {2/W},{W/B} -> True
{U},{U} {1} -> True
{W},{R},{G} {1},{2} -> True

Có thể có mana không màu trong hồ bơi?
nutki

@nutki Trong trò chơi thực sự, vâng. Trong thử thách, không. Chỉ có năm màu được xác định trong thử thách tồn tại cho các mục đích của thử thách.
Rainbolt

Tôi đã rời xa ma thuật quá lâu. Chi phí lai?!?
Sparr

2
@Sparr Chúng được giới thiệu ở Ravnica, trở lại năm 2005
murgatroid99

@ murgatroid99 Tôi nghỉ việc khi 6E ra đời. Không ai trong số bạn bè của tôi sẵn sàng thích nghi với các quy tắc mới :(
Sparr

Câu trả lời:


7

Pyth, 55 53 52 50 byte

FN*Fmsm?k}kG^Gvkcd\/ceKc-rz0`Hd\,#=sN)I!.-NhK1B)E0

Dùng thử trực tuyến: Trình diễn hoặc thử nghiệm khai thác

Lưu ý rằng thời gian và bộ nhớ phức tạp là thực sự xấu. Vì vậy, ví dụ thứ hai không hoạt động. Tôi phân bổ khoảng 1,6 GB Ram trước khi nó gặp sự cố trên máy của tôi.

Giải trình

Giải thích cho giải pháp 53. Sự khác biệt duy nhất là, phân tích cú pháp ban đầu xảy ra ở giữa thay vì bắt đầu.

Kc-rz0"{}"dFN*Fmsm?k}kG^Gvkcd\/ceKc-rz0`H\,#=sN)I!.-NhK1B)E0

Vì vậy, đây là phân tích cú pháp ban đầu.

Kc-rz0`Hd
   rz0     convert input() to lowercase
  -   `H   remove all curly brackets (`H = "{}")
 c      d  split at the space
K          assign to K

Vì vậy, đầu vào "{W},{R},{R} {2/W},{W/B}"được chuyển đổi thành ['w,r,r', '2/w,w/b'].

m               ceK\,    map each cost d of the costs split by "," to:
 s                         the sum of
  m         cd\/           map each value k of cost split by "/" to:
    k                        k
   ? }kG                     if k in "abcdef...xyz" else
        ^Gvk                 Cartesian product with "abc...yz" of int(k) repeats

Vậy cái này làm gì? Đầu vào chi phí '2/w,w/b'được chuyển đổi thành:

[['aa', 'ab', 'ac', ..., 'zx', 'zy', 'zz', 'w'], 'wb']

Mỗi chuỗi trong ['aa', 'ab', 'ac', ..., 'zx', 'zy', 'zz', 'w']thỏa mãn {2/W}và mỗi char trong 'wb'thỏa mãn {w/b}.

Bây giờ chúng tôi tạo ra sản phẩm Cartesian của các danh sách này (hoặc chuỗi) và xem, nếu có bất kỳ sự kết hợp nào có thể được tạo ra với mana-pool.

FN*F...              )      for N in Cartesian product of ...:
       #   )                   while 1:
        =sN                      N = sum(N)
                               this flattens N
            I!.-NhK            if not (subtract mana pool from N):
                   1             print 1 (True)
                    B            break
                      E      else:
                       0       print 0 (False)

1
giá trị trung thực và giả mạo được cho phép, không chỉ TrueFalse.
isaacg

Bạn có thể lưu một nhân vật bằng cách nhập vào bài tập K. Đặt Kc-rz0"{}")nơi Kđược sử dụng đầu tiên và xóa nhiệm vụ ban đầu K.
isaacg

@isaacg ơi, lẽ ra đã thấy vậy. Cảm ơn.
Jakube

@Rainbolt Bạn đã chấp nhận một giải pháp không hoạt động. Vâng, nó hoạt động khi tôi đăng nó, nhưng Pyth đã thay đổi rất nhiều. Tôi đã cập nhật nó và cũng lưu thêm 2 byte.
Jakube

@Jakube Cảm ơn, nhưng câu trả lời này cần phải hoạt động bằng cách sử dụng một trình thông dịch có sẵn tại thời điểm thử thách được đăng, chứ không phải một số thông dịch viên cập nhật mới.
Rainbolt

2

Python 2.7, 412 ký tự

import re,collections as C
r,C=re.findall,C.Counter
def g(m,h,c,v):
 try:return t(m,h,c+int(v))
 except:
  if m[v]:return t(m-C({v:1}),h,c)
def t(m,h,c):return any(g(m,h[1:],c,v)for v in h[0].split('/'))if h else sum(m.values())>=c
def f(m,c):m=C(r(r'\w',m));c=[filter(None, x)for x in zip(*r(r'(\w+/\w+)|(\d+)|(\w)',c))];m.subtract(C(c[2]));print all(x>=0 for x in m.values())*t(m,c[0],sum(int(x)for x in c[1]))

Các chức năng flà một trong đó kiểm tra. Nó lấy pool mana và chi phí làm đối số chuỗi, và in 1khi mana thỏa mãn chi phí và mặt 0khác. Ví dụ, f('{R},{R},{G},{B},{R}', '{4},{R}')in 1.

Ungolfed, về cơ bản nó trông như thế này

import re
from collections import Counter
def helper(mana, hybrids, colorless, option):
  try:
    option = int(option) # See if option is an integer
    # For colorless hybrid, just add the value to the colorless amount
    # to check at the end.
    return check_hybrids(mana, hybrids, colorless + option)
  except ValueError: # Option is a mana letter
    # For colored hybrid costs, check if any of that color is
    # available, then try to pay the rest of the cost with 1 less
    # of that color.
    if mana[option] >= 0:
      return check_hybrids(mana - Counter({option: 1}), hybrids, colorless)
    else:
      return False
def check_hybrids(mana, hybrids, colorless):
  '''Check whether the given mana pool can pay the given hybrid costs and colorless costs'''
  if hybrids:
    # For each option in the first hybrid cost, check whether the
    # rest of the cost can be paid after paying that cost
    return any(helper(mana, hybrids[1:], colorless, option) for option in hybrids[0].split('/'))
  else:
    # When there are no remaining hybrid costs, if there is enough
    # remaining mana to pay the colorless costs, we have success
    return sum(m.values()) > colorless
def can_cast(mana_str, cost_str):
  mana = Counter(re.findall(r'\w', mana_str))
  # transpose to get separate lists of hybrid, colorless, and colored symbols
  cost = zip(*re.findall(r'(\w+/\w+)|(\d+)|(\w)',cost_str))
  cost = [filter(None, sublist) for sublist in cost] # Remove unfound symbols
  mana.subtract(Counter(cost[2]))
  # After subtracting the single-colored cost from the mana pool, if
  # anything in the mana pool is negative, we didn't have enough to
  # pay for that color.
  if any(x <=0 for x in mana.values()):
    return False
  return check_hybrids(mana, cost[0], sum(int(x)for x in cost[1]))
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.