Инвертирование списков списков индексов

14

Вдохновлен этим постом StackOverflow.

Вступление

Работа Боба заключается в создании электронных таблиц и их организации. То, как он их организует, известно очень немногим, кроме Боба, но он создает список каждой из электронных таблиц, входящих в одну группу. В электронной таблице, которую он создает, есть куча данных, но есть только одна часть данных, на которую мы сейчас обращаем внимание: количество дней между днем, когда он начал эту работу, и днем, когда он создал электронную таблицу. В первый день он создал две электронные таблицы, отметил их обе 0и отсортировал их по месту.

Теперь его начальник просит рассмотреть, какие электронные таблицы происходят каждый день, и ваша задача - написать код, который выяснит это для Боба; у него слишком много таблиц, чтобы сделать это вручную.

вход

Информация Боба, которую он дает вам, представлена ​​в виде зубчатого массива (с индексами 0 или 1), где каждый элемент имеет форму x = a[i][j]. aэто то, что я называю самим зубчатым массивом, iэто тип электронной таблицы и xдата создания массива. jневажно.

Задание

При наличии неровного массива дней создания электронных таблиц, организованного по их типу, верните неровный массив типов электронных таблиц, упорядоченных по дню создания электронных таблиц.

Примеры

Боб не собирается просто оставлять вас с этими абстрактными данными. Он дал мне подмножество некоторых своих электронных таблиц, чтобы помочь вам выяснить, что все должно быть.

Пример ввода (с 0 индексами):

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

Пример вывода (с комментарием, который, конечно, не требуется):

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
]

Обратите внимание, что Боб не всегда делает две таблицы каждый день, и поэтому выходные данные могут быть неровными. Но он всегда создает по крайней мере одну электронную таблицу каждый день, поэтому в выходных данных никогда не будет необходимости содержать пустые массивы - хотя, если в конце выходных данных есть пустые массивы, их не нужно удалять.

Больше тестовых случаев:

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

Внутренние списки вывода не нужно сортировать.

Как всегда, нет стандартных лазеек и, конечно же, выигрывает самый короткий код.

(Поскольку это мой первый вопрос, пожалуйста, дайте мне знать, что я могу сделать, чтобы улучшить его.)

Стивен Х.
источник
Может Боб не делать никаких электронных таблиц?
xnor
1
@xnor Нет, Боб всегда будет создавать таблицы каждый день. Эти электронные таблицы настолько важны для работы компании, что, если Бобу приходится вызывать больных, временно создается другой человек для создания электронных таблиц того дня, и Боб организует их на следующее утро, прежде чем создавать свои собственные электронные таблицы.
Стивен Х.
1
@ Денис Я немного устал, когда собирал этот пример, и, думаю, это показало. : P Исправлено (оба)!
Стивен Х.
6
Хорошо смотритесь. Это очень хороший вызов, особенно если учесть, что ты первый. :) Кстати, если вы не знаете, у нас есть песочница, где сообщество может предоставить обратную связь, прежде чем "начать жить".
Деннис
1
Я отредактировал заявление на основе вашего комментария « Нет, Боб всегда будет создавать электронную таблицу каждый день », но теперь, когда я попытался оптимизировать свой собственный ответ, я понял, что он, возможно, более строг, чем вы рассчитывали. Разрешены ли конечные пустые массивы? Например, может [[0 0]]дать вывод [[0 0] []]?
Питер Тейлор

Ответы:

5

Pyth, 13 байт

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

Попробуйте онлайн

Андерс Касеорг
источник
4

Брахилог , 28 байт

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

объяснение

  • Основной предикат, Input ( ?) = список списков

    :1f.              Find all valid outputs of predicate 1 with ? as input
    
  • Предикат 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
    
  • Предикат 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]
    
Fatalize
источник
3

JavaScript (ES6), 58 байт

a=>a.map((b,i)=>b.map(j=>(r[j]=r[j]||[]).push(i)),r=[])&&r
Нил
источник
3

CJam ( 30 29 байт)

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

Онлайн демо

Любопытно, что использовать его короче, Wчем использовать ee, в основном потому, что я все равно хочу, чтобы индекс оказался в переменной. e]сохранил два байта поверх первого поиска максимального элемента mи инициализации массива m+1пустых массивов.

Спасибо Мартину за однобайтовую экономию путем сохранения значения Xвместо его манипулирования стеком.

NB. Если разрешены конечные пустые массивы, есть альтернативный 29-байтовый подход, вместо этого инициализируйте массив из столько пустых дней, сколько существует электронных таблиц:

q~_e_,Ma*\{W):W;{_2$=W+t}/}/`
Питер Тейлор
источник
3

CJam, 20 байтов

Спасибо Питеру Тейлору за то, что он позволил мне основать этот код на своем решении и сэкономил 3 байта.

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

Безымянный блок, который ожидает ввод сверху стека и заменяет его выводом.

Проверьте это здесь.

объяснение

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 байта

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

Проверьте это на Ideone .

Деннис
источник
2

Mathematica, 35 байт

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

Безымянная функция, которая принимает и возвращает рваный список. Использует индексы на основе 1.

К счастью, Maxавтоматически сглаживает все свои входные данные, поэтому мы получаем индекс последнего дня, даже если входные данные являются рваным списком. Затем мы просто вычисляем список #&@@@#~Position~iиндексов за весь день i. Само это выражение находит позицию iвнутри рваного списка (возвращается как массив индексов на последовательных глубинах), поэтому значения, которые мы хотим, являются первыми значениями каждого из этих списков. #&@@@стандартная игра в гольф для получения первого элемента из каждого подсписка, применяя#& к каждому из этих подсписков, что является неназванной функцией, которая возвращает свой первый аргумент.

В качестве альтернативы, мы можем определить унарный оператор для того же количества байтов (при условии, что исходный файл в кодировке ISO 8859-1):

±n_:=#&@@@n~Position~#&~Array~Max@n
Мартин Эндер
источник
2

Java, 314 байт

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;

Детальнее

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
источник
1
Вам действительно нужно Map?
Дрянная Монахиня
0

Perl 5, 48 байт

Подпрограмма:

{for$i(0..@_){map{push@{$b[$_]},$i}@{$_[$i]}}@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
источник