你会施法吗?


22

在《魔法:聚会》中,法师(称为“鹏洛客”)通过施展法术相互抗争。法术消耗魔法。存在五种法术力颜色:白色,蓝色,黑色,红色和绿色,分别表示为{W},{U},{B},{R}和{G}。

咒语的费用稍微复杂一些。成本可以是以下各项的任意组合:

  • 一种或多种颜色
  • 一个或多个无色,表示为{X},其中X是一个正整数
  • 一个或多个杂种,表示为{Y / Z},其中Y和Z是一种颜色(由五个字母之一表示)或无色,由一个正整数表示

尝试施放咒语时,以下规则适用:

  • 成本中的一种颜色必须由一种颜色的法术力来满足
  • 无色成本{X}可以由任何颜色的X魔法值来满足
  • 可以通过满足Y或Z来满足混合成本{Y / Z}
    • 请注意,大括号不嵌套
    • Y和Z不混合

编写一个程序或函数,给定一个法术力和一个成本池,当且仅当该池中的法术力可以满足该成本,否则打印或返回true(或某个真实值),否则返回false(或某个虚假值)。

魔力池是以下格式的非空字符串:

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

池中有无色法力值吗?
2015年

@nutki在真实游戏中,是的。在挑战中,没有。针对挑战的目的,仅存在挑战中定义的五种颜色。
2015年

我离开魔术太久了。混合费用?!?
Sparr

2
@Sparr他们是在2005
murgatroid99

@ murgatroid99 6E出来时我辞职了。我的朋友都不愿意适应新规则:(
Sparr,2015年

Answers:


7

Pyth,55 53 52 50字节

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

在线尝试:演示测试工具

注意,时间和内存的复杂性确实很差。因此,第二个示例不起作用。在计算机崩溃之前,我分配了约1.6 GB的Ram。

说明

说明是针对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
允许使用真实和虚假的值,而不仅仅是TrueFalse
isaacg,2015年

您可以通过将赋值插入来保存字符K。把Kc-rz0"{}")这里K是第一次使用,并删除初始分配K
isaacg 2015年

@isaacg哦,应该已经知道了。谢谢。
2015年

@Rainbolt您接受了无效的解决方案。当我发布它时,它很好用,但是Pyth改变了很多。我更新了它,还节省了2个字节。
贾库贝

@Jakube谢谢,但是此答案需要使用发布挑战时可用的解释器来工作,而不是使用一些新的更新的解释器。
Rainbolt

2

Python 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}')prints 1

脱开,基本上看起来像这样

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]))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.