Buku mantra penyihir

10

Sunting : Saya belum pernah bermain D & D sebelumnya jadi ketika saya awalnya membuat pertanyaan ini saya tidak benar meneliti itu. Saya minta maaf untuk ini, dan saya membuat beberapa pengeditan yang mungkin membatalkan jawaban untuk tetap setepat mungkin pada aturan 5nd. Maaf.


Penggemar D & D dari Hot Network Question baru-baru ini tampaknya memiliki masalah untuk mengetahui apakah mantra yang dipilih oleh penyihir sejajar dengan kemungkinan - dan saya pikir kita harus membantu!

pengantar

(semua ini sudah dijelaskan dalam pertanyaan yang disebutkan sebelumnya)

Seorang penyihir tahu dua mantra level 1 dari awal (level 1): [1, 1]

  • Setiap kali penyihir mendapatkan level (kecuali untuk level 12, 14, 16, 18, 19 dan 20) mereka belajar mantra baru (wajib).

  • Selain itu, ketika naik level seseorang dapat memilih (opsional) untuk mengganti salah satu mantra dengan yang lain.

Mantra yang dipelajari dan diganti haruslah level slot mantera yang valid yang setengah dari level penyihirmu dibulatkan. Lihat tabel ini:

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

Ini berarti pada level 3 seseorang dapat memiliki level mantra [1, 1, 2, 2]seperti ini:

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

Tidak perlu memilih mantra level tertinggi yang bisa Anda akses.

Level mantra [1, 1, 1, 1]sangat valid untuk level 3.

Terakhir, ingat bahwa mengganti mantra adalah opsi opsional untuk setiap level . Ini berarti bahwa beberapa level dapat melewati penggantian, sementara yang lain memanfaatkannya.

Tantangan

Buat program atau fungsi yang membutuhkan bilangan bulat (level) antara 1 dan 20.

Itu juga harus mengambil array bilangan bulat (level mantra) dengan nilai mulai dari 1 hingga 9 dalam urutan apa pun (9 adalah level mantra maksimum).

Output dari program harus berupa nilai kebenaran / kepalsuan yang memvalidasi jika level mantra yang dipilih valid untuk penyihir dari level yang diberikan.

Uji kasus

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]

Ini adalah - byte terkecil menang!

Daniel
sumber
1
Bisakah kita mengambil daftar ejaan yang diurutkan sesuai keinginan kita?
Veskah
Berapa level mantra maksimum untuk setiap level kelas?
Nitrodon
@Nitrodon Saya kira 19?
Don Thousand
@Nitrodon, mungkin 9 karena input array hanya dapat berisi " nilai mulai dari 1 hingga 9 " tetapi level mantra maksimum yang perlu kita tangani harus dinyatakan lebih eksplisit dalam spesifikasi. Dan itu bisa dilakukan dengan beberapa kasus uji lagi. Tantangan yang bagus, sebaliknya.
Shaggy
4
1. "Ini juga harus mengambil array bilangan bulat (level mantra) dengan nilai mulai dari 1 hingga 9 (dalam urutan apa pun)" - bagaimana dengan level 10-19? 2. "Namun pada level 4 level mantra [2,2,3,3]tidak akan mungkin terjadi karena membutuhkan lebih banyak penggantian daripada penyihir level itu yang akan memiliki akses." - bukankah fakta bahwa daftar itu panjangnya 4 daripada alasan yang lebih mendasar di sini? (Saya berasumsi [1,3,2,2,3]mungkin untuk level 4 dengan pergi dari level 3 [1,1,2(replaced),2(new)]ke [1,3(replaced),2,2,3(new)]?)
Jonathan Allan

Jawaban:

5

Java (JDK 10) , 191 byte

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

Cobalah online!

  • Persyaratan input: daftar mantra harus dipesan dari tingkat mantra terbesar hingga terendah.

Penjelasan

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

Tabel 1: Distribusi mantra dimaksimalkan untuk setiap tingkat penyihir, digunakan dari jawaban Axoren pada pertanyaan terkait .

masukkan deskripsi gambar di sini

Kredit

Olivier Grégoire
sumber
1
return l<1&java.util.Arrays.equals(m,new int[9]);bisa z=0;for(int i:m)z+=i;return l+z==0;sebaliknya. Atau jika nilai-nilai di mtidak pernah bisa negatif pada akhirnya, ==0bisa jadi <1.
Kevin Cruijssen
@KevinCruijssen Terima kasih! Dan ruangan berdaun itu untuk memperbaiki bug dengan terlalu banyak mantra dalam daftar.
Olivier Grégoire
Ah, for(int i:m)l|=i;bahkan lebih pintar! Bagus
Kevin Cruijssen
Saya yakin dua loop terakhir dapat digabungkan, saya hanya tidak tahu caranya sekarang.
Olivier Grégoire
1
@CameronAavik Anda mungkin melewatinya dengan nomor yang dipesan naik ( new int[]{5,6,6,6,7,7,7,8,8,8,9,9,9,9,9}). Jika saya masukan mereka turun ( new int[]{9,9,9,9,9,8,8,8,7,7,7,6,6,6,5}, seperti yang tertulis dalam persyaratan input yang saya tulis di bawah golf), itu berhasil. Saya menambahkan test case untuk menunjukkan bahwa itu memang berhasil.
Olivier Grégoire
2

Python 3 , 98 byte

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)

Cobalah secara Online!

Tidak Disatukan:

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)

sunting: solusi yang diperbaiki untuk menggunakan aturan D & D yang benar

Cameron Aavik
sumber
Saya memberi +1, meskipun print(v(20, [6,6,6,6,7,7,7,8,8,8,9,9,9,9,9])) # Falsecetakan benar. Itu harus mencetak salah.
Olivier Grégoire
@ OlivierGrégoire Saya menggunakan aturan OP untuk tingkat keterampilan apa yang valid dalam kode yang disediakan. Lihat catatan di bagian bawah posting yang menunjukkan modifikasi untuk menggunakan aturan DnD yang sebenarnya.
Cameron Aavik
Oh, salahku. Maaf. Outputnya benar dengan perubahan itu.
Olivier Grégoire
Yah, sudah diselesaikan: itu aturan D & D yang perlu diterapkan, bukan yang min(9,n-1).
Olivier Grégoire
1

Arang , 51 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Mengambil level mantra dalam urutan naik sebagai string. Penjelasan:

Nθ

Masukkan level.

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

Lakukan decoding run-length pada string yang 0544443335menghasilkan string 11111222233334444555566677788899999. String ini kemudian diiris mulai dari level (1-diindeks) dan berakhir di level dua kali lipat (jika kurang dari 12) atau 6 + 1,5 *, dibulatkan ke atas, kecuali untuk level 19, yang dibulatkan ke bawah. A 0diberi sufiks untuk memastikan tidak ada terlalu banyak mantra.

¬ΣES›ι§θκ

Bandingkan level mantra dengan substring dan cetak a -jika tidak ada yang berlebihan.

Neil
sumber
Saya pikir ini gagal untuk panjang kurang dari yang seharusnya, karena saya pikir akuisisi mantra adalah wajib pada level yang tidak terdaftar; Saya telah meminta klarifikasi.
Jonathan Allan
Tampaknya juga gagal karena 11113pada level 4yang merupakan hasil dari tidak ada upgrade opsional, mengambil 1di level 2, 1di level 3 dan 3, di level 4.
Jonathan Allan
@JonathanAllan Level mantra maksimum Anda adalah langit-langit setengah dari level karakter Anda (atau 9, karena itulah maksimum yang dimungkinkan). Mungkin pertanyaannya tidak menjelaskan.
Neil
(Pada dasarnya saya telah mengikuti jawaban dalam pertanyaan terkait seperti apa tingkat mantra yang mungkin.)
Neil
Saya tidak ingin mencoba memahami dan merekonsiliasi dua spesifikasi, OP telah mengkonfirmasi min (9, n-1) dalam komentar. Mungkin pertanyaan ini di sana ...
Jonathan Allan
0

JavaScript (ES6), 79 byte

(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

Cobalah online!

Kode uji

Di bawah ini adalah tautan ke beberapa kode uji yang mengambil tingkat penyihir sebagai input dan mengembalikan array level mantra maksimum, menggunakan logika yang sama dengan fungsi di atas.

Cobalah online!

Bagaimana?

Tabel referensi

 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 

Jumlah mantra

L.NL.

NL.={L.+1jika L.<12(L.+13)/2jika 12L.1615jika L.>16

jNL.-1-1

Level mantra maksimum

L.1sayaNL.M.L.,sayasaya

M.L.,saya={(L.+saya+2)/4jika L.+saya<25(L.+saya+4)/4jika 25L.+saya309jika L.+saya>30

xSebuah

Arnauld
sumber
0

Groovy , 155 byte

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}

Menghasilkan spellbook terbaik, lalu memeriksa apakah spellbook yang masuk ke metode tidak lebih baik.

Tidak disatukan, dengan tipe implisit yang dibuat eksplisit:

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
}

Cobalah online!

archangel.mjj
sumber