六角形の隣接

Example Hexagon Spiral

The above image displays a hexagonal grid of hexagons. Each cell
in the grid is assigned an index, starting from the center and
spiraling counterclockwise around as shown. Note that the
grid will continue indefinitely – the above picture is simply the
first section. The next hexagon would be adjacent to 60 and
37.

あなたの仕事は、このグリッド上の2つの指定されたセルが隣接しているかどうかを判断することです。

2つのセルインデックスが与えられている場合は真の値を出力し、そうでない場合はfalseの値を出力するプログラムまたは関数を記述します。

実用的な理由で制限されていない場合、コードは理論的にどんなサイズの入力に対しても機能するはずです。

真実のテストケース:

0, 1
7, 18
8, 22
24, 45
40, 64
64, 65

偽のテストケース:

6, 57
29, 90
21, 38
38, 60
40, 63
41, 39
40, 40

This is
so the shortest answer in bytes wins. Explanations, even for
non-esoteric languages, are encouraged.

ベストアンサー

Elixir, 263 257 264
223 214 218 214 bytes

a=fn x,y->i=&(&1*(&1-1)*3+1)
[x,y]=Enum.sort [x,y]
if x<1,do: y in 1..6,else: (y-x==1||fn->a=y-trunc i.((r=(:math.sqrt(12*x-3)+3)/6)+1)
t=trunc r
a in [0,1,rem(b=x-i.(t)+1, t)<1&&b-t*6!=0&&2]||b<2&&a==-1 end.())end

Try it
online!

非球形バージョン

def get_ring(x) do
    1/6*(:math.sqrt(12*x-3)+3)
end

def inv_get_ring(x), do: x*(x-1)*3+1

def ring_base(x), do: inv_get_ring(trunc(x))

def is_corner(x) do
    ring = trunc(get_ring(x))
    inv_ring = ring_base(リング)
    stuff = (x-inv_ring+1)
    rem(stuff, ring) == 0
end

def is_last(x),do: ring_base(get_ring(x)+1)-1 == x
def is_first(x),do: ring_base(get_ring(x)) == x

def hex_adj(x, y) do
    {x, y} = {min(x,y), max(x,y)}
    cond do 
        x == 0 ->y in 1..6      
        y-x==1 -> true
        true ->
            adj = trunc(inv_get_ring(get_ring(x)+1))
            number = if is_corner(x)&&!is_last(x), do: 2, else: 1
            if y-adj in 0..number do
                true
            else
                is_first(x) && y == adj-1
            end
    end
end
  • trunc(number) Returns the integer part of
    number
  • rem(a,b) Returns the remainder of a/b
  • cond do end This is equivalent to else if or
    switch case clauses in many imperative languages

説明

get_ring(index)

インデックスの「リング」を計算します。

例:1-6の場合は1、7-18の場合は2など

This only applies if the result is floored.
Trailing digits represent how far that tile is around the
ring.

inv_get_ring(リング)

Calculates the inverse of get_ring(index).

ring_base(リング)

リング内の最初のタイルのインデックスを計算します。

is_corner(index)

コーナーは、外側の輪に3つの奇妙なタイルがあるタイルです。 最も内側のリングは完全にコーナーから構成されています。

例:21,24,27,30,33,36

is_last(index)

このインデックスがリング内で最高の場合はtrueです。

is_first(index)

これがリングのベースタイルである場合はtrueです。

返信を残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です