Inversione di elenchi di elenchi di indici


14

Ispirato da questo post StackOverflow.

introduzione

Il lavoro di Bob è quello di creare fogli di calcolo e organizzarli. Il modo in cui li organizza è noto a pochi, tranne Bob, ma crea un elenco di ciascuno dei fogli di calcolo che rientrano nello stesso gruppo. Ci sono un sacco di dati nel foglio di calcolo che crea, ma c'è solo un dato che stiamo guardando in questo momento: il numero di giorni tra il giorno in cui ha iniziato questo lavoro e il giorno in cui ha creato il foglio di calcolo. Il primo giorno ha creato due fogli di calcolo, li ha annotati entrambi 0e li ha ordinati nella posizione corretta.

Ora, il suo capo sta chiedendo una revisione di che tipo di foglio di calcolo è successo ogni giorno, ed è il tuo lavoro scrivere un codice che lo capirà per Bob; ha troppi fogli di calcolo per farlo a mano.

Ingresso

Le informazioni di Bob che ti fornisce si presentano sotto forma di un array frastagliato (0-o-1 indicizzato) in cui ogni dato è del modulo x = a[i][j]. aè quello che sto chiamando l'array frastagliato stesso, iè il tipo di foglio di calcolo ed xè la data di creazione dell'array. jnon è importante.

L'obiettivo

Data una matrice frastagliata di giorni di creazione di fogli di calcolo organizzati per tipo, restituisce una matrice frastagliata di tipi di fogli di calcolo organizzati per giorno di creazione di fogli di calcolo.

Esempi

Bob non ti lascerà solo con questi dati astratti. Mi ha dato un sottoinsieme di alcuni dei suoi fogli di calcolo per aiutarti a capire cosa dovrebbe essere tutto.

Esempio di input (indicizzato 0):

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

Esempio di output (con commento, che ovviamente non è richiesto):

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
]

Nota che Bob non sempre crea due fogli di calcolo ogni giorno, quindi anche l'output potrebbe essere frastagliato. Ma crea sempre almeno un foglio di calcolo ogni giorno, quindi l'output non dovrà mai contenere array vuoti - anche se alla fine l'output ha array vuoti, non è necessario rimuoverli.

Altri casi di test:

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

Non è necessario ordinare gli elenchi interni dell'output.

Come sempre, nessuna scappatoia standard, e ovviamente il codice più corto vince.

(Dato che questa è la mia prima domanda, per favore fatemi sapere tutto ciò che posso fare per migliorarlo.)


Bob potrebbe non creare fogli di calcolo di qualche tipo?
xnor

1
@xnor No, Bob creerà sempre un foglio di calcolo ogni giorno. Questi fogli di calcolo sono così cruciali per il funzionamento dell'azienda che se Bob deve chiamare un malato, un'altra persona viene temporaneamente inviata per creare i fogli di calcolo di quel giorno e Bob li organizza la mattina successiva prima di creare i suoi fogli di calcolo.
Steven H.

1
@Dennis Ero un po 'stanco nel mettere insieme quell'esempio, e immagino lo abbia mostrato. : P Risolto (entrambi)!
Steven H.

6
Sembra buono Questa è una bella sfida, soprattutto considerando che è la tua prima volta. :) A proposito, nel caso non lo sapessi, abbiamo una sandbox in cui la community può fornire feedback prima di "andare in diretta".
Dennis,

1
Ho modificato in una dichiarazione basata sul tuo commento " No, Bob creerà sempre un foglio di calcolo ogni giorno ", ma ora che ho provato a ottimizzare la mia risposta, mi sono reso conto che forse è più restrittivo di quanto tu pensassi. Sono consentiti array vuoti finali? Ad esempio può [[0 0]]dare output [[0 0] []]?
Peter Taylor,

Risposte:



5

Pyth, 13 byte

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

Provalo online



4

Brachylog , 28 byte

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

Spiegazione

  • Predicato principale, Input ( ?) = un elenco di elenchi

    :1f.              Find all valid outputs of predicate 1 with ? as input
    
  • Predicato 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
    
  • Predicato 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 byte

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

3

CJam ( 30 29 byte)

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

Demo online

Curiosamente è più breve andare in giro Wche usarlo ee, principalmente perché voglio comunque che l'indice finisca in una variabile. e]ha salvato due byte prima trovando l'elemento massimo me inizializzando una matrice di m+1array vuoti.

Grazie a Martin per il risparmio di un byte memorizzando un valore Xinvece di destreggiarlo nello stack.

NB Se sono consentiti array vuoti finali, esiste un approccio alternativo a 29 byte inizializzando invece l'array di tanti giorni vuoti quanti sono i fogli di calcolo:

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

3

CJam, 20 byte

Grazie a Peter Taylor per avermi permesso di basare questo codice sulla sua soluzione e di aver salvato 3 byte.

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

Un blocco senza nome che prevede l'input in cima allo stack e lo sostituisce con l'output.

Provalo qui.

Spiegazione

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 byte

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

Provalo su Ideone .


2

Mathematica, 35 byte

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

Una funzione senza nome che accetta e restituisce un elenco irregolare. Utilizza indici basati su 1.

Per fortuna Maxappiattisce automaticamente tutti i suoi input, quindi questo ci dà l'indice dell'ultimo giorno anche se l'input è un elenco irregolare. Quindi calcoliamo semplicemente un elenco di #&@@@#~Position~iindici per tutto il giorno i. Questa stessa espressione trova la posizione iall'interno dell'elenco sfilacciato (restituisce una matrice di indici a profondità successive), quindi i valori che vogliamo sono i primi valori di ciascuna di quelle liste. #&@@@è un trucco di golf standard per recuperare il primo elemento da ogni #&lista secondaria, applicando a ciascuna di quelle liste secondarie, che è una funzione senza nome che restituisce il suo primo argomento.

In alternativa, possiamo definire un operatore unario per lo stesso conteggio byte (supponendo un file sorgente codificato ISO 8859-1):

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

2

Java, 314 byte

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;

dettagliata

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
Ne hai davvero bisogno Map?
Leaky Nun,

0

Perl 5, 48 byte

Una subroutine:

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

Guardalo in azione in questo modo:

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])'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.