Keep Hacking :)

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

有趣的猜數字謎題

這種題目感覺就是百出不厭,一些公司的面試題也會出現,不過解起來也是十分有趣:D

題目

老師心中想了一個兩位數。他把這兩位數的兩個數字和告訴了A,把這個兩位數的正因數個數告訴了B。

A:我不知道。

B:我也不知道, 但我知道是否為偶數。

A:我知道了。

B:我也知道了。

請問此兩位數是誰?

以前自己做這種題目,都是拿著筆一個一個慢慢淘汰,不過今天要選擇用把我的解題邏輯寫成程式碼,讓電腦幫我做淘汰這件事情:p

附上我的程式碼跟解題邏輯:

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
42
43
44
45
46
47
48
49
50
51
52
53
54
#!/usr/bin/env ruby

$digit_sum_hash = Hash.new { |hash, key| hash[key] = [] }
$div_num_hash = Hash.new { |hash, key| hash[key] = [] }
$num_list = (10 .. 99).to_a

def sum_of_digit(num)
  return num.to_s.split(//).map(&:to_i).inject(:+)
end

def num_of_div(num)
  ans = 0
  (1 .. num).each do |e|
    ans += 1 if num % e == 0
  end
  return ans
end

$num_list.each do |e|
  $digit_sum_hash[sum_of_digit(e)].push(e)
  $div_num_hash[num_of_div(e)].push(e)
end

def first_step(n)
  return $digit_sum_hash[sum_of_digit(n)].length >= 2
end

def second_step(n)
  subset = $div_num_hash[num_of_div(n)].select { |e| first_step(e) }
  return subset.length >= 2 &&
        (subset.all? { |e| e.even? } || subset.all? { |e| !(e.even?) })
end

def third_step(n)
  subset = $digit_sum_hash[sum_of_digit(n)].select { |e| second_step(e) }
  return (subset.length == 1)
end

def forth_step(n)
  subset = $div_num_hash[num_of_div(n)].select { |e|
    first_step(e) && third_step(e)
  }
  return (subset.length == 1)
end

def final_step
  subset = $num_list.select { |e|
    first_step(e) && second_step(e) &&
    third_step(e) && forth_step(e)
  }
  return subset
end

p final_step()

程式碼很多地方没有最佳化,因爲數字都還蠻小的(遮臉),如果有更好的寫法,還請不吝指教一下:D

解題邏輯也很直觀,就照着對話依序删减可能的數字,最後一步就會跑出唯一的解答。

下次有機會在分享一些有趣的題目:D

Comments