1
1

More than 5 years have passed since last update.

# ハニカム歩き(2013.5.10の過去問)

Posted at

``````module Doukaku.Honeycomb (solve) where

type Point = (Double, Double)
type Direction = (Double, Double)

solve :: String -> String
solve = map snd . scanl (\ (p, _) d -> moveOn p d) ((0, 0), 'A') . map direct

direct :: Char -> Direction
direct '0' = (0, 1)
direct '1' = (cos (pi / 6), sin (pi / 6))
direct '2' = (cos (pi / 6), - sin (pi / 6))
direct '3' = (0, - 1)
direct '4' = (- cos (pi / 6), - sin (pi / 6))
direct '5' = (- cos (pi / 6), sin (pi / 6))

(.>.) :: Direction -> Direction -> Direction
(x, y) .>. (x', y') = (x + x', y + y')

move :: Point -> Direction -> Point
move (x, y) (dx, dy) = (x + dx, y + dy)

moveOn :: Point -> Direction -> (Point, Char)
moveOn p d = let p' = move p d
in case whereIs p' of
Just c -> (p', c)
Nothing -> (p, '!')

points :: [(Point, Char)]
points = zip points' alpha
where
alpha = ['A' .. 'Z'] ++ ['a' .. 'k']
circle n = reset \$ concatMap (replicate n . direct) "234501"
where
reset [] = direct '0' : []
reset ds = init ds ++ (last ds .>. direct '0') : []
directions = concatMap circle [0..]
points' = scanl move (0, 0) directions

whereIs :: Point -> Maybe Char
whereIs pt = fmap snd . head' . filter (inIt pt . fst) \$ points
where

inIt :: Point -> Point -> Bool
inIt (x, y) (cx, cy) = (x - cx) ^ (2 :: Int) + (y - cy) ^ (2 :: Int) < 0.5 ^ (2 :: Int)
``````

`(0, 0)`の座標からスタートして、`1`の長さずつxy平面を移動させています。

http://qiita.com/items/55641767510c2f9f235f に他の方の回答もありますので、見ると参考になるでしょう。

1
1
0

Register as a new user and use Qiita more conveniently

1. You get articles that match your needs
2. You can efficiently read back useful information
3. You can use dark theme
What you can do with signing up
1
1