無聊なる日々の雑記

音楽のこととかプログラムのこととかつらつらと・・・

森博嗣 ビリヤードの問題をPython (jupyter) を使って力技で解いてみた

森博嗣 ビリヤード

で検索すると,どんな問題か出てくるので興味のある方は検索して下さい.

 

以下,プログラミング素人による度し難いコードをそのまま貼ります.

 

----

import numpy as np import itertools

 

# すべての数字が連続しているかの確認 def sort_fun(input):     sort_a = np.sort(input)     len_input = len(input)     for k in range(len_input-1):         if 1 != sort_a[k+1] - sort_a[k]:             output = 1             return output     output = 0     return output

 

# 数字の全パターン取り出し def find_each_sum(input):     rep = len(input)     input2 = list(input)+list(input)     output =     if rep > 1:         for i in range(rep-1):             for j in range(rep):                 output.append(sum(input2[j:j+i+1]))         output.append(sum(input[:]))     return output

 

def adeq_num(input):     max_num = input**2-input+1     total_mat = np.array(list(range(max_num-2)))+3     total_com = list(itertools.combinations(total_mat, input-2))

    col,row = np.shape((total_com))     out =      for ite in range(col):         if sum(total_com[ite]) == max_num-3:             adeq = list([1,2])+list(total_com[ite])             out.append(adeq)     return out

 

# ビリヤードの玉の数 n = 5 out_mat = adeq_num(n) len_adeq = len(out_mat)

result = [] for kk in range(len_adeq):     each_cand = list(itertools.permutations(out_mat[kk][1:], n-1))     cand_num = len(each_cand)          for ite in range(cand_num):         new_mat = list([1]) + list(each_cand[ite])         each_sum = find_each_sum(new_mat)         if sort_fun(each_sum) == 0:             result.append(new_mat)             print(new_mat)

 

----

 

4個の場合 [1, 3, 2, 7], [1, 7, 2, 3], [1, 2, 6, 4], [1, 4, 6, 2]

5個の場合 [1, 3, 10, 2, 5], [1, 5, 2, 10, 3] 6個の場合 [1, 7, 3, 2, 4, 14],[1, 14, 4, 2, 3, 7], [1, 3, 6, 2, 5, 14],[1, 14, 5, 2, 6, 3], [1, 3, 2, 7, 8, 10],[1, 10, 8, 7, 2, 3], [1, 2, 5, 4, 6, 13],[1, 13, 6, 4, 5, 2], [1, 2, 7, 4, 12, 5],[1, 5, 12, 4, 7, 2] 7個の場合 なし 8個の場合 [1, 4, 22, 7, 3, 6, 2, 12],[1, 12, 2, 6, 3, 7, 22, 4], [1, 6, 12, 4, 21, 3, 2, 8],[1, 8, 2, 3, 21, 4, 12, 6], [1, 4, 2, 10, 18, 3, 11, 8],[1, 8, 11, 3, 18, 10, 2, 4], [1, 3, 5, 11, 2, 12, 17, 6],[1, 6, 17, 12, 2, 11, 5, 3], [1, 3, 8, 2, 16, 7, 15, 5],[1, 5, 15, 7, 16, 2, 8, 3], [1, 2, 10, 19, 4, 7, 9, 5],[1, 5, 9, 7, 4, 19, 10, 2]

 

9個場合はメモリーエラー

 

総当たりという力技なので随所スリムにできると思います.

興味ある方はこの酷いコードをいじってみて下さい.

 

こうして貴重な休日を二日ほど消費したわけだ・・・