巫师的法术书


10

编辑我以前没有玩过D&D,所以当我最初提出这个问题时,我没有进行适当的研究。对此我深表歉意,我正在做一些修改,这些修改可能会使答案无效,以使它们尽可能完全符合dnd 5e规则。抱歉。


最近的热门网络问题中的D&D爱好者似乎在确定巫师选择的咒语是否与可能性相符时遇到了一些麻烦-我想我们应该提供帮助!

介绍

(所有这些已经在前面提到的问题中进行了描述)

巫师从开始就知道两个1级法术(1级): [1, 1]

  • 每次巫师获得一个等级(除了等级12、14、16、18、19和20),他们都会学习一个新的法术(强制性)。

  • 此外,升级时,可以选择(可选)其中一个咒语替换为另一个。

学习和替换的法术必须是有效的法术槽位,是你巫师等级的一半。见下表:

Sorcerer level  Highest spell level possible
1               1
2               1
3               2
4               2
5               3
6               3
7               4
8               4
9               5
10              5
11              6
12              6
13              7
14              7
15              8
16              8
17              9
18              9
19              9
20              9

这意味着在3级时,可以具有如下的咒语等级[1, 1, 2, 2]

Level 1: [1, 1] (initial)
Level 2: [1, 1, 1 (new)]
Level 3: [1, 1, 2 (replaced), 2 (new)]

不需要选择您可以访问的最高级别的咒语。

咒语等级[1, 1, 1, 1]对于等级3完全有效。

最后,请记住,替换咒语是每个级别的可选选项。这意味着某些级别可以跳过替换,而其他级别则可以使用它。

挑战

编写一个程序或函数,其值在1到20之间。

它还应采用整数(咒语级别)数组,其值的范围为1到9(任意顺序)(最大咒语级别为9)。

程序的输出应为真/假值,以验证所选法术等级对于给定等级的巫师是否有效。

测试用例

Level: 1
Spells: [1, 1]
Output: true

Level: 8
Spells: [1, 1, 2, 3, 3, 5]
Ouput: false

Reason: A level 8 can't ever have access to a level 5 spell.

Level: 5
Spells: [1, 1, 1, 2, 2, 2, 3]
Output: false

Reason: A level 5 can't have access to 7 spells

Level: 11
Spells: [3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6]
Output: false

Reason: Too many spell upgrades.
        The highest valid selection for level 11 is
        [3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6]

这是 -最少的字节数获胜!


1
我们可以按照所需的方式对咒语列表进行排序吗?
Veskah

每个课程等级的最大法术等级是多少?
Nitrodon '18

@Nitrodon我认为19?
Don Thousand

@Nitrodon,假设数组输入只能包含“ 1到9范围内的值 ”,则假定为9,但我们需要处理的最大拼写级别应在规范中更明确地说明。它可以使用更多的测试用例。很好的挑战,否则。
粗野的

4
1.“还应该采用整数数组(法术等级),值的范围是1到9(以任何顺序)”-10-19级如何?2.“但是在第4级,该咒语级别[2,2,3,3]是不可能的,因为与该级别的巫师相比,它需要更多的替换。” -列表长度为4而不是5的事实不是这里更根本的原因吗?(我认为[1,3,2,2,3]从4级[1,1,2(replaced),2(new)]到3级有可能达到4级[1,3(replaced),2,2,3(new)]
乔纳森·艾伦

Answers:


5

Java(JDK 10),191字节

L->S->{int m[]=new int[9],z=0,Z=0,l=0;for(m[0]++;l++<L;z+=--m[z]<1?1:0)m[Z=~-l/2-l/19]+=l<12?2:l>17?1:1+l%2;l=0;for(int s:S){if(--s>Z)l++;Z-=--m[Z>0?Z:0]<1?1:0;}for(int i:m)l|=i;return l==0;}

在线尝试!

  • 输入要求:咒语列表必须从最大的咒语等级到最低的咒语等级排序。

说明

L->S->{                                        // Curried-lambda with 2 parameters: sorcerer-level and spell list
 int m[]=new int[9],                           // Declare variables: m is the max level  of each spell.
     z=0,                                      // z is the minimum spell level of the maximized spell list.
     Z=0,                                      // Z is the maximum spell level for the current level.
     l=0;                                      // l is first a level counter, then a reused variable
 for(m[0]++;l++<L;z+=--m[z]<1?1:0)             // for each level, compute the maximized known spells.
  m[Z=~-l/2-l/19]+=l<12?2:l>17?1:1+l%2;        // 
                                               // Now m is the row for level L in the table below.
 l=0;                                          // l now becomes an error indicator
 for(int s:S){                                 // This loop checks if the spell-list matches the spells allowed for that level.
  if(--s>Z)l++;                                // Spell-levels are 1-based, my array is 0-based so decrease s.
  Z-=--m[Z>0?Z:0]<1?1:0;                       // Remove a max level if we've expleted all the spells, avoiding exception.
 }                                             //
 for(int i:m)l|=i;                             // Make sure there are no more values in m.
 return l==0;                                  // Return true if no miscount were encountered.
}

表1:根据关联问题的Axoren答案,使用了每个巫师级别的最大法术分布。

在此处输入图片说明

学分


1
return l<1&java.util.Arrays.equals(m,new int[9]);可以z=0;for(int i:m)z+=i;return l+z==0;代替。或者,如果in中的值最后m不能永远为负,==0则可以为<1
凯文·克鲁伊森

@KevinCruijssen谢谢!这就留出了修复列表中包含太多咒语的错误的空间。
奥利维尔·格雷戈雷

啊,for(int i:m)l|=i;更聪明!好一个。
凯文·克鲁伊森

我确定最后两个循环可以合并,但我不知道现在如何。
奥利维尔·格雷戈雷18'Sep

1
@CameronAavik您可能以数字升序(new int[]{5,6,6,6,7,7,7,8,8,8,9,9,9,9,9})传递了它。如果我将它们降序输入(new int[]{9,9,9,9,9,8,8,8,7,7,7,6,6,6,5}如我在高尔夫球下面写的输入要求中所述),则它可以工作。我添加了测试用例以表明它确实有效。
奥利维尔·格雷戈雷

2

Python 3,98字节

v=lambda L,S:(max(S)*2-2<L)&v(L-1,[1]+sorted(S)[:(chr(L*3)in'$*069<')-2])if L>1else(1,1)==tuple(S)

在线尝试!

取消高尔夫:

def v(L, S):
    # recursion base case
    if L <= 1:
        return tuple(S) == (1, 1)
    # if the highest level skill is not valid for the level, then return False.
    if max(S)*2 - 2 < L:
        return False
    # hacky way to determine if the level gets a new skill
    has_new_skill = chr(L*3) in '$*069<'
    sorted_skills = sorted(S)
    # this step removes the highest skill and adds a level 1 skill (replacement)
    # if there is a new skill, then it removes the second highest skill as well
    new_skills = [1] + sorted_skills[:has_new_skill - 2]
    return v(L-1, new_skills)

编辑:更正了解决方案,以使用正确的D&D规则


我+1了,尽管print(v(20, [6,6,6,6,7,7,7,8,8,8,9,9,9,9,9])) # False打印正确。它应该打印为false。
奥利维尔·格雷戈尔(OlivierGrégoire)

@OlivierGrégoire我正在使用OP的规则来确定所提供的代码中有效的技能水平。请参阅文章底部的注释,该注释显示了为使用实际DnD规则所做的修改。
卡梅伦·阿维克

哦,我的坏。抱歉。更改后输出正确。
奥利维尔·格雷戈尔(OlivierGrégoire)

好了,这已经解决了:需要应用D&D规则,而不是min(9,n-1)一个。
奥利维尔·格雷戈雷

1

木炭,51字节

Nθ≔⁺✂⭆”)⊟⊞<⁴H”×IκIιθ⎇‹θ¹²⊕⊗θ⁺⁶⁺θ⊘⁺‹θ¹⁹θ¹0θ¬ΣES›ι§θκ

在线尝试!链接是详细版本的代码。以字符串的升序顺序获取咒语等级。说明:

Nθ

输入水平。

≔⁺✂⭆”)⊟⊞<⁴H”×IκIιθ⎇‹θ¹²⊕⊗θ⁺⁶⁺θ⊘⁺‹θ¹⁹θ¹0θ

串上执行运行长度译码0544443335得到的字符串中11111222233334444555566677788899999。然后对字符串进行切片,从级别(1索引)开始,以两倍级别(如果小于12)或6 + 1.5 *结束,四舍五入,但级别19向下舍入。0后缀A 以确保没有太多的咒语。

¬ΣES›ι§θκ

将拼写级别与子字符串进行比较,-如果都不过度,则显示。


我认为这失败的长度少于必须的长度,因为我认为在未列出的水平上拼写是必不可少的。我已经要求澄清。
乔纳森·艾伦

由于没有可选升级,因此似乎11113在级别上4也失败了,级别12,1级别3和3级别4
Jonathan Allan

@JonathanAllan您的最大法术等级是角色等级一半的上限(或9,因为这是最大可能的上限)。也许这个问题并不清楚。
尼尔

(基本上,我遵循链接的问题的答案,知道可能的咒语等级是多少。)
Neil

我不想尝试理解和协调两个规范,OP已在评论中确认了min(9,n-1)。也许在那里查询...
Jonathan Allan '18

0

JavaScript(ES6),79个字节

(level)(array)01

l=>a=>!a.some(x=>x>(j--,++l>30?9:l+(l<25?2:4)>>2),j=l<12?l:l>16?14:l+11>>1)&!~j

在线尝试!

测试码

下面是一些测试代码的链接,这些测试代码使用与上述函数相同的逻辑,将巫师级别作为输入并返回最大拼写级别的数组。

在线尝试!

怎么样?

参考表

 Sorcerer level | # of spells | Maximum spell levels          
----------------+-------------+-------------------------------
        1       |      2      | 1,1                           
        2       |      3      | 1,1,1                         
        3       |      4      | 1,1,2,2                       
        4       |      5      | 1,2,2,2,2                     
        5       |      6      | 2,2,2,2,3,3                   
        6       |      7      | 2,2,2,3,3,3,3                 
        7       |      8      | 2,2,3,3,3,3,4,4               
        8       |      9      | 2,3,3,3,3,4,4,4,4             
        9       |     10      | 3,3,3,3,4,4,4,4,5,5           
       10       |     11      | 3,3,3,4,4,4,4,5,5,5,5         
       11       |     12      | 3,3,4,4,4,4,5,5,5,5,6,6       
       12       |     12      | 3,4,4,4,4,5,5,5,5,6,6,6       
       13       |     13      | 4,4,4,4,5,5,5,5,6,6,6,7,7     
       14       |     13      | 4,4,4,5,5,5,5,6,6,6,7,7,7     
       15       |     14      | 4,4,5,5,5,5,6,6,6,7,7,7,8,8   
       16       |     14      | 4,5,5,5,5,6,6,6,7,7,7,8,8,8   
       17       |     15      | 5,5,5,5,6,6,6,7,7,7,8,8,8,9,9 
       18       |     15      | 5,5,5,6,6,6,7,7,7,8,8,8,9,9,9 
       19       |     15      | 5,5,6,6,6,7,7,7,8,8,8,9,9,9,9 
       20       |     15      | 5,6,6,6,7,7,7,8,8,8,9,9,9,9,9 

咒语数

LNL

NL={L+1if L<12(L+13)/2if 12L1615if L>16

jNL11

最大法术等级

L1iNLML,ii

ML,i={(L+i+2)/4if L+i<25(L+i+4)/4if 25L+i309if L+i>30

xa


0

Groovy,155个字节

def f(int[]a, int b){l=[1]
b.times{n->l[0]=++n%2?n/2+1:n/2
if(n<18&(n<12|n%2>0))l.add(l[0])
l.sort()}
for(i=0;i<a.size();)if(a[i]>l[i++])return false
true}

生成可能的最佳拼写本,然后检查传递给该方法的拼写本是否更好。

Ungolfed,显式的隐式类型是明确的:

boolean spellChecker(int[] a, int b) {
    // l will be our best possible spellbook
    List<BigDecimal> l = [1]
    b.times { n ->
        n++ // iterate from 1 to b, not 0 to b-1
        l[0] = n % 2 != 0 ? n / 2 + 1 : n / 2 // update the lowest value to the best permitted
        if (n < 18 & (n < 12 | n % 2 > 0))
            l.add(l[0]) // if permitted, add another best spell
        l.sort() // ensure 0th position is always worst, ready for updating next loop
    }
    for (int i = 0; i < a.size(); i++)
        if (a[i] > l[i]) // if the submitted spell is of a higher level
            return false // also rejects when l[i] is undefined. (too many spells)
    return true
}

在线尝试!

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.