Згрупуйте список за періодичністю


26

З урахуванням списку цілих чисел, групуйте елементи, які зустрічаються найбільше спочатку, потім групуйте наступне найбільше тощо, поки кожен унікальний елемент у списку не згрупується один раз.


Приклади:

Вхід: [1,2,3]

Вихід: [[1,2,3]]


Вхід: [1,1,1,2,2,3,3,4,5,6]

Вихід: [[1],[2,3],[4,5,6]]


Вхід: [1,1,1,4,5,6,6,6,7,7,8,8,8,8,8,8,8,9,5,6,5,6,5,6,5,6,-56]

Вихід: [[6, 8],[5],[1],[7],[9,4,-56]]


Вхід: []

Вихід: []


Вхід: (empty input)

Вихід: ERROR/Undefined/Doesn't matter


Правила

  • Групування повинні переходити від максимальної до мінімальної частоти.
  • Внутрішній порядок угрупування є довільним ( [8,6]натомість EG 3 може бути ).
  • Це , виграє найменший байт.

Пов'язані


1
Чи може висновок бути у рядковому форматі? Тобто Список списків, але кожне число, представлене символом, а не цілим числом.
mb7744

Відповіді:



7

Математика, 43 байти

Union/@SortBy[l=#,f=-l~Count~#&]~SplitBy~f&

Спробуйте в Інтернеті! (Використання математики.)

Як варіант:

SortBy[Union[l=#],f=-l~Count~#&]~SplitBy~f&

5
Немає вбудованого?
Чарівний восьминіг Урна

Це GatherByваріант, не впевнений, тому що я не знаю мови.
Чарівний восьминога Урна

1
@carusocomputing Він сортує групи за першим появою елементів у вихідному списку, тому мені все одно доведеться сортувати групи після цього. Сортувавши список спочатку, я можу зберегти байт за допомогою SplitBy(також SortByби насправді було б складніше, якби я був GatherByпершим).
Мартін Ендер

Цікаво, так що "має бути в порядку від максимальних до мінімальних" помилок, що вгору?
Magic Octopus Urn

@carusocomputing Точно.
Мартін Ендер

5

Python 2 , 145 141 байт

import collections as c,itertools as i;o=lambda n:lambda l:l[n]
print[map(o(0),g)for _,g in i.groupby(c.Counter(input()).most_common(),o(1))]

Спробуйте в Інтернеті!

Це моє перше подання після багатьох років читання.

В основному він розміщує всі елементи в лічильнику (словник кількості кожного елемента в списку), а .most_common () розміщує елементи в частотному порядку, що обманює . Після цього лише питання про форматування елементів у потрібному списку.

Збережено 4 байти завдяки ов .


4
Ласкаво просимо до PPCG :). Не захоплюйтесь так, як я.
Чарівний восьминога Урна

Створення власної функції itemgetter на 4 байти коротше, ніж імпорт:o=lambda n:lambda l:l[n]
1717

5

JavaScript (ES6), 95 101 байт

a=>a.map(x=>(o[a.map(y=>n+=x!=y,n=0)|n]=o[n]||[])[x*x+(x>0)]=x,o=[])&&(F=o=>o.filter(a=>a))(o).map(F)

Як?

Для кожного елемента x вхідного масиву a обчислюємо число n елементів a, яке відрізняється від x :

a.map(y => n += x != y, n = 0) | n

Ми використовуємо індекси n і x для заповнення масиву o :

(o[n] = o[n] || [])[x * x + (x > 0)] = x

Редагувати : Оскільки JS не підтримує індекси негативного масиву, нам потрібна формула x * x + (x > 0)для формування позитивних індексів.

Це дає нам масив масивів, що містять унікальні елементи вихідного списку, згруповані за частотою та упорядковані від найчастіших до найменших частот.

Однак і зовнішній, і внутрішній масиви потенційно мають багато порожніх прорізів, які ми хочемо відфільтрувати. Ми робимо це за допомогою функції F , застосованої до o та кожного з його елементів:

F = o => o.filter(a => a)

Тестові справи


Я думаю, що Setекономить байти: a=>a.map(e=>(r[n=0,a.map(f=>n+=e!=f),n]||(r[n]=new Set)).add(e),r=[])&&r.filter(s=>s).map(s=>[...s]).
Ніл

@Neil Це сильно відрізняється від мого нинішнього підходу. Можливо, ви повинні опублікувати це як нову відповідь?
Арнольд

Я не думав, що перехід o[n]від масиву до набору був таким різним, але я вже гольфував @ RickHitchcock у відповідь так чи інакше, тому сенсу не так багато.
Ніл



2

Clojure, 74 байти

#(for[[_ g](sort-by(comp - key)(group-by val(frequencies %)))](map key g))

Виглядає досить багатослівно: /


Побийте мене до цього (і побийте мене на кілька байт, розумне використання comp -для зворотного руху !). Не такий короткий, як інші мови, але я подумав, що це забавно, оскільки в Clojure вбудовані "групова" та "частотна частота".
MattPutnam

Коли я прочитав опис завдання, я сподівався на 50 або 60 байт, але реальна реалізація виявилася трохи складнішою.
NikoNyrh

2

Perl 6 , 43 байти

*.Bag.classify(-*.value).sort».value».key

Перевірте це

Розширено:

*                   # WhateverCode lambda (this is the input)
                    # [1,1,1,2,2,3,3,4,5,6]

.Bag                # turn into a Bag
                    # (1=>3,5=>1,4=>1,3=>2,6=>1,2=>2).Bag

.classify(-*.value) # classify by how many times each was seen
                    # {-2=>[3=>2,2=>2],-3=>[1=>3],-1=>[5=>1,4=>1,6=>1]}

.sort\              # sort (this is why the above is negative)
                    # {-3=>[1=>3],-2=>[3=>2,2=>2],-1=>[5=>1,4=>1,6=>1]}

».value\            # throw out the classification
                    # ([1=>3],[3=>2,2=>2],[5=>1,4=>1,6=>1])

».key               # throw out the counts
                    # ([1],[3,2],[5,4,6])

О, я завжди про це забуваю Bag, приємний!
Чарівний восьминога Урна


2

MATL , 9 байт

9B#uw3XQP

Вхід - вектор стовпця, який використовується ;як роздільник.

Спробуйте в Інтернеті!

Пояснення

9B#u   % Call 'unique' function with first and fourth outputs: unique entries and
       % number of occurrences
w      % Swap
3XQ    % Call 'accumarray' with anonymous function @(x){sort(x).'}. The output is
       % a cell array with the elements of the input grouped by their frequency.
       % Cells are sorted by increasing frequency. Some cells may be empty, but
       % those won't be displayed
P      % Flip cell array, so that groups with higher frequency appear first.
       % Implicitly display

2

k, 22 байти

{x@!x}{(>x)@=x@>x}#:'=

Спробуйте в Інтернеті.

( Начебто AW's k вимагає додаткового додатку @перед #, але oK не робить.)

Пояснення:

                     = /group identical numbers in a map/dict
                  #:'  /get number of times each number is repeated
                       /this is almost the answer, but without the inner lists
      {      x@>x}     /order "number of times" greatest to least
            =          /group them (to make the smaller groups)
       (>x)@           /get the actual numbers into place
{x@!x}                 /get values of the map/dict it's in

github.com/JohnEarnest/ok для всіх, хто цікавиться, що kце таке ok? Ба-дум-цсссс ...
Чарівний восьминіг Урна


2

Математика, 79 байт

Table[#&@@@f[[i]],{i,Length[f=GatherBy[Sort[Tally@#,#1[[2]]>#2[[2]]&],Last]]}]&

вхід

[{1, 1, 1, 4, 5, 6, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 9, 5, 6, 5, 6, 5, 6, 5, 6, -56}]

вихід

{{8, 6}, {5}, {1}, {7}, {-56, 9, 4}}


GatherBy, про якого я згадав Мартіна! Мені було цікаво, як це буде зроблено :).
Чарівний восьминога Урна

Sort[...,...&]просто SortBy[...,-Last@#&].
Мартін Ендер

Length[f=...]. І First/@є #&@@@.
Мартін Ендер

виправлено, виправлено та зафіксовано
J42161217

2

R , 84 77 байт

-7 байт завдяки mb7744

unique(lapply(x<-sort(table(scan()),T),function(y)as.double(names(x[x==y]))))

Читає від stdin; повертає список із підрядниками цілих чисел у порядку збільшення. Якщо ми могли б повернути рядки замість ints, я міг би скинути 11 байт (видалення виклику доas.double ), але це про це. tableФункція R виконує тут важкий підйом, рахуючи події кожного члена його входу; то вона агрегує їх по count ( names). Звичайно, це рядок, тому ми повинні примусити його до цілого чи подвійного.

Спробуйте в Інтернеті!


Ви можете втратити 7 байтів, усунувши "що" та скориставшись логічним індексуванням
mb7744

@ mb7744 о да.
Джузеппе

1
Я взяв ще один удар у нього з Р. Прикро, як довго триває лямбда-синтаксис, тому я поставив за мету намагатися уникнути цього. В обмін мені довелося використовувати вкладені lapply, але принаймні в такому випадку я можу призначити коротку змінну lapply. Я не можу привласнити змінну функції function...
mb7744

2

JavaScript (ES6), 100 98 96 93 байт

Збережено 2 байти завдяки @Neil (плюс він виправив помилку в крайньому регістрі в моєму коді). Збережено ще 3 байти завдяки @TomasLangkaas.

a=>a.sort().map((_,n)=>a.filter((v,i)=>i-a.indexOf(v)==n&v!=a[i+1])).filter(a=>a+a).reverse()

Тестові справи

f=
a=>a.sort().map((_,n)=>a.filter((v,i)=>i-a.indexOf(v)==n&v!=a[i+1])).filter(a=>a+a).reverse()

console.log(JSON.stringify(f([1,2,3])))
console.log(JSON.stringify(f([1,1,1,2,2,3,3,4,5,6])))
console.log(JSON.stringify(f([1,1,1,4,5,6,6,6,7,7,8,8,8,8,8,8,8,9,5,6,5,6,5,6,5,6,-56])))
console.log(JSON.stringify(f([])))


Ваш тест зіпсований (не працює на нуль) , але я думаю , що ви все ще можете зберегти байти шляхом фільтрації і реверсування замість unshifting: a=>a.sort().map((_,n)=>a.filter((v,i)=>i-a.indexOf(v)==n&v!=a[i+1])).filter(a=>1/a[0]).reverse().
Ніл

Ах, я повинен був знати тестувати на 0! Ваш код виправляє його, плюс він коротший, тому дякую за це
Рік Хічкок

Збережіть ще 3 байти, змінивши .filter(a=>1/a[0])на .filter(a=>''+a).
Томаш Лангкаас

Гарний, @TomasLangkaas, дякую. (Економить 2 байти.)
Рік Хічкок

Мої погані (проблеми з підрахунком), але .filter(a=>a+a)забезпечив би додатковий байт.
Томаш Лангкаас

1

V , 60 , 54 байти

Úòͨ¼¾©î±/± ±òHòø 
pkJjòú!
Ǩ^ƒ ©î±/o
Îf ld|;D
òV{Jk

Спробуйте в Інтернеті!

Hexdump:

00000000: daf2 cda8 bc81 bea9 eeb1 2fb1 20b1 f248  ........../. ..H
00000010: f2f8 200a 706b 4a6a f2fa 210a c7a8 5e83  .. .pkJj..!...^.
00000020: 20a9 81ee b12f 6f0a ce66 206c 647c 3b44   ..../o..f ld|;D
00000030: 0af2 567b 4a6b                           ..V{Jk

Наскільки я люблю V, я майже впевнений, що це найгірша можлива мова для завдання. Тим більше, враховуючи, що він не підтримує списки, а в основному не підтримує номери. Просто струнна маніпуляція.


1

C #, 119 байт

Просто швидкий удар у неї:

using System.Linq;
a=>a.GroupBy(x=>x)
    .GroupBy(x=>x.Count(),x=>x.Key)
    .OrderBy(x=>-x.Key)
    .Select(x=>x.ToArray())
    .ToArray()

2
+1 Ви можете видалити System.Func<int[],int[][]>F=та остаточний ;. Це не є частиною підрахунку байтів для цього виду лямбда.
Kevin Cruijssen

@KevinCruijssen, я поняття не мав. Спасибі!
Hand-E-Food

1

R , 66 байт

(l=lapply)(l(split(x<-table(scan()),factor(-x)),names),as.integer)

Спробуйте в Інтернеті!

Якщо у висновку цілі числа можуть бути у рядковому форматі, вони можуть опуститися до 48 байт (як зазначено у відповіді @ Джузеппе).


Безголівки:

input <- scan(); # read input
x <- table(input); # count how many times each integer appears, in a named vector
y <- split(x, factor(-x)) # split the count into lists in increasing order
z <- lapply(y, names) # access the the original values which are still
                      # attached via the names
lapply(z, as.integer) # convert the names back to integers

as.doubleкоротший на один байт, і він повинен працювати так само, якas.integer
Джузеппе

Ну, це залежить від того, чи хочете ви повернути ціле чи подвійне. Якщо з "подвійним" нормально, можливо, персонаж був би таким же, і ми могли б зберегти кілька байт.
mb7744

1

PowerShell, 77, 70 байт

($a=$args)|group{($a-eq$_).count}|sort n* -Des|%{,($_.group|sort -u)}

NB: Щоб побачити, що ці результати правильно згруповані (оскільки візуально немає розмежування між вмістом кожного масиву), ви можете додати | write-host до кінця вищевказаного рядка.

Подяка

Завдяки:

  • TesselilingHeckler для економії 7 байт шляхом масового рефакторингу / переписування, щоб отримати більш гольфний підхід.

Попередній

77 байт

param($x)$x|group|sort count -desc|group count|%{,($_.group|%{$_.group[0]})}

Приємно, дякую. Мені довелося включити ,()групування для групи (оскільки вихід просто показував як один безперервний масив). Це набагато голіший, ніж моя первісна спроба; дивовижна робота!
JohnLBevan

0

Groovy, 71 байт

{a->a.groupBy{a.count(it)}.sort{-it.key}.values().collect{it.unique()}}

Я фактично щойно дізнався про groupBy після створення цього. Я не знав, що колекція не була моїм єдиним вибором.


{
    a->                 // [1,2,1,2,3,3,3,6,5,4]
    a.groupBy{      
        a.count(it)     // [2:[1,2,1,2],3:[3,3,3],1:[6,5,4]]
    }.sort{             
        -it.key         // [3:[3,3,3],2:[1,2,1,2],1:[6,5,4]]
    }.values().collect{ // [[3,3,3],[1,2,1,2],[6,5,4]]
        it.unique()
    }                   // [[3],[1,2],[6,5,4]]
}

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