Keep Hacking :)

Life is complex, it has both real and imaginary parts.

Project Euler 61的解答

題目介紹了六種數列,分別是三角形數、四角形數、五角形數、六角形數、七角形數和八角形數。現在問題要找出來六個數字,分別在這六個數列中,而且可以頭尾相連連成一圈。網頁上有舉一個長度為四的數列,如果不懂的話可以去看看。

做表查一下

這題好像出奇的簡單啊啊啊啊,我的做法是把這六種數列的頭兩位數字做成一個表,然後用後兩位數去查有沒有合的數字,然後就一直查下去,直到有六個數字分別來自六個數列並頭尾相連成一圈。

附上程式碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#!/usr/bin/env ruby -wKU
func = {
  3 => ->(x) {x * (x + 1) / 2},
  4 => ->(x) {x * x},
  5 => ->(x) {x * (3 * x - 1) / 2},
  6 => ->(x) {x * (2 * x - 1)},
  7 => ->(x) {x * (5 * x - 3) / 2},
  8 => ->(x) {x * (3 * x - 2)}
}

n, num, $type8 = 0, 0, []
$nums = Hash.new { |hash, key| hash[key] = [] }
while true
  n += 1
  (3 .. 8).reverse_each do |x|
    num = func[x].(n)
    if (1000 .. 9999).include?(num)
      if x == 8
        $type8 << num
      else
        $nums[num / 100] << [num, x]
      end
    end
  end
  break if num > 9999
end

def solve(num_set, types)
  if types.size == 6
    if num_set[0] / 100 == num_set[-1] % 100
      puts num_set.reduce(:+)
    end
  else
    $nums[num_set[-1] % 100].each do |n|
      unless types.include?(n[1])
        solve(num_set + [n[0]], types + [n[1]])
      end
    end
  end
end
$type8.each { |e| solve([e], [8]) }

Comments