Esticar uma matriz


13

Anteriormente , defini o processo de esmagar uma matriz

Em uma paixonite, lemos a matriz da esquerda para a direita. Se em um ponto encontramos dois elementos iguais seguidos, removemos o primeiro e duplicamos o segundo.

Por exemplo, aqui está o processo de esmagar a seguinte matriz

[5,2,2,4]
 ^
[5,2,2,4]
   ^
[5,2,2,4]
     ^
[5,4,4]
   ^
[5,4,4]
     ^
[5,8]
   ^

Observe que o mesmo elemento pode ser recolhido várias vezes. No exemplo 2,2,4foi recolhido 8em uma única passagem.

Agora, esmagar matrizes é fácil, o difícil é esmagá-las. Sua tarefa é pegar uma matriz de números inteiros positivos como entrada e gerar a maior matriz que pode formar a entrada quando pressionada repetidamente. Por exemplo, a matriz [4]é formada por esmagamento, [2,2]que por sua vez é formado por esmagamento [1,1,1,1]. Como não podemos ter valores não inteiros, [1,1,1,1]não podemos mais ser esmagados e, portanto, é a nossa resposta.

Você nunca receberá um 0em sua matriz de entrada porque essas matrizes podem ser expandidas indefinidamente. Você também nunca receberá um caso com dois do mesmo número ímpar um ao lado do outro; esses casos não podem ser o resultado de uma trituração.

Isso é então as respostas serão pontuadas com o tamanho da fonte medido em bytes, com menos bytes sendo melhores.

Antes de começar a responder, quero apenas dizer que esse desafio é significativamente mais difícil do que parece. Verifique sua intuição à medida que avança e verifique se sua resposta passa em todos os casos de teste.

Casos de teste

[] -> []
[5] -> [5]
[6] -> [3,3]
[8] -> [1,1,1,1,1,1,1,1]
[4,8] -> [1,1,1,1,1,1,1,1,1,1,2]
[2,8] -> [1, 1, 1, 1, 2, 1, 1, 1, 1]
[4,4] -> [1,1,1,1,1,1,1,1]

1
Desculpe, mas ainda não consigo entender a regra. por que [1,1,1,1,1,1,1,1,1,1,2]produzir em [4, 8]vez de [8, 4]? deve ser isso [1,>1,1,1,1,1,1,1,1,1,2], [2,1,>1,1,1,1,1,1,1,2], [2,>2,1,1,1,1,1,1,2], [4,1,>1,1,1,1,1,2], [4,2,1,>1,1,1,2], [4,2,>2,1,1,2], [4,>4,1,1,2], [8,1,>1,2], [8,2,>2], [8,4]?
TSH

2
@tsh Acho que você tem um equívoco na maneira como a britagem funciona. Aqui é o caminho que leva primeira passagem: [1,>1,1,1,1,1,1,1,1,1,2], [2,>1,1,1,1,1,1,1,1,2], [2,1,>1,1,1,1,1,1,1,2], [2,2,>1,1,1,1,1,1,2], [2,2,1,>1,1,1,1,1,2], [2,2,2,>1,1,1,1,2], [2,2,2,1,>1,1,1,2], [2,2,2,2,>1,1,2], [2,2,2,2,1,>1,2], [2,2,2,2,2,>2], [2,2,2,2,4>], segunda passagem: [2,>2,2,2,4], [4,>2,2,4], [4,2,>2,4], [4,4,>4], [4,8>]. Espero que isso esclareça. Se você deseja que algum código veja a pergunta anterior, tem respostas que implementam uma função de esmagamento.
Post Rock Garf Hunter

Tudo bem se eu apresentar números, cada um separado por uma nova linha?
scottinet

@ scottinet Essa é uma maneira razoável de gerar uma lista. Continue.
Post Rock Garf Hunter

O caso de teste [4, 4]deve ser removido, pois nunca podemos obter esse array após uma sequência de alongamento => esmagamento, pois isso terminará com[8]
scottinet

Respostas:


2

JavaScript (Node.js) , 237 221 213 186 bytes

f=a=>a.map(b=>{for(i=1;~b%2;b/=2)i*=2;return Array(i).fill(b)}).reduce((t,c,i,s)=>{b=c.slice();if(i)r=2*s[--i].length,b.length>=r&&b[0]==s[i][0]?b[r-2]+=b.pop():b;return t.concat(b)},[])

Experimente online!

Esse algoritmo calcula matrizes esticadas ideais, estendendo cada número ao máximo e, se necessário, retalha um par de números no lugar certo, criando efetivamente um "bloqueador de esmagamento", interrompendo a sequência de esmagamento do número anterior.

Por exemplo:

[1, 1, 1, 1, 1, 1][4,2]uma vez esmagado, mas [1, 1, 1, 1, 2]resulta em[2, 4]

O desafio é determinar onde exatamente um bloqueador de esmagamento deve ser colocado, para que o esmagamento da matriz resultante dê o resultado certo:

  • Um bloqueador de esmagamento precisa ser colocado apenas se o número esticado anterior for igual ao atual e se a sequência esticada atual for maior que a anterior. Por exemplo, [2, 4]exige um bloqueador de esmagamento (o número é esticado 1, repetido, e [1, 1]é mais curto do que [1,1,1,1]), mas [4, 2]e [2, 6]não requerem um
  • se chamarmos na sequência esticada anterior e se a condição acima for verificada, a sequência atual será uma repetição da nsequência. Para interromper a sequência de esmagamento do número anterior, precisamos colocar o bloqueador de esmagamento no final da segunda nsequência do número atual para esticar. Exemplo:, [2, 8] => [(1, 1)=n, (1, 1) + (2) + (1, 1) + ...]ou[4, 8] => [(1, 1, 1, 1)=n, (1, 1, 1, 1) + (1, 1, 2) + ...]


1

Python 2 , 230 228 226 bytes

Funciona iterando todas as listas possíveis com a mesma soma que a entrada. Removendo aqueles que não são iguais à matriz de entrada em algum estado esmagado, selecionando o mais longo.

Editar: -2 bytes removendo o ifna função principal

Editar: -2 bytes removendo dois colchetes desnecessários

lambda x:max((c(z[:],x),len(z),z)for z in b(sum(x)))[2]
def c(x,y):
 i=e=1
 while x[i:]:
	if x[~-i]==x[i]:del x[i];i-=1;x[i]*=2;e=2
	i+=1
 return x==y or~-e and c(x,y)
b=lambda s:[z+[-~i]for i in range(s)for z in b(s+~i)]+[[]]

Experimente online!

Explicação

Função principal, responsável por encontrar todas as soluções possíveis e selecionar a mais longa

lambda x:max((c(z[:],x),len(z),z)for z in b(sum(x)))[2]

Função de esmagamento, que verifica se y é igual a um dos esmagamentos.

def c(x,y):
 i=e=1
 while x[i:]:
	if x[~-i]==x[i]:del x[i];i-=1;x[i]*=2;e=2
	i+=1
 return x==y or~-e and c(x,y)

Gere todas as permutações possíveis com a soma fornecida

b=lambda s:[z+[-~i]for i in range(s)for z in b(s+~i)]+[[]]

0

05AB1E , 41 37 bytes

vy[DÉ#2÷]DYQX©NoDU‹&sDV¸X∍sić·®·Íǝ}»,

Experimente online!

Porta da minha solução Javascript.

Explicações:

vy                   for each member of the list
[DÉ#2÷]              divide by 2 until odd: stack = stretched value, N = iterations
DYQ                  stetched value equal to the previous one?
X©NoDU‹              previous size < current one? (+store the new size in X)
&                    AND on the 2 previous tests
sDV¸X∍s              build a list of the new stretched value repeated X times
                      (+store the new stetched value in Y)
ić·®·Íǝ}             if the previous tests are true:
                       reduce the result list size by 1
                       multiply by 2 the number at the crush block position
»,                   join by newline + print the list
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.