আপনার উদাহরণস্বরূপ ডেটা এবং সীমাবদ্ধতাগুলি কেবলমাত্র কয়েকটি সমাধানের অনুমতি দেয় — আপনার অবশ্যই জন বি বাজানো উচিত, উদাহরণস্বরূপ other আমি ধরে নিচ্ছি যে আপনার আসল পুরো প্লেলিস্টটি মূলত জন বি নয়, এলোমেলোভাবে অন্যান্য জিনিসগুলি এটি ভেঙে দেবে ।
এটি অন্য এলোমেলো পদ্ধতির। @ ফ্রয়েস্টছুটজের সমাধানের বিপরীতে, এটি দ্রুত চলে। এটি আপনার মানদণ্ডের সাথে মেলে এমন কোনও ফলাফলের গ্যারান্টি দেয় না। আমি একটি দ্বিতীয় পদ্ধতিরও উপস্থাপন করি যা আপনার উদাহরণের ডেটাতে কাজ করে - তবে আমার সন্দেহ হয় যে আপনার আসল তথ্যগুলিতে খারাপ ফলাফল আসবে। আপনার আসল ডেটা (অবরুদ্ধ) থাকায় আমি 3 approach পদ্ধতির যোগ করি যা একটি অভিন্ন র্যান্ডম, এটি এককভাবে একই শিল্পীর দুটি গান এড়ানো ব্যতীত। মনে রাখবেন যে এটি কেবলমাত্র বাকী গানের "ডেক" এর মধ্যে 5 টি "আঁক" তোলে, যদি তার পরেও এটি কোনও নকল শিল্পীর মুখোমুখি হয় তবে এটি যেভাবেই গানের আউটপুট পাবে — এইভাবে, এটির গ্যারান্টিযুক্ত যে প্রোগ্রামটি শেষ হবে।
পদ্ধতির ঘ
মূলত, এটি প্রতিটি পয়েন্টে একটি প্লেলিস্ট উত্পন্ন করে জিজ্ঞাসা করে, "আমার কাছে এখনও কোন শিল্পীর গান নেই?" তারপরে একটি এলোমেলো শিল্পীকে বাছাই করা এবং অবশেষে সেই শিল্পীর একটি এলোমেলো গান। (এটি, প্রতিটি শিল্পী গানের সংখ্যার অনুপাতে নয়, সমানভাবে ওজনযুক্ত))
আপনার প্রকৃত প্লেলিস্টে একবার ব্যবহার করে দেখুন এবং দেখুন এটি অভিন্নভাবে এলোমেলো চেয়ে ভাল ফলাফল দেয় কিনা।
ব্যবহার:./script-file < input.m3u > output.m3u
chmod +x
অবশ্যই এটি নিশ্চিত করুন । নোট করুন এটি কিছু এম 3 ইউ ফাইলের শীর্ষে থাকা স্বাক্ষর রেখাটি সঠিকভাবে পরিচালনা করে না ... তবে আপনার উদাহরণটিতে এটি নেই।
#!/usr/bin/perl
use warnings qw(all);
use strict;
use List::Util qw(shuffle);
# split the input playlist by artist
my %by_artist;
while (defined(my $line = <>)) {
my $artist = ($line =~ /^(.+?) - /)
? $1
: 'UNKNOWN';
push @{$by_artist{$artist}}, $line;
}
# sort each artist's songs randomly
foreach my $l (values %by_artist) {
@$l = shuffle @$l;
}
# pick a random artist, spit out their "last" (remeber: in random order)
# song, remove from the list. If empty, remove artist. Repeat until no
# artists left.
while (%by_artist) {
my @a_avail = keys %by_artist;
my $a = $a_avail[int rand @a_avail];
my $songs = $by_artist{$a};
print pop @$songs;
@$songs or delete $by_artist{$a};
}
পদ্ধতির ঘ
দ্বিতীয় পদ্ধতির হিসাবে, এলোমেলো শিল্পী বাছাইয়ের পরিবর্তে , আপনি সবচেয়ে বেশি গান সহ শিল্পীকে বাছাই করতে ব্যবহার করতে পারেন , তিনিও আমরা বেছে নেওয়া শেষ শিল্পী নন । প্রোগ্রামটির চূড়ান্ত অনুচ্ছেদটি তখন পরিণত হয়:
# pick the artist with the most songs who isn't the last artist, spit
# out their "last" (remeber: in random order) song, remove from the
# list. If empty, remove artist. Repeat until no artists left.
my $last_a;
while (%by_artist) {
my %counts = map { $_, scalar(@{$by_artist{$_}}) } keys %by_artist;
my @sorted = sort { $counts{$b} <=> $counts{$a} } shuffle keys %by_artist;
my $a = (1 == @sorted)
? $sorted[0]
: (defined $last_a && $last_a eq $sorted[0])
? $sorted[1]
: $sorted[0];
$last_a = $a;
my $songs = $by_artist{$a};
print pop @$songs;
@$songs or delete $by_artist{$a};
}
প্রোগ্রামের বাকি অংশগুলি একই থাকে। দ্রষ্টব্য যে এটি এখন পর্যন্ত এটি করার পক্ষে সবচেয়ে কার্যকর উপায় নয় তবে কোনও বুদ্ধিমান আকারের প্লেলিস্টের জন্য এটি যথেষ্ট দ্রুত হওয়া উচিত। আপনার উদাহরণের ডেটা দিয়ে, সমস্ত উত্পন্ন প্লেলিস্টগুলি জন বি গান, তারপরে আন্না এ। গান, তারপরে একটি জন বি গান দিয়ে শুরু হবে। তারপরে, এটি অনেক কম অনুমানযোগ্য (জন বি ছাড়া সবাই যেমন একটি গান বাকি আছে)। নোট করুন যে এটি পার্ল ৫.7 বা তার পরেও ধরেছে।
পদ্ধতির ঘ
ব্যবহারটি পূর্ববর্তী ২ এর মতোই the 0..4
অংশটি নোট করুন , সেখান থেকে 5 টি সর্বোচ্চ ব্যবহারের চেষ্টা করে। আপনি চেষ্টা সংখ্যা আপ করতে পারে, উদাহরণস্বরূপ, 0..9
10 মোট দিতে হবে। ( 0..4
= 0, 1, 2, 3, 4
, আপনি লক্ষ্য করবেন যে আসলে 5 টি আইটেম)।
#!/usr/bin/perl
use warnings qw(all);
use strict;
# read in playlist
my @songs = <>;
# Pick one randomly. Check if its the same artist as the previous song.
# If it is, try another random one. Try again 4 times (5 total). If its
# still the same, accept it anyway.
my $last_artist;
while (@songs) {
my ($song_idx, $artist);
for (0..4) {
$song_idx = int rand @songs;
$songs[$song_idx] =~ /^(.+?) - /;
$artist = $1;
last unless defined $last_artist;
last unless defined $artist; # assume unknown are all different
last if $last_artist ne $artist;
}
$last_artist = $artist;
print splice(@songs, $song_idx, 1);
}