Jdi na navigaci předmětu

2. Porovnání (Newtonův fraktál)

Porovnání jednotlivých řešení po měkkém deadline druhého úkolu.

using CSV, DataFrames
"""

    record_rank!(data_frame, column)

Pomocná hodnotící funkce přidělující body do sloupce `score` tabulky
`data_frame` podle pořadí ve sloupci `column` (seřazeném).

"""
function record_rank!(data_frame::DataFrame, column::Symbol)
    rank = 1
    value = first(data_frame[!, column])

    for row in eachrow(data_frame)
        if ismissing(row[column])
            row[:score] += 42
            continue
        elseif ismissing(value)
            value = row[column]
        elseif row[column] != value
            value = row[column]
            rank += 1
        end

        row[:score] += rank
    end
end;

Načtení dat, smazání username a přidání "skórovacího" sloupce a výpis základních statistik datasetu.

df = CSV.read("benchmark02.csv", DataFrame)
df[!, "score"] .= 0
select!(df, Not(:username))
describe(df)
11×7 DataFrame
Rowvariablemeanminmedianmaxnmissingeltype
SymbolUnion…AnyUnion…AnyInt64Type
1nickAeloria of the Seven Sigilskalvotom0String
2code107.3624110.01902Union{Missing, Int64}
3comment36.16628.01312Union{Missing, Int64}
4correctness0.826923false1.0true0Bool
5newton_t3379.032067.223115.8817022.08Union{Missing, Float64}
6newton_m374.54500.0164808Union{Missing, Int64}
7constructor_t1.7945e6261.02.45268e64.42194e68Union{Missing, Float64}
8constructor_m3.23639e7320002963.20003e7480003848Union{Missing, Int64}
9compute_t9.39814e81.28338e88.46475e84.56455e99Union{Missing, Float64}
10compute_m2.63132e810561.28e839737269289Union{Missing, Int64}
11score0.000.000Int64

Do měření započítávám pouze odevzdání, která počítají správné výsledky na jednoduchém případu.

Dále mezi hodnocené zařazuji i své odevzdání (nick kalvotom), kód vygenerovaný pomocí ChatGPT (nick chatgpt).

df = df[df[:, :correctness], :];

Parametry kódu

Počet řádek kódu. Čím méně, tím lépe, což ale vždy neplatí, že. Měření pomocí nástroje cloc.

sort!(df, :code)
record_rank!(df, :code)
show(df[!,[:nick, :code, :score]], allrows=true)
43×3 DataFrame
 Row  nick                               code    score 
      String                             Int64?  Int64 
─────┼──────────────────────────────────────────────────
   1 │ Orlien Silverchant                     73      1
   2 │ Zytherin the Forgotten                 75      2
   3 │ Ilyrien Dawnpetal                      81      3
   4 │ Rhovar Mistborn                        86      4
   5 │ Galdur the Wise                        93      5
   6 │ Erenwyn the Whispering                 93      5
   7 │ Seraphyne Windwhisper                  95      6
   8 │ Sareth the Verdant                     95      6
   9 │ Elithar Dawnseeker                     96      7
  10 │ Talvorn Runebreaker                    96      7
  11 │ Cyralis Moonbinder                     97      8
  12 │ Caelwyn of the Crystal Spire           98      9
  13 │ Vessryn Bloodsong                      99     10
  14 │ kalvotom                              100     11
  15 │ Tirvian Shadowmantle                  100     11
  16 │ Dravok the Gloomed                    101     12
  17 │ Maerilith Stormweaver                 103     13
  18 │ Maranelle Frostpetal                  110     14
  19 │ Althira Starweaver                    110     14
  20 │ Eldaric Runehand                      111     15
  21 │ Talmek the Shattered                  115     16
  22 │ Vyrion the Eternal                    116     17
  23 │ Korvath the Obsidian                  120     18
  24 │ Mirelda Starbloom                     122     19
  25 │ Faelora Nightbloom                    122     19
  26 │ Yseline Frostwhisper                  122     19
  27 │ Kerron the Unseen                     123     20
  28 │ Selvethra of the Whispering Woods     124     21
  29 │ Aeloria of the Seven Sigils           127     22
  30 │ Xandor the Arcane                     127     22
  31 │ Thalendir Brightflame                 129     23
  32 │ Zerathorn the Pale                    129     23
  33 │ Korthen Deepflame                     134     24
  34 │ Velmaris Lightbinder                  134     24
  35 │ Thamior Embercloak                    136     25
  36 │ Lunara Dreambinder                    141     26
  37 │ Sylthara the Veiled                   142     27
  38 │ Nimriel the Golden                    143     28
  39 │ chatgpt                               148     29
  40 │ Orren Emberforge                      154     30
  41 │ Velindra the Azure                    162     31
  42 │ Bramor the Tempest                    179     32
  43 │ Eldwyn of the Shimmering Vale         190     33

Počet řádek komentářů (včetně docstringů). Zde naopak čím více, tím lépe.

sort!(df, :comment, rev=true)
record_rank!(df, :comment)
show(df[!,[:nick, :comment, :score]], allrows=true)
43×3 DataFrame
 Row  nick                               comment  score 
      String                             Int64?   Int64 
─────┼───────────────────────────────────────────────────
   1 │ Bramor the Tempest                     131     33
   2 │ Eldaric Runehand                       118     17
   3 │ Eldwyn of the Shimmering Vale          118     35
   4 │ Faelora Nightbloom                      87     22
   5 │ Kerron the Unseen                       64     24
   6 │ Orlien Silverchant                      60      6
   7 │ Maerilith Stormweaver                   58     19
   8 │ Aeloria of the Seven Sigils             49     29
   9 │ Talmek the Shattered                    47     24
  10 │ Xandor the Arcane                       45     31
  11 │ Korthen Deepflame                       42     34
  12 │ Seraphyne Windwhisper                   41     17
  13 │ Velmaris Lightbinder                    41     35
  14 │ Nimriel the Golden                      41     39
  15 │ chatgpt                                 41     40
  16 │ Rhovar Mistborn                         40     16
  17 │ Thamior Embercloak                      40     37
  18 │ Zerathorn the Pale                      38     36
  19 │ Lunara Dreambinder                      36     40
  20 │ Korvath the Obsidian                    32     33
  21 │ Vessryn Bloodsong                       31     26
  22 │ kalvotom                                31     27
  23 │ Cyralis Moonbinder                      29     25
  24 │ Sylthara the Veiled                     28     45
  25 │ Althira Starweaver                      27     33
  26 │ Selvethra of the Whispering Woods       27     40
  27 │ Thalendir Brightflame                   26     43
  28 │ Caelwyn of the Crystal Spire            25     30
  29 │ Orren Emberforge                        24     52
  30 │ Maranelle Frostpetal                    23     37
  31 │ Yseline Frostwhisper                    23     42
  32 │ Tirvian Shadowmantle                    21     35
  33 │ Galdur the Wise                         20     30
  34 │ Elithar Dawnseeker                      20     32
  35 │ Talvorn Runebreaker                     20     32
  36 │ Zytherin the Forgotten                  19     28
  37 │ Ilyrien Dawnpetal                       18     30
  38 │ Erenwyn the Whispering                  18     32
  39 │ Dravok the Gloomed                      18     39
  40 │ Vyrion the Eternal                      18     44
  41 │ Velindra the Azure                      15     59
  42 │ Sareth the Verdant                      14     35
  43 │ Mirelda Starbloom                       14     48

Metoda newton

Test efektivity a paměťové náročnosti metody newton, která provádí čistě iterace. Rychlost (čas, první tabulka) je přepočtena relativně vzhledem k nejrychlejšímu řešení. Druhá tabulka není normalizována, ani to nejde, vzhledem k nulovým hodnotám.

sort!(df, :newton_t)
df[!, :newton_t] /= df[1, :newton_t]
record_rank!(df, :newton_t)
show(df[!,[:nick, :newton_t, :score]], allrows=true)
43×3 DataFrame
 Row  nick                               newton_t  score 
      String                             Float64   Int64 
─────┼────────────────────────────────────────────────────
   1 │ kalvotom                            1.0         28
   2 │ Mirelda Starbloom                   1.09798     50
   3 │ Orlien Silverchant                  1.12819      9
   4 │ Aeloria of the Seven Sigils         1.14324     33
   5 │ Galdur the Wise                     1.3355      35
   6 │ Maerilith Stormweaver               1.36297     25
   7 │ Velindra the Azure                  1.39855     66
   8 │ Eldaric Runehand                    1.39957     25
   9 │ Lunara Dreambinder                  1.40769     49
  10 │ Kerron the Unseen                   1.4136      34
  11 │ Maranelle Frostpetal                1.42596     48
  12 │ Faelora Nightbloom                  1.45289     34
  13 │ Ilyrien Dawnpetal                   1.45988     43
  14 │ Thalendir Brightflame               1.49155     57
  15 │ Elithar Dawnseeker                  1.49397     47
  16 │ Talvorn Runebreaker                 1.49397     47
  17 │ Caelwyn of the Crystal Spire        1.49458     46
  18 │ Xandor the Arcane                   1.49512     48
  19 │ Seraphyne Windwhisper               1.49579     35
  20 │ Vessryn Bloodsong                   1.49936     45
  21 │ Selvethra of the Whispering Woods   1.50123     60
  22 │ Bramor the Tempest                  1.50667     54
  23 │ Tirvian Shadowmantle                1.50788     57
  24 │ Yseline Frostwhisper                1.5279      65
  25 │ Thamior Embercloak                  1.52971     61
  26 │ Zytherin the Forgotten              1.53818     53
  27 │ Rhovar Mistborn                     1.53999     42
  28 │ Erenwyn the Whispering              1.54241     59
  29 │ Cyralis Moonbinder                  1.54362     53
  30 │ Sylthara the Veiled                 1.5467      74
  31 │ Velmaris Lightbinder                1.56847     65
  32 │ Korvath the Obsidian                1.59332     64
  33 │ Korthen Deepflame                   1.59514     66
  34 │ Nimriel the Golden                  1.59635     72
  35 │ Althira Starweaver                  1.59997     67
  36 │ Vyrion the Eternal                  1.60179     79
  37 │ Orren Emberforge                    1.60239     88
  38 │ Sareth the Verdant                  1.603       72
  39 │ Dravok the Gloomed                  1.60421     77
  40 │ chatgpt                             1.60481     79
  41 │ Zerathorn the Pale                  1.66056     76
  42 │ Eldwyn of the Shimmering Vale       1.74721     76
  43 │ Talmek the Shattered                8.23424     66

A pak paměť ve stejném experimentu, čím méně, tím lépe.

sort!(df, :newton_m)
record_rank!(df, :newton_m)
show(df[!, [:nick, :newton_m, :score]], allrows=true)
43×3 DataFrame
 Row  nick                               newton_m  score 
      String                             Int64?    Int64 
─────┼────────────────────────────────────────────────────
   1 │ kalvotom                                  0     29
   2 │ Mirelda Starbloom                         0     51
   3 │ Orlien Silverchant                        0     10
   4 │ Aeloria of the Seven Sigils               0     34
   5 │ Galdur the Wise                           0     36
   6 │ Maerilith Stormweaver                     0     26
   7 │ Velindra the Azure                        0     67
   8 │ Eldaric Runehand                          0     26
   9 │ Lunara Dreambinder                        0     50
  10 │ Kerron the Unseen                         0     35
  11 │ Maranelle Frostpetal                      0     49
  12 │ Faelora Nightbloom                        0     35
  13 │ Ilyrien Dawnpetal                         0     44
  14 │ Thalendir Brightflame                     0     58
  15 │ Elithar Dawnseeker                        0     48
  16 │ Talvorn Runebreaker                       0     48
  17 │ Caelwyn of the Crystal Spire              0     47
  18 │ Xandor the Arcane                         0     49
  19 │ Seraphyne Windwhisper                     0     36
  20 │ Vessryn Bloodsong                         0     46
  21 │ Selvethra of the Whispering Woods         0     61
  22 │ Bramor the Tempest                        0     55
  23 │ Tirvian Shadowmantle                      0     58
  24 │ Yseline Frostwhisper                      0     66
  25 │ Thamior Embercloak                        0     62
  26 │ Zytherin the Forgotten                    0     54
  27 │ Rhovar Mistborn                           0     43
  28 │ Erenwyn the Whispering                    0     60
  29 │ Cyralis Moonbinder                        0     54
  30 │ Sylthara the Veiled                       0     75
  31 │ Velmaris Lightbinder                      0     66
  32 │ Korvath the Obsidian                      0     65
  33 │ Korthen Deepflame                         0     67
  34 │ Nimriel the Golden                        0     73
  35 │ Althira Starweaver                        0     68
  36 │ Vyrion the Eternal                        0     80
  37 │ Orren Emberforge                          0     89
  38 │ Sareth the Verdant                        0     73
  39 │ Dravok the Gloomed                        0     78
  40 │ chatgpt                                   0     80
  41 │ Zerathorn the Pale                        0     77
  42 │ Eldwyn of the Shimmering Vale             0     77
  43 │ Talmek the Shattered                  16480     68

Konstruktor Newton

Test konstruktoru typu Newton z pohledu časové a paměťové náročnosti. Jak vidíte, i zde jde velký prostor pro zamyšlení.

sort!(df, :constructor_t)
df[!, :constructor_t] /= df[1, :constructor_t]
record_rank!(df, :constructor_t)
show(df[!,[:nick, :constructor_t, :score]], allrows=true)
43×3 DataFrame
 Row  nick                               constructor_t  score 
      String                             Float64        Int64 
─────┼─────────────────────────────────────────────────────────
   1 │ kalvotom                                 1.0         30
   2 │ Velmaris Lightbinder                     1.03831     68
   3 │ Tirvian Shadowmantle                     1.0728      61
   4 │ Faelora Nightbloom                       1.15326     39
   5 │ Ilyrien Dawnpetal                        1.15326     48
   6 │ Korthen Deepflame                        1.15326     71
   7 │ Orlien Silverchant                       1.19157     15
   8 │ Erenwyn the Whispering                   1.19157     65
   9 │ Thalendir Brightflame                    1.30651     64
  10 │ Zerathorn the Pale                    1901.87        84
  11 │ Eldaric Runehand                      2285.59        34
  12 │ Althira Starweaver                    2967.17        77
  13 │ Bramor the Tempest                    3734.38        65
  14 │ Aeloria of the Seven Sigils           3746.92        45
  15 │ Vyrion the Eternal                    3758.78        92
  16 │ Orren Emberforge                      3786.03       102
  17 │ Dravok the Gloomed                    4018.39        92
  18 │ Mirelda Starbloom                     4120.34        66
  19 │ Caelwyn of the Crystal Spire          4247.87        63
  20 │ Selvethra of the Whispering Woods     4587.85        78
  21 │ Elithar Dawnseeker                    9317.45        66
  22 │ Seraphyne Windwhisper                 9390.59        55
  23 │ Yseline Frostwhisper                  9403.91        86
  24 │ Lunara Dreambinder                    9492.24        71
  25 │ Sareth the Verdant                    9527.4         95
  26 │ Xandor the Arcane                     9776.11        72
  27 │ Sylthara the Veiled                   9824.25        99
  28 │ Korvath the Obsidian                  9969.96        90
  29 │ Nimriel the Golden                    9985.16        99
  30 │ Velindra the Azure                   10006.8         94
  31 │ Vessryn Bloodsong                    10149.5         74
  32 │ Galdur the Wise                      10170.6         65
  33 │ Maranelle Frostpetal                 10180.2         79
  34 │ Kerron the Unseen                    10441.1         66
  35 │ Talmek the Shattered                 10473.7        100
  36 │ Cyralis Moonbinder                   10528.0         87
  37 │ Rhovar Mistborn                      10631.0         77
  38 │ Thamior Embercloak                   10871.4         97
  39 │ Maerilith Stormweaver                11435.2         62
  40 │ Eldwyn of the Shimmering Vale        13088.7        114
  41 │ Zytherin the Forgotten               14908.4         92
  42 │ chatgpt                              16371.0        119
  43 │ Talvorn Runebreaker                  16942.3         88
sort!(df, :constructor_m)
record_rank!(df, :constructor_m)
show(df[!, [:nick, :constructor_m, :score]], allrows=true)
43×3 DataFrame
 Row  nick                               constructor_m  score 
      String                             Int64?         Int64 
─────┼─────────────────────────────────────────────────────────
   1 │ kalvotom                                32000296     31
   2 │ Velmaris Lightbinder                    32000296     69
   3 │ Tirvian Shadowmantle                    32000296     62
   4 │ Faelora Nightbloom                      32000296     40
   5 │ Ilyrien Dawnpetal                       32000296     49
   6 │ Korthen Deepflame                       32000296     72
   7 │ Orlien Silverchant                      32000296     16
   8 │ Erenwyn the Whispering                  32000296     66
   9 │ Zerathorn the Pale                      32000296     85
  10 │ Eldaric Runehand                        32000296     35
  11 │ Althira Starweaver                      32000296     78
  12 │ Bramor the Tempest                      32000296     66
  13 │ Aeloria of the Seven Sigils             32000296     46
  14 │ Vyrion the Eternal                      32000296     93
  15 │ Orren Emberforge                        32000296    103
  16 │ Dravok the Gloomed                      32000296     93
  17 │ Mirelda Starbloom                       32000296     67
  18 │ Caelwyn of the Crystal Spire            32000296     64
  19 │ Selvethra of the Whispering Woods       32000296     79
  20 │ Elithar Dawnseeker                      32000296     67
  21 │ Seraphyne Windwhisper                   32000296     56
  22 │ Yseline Frostwhisper                    32000296     87
  23 │ Lunara Dreambinder                      32000296     72
  24 │ Sareth the Verdant                      32000296     96
  25 │ Xandor the Arcane                       32000296     73
  26 │ Sylthara the Veiled                     32000296    100
  27 │ Korvath the Obsidian                    32000296     91
  28 │ Nimriel the Golden                      32000296    100
  29 │ Velindra the Azure                      32000296     95
  30 │ Vessryn Bloodsong                       32000296     75
  31 │ Galdur the Wise                         32000296     66
  32 │ Maranelle Frostpetal                    32000296     80
  33 │ Talmek the Shattered                    32000296    101
  34 │ Cyralis Moonbinder                      32000296     88
  35 │ Rhovar Mistborn                         32000296     78
  36 │ Thamior Embercloak                      32000296     98
  37 │ Maerilith Stormweaver                   32000296     63
  38 │ chatgpt                                 32000296    120
  39 │ Talvorn Runebreaker                     32000296     89
  40 │ Thalendir Brightflame                   32000360     66
  41 │ Kerron the Unseen                       32000408     69
  42 │ Eldwyn of the Shimmering Vale           32000424    118
  43 │ Zytherin the Forgotten                  48000384     97

Metoda compute!

Test metody provádějící samotný výpočet a následné přiřazení výsledků k nalezeným kořenům. Opět testuji časovou a paměťovou náročnost.

sort!(df, :compute_t)
df[!, :compute_t] /= df[1, :compute_t]
record_rank!(df, :compute_t)
show(df[!,[:nick, :compute_t, :score]], allrows=true)
43×3 DataFrame
 Row  nick                               compute_t      score 
      String                             Float64?       Int64 
─────┼─────────────────────────────────────────────────────────
   1 │ Maerilith Stormweaver                    1.0         64
   2 │ Thamior Embercloak                       3.46445    100
   3 │ kalvotom                                 4.48503     34
   4 │ Mirelda Starbloom                        4.84819     71
   5 │ Eldaric Runehand                         5.61979     40
   6 │ Aeloria of the Seven Sigils              5.77015     52
   7 │ Selvethra of the Whispering Woods        5.81756     86
   8 │ Lunara Dreambinder                       6.03232     80
   9 │ Galdur the Wise                          6.1175      75
  10 │ Maranelle Frostpetal                     6.12431     90
  11 │ Velindra the Azure                       6.12815    106
  12 │ Orlien Silverchant                       6.18021     28
  13 │ Kerron the Unseen                        6.22315     82
  14 │ Ilyrien Dawnpetal                        6.31753     63
  15 │ Faelora Nightbloom                       6.3815      55
  16 │ Elithar Dawnseeker                       6.38935     83
  17 │ Yseline Frostwhisper                     6.47549    104
  18 │ Bramor the Tempest                       6.48255     84
  19 │ Xandor the Arcane                        6.48907     92
  20 │ Dravok the Gloomed                       6.58741    113
  21 │ Tirvian Shadowmantle                     6.59568     83
  22 │ Sylthara the Veiled                      6.63632    122
  23 │ Velmaris Lightbinder                     6.64143     92
  24 │ Vyrion the Eternal                       6.75217    117
  25 │ Cyralis Moonbinder                       6.82806    113
  26 │ Sareth the Verdant                       6.84734    122
  27 │ Korvath the Obsidian                     6.88628    118
  28 │ Caelwyn of the Crystal Spire             7.15516     92
  29 │ Nimriel the Golden                       7.32284    129
  30 │ Zerathorn the Pale                       7.41458    115
  31 │ Thalendir Brightflame                    7.51646     97
  32 │ Erenwyn the Whispering                   7.55022     98
  33 │ Zytherin the Forgotten                   7.74482    130
  34 │ Rhovar Mistborn                          7.85948    112
  35 │ Korthen Deepflame                        7.95374    107
  36 │ Orren Emberforge                         7.98812    139
  37 │ Eldwyn of the Shimmering Vale            7.99339    155
  38 │ Althira Starweaver                       8.5542     116
  39 │ Talvorn Runebreaker                      8.70592    128
  40 │ Seraphyne Windwhisper                    9.15685     96
  41 │ chatgpt                                  9.84096    161
  42 │ Talmek the Shattered                    35.5667     143
  43 │ Vessryn Bloodsong                  missing          117

A pak paměť, čím méně, tím lépe.

sort!(df, :compute_m)
record_rank!(df, :compute_m)
show(df[!, [:nick, :compute_m, :score]], allrows=true)
43×3 DataFrame
 Row  nick                               compute_m   score 
      String                             Int64?      Int64 
─────┼──────────────────────────────────────────────────────
   1 │ Selvethra of the Whispering Woods        1056     87
   2 │ Eldaric Runehand                     96000000     42
   3 │ Dravok the Gloomed                   96000000    115
   4 │ Eldwyn of the Shimmering Vale        96000000    157
   5 │ Maerilith Stormweaver               128000000     67
   6 │ kalvotom                            128000000     37
   7 │ Mirelda Starbloom                   128000000     74
   8 │ Lunara Dreambinder                  128000000     83
   9 │ Galdur the Wise                     128000000     78
  10 │ Maranelle Frostpetal                128000000     93
  11 │ Kerron the Unseen                   128000000     85
  12 │ Ilyrien Dawnpetal                   128000000     66
  13 │ Faelora Nightbloom                  128000000     58
  14 │ Elithar Dawnseeker                  128000000     86
  15 │ Yseline Frostwhisper                128000000    107
  16 │ Bramor the Tempest                  128000000     87
  17 │ Xandor the Arcane                   128000000     95
  18 │ Tirvian Shadowmantle                128000000     86
  19 │ Sylthara the Veiled                 128000000    125
  20 │ Velmaris Lightbinder                128000000     95
  21 │ Vyrion the Eternal                  128000000    120
  22 │ Cyralis Moonbinder                  128000000    116
  23 │ Sareth the Verdant                  128000000    125
  24 │ Korvath the Obsidian                128000000    121
  25 │ Zerathorn the Pale                  128000000    118
  26 │ Velindra the Azure                  128016144    110
  27 │ Caelwyn of the Crystal Spire        159649232     97
  28 │ Nimriel the Golden                  160000624    135
  29 │ Aeloria of the Seven Sigils         176000000     59
  30 │ Orlien Silverchant                  176000000     35
  31 │ Thalendir Brightflame               176000000    104
  32 │ Erenwyn the Whispering              176000000    105
  33 │ Zytherin the Forgotten              176000000    137
  34 │ Rhovar Mistborn                     176000000    119
  35 │ chatgpt                             224000000    169
  36 │ Thamior Embercloak                  256000576    109
  37 │ Korthen Deepflame                   391497760    117
  38 │ Orren Emberforge                    407497760    150
  39 │ Althira Starweaver                  407497760    127
  40 │ Talvorn Runebreaker                 407497760    139
  41 │ Seraphyne Windwhisper               639296000    108
  42 │ Talmek the Shattered               3973726928    156
  43 │ Vessryn Bloodsong                     missing    159

Závěrečná tabulka

Zaznamenávali jsme v každé kategorii (sdílené) pořadí. Čím nižší hodnota, tím lepší výsledek.

sort!(df, :score)
show(df[!,[:nick, :score]], allrows=true)
43×2 DataFrame
 Row  nick                               score 
      String                             Int64 
─────┼──────────────────────────────────────────
   1 │ Orlien Silverchant                    35
   2 │ kalvotom                              37
   3 │ Eldaric Runehand                      42
   4 │ Faelora Nightbloom                    58
   5 │ Aeloria of the Seven Sigils           59
   6 │ Ilyrien Dawnpetal                     66
   7 │ Maerilith Stormweaver                 67
   8 │ Mirelda Starbloom                     74
   9 │ Galdur the Wise                       78
  10 │ Lunara Dreambinder                    83
  11 │ Kerron the Unseen                     85
  12 │ Elithar Dawnseeker                    86
  13 │ Tirvian Shadowmantle                  86
  14 │ Selvethra of the Whispering Woods     87
  15 │ Bramor the Tempest                    87
  16 │ Maranelle Frostpetal                  93
  17 │ Xandor the Arcane                     95
  18 │ Velmaris Lightbinder                  95
  19 │ Caelwyn of the Crystal Spire          97
  20 │ Thalendir Brightflame                104
  21 │ Erenwyn the Whispering               105
  22 │ Yseline Frostwhisper                 107
  23 │ Seraphyne Windwhisper                108
  24 │ Thamior Embercloak                   109
  25 │ Velindra the Azure                   110
  26 │ Dravok the Gloomed                   115
  27 │ Cyralis Moonbinder                   116
  28 │ Korthen Deepflame                    117
  29 │ Zerathorn the Pale                   118
  30 │ Rhovar Mistborn                      119
  31 │ Vyrion the Eternal                   120
  32 │ Korvath the Obsidian                 121
  33 │ Sylthara the Veiled                  125
  34 │ Sareth the Verdant                   125
  35 │ Althira Starweaver                   127
  36 │ Nimriel the Golden                   135
  37 │ Zytherin the Forgotten               137
  38 │ Talvorn Runebreaker                  139
  39 │ Orren Emberforge                     150
  40 │ Talmek the Shattered                 156
  41 │ Eldwyn of the Shimmering Vale        157
  42 │ Vessryn Bloodsong                    159
  43 │ chatgpt                              169