採用試験に挑戦!

採用試験に挑戦 - 気楽に諸々をみて自分でもやってみたよ。SQL*1で。

問題:座標のグリッド揃え

  きれいにそろった図形というのはきれいな物です。
  図形をそろえる上で、グリッド揃え等が必要になったりするでしょう。
  これには座標をある一定のグリッド間隔に丸める必要があります。

 struct Position { int x; int y; } (Javaの場合にはclass)を int gridPitch に丸めるFitToGrid関数を書いて下さい。

採用面接で使った課題


structもclassもかったるいので、こんなテーブルを用意。

CREATE TABLE [dbo].[Positions](
	[x] [int] NOT NULL,
	[y] [int] NOT NULL,
 CONSTRAINT [PK_Position] PRIMARY KEY CLUSTERED 
(
	[x] ASC,
	[y] ASC
) ON [PRIMARY]
) ON [PRIMARY]


gridPitchもテーブルで指定しちゃえ。

CREATE TABLE [dbo].[GridPitches](
	[grid_pitch] [int] NOT NULL,
 CONSTRAINT [PK_GridPitches] PRIMARY KEY CLUSTERED 
(
	[grid_pitch] ASC
) ON [PRIMARY]
) ON [PRIMARY]


FitToGrid関数は、結果として取得できれば問題ないと解釈して作らずに、こんな感じ。

SELECT
    x
  , y
  , grid_pitch
    -- 予想値を使った場合のずれの方が小さければ予想値が、そうでなければ次の値が結果
  , CASE WHEN diff_x1 <= diff_x2 THEN probable_x ELSE next_probable_x END AS fit_to_grid_x
  , CASE WHEN diff_y1 <= diff_y2 THEN probable_y ELSE next_probable_y END AS fit_to_grid_y
FROM
    (SELECT
        x
      , y
        -- xとyの予想値
      , x / grid_pitch AS probable_x
      , y / grid_pitch AS probable_y
        -- xとyの予想値の次の値
      , x / grid_pitch + SIGN(x) AS next_probable_x
      , y / grid_pitch + SIGN(y) AS next_probable_y
        -- 予想値を使った場合のずれ
      , ABS(x - (x / grid_pitch * grid_pitch)) AS diff_x1
      , ABS(x - (x / grid_pitch + SIGN(x)) * grid_pitch) AS diff_x2
        -- 予想値の次の値を使った場合のずれ
      , ABS(y - (y / grid_pitch * grid_pitch)) AS diff_y1
      , ABS(y - (y / grid_pitch + SIGN(y)) * grid_pitch) AS diff_y2
      , grid_pitch
    FROM
        Positions, GridPitches) T
;


家に帰ってから検証しようかと思ったけどGridPitchesに0が入ってた場合の処理入れてないや。ハイ不正解。
ま、SQLでやってる時点で不採用確実ですけどね!

*1:SQL Server2000