Інвертування списків списків індексів


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
@Dennis Я трохи втомився, коли складав цей приклад, і, мабуть, це показало. : P Виправлено (обидва)!
Стівен Х.

6
Хороший вигляд. Це дуже приємне завдання, особливо враховуючи, що це ваш перший. :) До речі, якщо ви не знаєте, у нас є пісочниця, де громада може надати зворотній зв'язок перед тим, як "жити".
Денніс

1
Я відредагував заяву на основі вашого коментаря " Ні, Боб завжди створюватиме таблицю щодня ", але тепер, коли я спробував оптимізувати власну відповідь, я зрозумів, що це, можливо, більш обмежує, ніж ви планували. Чи дозволено прослуховувати порожні масиви? Наприклад, може [[0 0]]дати вихід [[0 0] []]?
Пітер Тейлор

Відповіді:





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]
    


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а не жонглюючи ним навколо стека.

Примітка: Якщо дозволено записувати порожні масиви, існує альтернативний 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

Математика, 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;
}

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])'
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.