কোড হাফম্যান!


13

নাহলে সে হাফ-ফুফফুঁক করবে এবং আপনার বাড়িটি নীচে ফেলে দেবে!

এটি সম্পূর্ণ অপ্রাসঙ্গিক ছিল। এই চ্যালেঞ্জটি হফম্যান কোডিং সম্পর্কে । এর সংক্ষিপ্তসারটি হ'ল একটি প্রদত্ত পাঠ্যের অক্ষরের ফ্রিকোয়েন্সিটি এর প্রতিনিধিত্বকে সংক্ষিপ্ত করতে ব্যবহৃত হয়। অন্য কথায়, আসুন আমরা আমাদের বর্ণমালা এবং স্থান aমাধ্যমে বলা যাক z। এটি ২ 27 টি অক্ষর। তাদের প্রত্যেককে মাত্র 5 টি বিটকে অনন্যভাবে এনকোড করা যায় কারণ 5 টি বিটের 32 টি অক্ষরের জন্য পর্যাপ্ত জায়গা রয়েছে। তবে, অনেক পরিস্থিতিতে (যেমন ইংরেজি, বা সাধারণ ভাষাগুলি), কিছু চরিত্রগুলি অন্যদের চেয়ে বেশি ঘন ঘন হয়। আমরা ঘন ঘন অক্ষরগুলির জন্য কম বিট এবং কম ঘন ঘন চরিত্রগুলির জন্য আরও সম্ভবত বিট ব্যবহার করতে পারি। সম্পন্ন হয়েছে, বিটের সংখ্যায় সামগ্রিক সঞ্চয় রয়েছে এবং মূল পাঠ্যটি এখনও স্বতন্ত্রভাবে পুনর্গঠন করা যায়।

উদাহরণস্বরূপ "এই প্রশ্নটি হাফম্যান কোডিং সম্পর্কে" নেওয়া যাক। এই পাঠ্যটি 37 টি অক্ষর দীর্ঘ, যা সাধারণত 37 * 8 = 296 বিট হবে যদিও আমরা প্রতিটি অক্ষরের জন্য কেবলমাত্র 5 বিট ব্যবহার করি তবে কেবলমাত্র 37 * 5 = 185 বিট । মন যে রাখতে.

এখানে প্রতিটি চরিত্রের একটি (সার্টা) সারণি এবং পাঠ্যে তাদের ফ্রিকোয়েন্সি রয়েছে, যা বেশিরভাগ থেকে কমপক্ষে ঘন ঘন (যেখানে _ কোনও জায়গার জন্য দাঁড়িয়েছে) সাজানো হয়:

_ 5
i 4
n 3
o 3
s 3
t 3
u 3
a 2
f 2
h 2
b 1
c 1
d 1
e 1
g 1
m 1
q 1

একটি সম্পর্কিত অনুকূল কোডিং হতে পারে:

_ 101
i 011
n 1100
o 1101
s 1110
t 1111
u 001
a 10011
f 0001
h 0101
b 00000
c 00001
d 01000
e 01001
g 10000
m 10001
q 10010

এটি অবিলম্বে পরিষ্কার হওয়া উচিত যে প্রতিটি চরিত্রের জন্য কেবল 5 বিট ব্যবহার করার চেয়ে এটি আরও ভাল এনকোডিং হবে। আসুন জেনে নেওয়া যাক আরও কত ভাল, যদিও!

145 বিট , তুলনায় 185! এটি 40 বিটের সঞ্চয় বা 20% এরও বেশি! (এটি অবশ্যই ধরে নেওয়া যায় যে কাঠামো সম্পর্কে তথ্য ডিকোডিংয়ের জন্য উপলব্ধ)) এই কোডিংটি সর্বোত্তম কারণ কোনও চরিত্রের উপস্থাপনা পরিবর্তন করে কোনও বিট বাদ দেওয়া যাবে না।

কাজটি

  • একটি পরামিতি সহ একটি প্রোগ্রাম বা ফাংশন লিখুন যা ...
  • STDIN (বা সমতুল্য) থেকে অথবা একক যুক্তি হিসাবে ইনপুট নেয়।
  • উপরের মত একটি সর্বোত্তম হাফম্যান কোডিং আউটপুট আউটপুট হিসাবে ফ্রিকোয়েন্সি অনুসারে বাছাই করা অক্ষর (একটি ফ্রিকোয়েন্সি ক্লাসের মধ্যে অর্ডার কোনও ব্যাপার না)।
  • আপনি ধরে নিতে পারেন যে ইনপুটটির অক্ষরগুলি ASCII রেঞ্জের 32..126সাথে একটি নতুন লাইন সীমাবদ্ধ ।
  • আপনি ধরে নিতে পারেন ইনপুটটি 10,000 অক্ষরের চেয়ে বেশি নয় (আদর্শভাবে, তত্ত্ব অনুসারে, ইনপুটটি আনবাউন্ড করা উচিত)।
  • আপনার কোডটি যুক্তিসঙ্গত দ্রুত শেষ করা উচিত। উপরের প্রদত্ত উদাহরণটি এক মিনিটের বেশি বেশি খারাপ হওয়া উচিত নয়। (এটি নিষ্ঠুর শক্তিকে উড়িয়ে দেওয়ার উদ্দেশ্যে করা হয়েছে।)
  • স্কোরিং বাইটে রয়েছে।

উদাহরণ

x
---
x 0

xxxxxxxxx
---
x 0

xxxxxxxxy
---
x 0
y 1 (these may be swapped)

xxxxxyyyz
---
x 0
y 10
z 11

uuvvwwxxyyzz
---   (or) 
u 000      000
v 001      001
w 100      010
x 101      011
y 01       10
z 11       11

this question is about huffman coding
---
  101
i 011
n 1100
o 1101
s 1110
t 1111
u 001
a 10011
f 0001
h 0101
b 00000
c 00001
d 01000
e 01001
g 10000
m 10001
q 10010

শুভ কোডিং!


মনে রাখবেন যে এই অনুরূপ প্রশ্নটি নিবিড়ভাবে সম্পর্কিত, এমনকি এটি এই যে এটি একটি সদৃশ। যাইহোক, মেটার বিষয়ে এখন পর্যন্ত sensক্যমত্যটি হ'ল বয়স্ক ব্যক্তিকে এটির একটি সদৃশ হিসাবে বিবেচনা করা উচিত।


1
আমি আপনার নোটের সাথে একমত নই: এটি একই প্রশ্ন যা বিদ্যমান উত্তরের জন্য আউটপুট ফর্ম্যাটটির একটি সহজ রূপান্তর প্রয়োজন, এবং তদ্ব্যতীত এই প্রশ্নের কোনও উত্তর স্বয়ংক্রিয়ভাবে পূর্ববর্তী প্রশ্নের উত্তর is
পিটার টেলর

@ পিটারটেলর: আমি আবারও আবেদন করতে চাই যে আপনি এই প্রশ্নটি আবার খোলেন। এইটির স্পেসিফিকেশনটি আরও ভাল (মার্টিনের বক্তব্য অনুসারে) এবং আমি পাইথ এবং সিজেমের উত্তরগুলি সহ আরও নতুন, আরও ভাল উত্তর দেখতে চাই। আমি মনে করি উভয় প্রশ্ন খোলা রেখে কোনও ক্ষতি নেই কারণ সেগুলি যথেষ্ট আলাদা। এই প্রশ্নটিতে পোস্ট করা পাঁচ জন ব্যবহারকারীর মধ্যে মাত্র দুজন সম্প্রতি এই সাইটে এসেছেন।
এল'েন্ডিয়া স্টারম্যান

@PeterTaylor: এছাড়াও, দ্বারা যাচ্ছে এই মানক , আমি বলতে চাই যে আমি মনে করি না যে উত্তরগুলি প্রশ্নের মধ্যে অনুলিপি করা এবং প্রতিযোগিতামূলক থাকতে পারে। অবশেষে, অন্য প্রশ্নটি চার বছরের পুরনো । এটির নতুন সংস্করণটি রাখা ভাল।
এল'ইনিয়া স্টারম্যান

আপনার উদাহরণে this question is about huffman coding , আমি বিটের সংখ্যা 136 নয় 145 হিসাবে গণনা করেছি
টিফিল্ড

1
আমি সত্যিই এই চ্যালেঞ্জ সম্পূর্ণ করার চেষ্টা ছিল চামচ , কিন্তু brainfuckery 2 ঘন্টা পরে আমি সিদ্ধান্ত নিলাম ... এটা ছেড়ে দিতে হবে সেরা হবে
Bassdrop Cumberwubwubwub

উত্তর:


2

পাইথ, 53 বাইট

jo_/zhNee.WtHa>JohNZ2+shKC<J2]s.b+RYNeKU2m,/zd]+d\ {z

প্রদর্শন

এখানে এমন একটি সংস্করণ যা অভ্যন্তরীণ অবস্থাটি দেখায়, তাই আপনি এনকোডিংটি নির্মিত হচ্ছে দেখতে পারেন:

jo_/zhNee.WtHvp+`a>JohNZ2+shKC<J2]s.b+RYNeKU2bm,/zd]+d\ {z

প্রদর্শন

একটি পরিষ্কার ছবির জন্য বিস্তৃত লাইন সহ একটি পরিবেশে আউটপুট অনুলিপি করুন।


4

পাইথন 2, 299 বাইট

একটি উত্তরে আমার চেষ্টা এখানে।

হাফম্যান কোডগুলি প্রদত্ত উদাহরণগুলির চেয়ে পৃথক, তবে তবুও সর্বোত্তম হওয়া উচিত।

i=raw_input();m=n=[(c,i.count(c))for c in set(i)]
while n[1:]:n.sort(key=lambda x:(x[1]));(a,b),(c,d)=n[:2];n=[((a,c),b+d)]+n[2:]
n=n[0][0]
r=[]
def a(b,s):
 if b[1:]:a(b[0],s+'0');a(b[1],s+'1')
 else:r.append(b+(s if s[1:]else s+'0'))
a(n,' ')
for y in sorted(r,key=lambda x:-dict(m)[x[0]]):print y

2

মতলব, 116 বাইট

tabulateএকটি ফ্রিকোয়েন্সি টেবিল তোলে। huffmandictপ্রতিটি চিহ্নের জন্য প্রতীক এবং সম্ভাবনার একটি তালিকা নেয় এবং কোড গণনা করে।

t=tabulate(input('')');
d=huffmandict(t(:,1),cell2mat(t(:,3))/100);
for i=1:size(d,1);disp([d{i,1},' ',d{i,2}+48]);end

2

রুবি, 189 180 বাইট

কাজ চলছে.

->s{m=s.chars.uniq.map{|c|[c,s.count(c)]}
while m[1]
(a,x),(b,y),*m=m.sort_by &:last
m<<[[a,b],x+y]
end
h={}
f=->q="",c{Array===c&&f[q+?0,c[0]]&&f[q+?1,c[1]]||h[c]=q}
f[m[0][0]]
h}

এটি একটি বেনামে ফাংশন; এটি কোনও কিছুর জন্য নির্ধারণ করুন f, এবং এটির সাথে কল করুন

f["some test string"]`

যা এইরকম একটি হ্যাশ ফেরত দেয়:

{"t"=>"00", "g"=>"0100", "o"=>"0101", " "=>"011", "e"=>"100", "n"=>"1010", "i"=>"1011", "m"=>"1100", "r"=>"1101", "s"=>"111"}

1

হাস্কেল, 227 বাইট

import Data.List
s=sortOn.(length.)
f x|[c]<-nub x=[(c,"0")]|1<2=g[(a,[(a!!0,"")])|a<-group$sort x]
g=h.s fst
h[x]=snd x
h((a,b):(c,d):e)=g$(a++c,map('0'#)b++map('1'#)d):e
n#(a,b)=(a,n:b)
p=unlines.map(\(a,b)->a:" "++b).s snd.f

ব্যবহারের উদাহরণ:

*Main> putStr $ p "this question is about huffman coding"
u 000
i 011
  101
a 0010
f 0011
h 1000
s 1100
t 1101
n 1110
o 1111
d 01000
e 01001
b 01010
c 01011
q 10010
g 100110
m 100111

কিভাবে এটা কাজ করে:

pকলগুলি fযা (চরিত্র, এনকোডিং)-জোড়াগুলির তালিকার আকারে হাফম্যান টেবিল তৈরি করে eg উদাহরণস্বরূপ [ ('a',"0"), ('b',"1") ], এনকোডিংগুলির দৈর্ঘ্য অনুসারে টেবিলটি সাজায়, আউটপুট জন্য প্রতিটি জোড়া ফর্ম্যাট করে এবং নতুন লাইনের সাথে যুক্ত হয়।

fপ্রথমে একক বর্ণের কেসটি পরীক্ষা করে সংশ্লিষ্ট টেবিলটি প্রদান করে। অন্যথায় এটি ইনপুট স্ট্রিংটি বাছাই করে এবং সমান অক্ষরের ক্রমগুলি গ্রুপ করে (যেমন "ababa"->> ["aaa","bb"]) এবং জোড়গুলিতে ম্যাপ করে (sequence , [(char, "")]), (-> [ ("aaa", [('a',"")]), ("bb", [('b', "")])]) প্রথম উপাদানটি ফ্রিকোয়েন্সিটির উপর নজর রাখতে ব্যবহৃত হয়, দ্বিতীয় উপাদানটি একটি অক্ষরের জোড়ার একটি তালিকা এবং এটি এনকোডিং এর (যা প্রথমে খালি)। এই হিসাবে দ্বারা প্রত্যাশিত সব একক উপাদান যাও Huffman টেবিল হয় pএবং দ্বারা একত্রিত করা হয় gএবং h

gপ্রথম উপাদানটির দৈর্ঘ্যে জোড়গুলির তালিকা বাছাই করে, যেমন ফ্রিকোয়েন্সি এবং কলগুলি hhপ্রথম দুটি উপাদানের হাফম্যান টেবিলগুলি একত্রিত করে, ফ্রিকোয়েন্সিগুলি একত্রিত করে এবং প্রথম (দ্বিতীয়) সারণীর প্রতিটি উপাদানের সামনে একটি 0( 1) রেখে । উভয় টেবিল সংযুক্ত করুন। gআবার কল করুন , যখন কোনও একক উপাদান বাকি আছে তখন থামুন, ফ্রিকোয়েন্সি অংশটি ফেলে দিন এবং পূর্ণ হাফম্যান টেবিলটি ফিরিয়ে দিন।


1

কে (এনএনজি / কে) , 78 বাইট

{h::0#'x;(#1_){{h[x],:!2;y,,,/x}.0 2_x@<#'x}/.=x;(?,/'x,'" ",'|'$h)(?x)?>#'=x}

এটি অনলাইন চেষ্টা করুন!

মুদ্রণের জন্য স্ট্রিংগুলির একটি তালিকা প্রদান করে

h::0#'xপ্রতিটি চরিত্রের জন্য একটি খালি তালিকা তৈরি করে (প্রযুক্তিগতভাবে, এটি প্রতিটি অক্ষরকে দৈর্ঘ্যে 0-এ আকার দেয়)। আমরা সেখানে বিপরীত হাফম্যান কোডগুলি সংরক্ষণ করব। আমরা বিশ্বব্যাপী করার জন্য অ্যাসাইনমেন্টের ::পরিবর্তে ব্যবহার করি যাতে এটি উপ-ফাংশনে দৃশ্যমান।:h

.=x তালিকার একটি তালিকা - অক্ষরের মান অনুসারে স্ট্রিংয়ের সূচকগুলি

(#1_) আর্গুমেন্টের দৈর্ঘ্য> 1 হলে প্রযুক্তিগতভাবে "1 ড্রপের দৈর্ঘ্য ...") এমন একটি ফাংশন যা সত্যবাদী ফেরত দেয়

(#1_){... এর }/অর্থ: যুক্তির দৈর্ঘ্য> 1 থাকা অবস্থায়, কোঁকড়ানো-ব্রেস ফাংশনটি প্রয়োগ করা চালিয়ে যান

x@<#'x দৈর্ঘ্য অনুসারে যুক্তি সাজান

0 2_ এটি একটি 2-উপাদান মাথা এবং একটি লেজ কাটা

{h[x],:!2;y,,,/x}hমাথায় থাকা সূচকগুলিতে 0 এবং 1 যুক্ত করে আপডেট করুন ; একক উপাদান হিসাবে মাথা দিয়ে লেজ ফিরে

(?,/'x,'" ",'|'$h)(?x)?>#'=xপ্রত্যেকে বিপরীত করুন h, সাজান, অনন্য, সম্পর্কিত অক্ষরগুলি পূর্বে চাপ দিন এবং সুন্দরভাবে ফর্ম্যাট করুন


0

জাভাস্ক্রিপ্ট (ES6) 279

মূলত, উইকিপিডিয়া থেকে বেসিক অ্যালগরিদম। আমি সম্ভবত আরও ভাল করতে পারি

f=s=>{for(n=[...new Set(s)].map(c=>({c:c,f:[...s].filter(x=>x==c).length}));n[1];n.push({l:a=n.pop(),r:b=n.pop(),f:a.f+b.f,c:a.c+b.c}))n.sort((a,b)=>b.f-a.f);t=(n,b)=>(n.b=b,n.r)?(t(n.l,b+0),t(n.r,b+1)):o.push(n);t(n[0],'',o=[]);return o.sort((a,b)=>b.f-a.f).map(x=>x.c+' '+x.b)}

নীচে স্নিপেটের ভিতরে আরও পঠনযোগ্য

f=s=>{
  for(n=[...new Set(s)].map(c=>({c:c,f:[...s].filter(x=>x==c).length}));
      n[1];
      n.push({l:a=n.pop(),r:b=n.pop(),f:a.f+b.f,c:a.c+b.c}))
    n.sort((a,b)=>b.f-a.f);
  t=(n,b)=>(n.b=b,n.r)?(t(n.l,b+0),t(n.r,b+1)):o.push(n);
  t(n[0],'',o=[]);
  return o.sort((a,b)=>b.f-a.f).map(x=>x.c+' '+x.b)
}

//TEST
console.log=x=>O.innerHTML+=x+'\n'

test=['xxxxxxxxy','uuvvwwxxyyzz','this question is about huffman coding']
.forEach(t=>console.log(t+'\n'+f(t).join`\n`+'\n'))
<pre id=O></pre>

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.