1世を探す旅

教育に良いブログを目指してます。

アタポン形式イベントでキリの良いポイントを取りたい

結論

つくった。

https://thimbleprojects.org/oomonokizoku/391260/

前置き

f:id:kzk_imastodon:20180112212719j:plain

紗枝はんかわいいですよね!スタドリあったので最新カードを交換して特訓しました!

そして今回のイベントが

f:id:kzk_imastodon:20180112212841j:plain

羽衣小町!!

去年の1月のスカチケを周子さんに使い、そのときの限定紗枝はんをみて、「欲しいッ」と思い、最終日に回していらしたことがまるでちょうど1年前のように思い返せます。

 

f:id:kzk_imastodon:20180112213827j:plain

かわいい。

 

ところで好きなユニットやアイドルのいるイベントが来ると、よっしゃいくぞーとポイントを稼ぐわけなのですが、最終的なポイント数がキリがいいとちょっとテンション上がりません?順位は無理としてもポイント数は自らの手で調整できる。

f:id:kzk_imastodon:20180112213949p:plain

今となってはもう少し頑張りたかったなとも思いますが、でもキリがいいのはテンションがいい。

 

ところで、インターネットをちょっと調べたんですけど、

デレステ Grooveイベント ポイント調整方法計算機

とGrooveはあるんですが、デレステのアタポン形式はちょっと見当たらなかったので、計算してみました!

計算

要は、楽曲で得られるポイント数がスタミナ10-19曲の順に25,28,31,34,37,40,44,47,50,53となっていて、それらを組み合わせて必要なポイント数にするという組み合わせを考える問題。なんで44のところだけ等差じゃないんでしょうね。

自分が最低限触れる計算ツールがpythonExcelしかなく、なぜそうなるかを証明出来ないのでフィーリングで話を進めます。

1周の定義を決める

1から1億ptまでの可能性を検討するのは大変です。キリのいいポイントに到達したい場合は恐らく最終日で、キリのいいポイントに到達したい人はジュエルを割ることを厭わない人であろうと仮定して、通常楽曲スタミナ19楽曲2倍消費を6回、イベントmas4倍消費を1回した53*6+320*4である1598ptを1周と仮定し、それらをm周した後に1598pt以下の端数nをどう稼いで目標N pt数に到達すればいいかを考えていくことにします。

{1598m + n = N }

ここでnは1598未満の自然数といいたいところですが、最低1回楽曲をプレイしなければポイントを稼ぐことができず、最低でもスタミナ10の楽曲が25pt得られてしまうので例えばn=1となったときにどう頑張っても目標のNピタリを狙うことはできません。なのでnはとある値以上である必要があります。

1ポイント刻み出来る最低値を探す

例えば3pt・4ptしか得られない場合、欲しい(端数である)n ptを得るためには、それぞれの楽曲をプレイした回数をa,bとして、

{3a + 4b = n}

を満たすa,bが存在するかを調べます。見てわかることとして1,2,ptを手に入れることは出来ません。実はどう組み合わせても5,10ptを実現することも出来ません。逆に11pt以上なら必ずそのnを満たすa,bが存在します(例: 3+4*2 = 11)(このあたり一次不定方程式とか絡んでるのかなぁと思ってるけどよく検討してない)

先ほどのとある値というのはこの11ptのことで、nを1pt毎に増やしていったとき、どのようなnでも上記の式を満たすa,bの組み合わせが存在する、nの最低値ということになります。言葉にすることで余計にわかりにくくなった気がしますが、とりあえずnが11以上のどの整数でもそれを満たすa,bは存在するので、端数として11以上であれば必ず目標の値ピタリになれる、逆に端数として例えば10だった場合、どう足掻いてもピタリ10ptを取ることができないという話です。

実際の楽曲で得られるポイントで最低値を探す

3,4ptの具体例はExcelで書き込みながら、「11……できた!12は余裕!13は……できた!もしかすると……」とやっていけばいいんですが(やった)、流石に25,28...53と10個もあるとそういうわけにはいかないので、雑にpython使って計算します。

import numpy as np
def score(a,b):
    return sum(np.array(a)*np.array(b))
Normal_Point = [25,28,31,34,37,40,44,47,50,53]

Point数配列と楽曲回数配列をかけ算して合計値を求めたいのがscore関数で、要素毎にかけ算して足したいという欲求のためだけにnumpyをimportしたけど多分forで良いです。

import itertools
d = {}
for i in itertools.product(range(4),repeat=len(Normal_Point)):
    s = score(Normal_Point,i)
    if s not in d:
        d[s] = i
    else:
        if sum(d[s]) > sum(i):
            d[s] = i

dは辞書型で、d[得点]とするとその得点になるための楽曲プレイ回数の配列が返ってきてほしいという願望のもと、for文書いてます。itertools.productは楽曲プレイ回数の配列を生成しているわけなのですが、最低値を求めるためのざっくりとした計算のために、同じスタミナ楽曲を最大でも3回(スタミナ消費は10パターンあるので最大30曲)しかプレイをしないという制限をかけています(1回で53pt得られる楽曲をたくさんした方が効率良いのは自明なのですがそれは後で考慮するため、今はこんな感じで)(rangeを大きくすれば全て解決するのですが、計算量がそれの10乗なので4ぐらいが平和)。

また、先ほどの例ですと、12ptを得るためには3ptを4回するか4ptを3回するか選べるわけですが、もちろん回数は少ない方がいいという設定で、回数が少ない方だけ辞書に登録しています(if文)。

で、辞書に登録された得点をkeysで取得してsortして結果を見てみると、

[0, 25, 28, 31, 34, 37, 40, 44, 47, 50, 53, ,..., 128, 130, 131, 132,...

 こんな感じで並んでいて、カッと目を見開くと(np.diffを使ったりexcelにコピペして数列の差を見るなりすると)、130ptからしばらく1pt刻みで増えているので、どうやら「アタポンイベントは130pt以上の任意の整数ならば、通常楽曲をプレイしまくれば必ず到達する!」と言えそうです。少なくとも、130ptから130+53=183ptまでは1pt刻みで増えているので、それ以降は全て53楽曲を行えばいいことから、130pt以上の任意の整数ならば~と言えそうです。

そのため、最初の式、

{1598m + n = N }

は、nが130以上1598+130未満の数となるようにmを定めれば良く、nについては

{53a + b = n }

として、bが130以上183未満の数となるようにaを定め、bについては上の辞書を参考にすれば良いことになります。

イベント楽曲を考慮する

じゃあn=1590のとき、何回プレイすればいいかな?!と期待して計算すると、53*17+159 = 53*30 = 1590、すなわち30回プレイする必要があります。多すぎる理由は明確で、今までの話はイベント楽曲を(1サイクルに含まれる1回以外)プレイしない前提で、通常楽曲だけで稼ぎきる話だったためです。

イベント楽曲は4倍を抜きで考えると、130,170,240,320得ることが出来ます。また、イベントアイテムを無限に所持してイベント楽曲だけをプレイし続けることが出来た場合、同様の計算をすると、どうやら710pt以上は10pt刻みで達成できるそうです(760pt達成のためにはrangeを5にする必要があります。1730では同じ難易度を5回する必要)。

まあ、残念ながらアイテム数は有限なので、一応このポイントゴルフを始めてから稼いだアイテムだけでイベント楽曲をこなす前提にした方がよさそうです。

 

ここから先として、

・イベント楽曲だけプレイした場合に再現出来るポイント数を列挙する

・それに必要なイベントアイテム数を計算する

・130ptから1598+130ptの間を1刻みで見ていく(i pt)

  ・そのpt以下で取得可能性のあるイベptを列挙する(j pt)

  ・この時、通常楽曲で得るのがi-jポイントとなる

  ・その時点でイベアイテムが2倍消費で(i-j)*2個存在するので、ここでj ptが実現可能かを調べる

  ・もし実現可能なら、i-j ptに必要な通常楽曲回数とj ptに必要なイベント楽曲回数を足す

  ・その計算を可能性のあるイベpt全てでやって、一番小さい回数をそのptでやる必要のある回数と定める

と、自分にはごり押しでしか探すことは出来ませんでしたが、やりたい計算はこんな感じになります。もう少し煮詰めれば作業減らせれるのかしら。

 

で、これを全てJavascriptで書き直すのは面倒くさかったのでjsonで吐き出して読み込ませたのが上のURLとなります。

検算

100000pt得るのに、スタミナ17(47)*3+スタミナ19(53)*373+Reg(170)+Pro(240)+Mas(320)*249 = 100000

得られるエムブレム 47*3*2+53*373*2 = 39820

消費するエムブレム 90+120+150*249 = 37560

……なんでこんなにオーバーランしてるんだ!と怒られそうですが、「通常楽曲スタミナ19楽曲2倍消費を6回、イベントmas4倍消費を1回した53*6+320*4である1598ptを1周」の1周につき18個多くもらってるので、ちりもつもればって話ですね!

あと、ログインボーナスで300個もらえるので、もう少し楽なはずです!よかった、Master373回もやらなくていいんですね!!

結論

スタミナ18曲の50ptを連打が一番頭使わないと思います。ともかくまだイベント曲2回しかやってないのでこの辺で。