Mam ogromną listę odtwarzania muzyki i chociaż niektórzy artyści mają wiele albumów, inni mają tylko jedną piosenkę. Chciałem posortować listę odtwarzania, aby ten sam artysta nie był odtwarzany dwa razy z rzędu lub jego piosenki nie kończyły się głównie na początku lub na końcu listy odtwarzania.
Przykładowa lista odtwarzania:
$ cat /tmp/playlist.m3u
Anna A. - Song 1
Anna A. - Song 2
I--Rock - Song 1
John B. - Song 1
John B. - Song 2
John B. - Song 3
John B. - Song 4
John B. - Song 5
Kyle C. - Song 1
U--Rock - Song 1
Dane wyjściowe z sort -R
lub shuf
:
$ sort -R /tmp/playlist.m3u
Anna A. - Song 1 #
U--Rock - Song 1
Anna A. - Song 2 # Anna's songs are all in the beginning.
John B. - Song 2
I--Rock - Song 1
John B. - Song 1
Kyle C. - Song 1
John B. - Song 4 #
John B. - Song 3 #
John B. - Song 5 # Three of John's songs in a row.
Czego oczekuję:
$ some_command /tmp/playlist.m3u
John B. - Song 1
Anna A. - Song 1
John B. - Song 2
I--Rock - Song 1
John B. - Song 3
Kyle C. - Song 1
Anna A. - Song 2
John B. - Song 4
U--Rock - Song 1
John B. - Song 5
text-processing
sort
random
Teresa e Junior
źródło
źródło
Odpowiedzi:
Gdybym musiał zastosować to przetasowanie do talii kart do gry, myślę, że najpierw przetasuję talię, a następnie wyświetlę karty w rzędzie na moich oczach i przetworzę od lewej do prawej, wszędzie tam, gdzie są sąsiednie trefl lub serce. , przenieś wszystkie oprócz jednego losowo w inne miejsce (choć nie obok innego tego samego typu).
Na przykład z taką ręką
Po podstawowym tasowaniu:
dwie grupy sąsiednich pik, musimy przenieść 1, 2 i 3. Dla 1 wyborów są następujące:
Wybieramy jeden losowo z tych 4. Następnie powtarzamy proces dla 2 i 3.
Wdrożono
perl
by to:Znajduje rozwiązanie dla artystów niesąsiadujących, jeśli istnieje (chyba że więcej niż połowa piosenek pochodzi od tego samego artysty) i powinna być jednolita AFAICT.
źródło
Twoje przykładowe dane i ograniczenia w rzeczywistości pozwalają tylko na kilka rozwiązań - na przykład musisz zagrać Johna B. Zakładam, że twoja pełna lista odtwarzania nie jest zasadniczo Johnem B, z losowymi innymi rzeczami, które mogą ją zepsuć .
To kolejne losowe podejście. W przeciwieństwie do rozwiązania @ frostschutz działa szybko. Nie gwarantuje to jednak, że wynik spełni twoje kryteria. Przedstawiam również drugie podejście, które działa na przykładowych danych - ale podejrzewam, że przyniesie złe wyniki na twoich prawdziwych danych. Mając twoje prawdziwe dane (zaciemnione), dodaję podejście 3 - które jest jednolite losowo, z tym wyjątkiem, że unika dwóch piosenek tego samego artysty z rzędu. Zauważ, że powoduje tylko 5 „wciągnięć” do „talii” pozostałych utworów, jeśli po tym nadal będzie musiał zmierzyć się ze zduplikowanym wykonawcą, i tak wyda ten utwór - w ten sposób gwarantuje to, że program faktycznie się zakończy.
Podejście 1
Zasadniczo generuje listę odtwarzania w każdym punkcie, pytając „z jakich artystów nadal mam nieodtwarzane utwory?” Następnie wybranie losowego artysty i wreszcie losowa piosenka tego artysty. (Oznacza to, że każdy artysta ma jednakową wagę, nieproporcjonalną do liczby utworów).
Wypróbuj swoją playlistę i sprawdź, czy przynosi lepsze wyniki niż jednolicie losowy.
Zastosowanie:
./script-file < input.m3u > output.m3u
Oczywiście, upewnij sięchmod +x
. Zauważ, że nie obsługuje poprawnie linii podpisu znajdującej się na górze niektórych plików M3U ... ale twój przykład tego nie miał.Podejście 2
Jako drugie podejście, zamiast wybierania losowego artysty , możesz użyć wybrania wykonawcy z największą liczbą piosenek, który nie jest również ostatnim artystą, którego wybraliśmy . Ostatni akapit programu staje się następnie:
Reszta programu pozostaje taka sama. Zauważ, że zdecydowanie nie jest to najskuteczniejszy sposób na zrobienie tego, ale powinno być wystarczająco szybkie dla list odtwarzania o rozsądnych rozmiarach. Na podstawie przykładowych danych wszystkie wygenerowane listy odtwarzania zaczną się od piosenki Johna B., potem piosenki Anny A., a następnie piosenki Johna B. Potem jest to znacznie mniej przewidywalne (ponieważ wszyscy oprócz Johna B. ma jeszcze jedną piosenkę). Zauważ, że zakłada to Perl 5.7 lub nowszy.
Podejście 3
Użycie jest takie samo jak w poprzednim 2. Zwróć uwagę na
0..4
część, z której pochodzi 5 maks. Prób. Możesz zwiększyć liczbę prób, np.0..9
Dałbyś 10 ogółem. (0..4
=0, 1, 2, 3, 4
, które zauważysz, to w rzeczywistości 5 pozycji).źródło
sed 's/ - .*//' output.m3u | uniq -d
). Czy możesz wyjaśnić, czy dba o to, aby niektórzy artyści nie znaleźli się na początku ani na końcu listy odtwarzania?Jeśli nie masz nic przeciwko temu, że jest okropnie nieefektywny ...
Po prostu toczy się i toczy się, aż dojdzie do wyniku, w którym nie ma dwóch lub więcej Johns z rzędu. Jeśli na twojej liście odtwarzania jest tak dużo Johns, że taka kombinacja nie istnieje lub jest bardzo mało prawdopodobne, aby została rzucona, to się zawiesi.
Przykład wyniku z wprowadzonymi danymi:
Jeśli odkomentujesz linie debugowania, powie ci, dlaczego nie powiodło się:
To powinno pomóc ustalić przyczynę w przypadku, gdy zawiesza się na czas nieokreślony.
źródło
sort
została zaprojektowana.shuf
tasuje listę odtwarzania 80 razy szybciej niżsort -R
. Ja też tego nie wiedziałem! Pozostawię na 15 minutshuf
, szanse są większe!echo "$D"
przedif
. Powinno to powiedzieć, które duplikaty uniemożliwiły wybór wyniku. To powinno ci powiedzieć, gdzie szukać problemu. (Edycja: Dodano możliwy kod debugowania do odpowiedzi.)sort
lubshuf
.Kolejne podejście przy użyciu Bash. Odczytuje listę odtwarzania w losowej kolejności, próbuje wstawić linię na drugim końcu listy, jeśli jest to duplikat, i odkłada pojedynczy duplikat, aby wstawić go w innym miejscu. Nie powiedzie się, jeśli istnieją potrójne duplikaty (pierwszy, ostatni i odłożone identycznie) i dołączą te złe wpisy na samym końcu listy. Wygląda na to, że jest w stanie rozwiązać obszerną listę, którą przesłałeś przez większość czasu.
Może być mądrzejszy ... w twoim przykładzie Johna, John zwykle będzie trwać przy byciu last_artist, ponieważ zawsze próbuje najpierw dołączyć first_artist. Więc jeśli dostanie dwóch innych artystów pomiędzy, nie jest wystarczająco mądry, aby dołączyć jednego na początku, a drugiego do końca, aby uniknąć potrójnego Johna. Tak więc z listami, które zasadniczo wymagają, aby każdy inny artysta był Johnem, masz więcej niepowodzeń niż powinieneś.
źródło