Invertendo listas de listas de índices


14

Inspirado por este post StackOverflow.

Introdução

O trabalho de Bob é criar planilhas e organizá-las. A maneira como ele os organiza é conhecida por muito poucos, exceto por Bob, mas ele cria uma lista de cada uma das planilhas que se enquadram no mesmo grupo. Há um monte de dados na planilha que ele cria, mas há apenas um dado que estamos vendo agora: o número de dias entre o dia em que ele iniciou esse trabalho e o dia em que ele fez a planilha. No primeiro dia, ele criou duas planilhas, anotou as duas 0e as classificou nos locais apropriados.

Agora, o chefe dele está pedindo uma revisão de quais tipos de planilhas acontecem todos os dias, e é seu trabalho escrever um código que descubra isso para Bob; ele tem muitas planilhas para fazer isso manualmente.

Entrada

As informações de Bob que ele fornece vêm na forma de um array irregular (indexado com 0 ou 1), em que cada dado é do formulário x = a[i][j]. aé o que estou chamando de matriz irregular, ié o tipo de planilha e xa data em que a matriz foi criada. jnão é importante.

A tarefa

Dada uma matriz irregular de dias de criação de planilhas organizada por seu tipo, retorne uma matriz irregular de tipos de planilhas organizada pelo dia de criação da planilha.

Exemplos

Bob não vai deixar você com esses dados abstratos. Ele me deu um subconjunto de algumas de suas planilhas para ajudá-lo a descobrir o que tudo deveria ser.

Exemplo de entrada (indexado 0):

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

Exemplo de saída (com comentário, o que obviamente não é necessário):

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
]

Observe que Bob nem sempre cria duas planilhas todos os dias e, portanto, a saída também pode ser irregular. Mas ele sempre cria pelo menos uma planilha todos os dias, portanto, a saída nunca precisará conter matrizes vazias - embora se sua saída tiver matrizes vazias no final, você não precisará removê-las.

Mais casos de teste:

[[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]]

As listas internas da saída não precisam ser classificadas.

Como sempre, não há brechas padrão e, claro, o código mais curto vence.

(Como esta é minha primeira pergunta, informe-me sobre qualquer coisa que eu possa fazer para melhorá-la.)


Bob não pode fazer planilhas de algum tipo?
Xnor

1
@xnor Não, Bob sempre cria uma planilha todos os dias. Essas planilhas são tão cruciais para a operação da empresa que, se Bob precisar ligar, outra pessoa é temporariamente postada para criar as planilhas daquele dia e Bob as organiza na manhã seguinte antes de criar suas próprias planilhas.
Steven H.

1
@ Dennis Eu estava um pouco cansado ao colocar esse exemplo juntos, e acho que mostrou. : P Fixo (ambos)!
Steven H.

6
Parece bom. Esse é um desafio muito bom, especialmente considerando que é o seu primeiro. :) Aliás, caso você não saiba, temos uma caixa de areia onde a comunidade pode fornecer feedback antes de "ir ao ar".
Dennis19 /

1
Editei em uma declaração baseada no seu comentário " Não, Bob sempre cria uma planilha todos os dias ", mas agora que tentei otimizar minha própria resposta, percebi que é possivelmente mais restritivo do que você pretendia. São permitidas matrizes vazias à direita? Por exemplo, pode [[0 0]]dar saída [[0 0] []]?
Peter Taylor

Respostas:



5

Pitão, 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

Experimente online



4

Braquilog , 28 bytes

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

Explicação

  • Predicado principal, Input ( ?) = uma 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]
    


3

JavaScript (ES6), 58 bytes

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

3

CJam ( 30 29 bytes)

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

Demonstração online

Curiosamente, é mais curto mexer no Wque usar ee, principalmente porque eu quero que o índice termine em uma variável de qualquer maneira. e]economizou dois bytes ao encontrar primeiro o elemento máximo me inicializar uma matriz de m+1matrizes vazias.

Agradecemos a Martin por economizar um byte, armazenando um valor em Xvez de manipulá-lo pela pilha.

NB Se forem permitidas matrizes vazias à direita, existe uma abordagem alternativa de 29 bytes ao inicializar a matriz de tantos dias vazios quanto planilhas:

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

3

CJam, 20 bytes

Agradeço a Peter Taylor por me deixar basear esse código em sua solução e economizar 3 bytes.

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

Um bloco sem nome que espera a entrada no topo da pilha e a substitui pela saída.

Teste aqui.

Explicação

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.

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

Teste em Ideone .


2

Mathematica, 35 bytes

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

Uma função sem nome que aceita e retorna uma lista irregular. Usa índices baseados em 1.

Felizmente, Maxnivela automaticamente todas as suas entradas, o que nos leva ao índice do último dia, mesmo que a entrada seja uma lista irregular. Em seguida, simplesmente calculamos uma lista de #&@@@#~Position~iíndices diários i. Essa expressão em si encontra a posição de identro da lista irregular (retorne como uma matriz de índices em profundidades sucessivas); portanto, os valores que queremos são os primeiros valores de cada uma dessas listas. #&@@@é um truque de golfe padrão para recuperar o primeiro elemento de cada sublist, aplicando#& a cada uma dessas sublistas, que é uma função sem nome que retorna seu primeiro argumento.

Como alternativa, podemos definir um operador unário para a mesma contagem de bytes (assumindo um arquivo de origem codificado ISO 8859-1):

±n_:=#&@@@n~Position~#&~Array~Max@n

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;

Detalhado

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

1
Você realmente precisa Map?
Freira vazando

0

Perl 5, 48 bytes

Uma sub-rotina:

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

Veja-o em ação como esta:

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])'
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.