El libro de hechizos de un hechicero

10

Editar : no he jugado D&D antes, así que cuando hice esta pregunta por primera vez, no la investigué correctamente. Pido disculpas por esto, y estoy haciendo algunas ediciones que podrían invalidar las respuestas para permanecer lo más fiel posible a las reglas dnd 5e. Lo siento.


Un fanático de D&D de una pregunta reciente de Hot Network parece tener algunos problemas para determinar si los hechizos elegidos de un hechicero se alinean con las posibilidades, ¡y creo que deberíamos ayudar!

Introducción

(todo esto ya se describe en la pregunta mencionada anteriormente)

Un hechicero conoce dos hechizos de nivel 1 desde el principio (nivel 1): [1, 1]

  • Cada vez que un hechicero gana un nivel (excepto los niveles 12, 14, 16, 18, 19 y 20) aprende un nuevo hechizo (obligatorio).

  • Además, al subir de nivel, uno puede elegir (opcional) reemplazar uno de los hechizos por otro.

Los hechizos aprendidos y reemplazados deben ser un nivel de ranura de hechizo válido que sea la mitad del nivel de tu hechicero redondeado. Ver esta tabla:

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

Esto significa que en el nivel 3 se pueden tener niveles de hechizo [1, 1, 2, 2]como este:

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

No es necesario elegir los hechizos de más alto nivel a los que tengas acceso.

Los niveles de hechizo [1, 1, 1, 1]son perfectamente válidos para un nivel 3.

Por último, recuerda que reemplazar un hechizo es una opción opcional para cada nivel . Esto significa que algunos niveles podrían omitir el reemplazo, mientras que otros lo utilizan.

El reto

Haga un programa o función que tome un número entero (nivel) entre 1 y 20.

También debe tomar una serie de enteros (niveles de hechizo) con valores que van del 1 al 9 en cualquier orden (9 es el nivel máximo de hechizo).

La salida del programa debe ser un valor verdadero / falso que valide si los niveles de hechizo elegidos son válidos para un hechicero del nivel dado.

Casos de prueba

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]

Este es el : ¡gana menos bytes!

Daniel
fuente
1
¿Podemos tomar la lista de hechizos ordenada como la queremos?
Veskah
¿Cuál es el nivel máximo de hechizo para cada nivel de clase?
Nitrodon
@ Nitrodon supongo 19?
Don Thousand
@Nitrodon, presumiblemente es 9 dado que la entrada de la matriz solo puede contener " valores que van del 1 al 9 ", pero el nivel máximo de hechizo que debemos manejar debería establecerse más explícitamente en la especificación. Y podría funcionar con un par de casos de prueba más. Buen desafío, de lo contrario.
Shaggy
44
1. "También debería tomar una serie de enteros (niveles de hechizo) con valores que van del 1 al 9 (en cualquier orden)". ¿Qué pasa con los niveles 10-19? 2. "Sin embargo, en el nivel 4, los niveles de hechizo [2,2,3,3]no serían posibles ya que requiere más reemplazo del que tendría acceso un hechicero de ese nivel". ¿No es el hecho de que la lista es de longitud 4 en lugar de 5 una razón más fundamental aquí? (Supongo que [1,3,2,2,3]es posible para un nivel 4 al pasar del nivel 3 [1,1,2(replaced),2(new)]a [1,3(replaced),2,2,3(new)]?)
Jonathan Allan

Respuestas:

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

Pruébalo en línea!

  • Requisito de entrada: la lista de hechizos debe ordenarse desde los niveles de hechizo más altos hasta el más bajo.

Explicaciones

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

Tabla 1: Distribución de hechizos maximizada para cada nivel de hechicero, utilizada a partir de la respuesta de Axoren en la pregunta vinculada .

ingrese la descripción de la imagen aquí

Créditos

Olivier Grégoire
fuente
1
return l<1&java.util.Arrays.equals(m,new int[9]);puede ser z=0;for(int i:m)z+=i;return l+z==0;en su lugar. O si los valores en mnunca pueden ser negativos al final, ==0puede ser <1.
Kevin Cruijssen
@KevinCruijssen ¡Gracias! Y eso dejó espacio para arreglar un error con demasiados hechizos en la lista.
Olivier Grégoire
¡Ah, for(int i:m)l|=i;es aún más inteligente! Buena esa.
Kevin Cruijssen
Estoy seguro de que los dos últimos bucles se pueden combinar, pero no sé cómo en este momento.
Olivier Grégoire
1
@CameronAavik Probablemente lo pasó con números ordenados ascendentes ( new int[]{5,6,6,6,7,7,7,8,8,8,9,9,9,9,9}). Si los ingreso descendiendo ( new int[]{9,9,9,9,9,8,8,8,7,7,7,6,6,6,5}como está escrito en el requisito de ingreso que escribí debajo del golf), funciona. Agregué el caso de prueba 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)

Pruébalo en línea!

Sin golf:

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)

editar: solución corregida para usar las reglas correctas de D&D

Cameron Aavik
fuente
I + 1'ed, aunque print(v(20, [6,6,6,6,7,7,7,8,8,8,9,9,9,9,9])) # Falseimprime cierto. Debe imprimir falso.
Olivier Grégoire
@ OlivierGrégoire Estoy usando las reglas de OP para qué niveles de habilidad son válidos en el código suministrado. Consulte la nota en la parte inferior de la publicación que muestra la modificación que debe realizar para utilizar las reglas reales de DnD.
Cameron Aavik
Oh mi error. Lo siento. La salida es correcta con ese cambio.
Olivier Grégoire
Bueno, está resuelto: es la regla de D&D que debe aplicarse, no la min(9,n-1)única.
Olivier Grégoire
1

Carbón , 51 bytes

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

Pruébalo en línea! El enlace es a la versión detallada del código. Toma los niveles de hechizo en orden ascendente como una cadena. Explicación:

Nθ

Ingrese el nivel.

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

Realice la decodificación de longitud de ejecución en la cadena que 0544443335resulta en la cadena 11111222233334444555566677788899999. Luego, esta cadena se corta comenzando en el nivel (1 indexado) y terminando en el nivel duplicado (si es menor que 12) o 6 + 1.5 *, redondeado hacia arriba, excepto para el nivel 19, que se redondea hacia abajo. A 0tiene el sufijo para garantizar que no haya demasiados hechizos.

¬ΣES›ι§θκ

Compara los niveles de hechizo con la subcadena e imprime un -si ninguno de ellos es excesivo.

Neil
fuente
Creo que esto falla por períodos menores de lo que deben ser, ya que creo que la adquisición de hechizos es obligatoria en los niveles no mencionados; Sin embargo, he pedido aclaraciones.
Jonathan Allan
También parece fallar 11113en el nivel 4que es el resultado de ninguna actualización opcional, tomando 1en el nivel 2, 1en el nivel 3 y 3en el nivel 4.
Jonathan Allan
@JonathanAllan Tu nivel de hechizo máximo es el techo de la mitad de tu nivel de personaje (o 9, ya que es el máximo posible). Tal vez la pregunta no lo dejó claro.
Neil
(Básicamente, he seguido las respuestas en la pregunta vinculada sobre cuáles son los posibles niveles de hechizo).
Neil
No quiero tratar de comprender y conciliar dos especificaciones, el OP ha confirmado min (9, n-1) en los comentarios. Tal vez pregunte esto allí ...
Jonathan Allan
0

JavaScript (ES6), 79 bytes

(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

Pruébalo en línea!

Código de prueba

A continuación hay un enlace a algún código de prueba que toma el nivel de hechicero como entrada y devuelve una matriz de niveles máximos de hechizos, utilizando la misma lógica que la función anterior.

Pruébalo en línea!

¿Cómo?

Tabla de referencia

 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 

Numero de hechizos

LNL

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

jNL11

Niveles máximos de hechizos

L1iNLML,ii

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

xa

Arnauld
fuente
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}

Genera el mejor libro de hechizos posible, luego verifica que el libro de hechizos pasado al método no sea mejor.

Sin golf, con tipos implícitos hechos explícitos:

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
}

Pruébalo en línea!

archangel.mjj
fuente