Mathematica 120 130
Editar
Esta versão funciona com matrizes de tamanhos variados.
l = List;
g = Grid@Cases[Outer[l, Sequence @@ MapIndexed[l, #, {2}], 1]~Flatten~(Length[#] - 1),
x_ /; LessEqual @@ x[[All, 1]] == True :> x[[All, 2, 2]] - 1] &
Uso
g@{{10, 20, 30}, {1, 22, 3}}
g@{{1, 5, 7, 10}, {2, 6, 6, 8, 12}, {4, 5, 9}}
g@{{10, 20, 30}, {1, 2, 3}}
g@{{1, -2, 3}, {-12, -7, 8, 9, 6}, {3, 99, 9}, {100, 10, -23}, {90, 10}}
Explicação
Usando o primeiro exemplo de cima,
a = {{10, 20, 30}, {1, 22, 3}}
MapIndexed
define índices para todos os elementos. NB: O Mathematica começa a contar com 1. (Mais tarde, levaremos isso em conta.)
MapIndexed[l, a, {2}]
{{{10, {1, 1}}, {20, {1, 2}}, {30, {1, 3}}}, {{1, {2, 1}}, {22, {2, 2}}, {3, {2, 3}}}}}
Outer
gera todas as listas, cada uma candidata como uma matriz sanduíche, e os índices de seus elementos; %
contém os resultados da saída anterior. Os números, 10
e 22
que destaquei após a saída, referem-se a uma matriz sanduíche {10,22}
que ainda não foi identificada como tal.
Outer[l, Sequence @@ %, 1]~Flatten~(Length[a] - 1)
{{{10, {1, 1}}, {1, {2, 1}}}, {{ 10 , {1, 1}}, { 22 , {2, 2}}}, {{10, { 1, 1}}, {3, {2, 3}}}, {{20, {1, 2}}, {1, {2, 1}}}, {{20, {1, 2}}, {22, {2, 2}}}, {{20, {1, 2}}, {3, {2, 3}}}, {{30, {1, 3}}, {1, {2, 1}}}, {{30, {1, 3}}, {22, {2, 2}}}, {{30, {1, 3}}, {3, {2, 3}}}}
Cases
testa cada elemento acima para determinar se uma relação LessEqual
(menor ou igual) é válida. Os resultados mostrados abaixo são aqueles em que os sanduíches de matriz foram detectados. Mais uma vez, destaquei {10,22}
na saída.
Cases[%, x_ /; LessEqual @@ x[[All, 1]] == True]
{{{ 10 , {1, 1}}, { 22 , {2, 2}}}, {{20, {1, 2}}, {22, {2, 2}}}}
%%
refere-se aos penúltimos resultados. :>
, [RuleDelayed] retorna essas partes das instâncias de interesse, ou seja, os índices dos sanduíches da matriz. -1
corrige o fato de o Mathematica iniciar matrizes com 1 em vez de 0.
Cases[%%,
x_ /; LessEqual @@ x [[Todos, 1]] == Verdadeiro:> x [[Todos, 2, 2]] - 1]
{{0, 1}, {1, 1}}
Grid
exibe os resultados em uma grade. A primeira linha 0 1
significa que o elemento 0 da primeira sub-lista (ou seja, 10 ) e o elemento 1 da segunda sub-lista (ou seja 22 ) constituem a primeira matriz sanduíche encontrada.
Grid@%
0 1
1 1