প্যালিনড্রোম সংক্ষেপণ


15

চ্যালেঞ্জ

এমন একটি প্রোগ্রাম লিখুন যা ASCII পাঠকে ক্ষতিগ্রস্থভাবে সংকুচিত করে এবং সংক্ষেপিত করে। কেস-সংবেদনশীল এবং বিরামচিহ্ন-সংবেদনশীল প্যালিনড্রোমস সহ প্যালিনড্রোমগুলির সাথে ভালভাবে কাজ করার জন্য এটি বিশেষভাবে তৈরি করা উচিত। ক্ষুদ্রতম উত্সের সাথে সেরা সংকোচনের জয়।

স্কোরিং

total_bytes_saved / sqrt(program_size) - সর্বোচ্চ স্কোর জয়

total_bytes_saved সংক্ষিপ্ততর স্ট্রিংগুলি মূলগুলির তুলনায় কতগুলি বাইট কম ছোট তা নীচের পরীক্ষার কেসগুলিতে মোট। program_sizeউভয় সংক্ষেপণ এবং ডিকম্প্রেশন প্রোগ্রামগুলির উত্স কোডের বাইটের আকার। দুজনের মধ্যে ভাগ করা কোডটি একবারেই গণনা করা যেতে পারে।

উদাহরণস্বরূপ, যদি সেখানে 10 টি পরীক্ষার কেস এবং একটি 100 বাইট প্রোগ্রামে 7 টি পরীক্ষার ক্ষেত্রে 5 বাইট সংরক্ষণ করা হয়, তাদের 2 টির মধ্যে 10 টি, তবে শেষ পরীক্ষার কেসটি 2 বাইট দীর্ঘ ছিল, সমাধানটি 5.3 স্কোর করবে। ( (7 * 5 + 10 * 2 - 2) / sqrt(100) = 5.3)

পরীক্ষার কেস

  • tacocat
  • toohottohoot
  • todderasesareddot
  • amanaplanacanalpanama
  • wasitacaroracatisaw?
  • Bob
  • IManAmRegalAGermanAmI
  • DogeeseseeGod
  • A Santa at NASA
  • Go hang a salami! I'm a lasagna hog.

বিধি

  1. স্ট্যান্ডার্ড লুফোলস প্রযোজ্য।
  2. কম্প্রেশনটি অবশ্যই প্রিন্টযোগ্য ASCII (বাইটস 32-126, সমেত) পাঠ্য স্ট্রিংগুলিতে কাজ করবে, কেবল প্যালিনড্রোমগুলি নয়। তবে আসলে কোনও ইনপুটগুলির জন্য স্থান সংরক্ষণ করতে হবে না।
  3. আউটপুট বাইট বা অক্ষরের যে কোনও ক্রম হতে পারে, এর প্রয়োগ বা অভ্যন্তরীণ উপস্থাপনা নির্বিশেষে (স্ট্রিং, তালিকা এবং অ্যারেগুলি সমস্ত ন্যায্য খেলা, উদাহরণস্বরূপ)। যদি ইউটিএফ -8 এ এনকোডিং হয় তবে অক্ষর নয়, বাইটগুলি গণনা করুন। প্রশস্ত স্ট্রিংগুলি (যেমন ইউটিএফ -16 বা ইউটিএফ -32) অনুমোদিত নয় কেবলমাত্র কোডপয়েন্টগুলি 0 এবং 255 এর মধ্যে না হওয়া পর্যন্ত অনুমোদিত নয়।
  4. সংক্ষিপ্তকরণ / ডিকম্প্রেশন বিল্টিনগুলি অনুমোদিত নয়।

আমাদের নিজস্ব উপভোগের জন্য, আপনার উত্স কোড সহ সংকুচিত স্ট্রিং পোস্ট করুন।

আপডেট 1: স্কোরিং থেকে পরিবর্তিত total_bytes_saved / program_sizeহয়েছেtotal_bytes_saved / sqrt(program_size) যাতে ভাল কম্প্রেশন এবং আক্রমনাত্মক golfing কম ওজন বেশি ওজন দিতে হবে। সেই অনুযায়ী আপনার স্কোর সামঞ্জস্য করুন।

আপডেট 2:wasitacaroraratisaw? হতে স্থিরwasitacaroracatisaw?


2
যদি কেস, বিরামচিহ্ন এবং স্পেসিং ইনপুট থেকে সরানো হয়, তবে কি গ্যারান্টিযুক্ত যে ইনপুটগুলি কঠোর প্যালিনড্রোম হবে? সম্পাদনা করুন: কিছুই নয় - আমি দেখতে পাচ্ছি wasitacaroraratisaw?যে
ডিজিটাল ট্রমা

2
আমরা ইনপুটটিতে কোন ASCII অক্ষরকে সমর্থন করব? এটা কি [32-126]?
আর্নৌল্ড

1
হ্যাঁ, আমি মনে করি না যে 1000 *অংশটি সত্যই প্রয়োজন, এবং আমি মনে করি না যে এটি স্কোরটিকে আরও "সন্তোষজনক" মনে করবে;)
এরিক দ্য আউটগলফার

1
আমরা কি সংক্ষেপণ / ডিকম্প্রেশনটি অন্তর্নির্মিত ব্যবহার করতে পারি?
লিন

4
খুব কম ইনপুট থাকলে, চতুর কিছু করার খুব বেশি সুযোগ নেই। কমপক্ষে কয়েকগুণ বেশি থাকলে ভাল লাগবে।
ব্যবহারকারী1502040

উত্তর:


16

জাভাস্ক্রিপ্ট (ES6), 3.143 (81 বাইট সংরক্ষিত, 664 বাইট প্রোগ্রাম)

R='replace',S=String.fromCharCode,T=c=>c.charCodeAt(),U='toUpperCase',V='0000000',W=(a,b,c=2)=>a.toString(c).slice(b),X=x=>'0b'+x,Y=a=>[...a].reverse().join``,Z=/[^]/g
C=s=>S(...((Y(q=s[U]()[R](/[^A-Z]/g,m=''))==q?(q=q.slice(0,p=-~q.length/2),p%1&&10):11)+q[R](Z,x=>W(T(x),2))+111+s[R](Z,c=>/[a-z]/.test(c)?W("00",m,m=1):m+(/[A-Z]/.test(c,m='')?"01":W(c<'!'?2:T(c)+384)))+V).match(/(?!0+$).{8}/g).map(X))
D=s=>{s=s[R](Z,c=>W(256+T(c),1))+V;M=r=>(s=s[R](p=s.match(`^${r}|`)[0],''),p);for([,a]=M`1.|0`,t=u=i='';!M`111`;)t+=W(X(M`.{5}`)-~8,0,36);for(t+=W(Y(t),a?a/0:1);p;)u+=M`0(?=00)|00?1`?(c=t[i++])?+p[1]?c[U]():c:'':M`10`?' ':M`11`&&S(X(M`.{7}`));return u+W(t,i)}

এখন যেহেতু আমি এই প্রোগ্রামটি (এবং স্কোরিং সিস্টেম) দিয়ে মোটামুটি সন্তুষ্ট, আমি একটি ব্যাখ্যা কিছুটা লিখব।

মূল ধারণাটি হ'ল বিটগুলির একটি স্ট্রিংয়ে ইনপুটটি সংকুচিত করা, তারপরে 8 বিটের প্রতিটি সেটকে একটি বাইটে সংকুচিত করুন। ব্যাখ্যার উদ্দেশ্যে, আমি কেবল বিট স্ট্রিংটি ব্যবহার করব।

বিট স্ট্রিংটি কয়েকটি বিভাগে বিভক্ত করা যেতে পারে:

input  -> Taco Cat.
output -> 0101000000100011011111110100001100100011101011100000000

0      | 10100 00001 00011 01111 111 | 01 00001 10 01 0001 110101110
header | letter data                 | styling data

শিরোনামটি একটি খুব সাধারণ ম্যাপিং:

0  -> odd-length palindrome
10 -> even-length palindrome
11 -> non-palindrome

লেটারের ডেটাও মোটামুটি সহজ। প্রথমত, সমস্ত অ-অক্ষরগুলি স্ট্রিং থেকে উত্তোলন করা হয় এবং সমস্ত অক্ষর বড়হাতে রূপান্তরিত হয়। যদি ফলাফলটির স্ট্রিংটি একটি প্যালিনড্রোম হয় তবে বিপরীত অর্ধেকটি কেটে ফেলা হয়। তারপরে এই ম্যাপিংটি প্রয়োগ করা হবে:

A -> 00001
B -> 00010
C -> 00011
D -> 00100
...
Z -> 11010

এই বিভাগটি দিয়ে সমাপ্ত হয় 111 । এর পরে স্টাইলিং ডেটা আসে, যা আপার / লোয়ার-কেস ডেটা এবং অ-অক্ষর সঞ্চয় করে। এটি এর মতো কাজ করে:

01 -> next letter as uppercase
0...01 (n 0s) -> next (n-1) letters as lowercase
10 -> space
11xxxxxxx -> character with code point 0bxxxxxxx

সুতরাং উপরোক্ত উদাহরণ দিয়ে যাচ্ছি, আমাদের আছে

header: 0 -> palindrome
letter data: 10100 00001 00011 01111 111 -> taco
styling data:
  01        -> T
  00001     -> aco
  10        -> <space>
  01        -> C
  0001      -> at
  110101110 -> .

বিট স্ট্রিংয়ের সমাপ্তি পৌঁছে গেলে বর্ণের ডেটা থেকে সমস্ত অক্ষর ফলাফলের সাথে সংযুক্ত করা হয়। এটি আমাদের শেষ পর্যন্ত করা থেকে বাঁচায়000...001 এবং স্ট্রিং থেকে এই বিটগুলি কেটে ফেলার অনুমতি দেয়।

পরীক্ষার কেসগুলির মধ্য দিয়ে যাচ্ছেন:

tacocat -> 3 bytes (-4)
    24 bits: 010100000010001101111111
toohottohoot -> 5 bytes (-7)
    35 bits: 10101000111101111010000111110100111
todderasesareddot -> 7 bytes (-10)
    49 bits: 0101000111100100001000010110010000011001100101111
amanaplanacanalpanama -> 8 bytes (-13)
    59 bits: 00000101101000010111000001100000110000001011100000100011111
wasitacaroracatisaw? -> 11 bytes (-9)
    84 bits: 010111000011001101001101000000100011000011001001111111000000000000000000001110111111
Bob -> 2 bytes (-1)
    16 bits: 0000100111111101
IManAmRegalAGermanAmI -> 13 bytes (-8)
    98 bits: 00100101101000010111000001011011001000101001110000101100111010100010100101000001010100000010100101
DogeeseseeGod -> 7 bytes (-6)
    54 bits: 000100011110011100101001011001100101111010000000000101
A Santa at NASA -> 8 bytes (-7)
    63 bits: 100000110011000010111010100000011110110010000011000011001010101
Go hang a salami! I'm a lasagna hog. -> 20 bytes (-16)
   154 bits: 1000111011110100000001011100011100001100110000101100000010110101001111010011000000110001100000000111010000110011101001110011000110000000001100000111010111

কি দারুন. আমি এই পদ্ধতির দ্বারা সত্যই মুগ্ধ। আমি কখনও বিট-প্যাকড এনকোডিংটি এইভাবে করার কথা ভাবিনি। (আমি ASCII কে 7 টি বিটে প্যাক করার ক্ষেত্রে ভাবিনি, তবে প্যালিনড্রোমগুলির জন্য খুব বেশি জায়গা সঞ্চয় করেন না) আমি প্রভাবিত হয়েছি যে আপনি স্থানও সংরক্ষণ করতে পেরেছিলেন Bob
বিফস্টার

4
এটি ইঞ্জিনিয়ারিংয়ের মূলসূত্রগুলির একটি দুর্দান্ত উদাহরণ। সমস্যার বিবরণ গ্রহণ, এটি সমাধানের বিভিন্ন উপায় সম্পর্কে চিন্তাভাবনা করা এবং প্রয়োজনীয়তার মধ্যে ব্যবসায়ের (যেমন বিভিন্ন স্টাইলকে কত বিট দিতে হবে) ইত্যাদি ইত্যাদি
রবার্ট ফ্রেজার

@ বিফস্টার ধন্যবাদ :-) Bobসত্যিই ঠিক জায়গায় পড়ে গিয়েছিল - শিরোনামের জন্য 1 বিট, দুটি অক্ষরের জন্য 10 + 3 বিট এবং একক বড় হাতের অক্ষরের জন্য 2 বিট। আমি যদি আমার সবচেয়ে চেষ্টা করে দেখি তবে এটি আর ছোট হতে পারে না ...
ETH প্রোডাকশনগুলি

1
@ কেভিন ক্রুজসেন সমস্যা হ'ল সমস্যাটি যুক্ত করা হচ্ছে এটি একটি স্ট্রিং, তাই এটি প্রথমে একটি সংখ্যায় রূপান্তর করতে হবে। এই -0+9
উপায়টি

1
@ এথ প্রডাকশনগুলি অবশ্যই আহ (অবশ্যই এটি একটি স্ট্রিং ছিল না)! +9স্ট্রিং যাবে CONCAT, যখন -~8করবেন +9arithmetically (যেহেতু -স্ট্রিং জন্য কিছু না, তাই এটি একটি সংখ্যা যেমন ব্যাখ্যা)। যে ক্ষেত্রে -~8বেশ স্মার্ট। :) চমৎকার উত্তর বিটিডব্লিউ, আমার কাছ থেকে +1! খুব স্মার্ট এই জাতীয় বিটগুলিতে সমস্ত তথ্য সঞ্চয় করে এমনকি একটি বাইট সংরক্ষণ করে Bob
কেভিন ক্রুইজসেন

2

পাইথন 2: 2.765 (70 বাইট সংরক্ষিত, 641 বাইট প্রোগ্রাম)

আমি আমার দৃষ্টিভঙ্গিটি কিছুটা পরিবর্তন করেছি। এটি এখন অসম্পূর্ণ প্যালিনড্রোমগুলিতে ভাল কাজ করে। কোনও সংকুচিত স্ট্রিং নেই যা ইনপুটটির চেয়ে দীর্ঘ হবে। নিখুঁত সম-দৈর্ঘ্যের প্যালিনড্রোমগুলি সর্বদা মূল আকারে 50% কে সংকুচিত করবে।

A=lambda x:chr(x).isalpha()
def c(s):
 r=bytearray(s);q=len(r);L=0;R=q-1;v=lambda:R+1<q and r[R+1]<15
 while L<=R:
  while not A(r[L])and L<R:L+=1
  while not A(r[R])and R:
   if v()and r[R]==32:r[R]=16+r.pop(R+1)
   R-=1
  j=r[L];k=r[R]
  if A(j)*A(k):
   if L!=R and j&31==k&31:
    r[L]+=(j!=k)*64;r[R]=1
    if v():r[R]+=r.pop(R+1)
   else:r[L]|=128;r[R]|=128
  L+=1;R-=1
 while r[-1]<16:r.pop()
 return r
def d(s):
 r='';t=[]
 for o in s:
  if 15<o<32:r+=' ';o-=16
  while 0<o<16:r+=chr(t.pop());o-=1
  if o==0:continue
  if 127<o<192:o-=64;t+=[o^32]
  elif o>192:o-=128
  elif A(o):t+=[o]
  r+=chr(o)
 while t:r+=chr(t.pop())
 return r

ফলাফল

'tacocat' <==> 'tac\xef'
4/7 (3 bytes saved)
'toohottohoot' <==> 'toohot'
6/12 (6 bytes saved)
'todderasesareddot' <==> 'todderas\xe5'
9/17 (8 bytes saved)
'amanaplanacanalpanama' <==> 'amanaplana\xe3'
11/21 (10 bytes saved)
'wasitacaroracatisaw?' <==> 'wasita\xe3ar\xef\x09?'
12/20 (8 bytes saved)
'Bob' <==> '\x82\xef'
2/3 (1 bytes saved)
'IManAmRegalAGermanAmI' <==> 'I\x8d\xa1n\x81m\x92e\xa7\xa1\xec'
11/21 (10 bytes saved)
'Dogeeseseegod' <==> '\x84ogees\xe5'
7/13 (6 bytes saved)
'A Santa at NASA' <==> 'A S\xa1\xaeta\x12\x14'
9/15 (6 bytes saved)
"Go hang a salami! I'm a lasagna hog." <==> "\x87o hang a salam\xa9!\x11'\x01\x11\x17\x13."
24/36 (12 bytes saved)

এবং বোনাস হিসাবে এটি আমার আগে থাকা আমার ভুল প্যালিনড্রোমে 6 বাইট সংরক্ষণ করে।

'wasita\xe3ar\xef\x02\xf2\x06?' <==> 'wasitacaroraratisaw?'
6 bytes saved

ব্যাখ্যা

ডিকম্প্রেশন একটি স্ট্যাক ব্যবহার করে। 32-127 এর কোডপয়েন্টগুলি আক্ষরিকভাবে চিকিত্সা করা হয়। যদি একটি অক্ষর একটি অক্ষর হয় তবে একটি মান স্ট্যাকের উপরেও চাপ দেওয়া হয়। 128-192 এর মানগুলি ফ্লিপযুক্ত অক্ষরের ক্ষেত্রে ব্যবহৃত হয়, তাই কেসফ্লিপ করা চিঠি (o^32 কারণ কীভাবে ASCII আউট করা হয়) স্ট্যাকের দিকে ঠেলাঠেলি করে এবং স্বাভাবিক বর্ণটি স্ট্রিংয়ের সাথে যুক্ত হয়। মানগুলি 192-255 টি স্ট্যাকের দিকে না ঠেলে চিঠিগুলি যুক্ত করতে ব্যবহৃত হয়, সুতরাং অক্ষর মেলে না এবং বেদ-দৈর্ঘ্যের প্যালিনড্রোমগুলিতে মাঝারি অক্ষরের জন্য ব্যবহৃত হয়। কোডপয়েন্টস 1-15 ইঙ্গিত দেয় যে স্ট্যাকটি সেই সংখ্যাটিতে পপ করা উচিত। কোডপয়েন্টস 17-31 অনুরূপ, তবে তারা স্ট্যাক থেকে পপিংয়ের আগে প্রথমে একটি স্থান মুদ্রণ করে। একটি ইনপুট শেষে একটি অন্তর্নিহিত "পপ খালি অবধি" নির্দেশনাও রয়েছে।

সংক্ষিপ্তকারক উভয় প্রান্ত থেকে কাজ করে এবং 1-31 এর মান হিসাবে মিলের অক্ষরগুলিতে ভাঁজ করে। এটি নন-অক্ষরের উপর ছেড়ে যায়। অক্ষর মেলে তবে কেসটি মেলে না, এটি বাম অক্ষরে 64৪ যোগ করে এবং ডান বর্ণটি বৃদ্ধি করে। এটি এটিকে স্থান বাঁচাতে দেয় IManAmRegalAGermanAmI। মাঝখানে বা যখন বর্ণগুলি মেলে না, এটি উভয় পক্ষের 128 টি পর্যন্ত। আমি সেখানে যুক্ত করতে পারছি না কারণ আমার যেখানে বিশেষ ঘটনা এড়ানো দরকার left == right। প্রতিবেশী পপ চিহ্নিতকারীগুলিকে ডানদিকে ভাঁজ করার সময়, আমাকে যাচাই করতে হবে যে প্রতিবেশী 16 টি কোডপয়েন্টে উপচে পড়বে না কারণ আমার স্পেসগুলির জন্য এটি দরকার need (এটি আসলে পরীক্ষার কেস স্ট্রিংগুলির জন্য কোনও ইস্যু নয়)

সম্পাদনা 1 : আর কোনও অসম্পূর্ণ সংস্করণ নেই।


1

পাইথন 3, 1.833 (25 বাইট সংরক্ষিত, 186 বাইট প্রোগ্রাম)

কেবল সাধারণ 0-ক্রমের সমান সম্ভাবনা এনট্রপি কোডিং। কোনও প্যালিনড্রোম-নির্দিষ্ট অপ্টিমাইজেশন নেই।

def C(s):
    u=0
    for c in s:u=u*96+ord(c)-31
    return u.to_bytes((u.bit_length()+7)//8,'big')
def D(a):
    u,s=int.from_bytes(a,'big'),''
    while u:s,u=s+chr((u%96)+31),u//96
    return s[::-1]

0

জাভা 8, স্কোর: 1.355 (20 বাইট সংরক্ষিত / 218 (107 + 111) বাইট)

সংক্ষিপ্ত ফাংশন (তিনটি অপ্রিনিতযোগ্য ASCII অক্ষর রয়েছে):

s->{int l=s.length();return s.contains(new StringBuffer(s).reverse())?s.substring(l/2)+(l%2<1?"":""):s;}

ডিকম্প্রেস ফাংশন (দুটি অপ্রিন্টযোগ্য ASCII অক্ষর রয়েছে):

s->{return s.contains("")?new StringBuffer((s=s.replaceAll("","")).substring(s.length()&1^1)).reverse()+s:s;}

ব্যাখ্যা:

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

কেবল নিখুঁত প্যালিনড্রোমগুলি সংকুচিত করে।

s->{                      // Method with String as both parameter and return-type
  int l=s.length();       //  Get the length of the input
  return s.contains(new StringBuffer(s).reverse())?
                          //  If the input is a palindrome:
    s.substring(l/2)      //   Only return the second halve of the String
    +(l%2<1?"":"")        //   + either one (if even) or two (if odd) unprintables 
   :                      //  Else:
    s;}                   //   Simply return the input again

s->{                      // Method with String as both parameter and return-type
  return s.contains("")?  //  If the input contains an unprintable:
    new StringBuffer((s=s.replaceAll("",""))
                          //   Remove the unprintables
                     .substring(s.length()&1^1))
                          //   And take either the full string (if even),
                          //   or minus the first character (if odd)
    .reverse()            //    And reverse that part
    +s                    //   And append the rest of the input (minus the unprintables)
   :                      //  Else:
    s;}                   //   Simply return the input again
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.