Destaque a caixa delimitadora, parte II: grade hexagonal

24

Você recebe uma grade hexagonal dos personagens .e #, assim:

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

Sua tarefa é preencher toda a caixa delimitadora alinhado ao eixo da #com ainda mais #:

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

A caixa delimitadora alinhada ao eixo é a menor forma hexagonal convexa que contém todas as #. Observe que, no caso da grade hexagonal, existem três eixos a serem considerados (L / E, SW / NE, NW / SE):

insira a descrição da imagem aqui

Aqui está outro exemplo para mostrar que, em alguns casos, um ou mais lados conterão apenas um #:

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

Você pode visualizá-los como hexágonos com lados degenerados ou pode desenhar a caixa delimitadora ao redor deles, como eu fiz acima, caso em que ainda são hexágonos:

insira a descrição da imagem aqui

Demasiado difícil? Tente a Parte I!

Regras

Você pode usar quaisquer duas distintas não espaciais caracteres imprimíveis ASCII (0x21 a 0x7E, inclusive), no lugar de #e .. Continuarei me referindo a eles como #e .pelo restante da especificação.

Entrada e saída podem ser uma única sequência separada por avanço de linha ou uma lista de sequências (uma para cada linha), mas o formato precisa ser consistente.

Você pode assumir que a entrada contém pelo menos uma #e todas as linhas têm o mesmo comprimento. Observe que existem dois "tipos" de linhas diferentes (começando com um espaço ou um não-espaço) - você pode não assumir que a entrada sempre começa com o mesmo tipo. Você pode assumir que a caixa delimitadora sempre se encaixa dentro da grade que você recebe.

Você pode escrever um programa ou função e usar qualquer um dos nossos métodos padrão de recebimento de entrada e saída.

Você pode usar qualquer linguagem de programação , mas observe que essas brechas são proibidas por padrão.

Isso é , então a resposta mais curta e válida - medida em bytes - vence.

Casos de teste

Cada caso de teste tem entrada e saída próximos um do outro.

#    #

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

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

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

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

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

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

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

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

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

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

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

. . . . # . . .         . . # # # # . . 
 . # . . . # . .         . # # # # # . .
. . . # . . . .         . . # # # # # . 
 . . . . . # . .         . . # # # # . .
Martin Ender
fonte
11
Minha cabeça está girando, tentando encontrar algum padrão óbvio. Você disse 'hexagonal', mas há apenas duas entradas formadas em hexágonos nos casos de teste. Estou perdido.
Anastasiya-Romanova秀
11
@ Anastasiya-Romanova 秀 Se você imaginar a forma passando pelos centros dos caracteres externos, sim, alguns hexágonos terão lados degenerados (como na grade retangular, onde você pode obter casos em que o retângulo se reduz a uma linha). No entanto, se você desenhar o retângulo ao redor dos caracteres (como fiz no diagrama), todos os exemplos serão hexágonos (alguns dos quais têm lados muito curtos).
Martin Ender
11
@ Anastasiya-Romanova the O novo diagrama ajuda?
Martin Ender
3
EU! olhares como II se eu tenho os óculos errados sobre ..
Neil
11
@ Neil Ou, você sabe, muito álcool;)
ThreeFx

Respostas:

7

Pyth , 82 71 bytes

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

Experimente online!

Explicação

  • Seja A o ponto com a coordenada y mais baixa e B o ponto com a coordenada y mais alta.

  • Seja C o ponto com o mais baixo (valor x menos valor y) e D o ponto com o mais alto.

  • Seja E o ponto com o mais baixo (valor x mais valor y) e F o ponto com o mais alto.

Então é equivalente a encontrar as coordenadas em que a coordenada y está entre A e B, o valor x menos o valor y está entre C e D, e o valor x mais o valor y está entre E e F.

Freira Furada
fonte
a primeira vez em que eu poderia postar uma solução mais cedo, se apenas o SE android aplicativo pode lidar corretamente com caracteres de tabulação (por alguma razão eles desapareceram quando colado): /
Sarge Borsch
@SargeBorsch Sinto muito :(
Leaky Nun
haha por que, é o aplicativo SE Android que me fez falhar: D
Sarge Borsch
6

Haskell, 256 254 243 bytes

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

Obrigado @ Damien por jogar golfe f!

A entrada é tomada como lista de lista de caracteres, a saída é fornecida da mesma maneira.

Então isso era uma fera para escrever. É baseado na idéia de LeakyNun, usando uma filtragem máxima e mínima nas coordenadas dos itens.

Estou realmente surpreso com o fato de m=maprealmente salvar bytes, pois parece muito caro.


Explicação:

Aqui está uma versão um pouco menos massacrada (ênfase em um pouco ):

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é uma função que atribui a cada caracter um índice (y-index, x-index), preservando a estrutura original da lista.

  • b: Dado um item da lista indexada, bcalcula [y-index, y - x, y + x].

  • p: Dado o campo indexado, retorne 3 funções Int -> Bool, a primeira das quais é a verificação do índice y, a segunda da diferença e a terceira da soma. min(snd e)cuida dos espaços (um espaço é menor que ambos). Esta função está embutida no código do golfe.

  • qdado o campo indexado, mudar tudo necessário .para #verificando se esse campo específico de retorno Truepara cada função de teste.

A solução final é então a composição de qe f.

ThreeFx
fonte
11
f=z(\y->z((,).(,)y)[0..])[0..]
Damien
ouh x=z x[0..] f=h$h.curry(,)
Damien
5

Python 3, 380 378 348 346 bytes

Observe que o recuo é com guias, não espaços.

Versão Golfed:

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

Teste no Ideone

Explicação (para versão não destruída abaixo):

Todo o processamento é feito sem nenhuma conversão; os caracteres de espaço são simplesmente ignorados.
A função axes_poscalcula três tuplas de coordenadas "3D" imaginárias, elas são acumuladas em (três elementos) mínimo e máximo de três tuplas ( bmin, bmax) para todos os #caracteres.

As coordenadas são calculadas em def axes_pos(x, y): return y, x + y, lc - y + x;
onde X conta de 0 para a direita e Y conta de 0 para baixo (da primeira linha à última).
A primeira coordenada imaginária é basicamente Y, porque é óbvio o porquê. Seu machado é ortogonal a verde (nas fotos do OP) O
segundo é ortogonal a vermelho e o terceiro é ortogonal a azul.

Na segunda passagem, a substituição é feita por todos os .caracteres cujas coordenadas "3D" se enquadram em bmin.. bmaxrange, element wise - isso é verificado nesta expressão all(bmin[j] <= p[j] <= bmax[j] for j in range(0, 3)).

Versão ungolfed com testes, também em 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()
Atualização 1:

Removido desnecessário -1para a terceira coordenada imaginária, porque não altera nada

Atualização 2,3:

Melhorias parcialmente implementadas sugeridas por Leaky Nun+ meu próprio também.

Sarge Borsch
fonte
Basicamente, usamos o mesmo algoritmo? Você poderia acrescentar uma explicação?
Leaky Nun
11
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
Além disso, a compreensão da lista pode ajudá-lo a obter alguns bytes de folga.
Leaky Nun
11
Eu acho que você pode se transformar len(L)-y+xemx-y
Freira Furada
11
Você pode ver a lista de linhas
Leaky Nun
5

Geléia , 45 35 13 42 41 bytes

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

Esta é uma lista de links; o último deve ser chamado na entrada para produzir a saída.

A E / S está na forma de matrizes de cadeias, onde .indica vazio e @indica preenchido.

Experimente online! ou verifique todos os casos de teste .

fundo

Vamos considerar o seguinte exemplo.

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

Ao desenhar um par ou linhas paralelas - o par mais próximo que envolve todas as posições preenchidas - em cada uma das três direções, podemos determinar a caixa delimitadora hexagonal.

Na implementação, substituímos todos os caracteres entre essas duas linhas por @e tudo fora dessas linhas por ., com a possível exceção de diagonais que contêm apenas espaços).

Para o eixo horizontal, isso fornece

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

para o eixo diagonal em queda, fornece

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

e para o eixo diagonal de elevação, fornece

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

Tomando o mínimo de caráter dos três, já que .< @, obtemos

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

Tudo o que resta a fazer é restaurar os espaços.

Como funciona

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
fonte
2

Python, 237 230 bytes

7 bytes graças a Dennis.

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]

Porto da minha resposta em Pyth .

Pega a matriz de linhas como entrada, gera uma matriz de caracteres 2D.

Freira Furada
fonte
2

Perl, 128 126 bytes

Inclui +6 para -0F\n

Execute com entrada no STDIN. Use 1para preenchido, 0para vazio. As linhas não precisam ser preenchidas com espaços no final:

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

Usa coordenadas do cubo. Determine o máximo e o mínimo durante o $= == 1loop e preenche as coordenadas entre esses limites durante o $= == 0loop. Os primeiros 58 loops são inúteis e existem apenas para serem preenchidos $-com o número de linhas

Ton Hospel
fonte
1

TSQL, 768 bytes

Eu escrevi uma consulta para resolver isso - o que achei bastante difícil. Não é capaz de competir com toda a excelente resposta mais curta. Mas queria publicá-lo de qualquer maneira para os interessados. Desculpe o tamanho da resposta - esperando que o codegolf também seja sobre abordagens diferentes.

Golfe:

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 @

Ungolfed:

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 @

Violino sem Golfe

t-clausen.dk
fonte
1

Oitava GNU, 212 , 196 bytes

Talvez não seja realmente o idioma preferido do jogador, mas é isso que faz o desafio, não é? Assumindo que m é tomado como uma matriz de caracteres: 178 bytes independentes e 196 se inseridos em uma função .

golfed:

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

ungolfed:

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

Explicação : construímos um sistema de coordenadas, 3 eixos - ortogonais aos lados dos hexágonos, localizamos max e min de cada coordenada e, em seguida, construímos uma máscara lógica começando com 1 em todos os lugares e logicamente e: cada restrição de max e min de coordenadas, finalmente redefinindo cada posição "verdadeira" restante para "#" char.

Se você quiser testá-lo, basta criar uma matriz m assim:

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

e, em seguida, chame f (m) e compare com m construindo uma matriz com os dois em:

['     before           after      ';m,ones(6,1)*'|',f(m)]
mathreadler
fonte
11
Bem-vindo ao PPCG! Respostas oitavas são mais que bem-vindas. :) Porém, duas coisas: 1) inclua o código que você realmente contou (sem espaço em branco desnecessário), para que as pessoas possam verificar a pontuação mais facilmente. Você pode incluir uma versão legível separadamente. 2) Parece que seu envio é um trecho que assume que a entrada a ser armazenada me a saída a ser armazenada k. As respostas devem sempre ser programas completos ou funções que podem ser chamadas.
Martin Ender
Obrigado! Sim, você está certo, eu incorporei k em uma função f agora e adicionei um trecho construindo um primeiro teste m para validação.
mathreadler