google の入社試験

rscの日記さんのところで知りました。
Googleの入社試験です。次の覆面算を解きなさい : IT速報

WWWDOT - GOOGLE = DOTCOM

ただし、EとMは交換可能。

Ruby で解いてみました。

def to_int(a, b, c, d ,e, f)
  a * 10 ** 5 + b * 10 ** 4 + c * 10 ** 3 + d * 10 ** 2 + e * 10 + f
end

ans = []
(0..9).to_a.permutation(9) do |ar|
  w, d, o, t, g, l, e, c, m = ar
  a = to_int(w, w, w, d, o ,t)
  b = to_int(g, o, o, g, l, e)
  f = to_int(d, o, t, c, o, m)
  ans << ar if a - b == f
end
p ans.uniq
#=>[[7, 5, 8, 9, 1, 0, 3, 4, 6], [7, 5, 8, 9, 1, 0, 6, 4, 3]]

つまり

(w, d, o, t, g, l, e, c, m)  = (7, 5, 8, 9, 1, 0, 3, 4, 6), (7, 5, 8, 9, 1, 0, 6, 4, 3)

実行時間は僕の環境で 4.5秒くらいです。実際に E と M が交換可能になっています。

追記(3/19)

コメント欄に書き込まれた mathnb さんの提出された覆面算も、まったく同様に解けます。同じで芸がないのですが。上と同じく Ruby で求めています。
多少改良したのはメソッド to_int で、引数を配列にすることにより任意の桁数で使えるようにしました。

def to_int(ar)
  r = 0
  ar.size.times {|i| r += ar[- i - 1] * (10 ** i)}
  r
end

ans = []
(0..9).to_a.permutation(8) do |ar|
  r, s, t, u, v, x, y, z = ar
  next if r.zero? or s.zero? or t.zero? or u.zero? or v.zero? or x.zero?
  a1 = to_int([r, s, t, u, v])
  a2 = to_int([s, s, t, u, v])
  a3 = to_int([t, t, t, u, v])
  a4 = to_int([u, u, u, u, v])
  a5 = to_int([v, v, v, v, v])
  b  = to_int([x, x, y, y, z, z])
  ans << ar if a1 + a2 + a3 + a4 + a5 == b
end
p ans.uniq    #=>[[2, 4, 9, 7, 8, 3, 6, 0]]

つまり

(r, s, t, u, v, x, y, z) = (2, 4, 9, 7, 8, 3, 6, 0)

です。実行時間は約 5.4秒でした。

少しだけ改良してみます。一の位を見ると z は明らかに 5 の倍数なので、0 または 5 です。なので、next if .. の行の下に

  next if z != 0 and z != 5

を挿入すると若干高速化し、実行時間は約 2.1秒になります。