バウンディングボックスを強調表示、パートII:六角形のグリッド


24

次のように、文字.との六角形のグリッドが与えられます#

 . . . . . . . .
. . . . # . . . 
 . # . . . # . .
. . . # . . . . 
 . . . . . # . .
. . . . . . . . 

あなたの仕事は#、さらに軸に沿った境界ボックス全体をさらに埋めること#です:

 . . . . . . . .
. . # # # # . . 
 . # # # # # . .
. . # # # # # . 
 . . # # # # . .
. . . . . . . . 

軸に揃えられた境界ボックスは、すべてを含む最小の凸六角形#です。六角形のグリッドの場合、考慮すべき3つの軸(W / E、SW / NE、NW / SE)があることに注意してください。

ここに画像の説明を入力してください

場合によっては、1つ以上のサイドに1つだけが含まれることを示す別の例を示します#

. . . . . . . .         . . . . . . . . 
 . # . . . . . .         . # # # # . . .
. . . . . # . .         . . # # # # . . 
 . . # . . . . .         . . # # # . . .
. . . . . . . .         . . . . . . . . 

これらを縮退した辺を持つ六角形として表示するか、上記のように境界ボックスを描くことができます。その場合、それらは依然として六角形です。

ここに画像の説明を入力してください

あまりにもハード?パートIをお試しください!

ルール

およびの代わりに、任意の2つの異なる非スペース印刷可能ASCII文字(0x21〜0x7Eを含む)を使用できます。私はとしてそれらを参照続けるだろうといえ明細書の残りの部分のために。#.#.

入力と出力は、単一の改行で区切られた文字列または文字列のリスト(各行に1つ)のいずれかですが、形式は一貫している必要があります。

入力に少なくとも1 #行が含まれ、すべての行が同じ長さであると想定できます。2つの異なる「種類」の行(スペースまたは非スペースで始まる)があることに注意してください- 入力が常に同じタイプで始まるとは限りません。境界ボックスは、与えられたグリッドの内側に常に収まると仮定できます。

プログラムまたは関数を記述し、入力を受け取り、出力を提供する当社の標準的な方法のいずれかを使用できます。

任意のプログラミング言語を使用できますが、これらの抜け穴はデフォルトでは禁止されています。

これはであるため、バイト単位で測定された最短の有効な答えが勝ちです。

テストケース

各テストケースには、入力と出力が隣り合っています。

#    #

 . .      . . 
# . #    # # #
 . .      . . 

 . #      . # 
. . .    . # .
 # .      # . 

 # .      # . 
. . .    . # .
 . #      . # 

 # .      # . 
# . .    # # .
 . #      # # 

 . #      # # 
# . .    # # #
 . #      # # 

. . #    . # #
 . .      # # 
# . .    # # .

# . .    # # .
 . .      # # 
. . #    . # #

. . . . . . . .         . . . . . . . . 
 . . # . # . . .         . . # # # . . .
. . . . . . . .         . . . # # . . . 
 . . . # . . . .         . . . # . . . .

. . . . . . . .         . . . . . . . . 
 . . # . . . # .         . . # # # # # .
. . . . . . . .         . . . # # # # . 
 . . . # . . . .         . . . # # # . .

. . . . . . . .         . . . . . . . . 
 . # . . . . . .         . # # # # . . .
. . . . . # . .         . . # # # # . . 
 . . . . . . . .         . . . . . . . .

. . . . . . . .         . . . . . . . . 
 . # . . . . . .         . # # # # . . .
. . . . . # . .         . . # # # # . . 
 . . # . . . . .         . . # # # . . .

. . . . # . . .         . . # # # # . . 
 . # . . . # . .         . # # # # # . .
. . . # . . . .         . . # # # # # . 
 . . . . . # . .         . . # # # # . .

1
明らかなパターンを見つけようとして頭が回転しています。「六角形」と言いましたが、テストケースでは六角形への入力形式は2つだけです。道に迷いました。
アナスタシヤロマノバ秀

1
@ Anastasiya-Romanova秀外側のキャラクターの中心を通過する形を想像すると、はい、いくつかの六角形は縮退した辺を持ちます(長方形が線に縮小する場合を得ることができる長方形のグリッドのように)。ただし、(図で行ったように)キャラクターの周りに長方形を描く場合、すべての例は六角形です(一部は非常に短い辺を持っています)。
マーティンエンダー

1
@ Anastasiya-Romanova秀新しい図は役立ちますか?
マーティンエンダー

3
私!IIのように見える私は..上の間違ったメガネがあれば
ニール

1
@ニールまたは、あなたが知っている、あまりにも多くのアルコール;)
ThreeFx

回答:


7

Pyth82 71バイト

L、hbebMqH @ S + GH1KhMyJs.e、Lkfq \#@ bTUb.zA、ySm-FdJySsMJj.es.eXW && gKkgG-kYgH + kYZ \。\#bz
MqH @ S [hGHeG)1j.es.eXW && ghMJs.e、Lkfq \#@ bTUb.zkgSm-FdJ-kYgSsMJ + kYZ \。\#bz

オンラインでお試しください!

説明

  • Aを最低のy座標を持つポイントとし、Bを最高のy座標を持つポイントとします。

  • Cを最小(x値からy値)のポイントとし、Dを最大のポイントとします。

  • Eを最低(x値+ y値)のポイントとし、Fを最高のポイントとします。

次に、y座標がAとBの間にあり、x値からy値を引いた値がCとDの間にあり、x値にy値を加えた値がEとFの間にある座標を見つけることに相当します。


SEアンドロイドアプリのみがタブ文字を正しく処理できた場合(何らかの理由で貼り付けたときに消えた)、最初にソリューションを投稿できたとき:/
Sarge Borsch

@SargeBorschごめんなさい:(
リーキー修道女

D:ハハ、それは私が失敗製SE Androidアプリ理由です
Sargeのボルシチ

6

Haskell、256 254 243バイト

import Data.List
f=z(\l->(,).(,))[0..]l)[0..]
q l=m(m(\e->min(snd e).(".#"!!).fromEnum.and.z($)(m(\x y->y>=minimum x&&y<=maximum x).transpose.m b.filter((==)'#'.snd).concat$l)$b e))l
b=(m uncurry[const,(-),(+)]<*>).pure.fst
z=zipWith
m=map
q.f

@Damien、ゴルフをありがとうf

入力は文字のリストのリストとして取得され、出力は同じ方法で提供されます。

スー、これは書くべき獣でした。これは、アイテムの座標に対する最大および最小ベースのフィルター処理を使用したLeakyNunのアイデアに基づいています。

m=mapコストがかかるように見えるので、実際にバイトを節約できるという事実に本当に驚いています。


説明:

以下は、少しだけ肉付けされていないバージョンです(やや強調):

import Data.List
f=zipWith(\y l->zipWith(\x e->((y,x),e))[0..]l)[0..]
p=map(\x y->y>=minimum x&&y<=maximum x).transpose.map b.filter((==)'#'.snd).concat
q l=map(map(\e->min(snd e).(".#"!!).fromEnum.and.zipWith($)(p$l)$b e))l
b=(map uncurry[const,(-),(+)]<*>).pure.fst
  • f(y-index, x-index)リストの元の構造を保持しながら、各文字にインデックスを割り当てる関数です。

  • b:インデックス付きリストのアイテムを指定すると、をb計算し[y-index, y - x, y + x]ます。

  • p:インデックス付きフィールドを指定すると、3つの関数が返されます。Int -> Bool最初の関数は、yインデックスのチェック、2番目の差、3番目の合計です。min(snd e)スペースを処理します(スペースは両方よりも小さい)。この関数は、ゴルフのコードにインライン化されています。

  • qインデックスフィールドを考えると、必要なすべての変更.には#、その特定のフィールドの復帰か否かをチェックすることによってTrue、すべてのテスト関数に。

最終的なソリューションは、との構成にqなりfます。


1
f=z(\y->z((,).(,)y)[0..])[0..]
ダミアン

またはh x=z x[0..] f=h$h.curry(,)
ダミアン

5

Pythonの3、380の 378 348 346バイト

インデントはスペースではなくタブで行われることに注意してください。

ゴルフバージョン:

def s(i):
    L=i.splitlines();E=enumerate;A=lambda x,y:(y,x+y,x-y);N=(2**64,)*3;X=(-2**64,)*3
    for y,l in E(L):
        for x,c in E(l):
            if c=='#':p=A(x,y);X=tuple(map(max,X,p));N=tuple(map(min,N,p))
    R=''
    for y,l in E(L):
        for x,c in E(l):
            if c!='.':R+=c
            else:p=A(x,y);f=all(N[j]<=p[j]<=X[j]for j in range(0,3));R+='.#'[f]
        R+='\n'
    return R

Ideoneでテストする

説明(以下の非ゴルフバージョンの場合):

すべての処理は変換なしで行われ、スペース文字は単にスキップされます。
関数axes_posは、3タプルの仮想「3D」座標を計算し、すべての文字の(要素ごとの)最小および最大3タプル(bminbmax)に累積し#ます。

座標はで計算されdef axes_pos(x, y): return y, x + y, lc - y + xます;
Xは0から右にカウントし、Yは0から下(最初の行から最後)にカウントします。
理由は明らかなので、最初の仮想座標は基本的にYです。そのaは緑の境界に直交しています(OPの写真で)
2番目は赤の境界に直交し、3番目は青の境界に直交しています。

2番目のパスでは、.「3D」座標が要素単位でbmin.. bmax範囲に入るすべての文字に対して置換が行われます。これは、この式でチェックされますall(bmin[j] <= p[j] <= bmax[j] for j in range(0, 3))

Ideoneのテスト付きのゴルフをしていないバージョン:

def solve(i):
    ls = i.splitlines()
    lc = len(ls)

    def axes_pos(x, y):
        return y, x + y, lc - y + x

    I = 2 ** 64
    bmin = (I, I, I)
    bmax = (0, 0, 0)

    for y, line in enumerate(ls):
        for x, char in enumerate(line):
            if char != '#': continue
            p = axes_pos(x, y)
            bmax = tuple(map(max, bmax, p))
            bmin = tuple(map(min, bmin, p))

    result = ''
    for y, line in enumerate(ls):
        for x, char in enumerate(line):
            if char != '.':
                result += char
            else:
                p = axes_pos(x, y)
                f = all(bmin[j] <= p[j] <= bmax[j] for j in range(0, 3))
                result += '#' if f else char
        result += '\n'

    return result


def run_test(a, b):
    result = solve(a)
    if result != b:
        raise AssertionError('\n' + result + '\n\nshould be equal to\n\n' + b)


def run_tests():
    run_test(
        "#\n",

        "#\n")

    run_test(
        " . . \n"
        "# . #\n"
        " . . \n",

        " . . \n"
        "# # #\n"
        " . . \n")

    run_test(
        " . # \n"
        ". . .\n"
        " # . \n",

        " . # \n"
        ". # .\n"
        " # . \n")

    run_test(
        " # . \n"
        ". . .\n"
        " . # \n",

        " # . \n"
        ". # .\n"
        " . # \n")

    run_test(
        " # . \n"
        "# . .\n"
        " . # \n",

        " # . \n"
        "# # .\n"
        " # # \n")

    run_test(
        " . # \n"
        "# . .\n"
        " . # \n",

        " # # \n"
        "# # #\n"
        " # # \n")

    run_test(
        ". . . . . . . . \n"
        " . . # . # . . .\n"
        ". . . . . . . . \n"
        " . . . # . . . .\n",

        ". . . . . . . . \n"
        " . . # # # . . .\n"
        ". . . # # . . . \n"
        " . . . # . . . .\n")

    run_test(
        ". . . . . . . . \n"
        " . . # . . . # .\n"
        ". . . . . . . . \n"
        " . . . # . . . .\n",

        ". . . . . . . . \n"
        " . . # # # # # .\n"
        ". . . # # # # . \n"
        " . . . # # # . .\n")

    run_test(
        ". . . . . . . . \n"
        " . # . . . . . .\n"
        ". . . . . # . . \n"
        " . . . . . . . .\n",

        ". . . . . . . . \n"
        " . # # # # . . .\n"
        ". . # # # # . . \n"
        " . . . . . . . .\n")

    run_test(
        ". . . . . . . . \n"
        " . # . . . . . .\n"
        ". . . . . # . . \n"
        " . . # . . . . .\n",

        ". . . . . . . . \n"
        " . # # # # . . .\n"
        ". . # # # # . . \n"
        " . . # # # . . .\n")

    run_test(
        ". . . . # . . . \n"
        " . # . . . # . .\n"
        ". . . # . . . . \n"
        " . . . . . # . .\n",

        ". . # # # # . . \n"
        " . # # # # # . .\n"
        ". . # # # # # . \n"
        " . . # # # # . .\n")


if __name__ == '__main__':
    run_tests()
更新1:

-1何も変更しないため、3番目の仮想座標に不要なものを削除しました

更新2,3:

Leaky Nun+私自身によって提案された部分的に実装された改善。


基本的に同じアルゴリズムを使用しますか?説明を追加してもらえますか?
リーキー修道女

1
def A(x,y):return y,x+y,len(L)-1-y+x->A=lambda x,y:(y,x+y,len(L)-1-y+x)
リーキー修道女

また、リストの内包表記は、いくつかのバイトをオフにするのに役立ちます。
リーキー修道女

1
私はあなたが回すことができると思うlen(L)-y+xx-y
漏れ修道女

1
行のリストを取得できます
漏れの修道女

5

ゼリー45 35 13 42 41 バイト

Ṁ€»\
ṚÇṚ«Çṁ"
ŒDṙZL$ÇṙL’$ŒḌ«Ç
ṚÇṚ«Ç
n⁶aÇo⁶

これはリンクのリストです。出力を生成するには、入力で最後のものを呼び出す必要があります。

I / Oは文字列配列の形式で、.空を@示し、塗りつぶしを示します。

オンラインでお試しください!または、すべてのテストケースを確認します

バックグラウンド

次の例を考えてみましょう。

. . . . . . . . 
 . @ . . . . . .
. . . . . @ . . 
 . . @ . . . . .

3つの方向のそれぞれに、ペアまたは平行線(すべての塗りつぶされた位置を囲む最も近いペア)を描画することにより、六角形の境界ボックスを決定できます。

実装では、これらの2行の間のすべての文字をで置き換え@、これらの行の外側のすべてをで置き換え.ます。ただし、スペースのみを含む対角線は例外です。

水平軸については、これにより

................
@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@

落下する対角軸については、

..@@@@@@@......
...@@@@@@@......
....@@@@@@@.....
 ....@@@@@@@....

上昇する対角軸については、

....@@@@@@@@@...
...@@@@@@@@@....
..@@@@@@@@@....
.@@@@@@@@@.... .

.<なので@、3つすべての文字単位の最小値を取得することにより、

...............
...@@@@@@@......
....@@@@@@@....
 ....@@@@@.... .

あとは、スペースを復元するだけです。

使い方

n⁶aÇo⁶           Main link. Argument: A (array of strings)

n⁶               Not-equal space; yield 0 for spaces, 1 otherwise.
  aÇ             Take the logical AND with the result the 4th helper link.
                 This will replace 1's (corresponding to non-space characters) with
                 the corresponding character that result from calling the link.
    o⁶           Logical OR with space; replaces the 0's with spaces.
ṚÇṚ«Ç            4th helper link. Argument: A

Ṛ                Reverse the order of the strings in A.
 Ç               Call the 3rd helper link.
  Ṛ              Reverse the order of the strings in the resulting array.
    Ç            Call the 3rd helper link with argument A (unmodified).
   «             Take the character-wise minimum of both results.
ŒDṙZL$ÇṙL’$ŒḌ«Ç  3rd helper link. Argument: L (array of strings)

ŒD               Yield all falling diagonals of L. This is a reversible operation,
                 so it begins with the main diagonal.
   ZL$           Yield the length of the transpose (number of columns).
  ṙ              Shift the array of diagonals that many units to the left.
                 This puts the diagonals in their natural order.
      Ç          Call the helper link on the result.
        L’$      Yield the decremented length (number of columns) of L.
       ṙ         Shift the result that many units to the left.
                 This puts the changed diagonals in their original order.
           ŒḌ    Undiagonal; reconstruct the string array.
              Ç  Call the 2nd helper link with argument L (unmodified).
             «   Take the character-wise minimum of both results.
ṚÇṚ«Çṁ"          2nd helper link. Argument: M (array)

Ṛ                Reverse the rows of M.
 Ç               Call the 1st helper link on the result.
  Ṛ              Reverse the rows of the result.
    Ç            Call the 1nd helper link with argument M (unmodified).
   «             Take the minimum of both results.
     ṁ"          Mold zipwith; repeat each character in the result to the left
                 as many times as needed to fill the corresponding row of M.
Ṁ€»\             1st helper link. Argument: N (array)

Ṁ€               Take the maximum of each row of N.
  »\             Take the cumulative maxima of the resulting characters.

2

Python、237 230バイト

デニスのおかげで7バイト。

def f(a):i=range(len(a[0]));j=range(len(a));b,c,d=map(sorted,zip(*[[x,x+y,x-y]for y in i for x in j if"?"<a[x][y]]));return[[[a[x][y],"#"][(a[x][y]>" ")*(b[0]<=x<=b[-1])*(c[0]<=x+y<=c[-1])*(d[0]<=x-y<=d[-1])]for y in i]for x in j]

Pythでの私の回答のポート。

入力として行の配列を取り、文字の2D配列を出力します。


2

Perl、128 126バイト

+6を含む -0F\n

STDINの入力で実行します。1塗りつぶし、0空の場合に使用します。行の最後にスペースを埋め込む必要はありません。

perl -M5.010 hexafill.pl
 0 0 0 0 0 0 0 0
0 0 1 1 1 1 0 0 
 0 1 1 1 1 1 0 0
0 0 1 1 1 1 1 0 
 0 0 1 1 1 1 0 0
0 0 0 0 0 0 0 0 
^D

hexafill.pl

#!/usr/bin/perl -0F\n
$-=map{s%$=%$=^!map{/$/;grep{pos=$`;$=?$_|="!"x$`.1:!/\b.*\G./}${--$@}}@F-$-+pos,$-+pos,$-%eeg;--$-;$=||say}@F while$=--

キューブ座標を使用します。$= == 1ループ中に最大値と最小値を決定し、ループ中にこれらの境界間の座標を塗りつぶし$= == 0ます。最初の58ループは無意味で$-、行数で埋めるためだけにあります


1

TSQL、768バイト

これを解決するためのクエリを作成しました-これは非常に難しいことがわかりました。すべての優れた短い答えに対抗することはできません。しかし、とにかく興味のある人には投稿したかった。答えの長さについては申し訳ありません-codegolfが異なるアプローチについても期待している

ゴルフ:

DECLARE @ varchar(max)=
'
. . . . # . . . 
 . # . . . # . .
. . . # . . . . 
 . . . . . # . .
. . . . . . . . 
'

;WITH c as(SELECT cast(0as varchar(max))a,x=0,y=1,z=0UNION ALL SELECT SUBSTRING(@,z,1),IIF(SUBSTRING(@,z,1)=CHAR(10),1,x+1),IIF(SUBSTRING(@,z,1)=CHAR(10),y+1,y),z+1FROM c WHERE LEN(@)>z)SELECT @=stuff(@,z-1,1,'#')FROM c b WHERE((exists(SELECT*FROM c WHERE b.y=y and'#'=a)or exists(SELECT*FROM c WHERE b.y<y and'#'=a)and exists(SELECT*FROM c WHERE b.y>y and'#'=a))and a='.')and(exists(SELECT*FROM c WHERE b.x<=x-ABS(y-b.y)and'#'=a)or exists(SELECT*FROM c WHERE b.x<=x+y-b.y and a='#'and b.y<y)and exists(SELECT*FROM c WHERE b.x<=x+b.y-y and a='#'and b.y>y))and(exists(SELECT*FROM c WHERE b.x>=x+ABS(y-b.y)and'#'=a)or exists(SELECT*FROM c WHERE b.x>=x-y+b.y and b.y<y and'#'=a)and exists(SELECT*FROM c WHERE b.x>=x-b.y+y and a='#'and b.y>y))OPTION(MAXRECURSION 0)PRINT @

ゴルフをしていない:

DECLARE @ varchar(max)=
'
. . . . # . . . 
 . # . . . # . .
. . . # . . . . 
 . . . . . # . .
. . . . . . . . 
'
;WITH c as
(
  SELECT 
    cast(0as varchar(max))a,x=0,y=1,z=0
  UNION ALL
  SELECT
    SUBSTRING(@,z,1),IIF(SUBSTRING(@,z,1)=CHAR(10),1,x+1),
    IIF(SUBSTRING(@,z,1)=CHAR(10),y+1,y),
    z+1
  FROM c
  WHERE LEN(@)>z
)
SELECT @=stuff(@,z-1,1,'#')FROM c b
WHERE((exists(SELECT*FROM c WHERE b.y=y and'#'=a)
or exists(SELECT*FROM c WHERE b.y<y and'#'=a)
and exists(SELECT*FROM c WHERE b.y>y and'#'=a)
)and a='.')
and 
(exists(SELECT*FROM c WHERE b.x<=x-ABS(y-b.y)and'#'=a)
or exists(SELECT*FROM c WHERE b.x<=x+y-b.y and a='#'and b.y<y)
and exists(SELECT*FROM c WHERE b.x<=x+b.y-y and a='#'and b.y>y))
and(exists(SELECT*FROM c WHERE b.x>=x+ABS(y-b.y)and'#'=a)
or exists(SELECT*FROM c WHERE b.x>=x-y+b.y and b.y<y and'#'=a)
and exists(SELECT*FROM c WHERE b.x>=x-b.y+y and a='#'and b.y>y))
OPTION(MAXRECURSION 0) 
PRINT @

フィドル・アンゴルフド


1

GNU Octave、 212、196のバイト

ゴルファーのお気に入りの選択言語ではないかもしれませんが、それが挑戦の理由ですよね?mがcharマトリックスと見なされると仮定します178バイトが独立しており、、関数に詰め込まれた場合は196です。

ゴルフ:

function k=f(m)[a,b]=size(m);[y,x]=ndgrid(1:a,1:b);t={y,y+x,x-y};k=m;s=x>0;for j=1:3l{j}=unique(sort(vec(t{j}.*(m==['#']))))([2,end]);s&=(l{j}(1)<=t{j})&(l{j}(2)>=t{j});endk(s&mod(x+y,2))=['#']end

なし:

function k=f(m)
[a,b]=size(m);[y,x]=ndgrid(1:a,1:b);t={y,y+x,x-y};k=m;s=x>0;
for j=1:3
  l{j}=unique(sort(vec(t{j}.*(m==['#']))))([2,end]);
  s&=(l{j}(1)<=t{j})&(l{j}(2)>=t{j});
end
k(s&mod(x+y,2))=['#']
end

説明:3軸の座標系を作成します-六角形の側面に直交し、各座標の最大値と最小値を見つけて、どこからでも論理的に1から始まる論理マスクを作成します:各座標の最大値と最小値の制約を設定し、最後に再設定します残りの各「true」位置から「#」文字へ。

テストする場合は、次のようにmマトリックスを作成するだけです。

m = [' . . . . . . . .. . . . # . . .  . # . . . # . .. . . # . . . .  . . . . . # . .. . . . . . . . ']; m = reshape(m,[numel(m)/6,6])';

次に、f(m)を呼び出して、両方の行列を作成してmと比較します。

['     before           after      ';m,ones(6,1)*'|',f(m)]

1
(遅刻)PPCGへようこそ!オクターブの回答は大歓迎です。:)ただし、次の2つです。1)スコアをより簡単に確認できるように、実際にカウントしたコード(不要な空白なし)を含めてください。読み取り可能なバージョンを個別に含めることができます。2)提出物は、入力がに保存されm、出力がに保存されるスニペットのようkです。回答は常に完全なプログラムまたは呼び出し可能な関数である必要があります。
マーティンエンダー

ありがとう!はい、そうです。関数fにkとmを埋め込み、検証用の最初のテストmを構成するスニペットを追加しました。
mathreadler
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.