Sandwiches de matriz

8

(Adaptado del problema C del primer calificador del Concurso de programación ACM de 2012/2013 )

Tiene varias matrices, llamadas A 1 , A 2 , ..., A n , cada una ordenada en orden ascendente. Cada elemento de la matriz será un entero de 32 bits.

Un sándwich es un conjunto de índices j 1 , j 2 , ..., j n tal que A 1 [j 1 ] ≤ A 2 [j 2 ] ≤ .... ≤ A n [j n ].
A i [0] es el primer elemento de A i .

Dados algunos arreglos, genere todos los emparedados posibles que pueda obtener de esos arreglos, separados por una nueva línea.

Si de alguna manera hay una función incorporada que hace esto en su idioma, no la use.

La entrada se puede dar de cualquier manera, la salida se debe separar con espacios en blanco, pero se puede dar en cualquier orden.

Caso de prueba:
[[1, 5, 7, 10], [2, 6, 6, 8, 12], [4, 5, 9]]

Salida:

0 0 0
0 0 1
0 0 2
0 1 2
0 2 2
0 3 2
1 1 2
1 2 2
1 3 2
2 3 2

Caso de prueba:
[[10, 20, 30], [1, 2, 3]]

Salida:

El código más corto gana.

beary605
fuente
1
¿Qué valores pueden contener las matrices? ¿Solo enteros positivos?
Ilmari Karonen
@IlmariKaronen: También contendrán enteros negativos.
beary605
@PeterTaylor: Por simplicidad, serán enteros de 32 bits.
beary605
@DavidCarraher: Es el próximo caso de prueba. Debería dejarlo más claro.
beary605
Gracias. Ahora veo que mi solución actual solo funciona para matrices de 3 elementos. Tendré que trabajar un poco más para generalizarlo.
DavidC

Respuestas:

2

APL (33)

↑1-⍨B/⍨{(⍳⍴A)∘≡⍋⍵⌷¨A}¨B←,⍳⊃∘⍴¨A←⎕

La entrada se lee desde el teclado, pero debe darse como una lista APL, es decir

(1 5 7 10) (2 6 6 8 12) (4 5 9)

Explicación:

  • B←,⍳⊃∘⍴¨A←⎕: A es la entrada evaluada, B es todos los conjuntos posibles de índices en las listas dadas en A.
  • {(⍳⍴A)∘≡⍋⍵⌷¨A}¨B: para cada conjunto de índices, obtenga los valores de las listas ( ⍵⌷¨A) y vea si están ordenados ( (⍳⍴A)∘=⍋)
  • B/⍨: seleccione de B todos los conjuntos de índices donde la expresión anterior era verdadera (es decir, todos los sándwiches)
  • 1-⍨: resta uno de todos los índices, porque esta pregunta supone que las matrices basadas en 0 y las matrices APL están basadas en 1 por defecto.
  • : organiza la lista de conjuntos de índices como una matriz (de modo que cada conjunto esté en su propia línea)
marinus
fuente
3

Mathematica 120 130

Editar

Esta versión funciona con matrices de diferentes tamaños.


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}}

resultados


Explicación

Usando el primer ejemplo de arriba,

a = {{10, 20, 30}, {1, 22, 3}}

MapIndexedestablece índices para todos los elementos. NB: Mathematica comienza a contar con 1. (Luego lo tendremos en cuenta).

MapIndexed[l, a, {2}]

{{{10, {1, 1}}, {20, {1, 2}}, {30, {1, 3}}}, {{1, {2, 1}}, {22, {2, 2}}, {3, {2, 3}}}}


Outergenera todas las listas, cada una candidata como un conjunto de sándwiches y los índices de sus elementos; %contiene los resultados de la salida anterior. Los números, 10y 22que destaqué después de que salieron, se refieren a una matriz de sándwich {10,22}que aún no se ha identificado 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}}}}


Casesprueba cada elemento de lo anterior para determinar si se LessEqualcumple una relación (menor o igual). Los resultados que se muestran a continuación son aquellos casos en los que se detectaron emparedados de matriz. Una vez más, destaqué {10,22}en la salida.

Cases[%, x_ /; LessEqual @@ x[[All, 1]] == True]

{{{ 10 , {1, 1}}, { 22 , {2, 2}}}, {{20, {1, 2}}, {22, {2, 2}}}}


%%se refiere a los penúltimos resultados. :>, [RuleDelayed] devuelve las partes de las instancias de interés, a saber, los índices de los sandwiches de matriz.  -1corrige el hecho de que Mathematica comienza matrices con 1 en lugar de 0. 

Cases[%%, 

X_ /; LessEqual @@ x [[All, 1]] == True:> x [[All, 2, 2]] - 1]

{{0, 1}, {1, 1}}


Gridmuestra los resultados en una cuadrícula. La primera fila 0 1significa que el elemento 0 de la primera sublista (es decir, 10 ) y el elemento 1 de la segunda sublista (es decir, 22 ) constituyen el primer conjunto sándwich que se encontró.

Grid@%

0 1

1 1

DavidC
fuente
No me gusta esta respuesta, ya que simplifica artificialmente su respuesta arreglando las matrices de números.
FUZxxl
Si quiere decir que solo funciona para matrices de 3 "filas", comparto su disgusto. El problema tiene que ver con permitir LessEqualtrabajar con matrices de tamaño indeterminado. Puede haber otros casos en los que la misma suposición impida la generalidad. Cuando tenga la oportunidad, generalizaré el enfoque.
DavidC
@FUZxxl Pude generalizar el enfoque. Echar un vistazo.
DavidC
3

GolfScript, 51 caracteres

~:A{,}%{*}*,{A{,.@.@/\@%}%\;}%{:k,,{.A=\k==}%.$=},`

Entrada de ejemplo (en stdin):

[[1 5 7 10] [2 6 6 8 12] [4 5 9]]

Ejemplo de salida (a stdout):

[[0 0 0] [0 0 1] [0 0 2] [0 1 2] [1 1 2] [0 2 2] [1 2 2] [0 3 2] [1 3 2] [2 3 2]]

(Tenga en cuenta que la entrada debe darse sin comas, de lo contrario, el programa probablemente se bloqueará).


Supongo que debería agregar alguna explicación sobre cómo funciona este código:

  • ~:Asolo evalúa la entrada como código GolfScript y asigna el resultado (una matriz de matrices) a A. También deja una copia de Aen la pila para el siguiente paso.

  • {,}%reemplaza cada subconjunto con su longitud, y {*}*multiplica esas longitudes juntas, dando el número total de posibles candidatos sandwich. Este número luego se convierte ,en una matriz de tantos enteros sucesivos a partir de 0.

  • {A{,.@.@/\@%}%\;}%convierte cada número en un candidato emparedado correspondiente (es decir, una matriz de índices válidos en cada sub-matriz en A). Por ejemplo, dada la entrada anterior, 0se asignaría a [0 0 0], 1a [1 0 0], 2a [2 0 0], 3a [3 0 0], 4a , [0 1 0]etc. (Averiguar exactamente cómo se logra el código que se deja como ejercicio para el lector interesado).

  • {:k,,{.A=\k==}%.$=},filtra los candidatos sandwich al mapear cada uno de ellos con los elementos correspondientes de las sub-matrices de A(de modo que, por ejemplo [0 0 0], produciría [1 2 4], [1 0 0]produciría [5 2 4], y así sucesivamente, para la entrada anterior), clasifica la matriz resultante y la compara con una copia no ordenada . Si son iguales, la matriz ya estaba ordenada y, por lo tanto, el candidato es un sándwich.

  • Finalmente, `solo convierte la matriz filtrada de sándwiches en una cadena para la salida.

Ilmari Karonen
fuente
Deben estar separados por espacios en blanco, para que los espacios o las pestañas funcionen también.
beary605
OK, he cambiado el formato de salida.
Ilmari Karonen
1

R - 89 caracteres

i=do.call(expand.grid,lapply(x,seq_along))
i[apply(diff(t(mapply(`[`,x,i)))>=0,2,all),]-1

dónde

x = list(c(1, 5, 7, 10), c(2, 6, 6, 8, 12), c(4, 5, 9))

o

x = list(c(10, 20, 30), c(1, 2, 3))
flodel
fuente
1

Pitón, 149 141 140

import itertools as I;x=input();r=range;print[p for p in I.product(*map(r,map(len,x)))if all(x[i][p[i]]<=x[i+1][p[i+1]]for i in r(len(x)-1))]

Python tiene una biblioteca útil de itertools que puede generar permutaciones. Esto solo itera sobre todas las permutaciones posibles de índices válidos y verifica si satisfacen los criterios.

Creo que puedo acortar esto, aún trabajando en ello.

Editar: ¡Ahora todas una línea para su lectura (en) conveniencia!

Scleaver
fuente
r=rangesalvará un personaje.
beary605
Gracias por el consejo. Nunca se me ocurrió que puedo alias funciones de la biblioteca.
Scleaver
1

Python 120

f=lambda p,k=0:['%i '%j+m for j,v in enumerate(p[0])if v>=k for m in f(p[1:],v)]if p else['']
print'\n'.join(f(input()))

... todavía pienso, "enumerar" es una palabra muy larga.

Daniel
fuente
1

GolfScript (44 caracteres)

~{.,,]zip}%{{`{+}+1$\/}%\;}*{2%.$=},{(;2%}%`

Mismo formato de entrada y salida que la entrada de Ilmari.

Manifestación

Desglose en bruto:

Asigna cada fila de entrada en una matriz de pares [value index]

{.,,]zip}%

Doblar un producto cartesiano sobre las filas

{{`{+}+1$\/}%\;}*

Filtre a aquellos cuyas entradas 0th, 2nd, 4th, etc. no disminuyan.

{2%.$=},

Asigne cada uno a sus entradas 1ra, 3ra, 5ta, etc.

{(;2%}%
Peter Taylor
fuente
0

Q, 43

{f(&)m~'(asc')m:x@'/:f:(cross/)(!:')(#:')x}
tmartin
fuente