Podświetl ramkę ograniczającą, część II: Siatka heksagonalna

24

Otrzymujesz sześciokątną siatkę postaci .i #, w ten sposób:

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

Twoim zadaniem jest, aby wypełnić całą oś wyrównany obwiedni #z dodatkowo #:

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

Obwiednia wyrównana do osi jest najmniejszym wypukłym sześciokątnym kształtem, który zawiera wszystkie elementy #. Zauważ, że w przypadku siatki sześciokątnej są należy wziąć pod uwagę trzy osie (W / E, SW / NE, NW / SE):

wprowadź opis zdjęcia tutaj

Oto kolejny przykład pokazujący, że w niektórych przypadkach jedna lub więcej stron będzie zawierać tylko jedną # :

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

Możesz albo zobaczyć je jako sześciokąty ze zdegenerowanymi bokami, lub możesz narysować wokół nich obwiednię, tak jak to zrobiłem powyżej, w którym to przypadku nadal są sześciokątami:

wprowadź opis zdjęcia tutaj

Zbyt trudne? Spróbuj część I!

Zasady

Możesz użyć dowolnych dwóch różnych znaków ASCII drukowalnych spacji (od 0x21 do 0x7E włącznie), zamiast #i .. Będę nadal odnosząc się do nich, jak #i .dla pozostałej części specyfikacji chociaż.

Dane wejściowe i wyjściowe mogą być albo pojedynczym ciągiem oddzielonym od linii, albo listą ciągów (po jednym dla każdej linii), ale format musi być spójny.

Możesz założyć, że wejście zawiera co najmniej jeden, #a wszystkie wiersze mają tę samą długość. Zauważ, że istnieją dwa różne „rodzaje” linii (zaczynające się spacją lub spacją) - możesz tego nie robić zakładać, że wejście zawsze zaczyna się od tego samego typu. Możesz założyć, że obwiednia zawsze pasuje do podanej siatki.

Możesz napisać program lub funkcję i użyć dowolnej z naszych standardowych metod otrzymywania danych wejściowych i zapewniania danych wyjściowych.

Możesz używać dowolnego języka programowania , ale pamiętaj, że te luki są domyślnie zabronione.

To jest , więc najkrótsza ważna odpowiedź - mierzona w bajtach wygrywa .

Przypadki testowe

Każdy przypadek testowy ma wejścia i wyjścia obok siebie.

#    #

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

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

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

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

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

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

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

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

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

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

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

. . . . # . . .         . . # # # # . . 
 . # . . . # . .         . # # # # # . .
. . . # . . . .         . . # # # # # . 
 . . . . . # . .         . . # # # # . .
Martin Ender
źródło
1
Moja głowa wiruje, próbując znaleźć jakiś oczywisty wzór. Powiedziałeś „heksagonalny”, ale w przypadkach testowych występują tylko dwa dane wejściowe w sześciokąty. Zgubiłem się.
Anastasiya-Romanova 秀
1
@ Anastasiya-Romanova 秀 Jeśli wyobrażasz sobie, że kształt przechodzi przez środek znaków zewnętrznych, to tak, niektóre sześciokąty będą miały zdegenerowane boki (jak na prostokątnej siatce, gdzie można uzyskać przypadki, w których prostokąt zmniejsza się do linii). Jeśli jednak narysujesz prostokąt wokół znaków (jak zrobiłem na schemacie), wszystkie przykłady są sześciokątami (niektóre z nich mają bardzo krótkie boki).
Martin Ender
1
@ Anastasiya-Romanova 秀 Czy nowy schemat pomaga?
Martin Ender
3
JA! wygląda jak II, jeśli mam złe okulary ...
Neil
1
@Neil Lub, wiesz, za dużo alkoholu;)
ThreeFx

Odpowiedzi:

7

Pyth , 82 71 bajtów

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

Wypróbuj online!

Wyjaśnienie

  • Niech A będzie punktem o najniższej współrzędnej y, a B punktem o najwyższej współrzędnej y.

  • Niech C będzie punktem o najniższej wartości (wartość x minus wartość y), a D punktem o najwyższej.

  • Niech E będzie punktem o najniższej wartości (wartość x plus wartość y), a F punktem o najwyższej wartości.

Zatem jest to równoważne ze znalezieniem współrzędnych, których współrzędna y znajduje się między A i B, wartość x minus wartość y jest pomiędzy C i D, a wartość x plus wartość y jest pomiędzy E i F.

Leaky Nun
źródło
po raz pierwszy, gdy mogłem opublikować rozwiązanie wcześniej, jeśli tylko aplikacja na Androida SE mogłaby poprawnie obsługiwać znaki tabulacji (z jakiegoś powodu zniknęły po wklejeniu): /
Sarge Borsch
@SargeBorsch Przepraszam :(
Leaky Nun
haha dlaczego, to aplikacja SE na Androida sprawiła, że ​​zawiodłem: D
Sarge Barszcz
6

Haskell, 256 254 243 bajtów

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

Dzięki @Damien za grę w golfa f!

Dane wejściowe są traktowane jako lista list znaków, dane wyjściowe są podawane w ten sam sposób.

To była bestia do napisania. Opiera się na pomyśle LeakyNun przy użyciu filtrowania opartego na maksimum i minimum na współrzędnych przedmiotów.

Jestem naprawdę zaskoczony faktem, że m=mapfaktycznie oszczędza bajty, ponieważ wydaje się to tak kosztowne.


Wyjaśnienie:

Oto nieco mniej zamaskowana wersja (nacisk nieco ):

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
  • fto funkcja, która przypisuje każdemu znakowi indeks (y-index, x-index), zachowując oryginalną strukturę listy.

  • b: Biorąc pod uwagę pozycję z indeksowanej listy, boblicza [y-index, y - x, y + x].

  • p: Biorąc pod uwagę pole indeksowane, zwróć 3 funkcje Int -> Bool, z których pierwszą jest sprawdzenie indeksu y, druga różnicy i trzecia suma. min(snd e)zajmuje się przestrzeniami (przestrzeń jest mniejsza od obu). Ta funkcja jest wbudowana w kod do gry w golfa.

  • qbiorąc pod uwagę pola indeksowane, zmień wszystkie niezbędne .do #sprawdzając czy tego zwrotu danej dziedzinieTrue do każdej funkcji testowej.

Ostatecznym rozwiązaniem jest wówczas skład qi f.

ThreeFx
źródło
1
f=z(\y->z((,).(,)y)[0..])[0..]
Damien
lubh x=z x[0..] f=h$h.curry(,)
Damien
5

Python 3, 380 378 348 346 bajtów

Zauważ, że wcięcie ma tabulatory, a nie spacje.

Wersja golfowa:

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

Przetestuj na Ideone

Objaśnienie (dla wersji bez golfa poniżej):

Wszystkie przetwarzanie odbywa się bez konwersji, znaki spacji są po prostu pomijane.
Funkcja axes_posoblicza 3-krotne wyimaginowane współrzędne „3D”, są one kumulowane w minimalnych i maksymalnych 3-krotnych ( bmin, bmax) dla wszystkich #znaków.

Współrzędne są obliczane w def axes_pos(x, y): return y, x + y, lc - y + x;
gdzie X liczy się od 0 do prawej, a Y liczy się od 0 do dołu (od pierwszej linii do ostatniej).
Pierwsza wyobrażona współrzędna to w zasadzie Y, ponieważ jest oczywiste, dlaczego. Jego topór jest prostopadły do ​​zielonych granic (na zdjęciach PO).
Drugi jest prostopadły do ​​czerwonych granic, a trzeci prostopadły do ​​niebieskich granic.

W drugim przejściu zastępowane są wszystkie .znaki, których współrzędne „3D” mieszczą się w bminbmaxzakresie, jeśli chodzi o element - jest to zaznaczone w tym wyrażeniu all(bmin[j] <= p[j] <= bmax[j] for j in range(0, 3)).

Wersja bez golfa z testami, także na 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()
Aktualizacja 1:

Usunięto niepotrzebne -1dla trzeciej wyobrażonej współrzędnej, ponieważ nic to nie zmienia

Aktualizacja 2,3:

Częściowo zaimplementowane ulepszenia sugerowane również przez Leaky Nun+ moje.

Barszcz Sarge
źródło
Czy w zasadzie używamy tego samego algorytmu? Czy możesz dołączyć wyjaśnienie?
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)
Leaky Nun
Ponadto, lista ze zrozumieniem może pomóc ci w odegraniu niektórych bajtów.
Leaky Nun
1
Myślę, że można włączyć len(L)-y+xdox-y
Dziurawy Nuna
1
Możesz wziąć listę linii
Leaky Nun
5

Galaretka , 45 35 13 42 41 bajtów

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

To jest lista linków; ostatni musi zostać wywołany na wejściu, aby uzyskać wynik.

I / O ma postać tablic łańcuchowych, gdzie .wskazuje pusty i @wskazuje wypełniony.

Wypróbuj online! lub zweryfikuj wszystkie przypadki testowe .

tło

Rozważmy następujący przykład.

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

Rysując parę lub równoległe linie - najbliższą parę obejmującą wszystkie wypełnione pozycje - w każdym z trzech kierunków, możemy określić sześciokątną ramkę ograniczającą.

W implementacji zamieniamy wszystkie znaki między tymi dwiema liniami @i wszystko poza tymi liniami na ., z możliwym wyjątkiem przekątnych zawierających tylko spacje).

W przypadku osi poziomej daje to

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

dla opadającej osi ukośnej daje

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

a dla podniesienia osi ukośnej daje

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

Biorąc pod względem charakteru minimum wszystkich trzech, ponieważ .< @, otrzymujemy

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

Pozostało tylko przywrócić miejsca.

Jak to działa

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.
Dennis
źródło
2

Python, 237 230 bajtów

7 bajtów dzięki Dennisowi.

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]

Port mojej odpowiedzi w Pyth .

Pobiera tablicę wierszy jako dane wejściowe, generuje tablicę znaków 2D.

Leaky Nun
źródło
2

Perl, 128 126 bajtów

Obejmuje +6 za -0F\n

Uruchom z wejściem na STDIN. Użyj 1dla wypełnionego, 0dla pustego. Linie nie muszą być wypełnione spacjami na końcu:

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$=--

Wykorzystuje współrzędne kostki. Określ maksimum i minimum podczas $= == 1pętli i wypełnia współrzędne między tymi granicami podczas $= == 0pętli. Pierwsze 58 pętli jest bezcelowe i jest tylko po to, by wypełnić $-je liczbą linii

Ton Hospel
źródło
1

TSQL, 768 bajtów

Napisałem zapytanie, aby rozwiązać ten problem - co było dla mnie dość trudne. Nie jest w stanie konkurować z doskonałą krótszą odpowiedzią. Ale i tak chciałem to opublikować dla zainteresowanych. Przepraszam za długość odpowiedzi - mam nadzieję, że codegolf dotyczy również różnych podejść.

Gra w golfa:

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 @

Nie golfowany:

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 @

Skrzypce bez golfa

t-clausen.dk
źródło
1

GNU Octave, 212 , 196 bajtów

Może nie jest to ulubiony język golfisty, ale to właśnie stanowi wyzwanie, prawda? Zakładając, że m jest traktowane jako macierz char: 178 bajtów autonomicznie i 196, jeśli są wypełnione funkcją .

grał w golfa:

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

bez golfa:

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

Wyjaśnienie : budujemy układ współrzędnych, 3 osie - prostopadłe do boków sześciokątów, znajdujemy maksimum i min dla każdej współrzędnej, następnie budujemy maskę logiczną zaczynając od 1 wszędzie i logicznie oraz: łącząc ograniczenia maks. I min. Każdej współrzędnej, w końcu ponownie ustawiając każda pozostała „prawdziwa” pozycja do znaku „#”.

Jeśli chcesz to przetestować, możesz po prostu utworzyć macierz m:

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

a następnie wywołaj f (m) i porównaj z m, budując macierz z obydwoma w:

['     before           after      ';m,ones(6,1)*'|',f(m)]
matematyk
źródło
1
(Spóźniony) Witamy w PPCG! Odpowiedzi na oktawy są mile widziane. :) Dwie rzeczy: 1) dołącz kod, który faktycznie policzyłeś (bez zbędnych białych znaków), aby ludzie mogli łatwiej sprawdzić wynik. Możesz dołączyć osobną wersję do odczytu. 2) Wygląda na to, że przesłanie jest fragmentem, który zakłada, że ​​dane wejściowe mają zostać zapisane, ma dane wyjściowe mają zostać zapisane k. Odpowiedzi powinny zawsze być pełnymi programami lub funkcjami wywoływalnymi.
Martin Ender
Dzięki! Tak, masz rację, teraz osadziłem k i mw funkcji f i dodałem urywek konstruujący pierwszy test m w celu sprawdzenia poprawności.
mathreadler