Skip to content

Instantly share code, notes, and snippets.

@rsky
Last active September 20, 2017 14:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rsky/3191a91136ffb405901321f186da4c46 to your computer and use it in GitHub Desktop.
Save rsky/3191a91136ffb405901321f186da4c46 to your computer and use it in GitHub Desktop.
戦果係数を自動で検出する試み
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from collections import Counter
import itertools
import math
CE = [8931, 1201, 1156, 5061, 4569, 4732, 3779, 4568, 5695, 4619, 4912, 5669, 6586]
data = (
(1, 337718798),
(2, 290021904),
(3, 927964716),
(4, 826824516),
(5, 817140688),
(6, 618849040),
(7, 731035312),
(8, 881267080),
(9, 705626154),
(10, 719657120),
(11, 797446892),
(12, 925227624),
(13, 1241105346),
(14, 164909310),
(15, 150753960),
(16, 648597516),
(17, 574405542),
(18, 594244560),
(19, 474392986),
(20, 566715216),
)
tmp_set = set()
for rank, value in data:
tmp_set.add(int(value / CE[rank % 13]))
gcd_list = []
for a, b in itertools.permutations(tmp_set, 2):
gcd_list.append(math.gcd(a, b))
counter = Counter([x for x in gcd_list if 0 < x < 100])
#print(len(gcd_list))
#print(counter)
print(u'戦果係数は {:d} です'.format(counter.most_common(1)[0][0]))
import java.math.BigInteger;
import java.util.*;
import java.util.stream.Collectors;
public class Calculator {
private static final int[] RANKING_RATE_MAGIC_NUMBERS =
{8931, 1201, 1156, 5061, 4569, 4732, 3779, 4568, 5695, 4619, 4912, 5669, 6586};
public static int detectRateCoefficient(Map<Integer, Long> source) {
Set<BigInteger> set = new HashSet<>();
source.entrySet()
.stream()
.map(e -> e.getValue() / RANKING_RATE_MAGIC_NUMBERS[e.getKey() % 13])
.map(BigInteger::valueOf)
.forEach(set::add);
List<BigInteger> list = new ArrayList<>(set);
List<Integer> gcdList = new ArrayList<>();
while (list.size() > 1) {
BigInteger a = list.remove(0);
list.stream()
.map(b -> b.gcd(a))
.map(BigInteger::intValue)
//.filter(i -> i < 100)
.forEach(gcdList::add);
}
return gcdList.stream()
.collect(Collectors.groupingBy(e -> e, Collectors.counting()))
.entrySet()
.stream()
.max(Comparator.comparing(Map.Entry::getValue))
.map(Map.Entry::getKey)
.orElse(0);
}
}
@rsky
Copy link
Author

rsky commented Sep 19, 2017

% python3 autodetect.py
{368, 92, 46}

@rsky
Copy link
Author

rsky commented Sep 19, 2017

十分なサンプルがあればAPIレスポンスのみから戦果係数を導出することも可能ぽい。

@rsky
Copy link
Author

rsky commented Sep 19, 2017

Counterを使って最大公約数のうちから再頻出するものを抽出するように改修。1ページ分で十分いけそう。

% python3 autodetect.py
Counter({46: 18, 92: 10})
戦果係数は 46 です

@rsky
Copy link
Author

rsky commented Sep 19, 2017

1〜20位までをサンプリングした場合、組み合わせは380通り。これなら計算量も問題にならないし、十分に信頼度の高いデータが取れそう。

Counter({46: 190, 92: 74, 138: 54, 322: 16, 230: 8, 276: 6, 644: 6, 1242: 4, 690: 4, 2254: 2, 4830: 2, 1610: 2, 3726: 2, 20930: 2, 460: 2, 184: 2, 9154: 2, 1334: 2})

@rsky
Copy link
Author

rsky commented Sep 20, 2017

組み合わせを作る必要はなく、reduceで収束した最大公約数が戦果係数
rsky/logbook-kai-plugins@ef53a41
rsky/logbook-kai-plugins@48e8d2c

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment