練習問題 3.5.2

整数
x
x= 10 * y + z
を満たす整数の対
(y,z)
で表現できる. たとえば,
27
(2,7)
(3,-3)
(1,17)
さらに他の対で表現できる. 可能な表現の中から,
-5 <= z < 5
かつ
abs y
ができるだけ小さくなるように選べる. どの整数もこの方法で唯一に表現できることを示し,
repint x
が整数
x
のこの標準表現を返すように関数
repint
を定義せよ.



  q = x `div` 10
  r = x `mod` 10     
  とすると
  x = q * 10 + r   (1)
  0 ≦ r < 10     (2)
  したがって,任意の整数 x は対(q,r)で一意に表現できる.
  また(1)を変形すると
  x = (q+1) * 10 + (r-10)   (3)
  であるから,任意の整数 x は対(q+1,r-10)で一意に表現できる.
  x `mod` 10 < 5 の場合は y = q,   z = r
  5 ≦ x `mod` 10 の場合は y = q+1, z = r - 10
  とすれば,y および z は問題の仕様を満す.
repint
の定義は以下のとおり.


repint    ::  Integer -> (Integer,Integer)
repint x  =   if r < 5 then (q,r) else (q+1,r-10)
  where
    (q,r) = x `divMod` 10