당신은 주문을 캐스팅 할 수 있습니까?


22

Magic : The Gathering에서 마법사 ( "planeswalkers"라고도 함)는 주문을 시전하여 서로 대결합니다. 주문에는 마나가 소모됩니다. 화이트, 블루, 블랙, 레드, 그린의 5 가지 마나가 각각 {W}, {U}, {B}, {R} 및 {G}로 표시됩니다.

주문의 비용은 약간 더 복잡합니다. 비용은 다음의 조합 일 수 있습니다.

  • 하나 이상의 색상
  • {X}로 표시되는 하나 이상의 무색 (여기서 X는 양의 정수임)
  • {Y / Z}로 표시되는 하나 이상의 하이브리드 (여기서 Y 및 Z는 색상 (5 개의 문자 중 하나로 표시됨)이거나 무색이며 양의 정수로 표시됨)

주문을 시전 할 때 다음 규칙이 적용됩니다.

  • 비용의 색상은 해당 색상의 하나의 마나로 충족되어야합니다.
  • 무색의 비용 {X}는 모든 색상의 X 마나로 충족 될 수 있습니다
  • Y 또는 Z를 만족시킴으로써 하이브리드 비용 {Y / Z}를 만족시킬 수있다
    • 중괄호는 중첩되지 않습니다.
    • Y와 Z는 하이브리드가 아닙니다

풀의 마나와 비용이 주어지면 해당 풀의 마나가 비용을 충족시킬 수있는 경우에만 참 (또는 일부 진실한 값)을 인쇄하거나 반환하는 프로그램이나 함수를 작성하고 그렇지 않으면 거짓 (또는 거짓 값)을 작성하십시오.

마나 풀은 비어 있지 않은 문자열 형식입니다.

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

비용은 비어 있지 않은 문자열 형식입니다.

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

형식 Pool Cost -> ExpectedOutput(풀과 비용 사이에 공백이 있음)으로 :

{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

수영장에 무색 마나가있을 수 있습니까?
nutki

@nutki 실제 게임에서는 그렇습니다. 도전에서 아닙니다. 챌린지에 정의 된 5 가지 색상 만 챌린지 목적으로 존재합니다.
Rainbolt

나는 마술에서 너무 오래 떨어져있었습니다. 하이브리드 비용?!?
Sparr

2
@Sparr 그들은 2005 년에 Ravnica에서 소개되었습니다
murgatroid99

6E가 나오면 종료합니다. 내 친구 중 누구도 새로운 규칙에 기꺼이 적응하지 않았습니다. (
Sparr

답변:


7

Pyth, 55 53 52 50 바이트

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

온라인으로 사용해보십시오 : 데모 또는 테스트 장치

시간과 메모리의 복잡성은 실제로 나쁩니다. 따라서 두 번째 예는 작동하지 않습니다. 내 컴퓨터에서 충돌하기 전에 약 1.6GB의 램을 할당합니다.

설명

53 솔루션에 대한 설명입니다. 유일한 차이점은 초기 구문 분석이 시작 대신 중간에 발생한다는 것입니다.

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

여기에 초기 파싱이 있습니다.

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

따라서 입력 "{W},{R},{R} {2/W},{W/B}"은로 변환됩니다 ['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

그래서 이것은 무엇을 하는가? 비용 입력 '2/w,w/b'은 다음과 같이 변환됩니다.

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

모든 문자열이 ['aa', 'ab', 'ac', ..., 'zx', 'zy', 'zz', 'w']만족 {2/W}되고 모든 문자가 'wb'만족 {w/b}됩니다.

이제 우리는이리스트 (또는 문자열)의 데카르트 곱을 생성하고, 마나 풀로 어떤 조합을 만들 수 있는지 확인합니다.

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
truthy 및 falsy 값이 아니라, 허용 TrueFalse.
isaacg

에 할당하여 문자를 저장할 수 있습니다 K. 넣어 Kc-rz0"{}")위치를 K먼저 사용하고,에 대한 초기 할당을 제거 K.
isaacg

@isaacg 아, 그것을 보았을 것입니다. 감사.
Jakube

@Rainbolt 귀하는 작동하지 않는 솔루션을 수락했습니다. 글을 올렸을 때 효과가 있었지만 Pyth는 많이 바뀌 었습니다. 나는 그것을 업데이트하고 2 바이트를 더 절약했다.
Jakube

@Jakube 감사합니다. 그러나이 답변은 새로운 업데이트 된 통역사가 아닌 챌린지 게시 당시에 사용 가능한 통역사를 사용하여 작동해야합니다.
Rainbolt

2

파이썬 2.7, 412 자

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]))

기능 f은 점검을 수행하는 기능 입니다. 그것은 마나 풀과 비용을 문자열 인수로 취하고 마나가 비용을 1만족시킬 때 인쇄합니다 0. 예를 들어 f('{R},{R},{G},{B},{R}', '{4},{R}')인쇄합니다 1.

Ungolfed, 기본적으로 다음과 같습니다

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]))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.