Odwracanie list list indeksów

14

Inspirowany tym postem StackOverflow.

Wprowadzenie

Zadaniem Boba jest tworzenie arkuszy kalkulacyjnych i ich organizowanie. Sposób, w jaki je organizuje, jest znany nielicznym, z wyjątkiem Boba, ale tworzy listę każdego z arkuszy kalkulacyjnych należących do tej samej grupy. W utworzonym przez siebie arkuszu kalkulacyjnym jest mnóstwo danych, ale w tej chwili analizujemy tylko jeden fragment: liczba dni między dniem, w którym zaczął to zadanie, a dniem, w którym utworzył ten arkusz. Pierwszego dnia stworzył dwa arkusze kalkulacyjne, zanotował je 0i posortował w odpowiednich miejscach.

Teraz jego szef prosi o sprawdzenie, jakie rodzaje arkuszy kalkulacyjnych zdarzały się każdego dnia, a Twoim zadaniem jest napisanie kodu, który to rozwiąże dla Boba; ma o wiele za dużo arkuszy kalkulacyjnych, aby zrobić to ręcznie.

Wejście

Informacje Boba, które ci podaje, mają postać postrzępionej tablicy (indeksowanej 0 lub 1), w której każdy układ odniesienia ma postać x = a[i][j]. ato, co nazywam samą postrzępioną tablicą, ito rodzaj arkusza kalkulacyjnego i xdata utworzenia tablicy. jjest nieważne.

Zadanie

Biorąc pod uwagę postrzępioną tablicę dni tworzenia arkuszy kalkulacyjnych uporządkowanych według ich typu, zwróć postrzępioną tablicę typów arkuszy kalkulacyjnych uporządkowanych według dnia utworzenia arkusza kalkulacyjnego.

Przykłady

Bob nie zamierza zostawić cię z tymi abstrakcyjnymi danymi. Dał mi podzbiór niektórych swoich arkuszy kalkulacyjnych, aby pomóc ci dowiedzieć się, co powinno być.

Przykładowe dane wejściowe (indeksowane 0):

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

Przykładowe dane wyjściowe (z komentarzem, który oczywiście nie jest wymagany):

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
]

Pamiętaj, że Bob nie zawsze tworzy dwa arkusze kalkulacyjne każdego dnia, więc wyniki mogą być również postrzępione. Ale zawsze tworzy co najmniej jeden arkusz kalkulacyjny każdego dnia, więc dane wyjściowe nigdy nie będą musiały zawierać pustych tablic - chociaż jeśli dane wyjściowe mają puste tablice na końcu, nie trzeba ich usuwać.

Więcej przypadków testowych:

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

Wewnętrzne listy danych wyjściowych nie muszą być sortowane.

Jak zawsze nie wygrywa żadna standardowa luka i oczywiście najkrótszy kod.

(Ponieważ jest to moje pierwsze pytanie, daj mi znać, co mogę zrobić, aby to poprawić).

Steven H.
źródło
Czy Bob może nie tworzyć żadnych arkuszy kalkulacyjnych?
xnor
1
@ xnor Nie, Bob zawsze tworzy arkusz kalkulacyjny każdego dnia. Te arkusze kalkulacyjne są tak ważne dla funkcjonowania firmy, że jeśli Bob musi zadzwonić z powodu choroby, zostaje tymczasowo wysłana inna osoba do tworzenia arkuszy kalkulacyjnych na ten dzień, a Bob organizuje je następnego dnia rano przed utworzeniem własnych arkuszy kalkulacyjnych.
Steven H.,
1
@Dennis Byłem trochę zmęczony, gdy składałem ten przykład i wydaje mi się, że to pokazało. : P Naprawiono (oba)!
Steven H.,
6
Wygląda dobrze. To bardzo miłe wyzwanie, szczególnie biorąc pod uwagę, że to twoje pierwsze. :) Btw, na wypadek, gdybyś nie był tego świadomy, mamy piaskownicę, w której społeczność może przekazać opinie przed „uruchomieniem”.
Dennis
1
Zredagowałem w oświadczeniu opartym na twoim komentarzu „ Nie, Bob zawsze będzie tworzył arkusz kalkulacyjny każdego dnia ”, ale teraz, kiedy próbowałem zoptymalizować własną odpowiedź, zdałem sobie sprawę, że jest to bardziej restrykcyjne niż zamierzałeś. Czy dozwolone są końcowe puste tablice? Np. Może [[0 0]]dać wynik [[0 0] []]?
Peter Taylor,

Odpowiedzi:

5

Pyth, 13 bajtów

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

Wypróbuj online

Anders Kaseorg
źródło
4

Brachylog , 28 bajtów

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

Wyjaśnienie

  • Główny predykat, Input ( ?) = lista list

    :1f.              Find all valid outputs of predicate 1 with ? as input
    
  • Predykat 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
    
  • Predykat 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]
    
Fatalizować
źródło
3

Lua, 114 bajtów

r={}for i,t in ipairs(...)do for _,v in ipairs(t)do if r[v] then r[v][#r[v]+1]=i else r[v]={i}end end end return r

Ideone to!

Zainspirowany odpowiedzią Dennisa w Pythonie 2 .

Leaky Nun
źródło
3

JavaScript (ES6), 58 bajtów

a=>a.map((b,i)=>b.map(j=>(r[j]=r[j]||[]).push(i)),r=[])&&r
Neil
źródło
3

CJam ( 30 29 bajtów)

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

Demo online

Co ciekawe, hackowanie jest krótsze Wniż używanie ee, głównie dlatego, że i tak chcę, aby indeks skończył się w zmiennej. e]zaoszczędzono dwa bajty przy pierwszym znalezieniu maksymalnego elementu mi zainicjowaniu tablicy m+1pustych tablic.

Dzięki Martinowi za jednobajtową oszczędność poprzez zapisanie wartości wX zamiast żonglowania nią wokół stosu.

NB: Jeśli dozwolone są końcowe puste tablice, istnieje alternatywne podejście 29-bajtowe, zamiast tego inicjuje tablicę tylu pustych dni, ile jest arkuszy kalkulacyjnych:

q~_e_,Ma*\{W):W;{_2$=W+t}/}/`
Peter Taylor
źródło
3

CJam, 20 bajtów

Dzięki Peter Taylor za pozwolenie mi oprzeć ten kod na swoim rozwiązaniu i zaoszczędzić 3 bajty.

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

Blok bez nazwy, który oczekuje danych wejściowych na szczycie stosu i zastępuje je danymi wyjściowymi.

Sprawdź to tutaj.

Wyjaśnienie

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
źródło
2

Python 2, 82 bajty

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

Przetestuj na Ideone .

Dennis
źródło
2

Mathematica, 35 bajtów

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

Nienazwana funkcja, która przyjmuje i zwraca obdartą listę. Wykorzystuje wskaźniki oparte na 1.

Na szczęście Maxautomatycznie spłaszcza wszystkie dane wejściowe, dzięki czemu otrzymujemy indeks z ostatniego dnia, mimo że dane wejściowe są postrzępione. Następnie po prostu obliczamy listę #&@@@#~Position~iindeksów całodniowych i. To wyrażenie samo znajduje pozycję iwewnątrz listy obdartej (zwraca jako tablicę indeksów na kolejnych głębokościach), więc pożądane wartości są pierwszymi wartościami każdej z tych list. #&@@@to standardowa sztuczka golfowa polegająca na pobieraniu pierwszego elementu z każdej #&podlisty poprzez zastosowanie do każdej z tych podlist, która jest nienazwaną funkcją, która zwraca swój pierwszy argument.

Alternatywnie możemy zdefiniować jednoargumentowy operator dla tej samej liczby bajtów (przy założeniu pliku źródłowego zakodowanego w standardzie ISO 8859-1):

±n_:=#&@@@n~Position~#&~Array~Max@n
Martin Ender
źródło
2

Java, 314 bajtów

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;

Szczegółowe

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
źródło
1
Czy naprawdę potrzebujesz Map?
Leaky Nun
0

Perl 5, 48 bajtów

Podprogram:

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

Zobacz to w akcji w następujący sposób:

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
źródło