Invertir listas de listas de índices

14

Inspirado en esta publicación de StackOverflow.

Introducción

El trabajo de Bob es crear hojas de cálculo y organizarlas. Muy pocos conocen la forma en que los organiza, excepto Bob, pero crea una lista de cada una de las hojas de cálculo que pertenecen al mismo grupo. Hay una gran cantidad de datos en la hoja de cálculo que crea, pero solo estamos viendo un dato en este momento: el número de días entre el día en que comenzó este trabajo y el día en que hizo la hoja de cálculo. El primer día creó dos hojas de cálculo, las anotó a ambas 0y las ordenó en sus ubicaciones adecuadas.

Ahora, su jefe está pidiendo una revisión de qué tipo de hoja de cálculo ocurre cada día, y es su trabajo escribir un código que lo resuelva para Bob; tiene demasiadas hojas de cálculo para hacerlo a mano.

Entrada

La información de Bob que te da viene en forma de una matriz dentada (indexada 0-o-1) donde cada dato es de la forma x = a[i][j]. aes lo que yo llamo la matriz irregular, iel tipo de hoja de cálculo y xla fecha en que se creó la matriz. jno es importante

La tarea

Dado un conjunto irregular de días de creación de hoja de cálculo organizados por su tipo, devuelve un conjunto irregular de tipos de hoja de cálculo organizados por día de creación de hoja de cálculo.

Ejemplos

Bob no te dejará con estos datos abstractos. Me ha dado un subconjunto de algunas de sus hojas de cálculo para ayudarlo a descubrir qué se supone que es todo.

Entrada de ejemplo (indexada a 0):

a = [
[3,2,5,0], # Bob doesn't necessarily sort his lists
[1,3],
[2,1,0,4],
[4,5,3],
[6,6]
]

Ejemplo de salida (con comentario, que por supuesto no es obligatorio):

output = [
[0,2] # On day 0, Bob made one type 0 and one type 2 spreadsheet
[1,2] # On day 1, Bob made one type 1 and one type 2 spreadsheet
[0,2] # On day 2, Bob made one type 0 and one type 2 spreadsheet
[0,1,3] # On day 3, Bob made one type 0, one type 1, and one type 3 spreadsheet
[2,3] # On day 4, Bob made one type 2 and one type 3 spreadsheet
[0,3] # On day 5, Bob made one type 0 and one type 3 spreadsheet   
[4,4] # On day 6, Bob made two type 4 spreadsheets
]

Tenga en cuenta que Bob no siempre hace dos hojas de cálculo todos los días, por lo que la salida también puede ser irregular. Pero siempre hace al menos una hoja de cálculo todos los días, por lo que la salida nunca tendrá que contener matrices vacías, aunque si su salida tiene matrices vacías al final, no necesita eliminarlas.

Más casos de prueba:

[[3,5,6,2],[0,0,0],[1,0,3,4]] -> [[1,1,1,2],[2],[0],[0,2],[2],[0],[0]]
[[-1]] -> Undefined behavior, as all input numbers will be non-negative integers. 
[[0],[0],[],[0]] -> [[0,1,3]]

No es necesario ordenar las listas internas de la salida.

Como siempre, no hay lagunas estándar y, por supuesto, gana el código más corto.

(Como esta es mi primera pregunta, hágame saber cualquier cosa que pueda hacer para mejorarla).

Steven H.
fuente
¿Podría Bob no hacer hojas de cálculo de algún tipo?
xnor
1
@xnor No, Bob siempre creará una hoja de cálculo todos los días. Estas hojas de cálculo son tan cruciales para la operación de la compañía que si Bob tiene que llamar para enfermarse, otra persona se publica temporalmente para crear las hojas de cálculo de ese día y Bob las organiza a la mañana siguiente antes de crear sus propias hojas de cálculo.
Steven H.
1
@ Dennis Estaba un poco cansado al armar ese ejemplo, y creo que se demostró. : P Fijo (ambos)!
Steven H.
66
Luciendo bien. Este es un desafío muy agradable, especialmente teniendo en cuenta que es el primero. :) Por cierto, en caso de que no lo sepas, tenemos un sandbox donde la comunidad puede proporcionar comentarios antes de "lanzarse".
Dennis
1
Edité una declaración basada en su comentario " No, Bob siempre creará una hoja de cálculo todos los días ", pero ahora que he intentado optimizar mi propia respuesta, me di cuenta de que posiblemente sea más restrictivo de lo que pretendía. ¿Se permiten arrays de matrices vacías? Por ejemplo, puede [[0 0]]dar salida [[0 0] []]?
Peter Taylor

Respuestas:

5

Pyth, 13 bytes

eMM.ghkSs,RVU

         ,RV      vectorized right map of pair, over:
            UQ      [0, …, len(input) - 1] and
              Q     input
                  (this replaces each date with a [date, type] pair)
        s         concatenate
       S          sort
   .ghk           group by first element (date)
eMM               last element (type) of each sublist

Pruébalo en línea

Anders Kaseorg
fuente
4

Brachylog , 28 bytes

:1f.
cdo:Im:?:2f.
t:.m:Im~h?

Explicación

  • Predicado principal, Input ( ?) = una lista de listas

    :1f.              Find all valid outputs of predicate 1 with ? as input
    
  • Predicado 1:

    c                 Concatenate the list of lists into a single list
     do               Remove duplicates and sort
       :Im            Take the Ith element of that sorted list
          :?:2f.      Find all valid outputs of predicate 2 with [Element:?] as input
    
  • Predicado 2:

    t:.m              Take the (Output)th element of the list of lists
        :Im           Take the Ith element of that list
           ~h?        This element is the element of the input [Element:List of lists]
    
Fatalizar
fuente
3

JavaScript (ES6), 58 bytes

a=>a.map((b,i)=>b.map(j=>(r[j]=r[j]||[]).push(i)),r=[])&&r
Neil
fuente
3

CJam ( 30 29 bytes)

Mq~{W):W;{:X)Me]_X=W+X\t}/}/`

Demostración en línea

Curiosamente, es más corto piratear Wque usar ee, principalmente porque quiero que el índice termine en una variable de todos modos. e]ahorró dos bytes al encontrar primero el elemento máximo me inicializar una matriz de m+1matrices vacías.

Gracias a Martin por un ahorro de un byte al almacenar un valor en Xlugar de hacer malabares alrededor de la pila.

Nota: si se permiten arrays de matrices vacías, existe un enfoque alternativo de 29 bytes al inicializar la matriz de tantos días vacíos como hojas de cálculo:

q~_e_,Ma*\{W):W;{_2$=W+t}/}/`
Peter Taylor
fuente
3

CJam, 20 bytes

Gracias a Peter Taylor por permitirme basar este código en su solución y guardar 3 bytes.

{ee::f{S*\+S/}:~:.+}

Un bloque sin nombre que espera la entrada en la parte superior de la pila y lo reemplaza con la salida.

Pruébalo aquí.

Explicación

ee    e# Enumerate the input. E.g. if the input is 
      e#   [[3 5 6 2] [0 0 0] [1 0 3 4]]
      e# this gives:
      e#   [[0 [3 5 6 2]] [1 [0 0 0]] [2 [1 0 3 4]]]
::f{  e# The exact details of how this works are a bit tricky, but in effect
      e# this calls the subsequent block once for every spreadsheet and
      e# its correspond index, so the first time we'll have 0 and 3 on the
      e# stack, the next time 0 5, and at the last iteration 2 and 4.
      e# Note that this is a map operation, so we'll end up with an array
      e# on the stack.
  S*  e#   So the stack holds [... index date] now. We start by creating
      e#   a string of 'date' spaces, so "   " on the first iteration.
  \+  e#   We swap this with the index and append the index.
  S/  e#   Now we split this thing on spaces, which gives us 'date' empty
      e#   lists and a list containing the index, e.g. [[] [] [] [0]].
}
:~    e# This flattens the first level of the result, so that we get a list
      e# of all those lists we just created. This is simply one list for
      e# every spreadsheet with its type in the last element.
:.+   e# Finally we fold pairwise concatenation over this list. All the 
      e# empty lists won't affect the result so we'll just end up with all
      e# the types in lists for the correct date.
Martin Ender
fuente
2

Python 2, 82 bytes

r=[];i=0
for t in input():
 for v in t:r+=[()]*-(~v+len(r));r[v]+=i,
 i+=1
print r

Pruébelo en Ideone .

Dennis
fuente
2

Mathematica, 35 bytes

Table[#&@@@#~Position~i,{i,Max@#}]&

Una función sin nombre que acepta y devuelve una lista irregular. Utiliza índices basados ​​en 1.

Afortunadamente Max, aplana automáticamente todas sus entradas, por lo que esto nos da el índice del último día a pesar de que la entrada es una lista irregular. Luego simplemente calculamos una lista de #&@@@#~Position~itodos los índices del día i. Esta expresión en sí misma encuentra la posición identro de la lista irregular (se devuelve como una matriz de índices a profundidades sucesivas), por lo que los valores que queremos son los primeros valores de cada una de esas listas. #&@@@es un truco de golf estándar para recuperar el primer elemento de cada sublista, aplicando#& a cada una de esas sublistas, que es una función sin nombre que devuelve su primer argumento.

Alternativamente, podemos definir un operador unario para el mismo conteo de bytes (suponiendo un archivo fuente codificado ISO 8859-1):

±n_:=#&@@@n~Position~#&~Array~Max@n
Martin Ender
fuente
2

Java, 314 bytes

int[][]f(int[][]n){int w=0;Map<Integer,List<Integer>>m=new TreeMap<>();for(int i=0;i<n.length;i++)for(Integer x:n[i]){if(m.get(x)==null)m.put(x,new ArrayList<>());m.get(x).add(i);w=x>w?x:w;}int[][]z=new int[w+1][];for(int i=0,j;i<w+1;i++){z[i]=new int[m.get(i).size()];j=0;for(int x:m.get(i))z[i][j++]=x;}return z;

Detallado

public static Integer[][] f(Integer[][]n)
{
    int w=0;
    Map<Integer,List<Integer>>m=new TreeMap<>();

    for(int i=0;i<n.length;i++)
    {
        for(Integer x : n[i])
        {
            if(m.get(x)==null) m.put(x,new ArrayList<Integer>());
            m.get(x).add(i);
            w=x>w?x:w;
        }
    }

    Integer[][]z=new Integer[w+1][];
    for(int i=0,j; i<w+1; i++)
    {
        z[i]=new Integer[m.get(i).size()];
        j=0;for(Integer x : m.get(i))z[i][j++]=x;
    }

    return z;
}
Khaled.K
fuente
1
¿Realmente necesitas Map?
Leaky Nun
0

Perl 5, 48 bytes

Una subrutina:

{for$i(0..@_){map{push@{$b[$_]},$i}@{$_[$i]}}@b}

Véalo en acción así:

perl -e'print "@$_$/" for sub{for$i(0..@_){map{push@{$b[$_]},$i}@{$_[$i]}}@b}->([3,2,5,0],[1,3],[2,1,0,4],[4,5,3],[6,6])'
msh210
fuente