Livro de feitiços de um feiticeiro

10

Edit : Eu não joguei D&D antes, então, quando fiz essa pergunta inicialmente, não a pesquisei adequadamente. Peço desculpas por isso e estou fazendo algumas edições que podem invalidar as respostas para permanecer o mais fiel possível às regras do dnd 5e. Desculpa.


Um fã de D&D de uma pergunta recente da Hot Network parece ter algum problema para descobrir se os feitiços escolhidos por um feiticeiro estão alinhados com as possibilidades - e acho que devemos ajudar!

Introdução

(tudo isso já está descrito na pergunta mencionada anteriormente)

Um feiticeiro conhece duas magias de nível 1 desde o início (nível 1): [1, 1]

  • Toda vez que um feiticeiro ganha um nível (exceto os níveis 12, 14, 16, 18, 19 e 20), ele aprende um novo feitiço (obrigatório).

  • Além disso, ao subir de nível, um pode escolher (opcional) substituir um dos feitiços por outro.

Os feitiços aprendidos e substituídos devem ter um nível válido de slot de feitiço, que é metade do nível do seu feiticeiro arredondado para cima. Veja esta tabela:

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

Isso significa que no nível 3 é possível ter os níveis de feitiço [1, 1, 2, 2]assim:

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

Não é necessário escolher os feitiços de nível mais alto aos quais você tem acesso.

Os níveis de feitiço [1, 1, 1, 1]são perfeitamente válidos para um nível 3.

Por fim, lembre-se de que substituir um feitiço é uma opção opcional para todos os níveis . Isso significa que alguns níveis podem pular a substituição, enquanto outros fazem uso dela.

O desafio

Crie um programa ou função que utilize um número inteiro (nível) entre 1 e 20.

Também deve levar uma matriz de números inteiros (níveis de feitiço) com valores que variam de 1 a 9 em qualquer ordem (9 é o nível máximo de feitiço).

A saída do programa deve ser um valor de verdade / falsidade, validando se os níveis de feitiço escolhidos são válidos para um feiticeiro do nível especificado.

Casos de teste

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]

Isso é - o menor número de bytes vence!

Daniel
fonte
11
Podemos classificar a lista de feitiços como queremos?
Veskah 19/09/18
Qual é o nível máximo de feitiço para cada nível de classe?
Nitrodon
@Nitrodon eu presumo 19?
Don Thousand
@Nitrodon, presumivelmente é 9, dado que a entrada da matriz pode conter apenas " valores que variam de 1 a 9 ", mas o nível máximo de feitiço que precisamos lidar deve ser declarado mais explicitamente na especificação. E isso poderia ter mais alguns casos de teste. Bom desafio, caso contrário.
Shaggy
4
1. "Também deve ser necessário um conjunto de números inteiros (níveis de feitiço) com valores que variam de 1 a 9 (em qualquer ordem)" - e os níveis 10 a 19? 2. "No entanto, no nível 4, os níveis de feitiço [2,2,3,3]não seriam possíveis, pois requer mais substituição do que um feiticeiro desse nível teria acesso." - não é o fato de a lista ter o tamanho 4 e não 5, uma razão mais fundamental aqui? (Suponho que [1,3,2,2,3]é possível para um nível 4, indo do nível 3 [1,1,2(replaced),2(new)]para [1,3(replaced),2,2,3(new)]?)
Jonathan Allan

Respostas:

5

Java (JDK 10) , 191 bytes

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;}

Experimente online!

  • Requisito de entrada: a lista de feitiços deve ser ordenada do maior para o menor.

Explicações

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.
}

Tabela 1: Distribuição maximizada de feitiços para cada nível de feiticeiro, usada na resposta de Axoren na pergunta vinculada .

insira a descrição da imagem aqui

Créditos

Olivier Grégoire
fonte
11
return l<1&java.util.Arrays.equals(m,new int[9]);pode ser em z=0;for(int i:m)z+=i;return l+z==0;vez disso. Ou se os valores em mnunca puderem ser negativos no final, eles ==0podem ser <1.
Kevin Cruijssen 20/09/18
@KevinCruijssen Thanks! E aquela sala com espaço para consertar um bug com muitos feitiços na lista.
Olivier Grégoire
Ah, for(int i:m)l|=i;é ainda mais esperto! Agradável.
Kevin Cruijssen 20/09/18
Tenho certeza de que os dois últimos loops podem ser combinados, mas não sei como agora.
Olivier Grégoire
11
@CameronAavik Você provavelmente passou com números ordenados crescente ( new int[]{5,6,6,6,7,7,7,8,8,8,9,9,9,9,9}). Se eu inseri-los em ordem decrescente ( new int[]{9,9,9,9,9,8,8,8,7,7,7,6,6,6,5}conforme descrito no requisito de entrada que escrevi abaixo do golfe), funcionará. Eu adicionei o caso de teste para mostrar que realmente funciona.
Olivier Grégoire
2

Python 3 , 98 bytes

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)

Experimente Online!

Ungolfed:

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)

edit: solução corrigida para usar regras corretas de D&D

Cameron Aavik
fonte
Marcado com +1, embora seja print(v(20, [6,6,6,6,7,7,7,8,8,8,9,9,9,9,9])) # Falseverdadeiro. Deve imprimir falso.
Olivier Grégoire
@ OlivierGrégoire Estou usando as regras do OP para quais níveis de habilidade são válidos no código fornecido. Veja a nota na parte inferior do post, que mostra a modificação a ser feita para usar as regras reais de DnD.
Cameron Aavik
Oh culpa minha. Desculpa. A saída está correta com essa alteração.
Olivier Grégoire
Bem, está resolvido: é a regra de D&D que precisa ser aplicada, não a regra min(9,n-1).
Olivier Grégoire
1

Carvão , 51 bytes

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

Experimente online! Link é a versão detalhada do código. Toma níveis de feitiço em ordem crescente como uma corda. Explicação:

Nθ

Insira o nível.

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

Execute a decodificação de comprimento de execução na sequência, 0544443335resultando na sequência 11111222233334444555566677788899999. Essa sequência é cortada, começando no nível (indexado 1) e terminando no nível dobrado (se menor que 12) ou 6 + 1,5 *, arredondado para cima, exceto para o nível 19, que é arredondado para baixo. A 0é um sufixo para garantir que não haja muitos feitiços.

¬ΣES›ι§θκ

Compare os níveis de ortografia com a substring e imprima a -se nenhum deles for excessivo.

Neil
fonte
Eu acho que isso falha por muito menos do que deveria, pois acho que a aquisição de feitiços é obrigatória nos níveis não listados; Pedi esclarecimentos.
Jonathan Allan
Também parece falhar para 11113ao nível 4que é o resultado de há atualizações opcionais, tendo 1no nível 2, 1nível 3 e 3, a nível 4.
Jonathan Allan
@ JonathanAllan Seu nível máximo de feitiço é o limite de metade do seu nível de personagem (ou 9, como esse é o máximo possível). Talvez a pergunta não tenha deixado isso claro.
Neil
(Basicamente, eu tenho seguido as respostas na questão ligada a respeito do que os possíveis níveis de magia são.)
Neil
Eu não quero tentar entender e conciliar duas especificações, o OP confirmou min (9, n-1) nos comentários. Talvez consultar esta lá ...
Jonathan Allan
0

JavaScript (ES6), 79 bytes

(level)(array)0 01 1

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

Experimente online!

Código de teste

Abaixo está um link para algum código de teste que leva o nível do feiticeiro como entrada e retorna uma matriz de níveis máximos de feitiço, usando a mesma lógica da função acima.

Experimente online!

Como?

Tabela de referência

 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 

Número de feitiços

euNeu

Neu={eu+1 1E se eu<12(eu+13)/2E se 12eu1615E se eu>16

jNeu-1 1-1 1

Níveis máximos de feitiço

eu1 1EuNeuMeu,EuEu

Meu,Eu={(eu+Eu+2)/4E se eu+Eu<25(eu+Eu+4)/4E se 25eu+Eu309E se eu+Eu>30

xuma

Arnauld
fonte
0

Groovy , 155 bytes

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}

Gera o melhor livro de feitiços possível e depois verifica se o livro de feitiços passado para o método não é melhor.

Sem golfinhos, com tipos implícitos explicitados:

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
}

Experimente online!

archangel.mjj
fonte