একটি অ্যারে থেকে মিনিমাম সমষ্টিটি সরিয়ে ফেলুন


18

সিউম খোদাই করা অ্যালগরিদম বা এর আরও জটিল সংস্করণ বিভিন্ন গ্রাফিক্স প্রোগ্রাম এবং লাইব্রেরিতে সামগ্রী-সচেতন চিত্রের আকার পরিবর্তন করতে ব্যবহৃত হয়। এটি গল্ফ করা যাক!

আপনার ইনপুটটি পূর্ণসংখ্যার একটি আয়তক্ষেত্রাকার দ্বিমাত্রিক অ্যারে হবে।

আপনার আউটপুট একই অ্যারে, এক কলাম সংকীর্ণ হবে, প্রতিটি সারি থেকে একটি এন্ট্রি মুছে ফেলা হবে, সেই সমস্ত প্রবেশাগুলির সর্বনিম্ন যোগফল সহ উপরে থেকে নীচে একটি পথ উপস্থাপন করে এমন এন্ট্রি।

সীম খোদাই চিত্র https://en.wikipedia.org/wiki/Seam_carving

উপরের চিত্রটিতে প্রতিটি কক্ষের মান লাল দেখানো হয়। কালো সংখ্যাগুলি হ'ল একটি ঘরের মান এবং তার উপরে তিনটি কোষের মধ্যে একটিতে সর্বনিম্ন কালো সংখ্যা (সবুজ তীর দ্বারা চিহ্নিত)) সাদা হাইলাইটেড পাথগুলি হ'ল সর্বনিম্ন দুটি সমষ্টি পথ, উভয়ই 5 এর যোগফল (1 + 2 + 2 এবং 2 + 2 + 1)।

এমন ক্ষেত্রে যেখানে সর্বনিম্ন অঙ্কের জন্য দুটি পাথ বাঁধা আছে, আপনি কোনটি সরান তা বিবেচ্য নয়।

স্টিডিন থেকে অথবা ফাংশন প্যারামিটার হিসাবে ইনপুট নেওয়া উচিত। এটি আপনার পছন্দের ভাষার জন্য বন্ধুত্ব এবং / বা ডিলিমিটর সহ সুবিধার সাথে ফর্ম্যাট করা যায়। কীভাবে ইনপুটটি প্রত্যাশিত তা আপনার উত্তরে উল্লেখ করুন specify

আউটপুট একটি দ্ব্যর্থহীন সীমিত বিন্যাসে স্টাডআউট হওয়া উচিত, বা 2 ডি অ্যারের সমতুল্য আপনার ভাষার সমতুল্য ফাংশন রিটার্ন মান হিসাবে (এতে নেস্টেড তালিকা ইত্যাদি অন্তর্ভুক্ত থাকতে পারে)।

উদাহরণ:

Input:
1 4 3 5 2
3 2 5 2 3
5 2 4 2 1
Output:
4 3 5 2      1 4 3 5
3 5 2 3  or  3 2 5 3
5 4 2 1      5 2 4 2

Input:
1 2 3 4 5
Output:
2 3 4 5

Input:
1
2
3
Output:
(empty, null, a sentinel non-array value, a 0x3 array, or similar)

সম্পাদনা: সংখ্যাগুলি সমস্ত অ-নেতিবাচক হবে এবং প্রতিটি সম্ভাব্য সিউমের সমষ্টি হবে যা একটি স্বাক্ষরিত 32 বিট পূর্ণসংখ্যায় ফিট করে।


উদাহরণগুলিতে সমস্ত কক্ষের মান একক সংখ্যা digit এটা কি নিশ্চিত? যদি তা না হয় তবে মানগুলির আকার / পরিসর সম্পর্কে আরও কিছু অনুমান করা যায়? উদাহরণস্বরূপ যে যোগফলটি 16/32-বিট মানের সাথে ফিট করে? বা কমপক্ষে যে সমস্ত মান ধনাত্মক?
রেটো কোড়াদি

@ রেটোকোরাডি পরিসরের বিশদ সহ সম্পাদনা করেছেন
স্পার

উত্তর:


5

সিজেম, 51 44 বাইট

{_z,1$,m*{_1>.-W<2f/0-!},{1$.=:+}$0=.{WtW-}}

এটি একটি বেনামে ফাংশন যা স্ট্যাক থেকে একটি 2D অ্যারে পপ করে এবং বিনিময়ে একটিকে ধাক্কা দেয়।

সিজেএম ইন্টারপ্রেটারে পরীক্ষার কেসগুলি অনলাইনে চেষ্টা করুন । 1

ধারণা

এই পদ্ধতির সারি উপাদানগুলির সমস্ত সম্ভাব্য সংমিশ্রণগুলিতে পুনরাবৃত্তি ঘটে, যেগুলি seams এর সাথে সামঞ্জস্য করে না তাদের ফিল্টার করে, সমষ্টি অনুসারে বাছাই করে, সর্বনিম্নটি ​​নির্বাচন করে এবং অ্যারে থেকে সংশ্লিষ্ট উপাদানগুলি সরিয়ে দেয়। 2

কোড

_z,   e# Get the length of the transposed array. Pushes the number of columns (m).
1$,   e# Get the length of the array itself. Pushes the number of rows (n).
m*    e# Cartesian power. Pushes the array of all n-tuples with elements in [0 ... m-1].
{     e# Filter:
  _1> e#     Push a copy of the tuple with first element removed.
  .-  e#     Vectorized difference.
  W<  e#     Discard last element.
  2f/ e#     Divide all by 2.
  0-  e#     Remove 0 from the results.
  !   e#     Push 1 if the remainder is empty and 0 otherwise.
},    e#     Keep only tuples which pushed a 1.

      e# The filtered array now contains only tuples that encode valid paths of indexes.

{     e# Sort by:
  1$  e#     Copy the input array.
  .=  e#     Retrieve the element of each row that corresponds to the index in the tuple.
  :+  e#     Add all elements.
}$    e#
0=    e# Retrieve the tuple of indexes with minimum sum.
.{    e# For each row in the array and the corresponding index in the tuple:
  Wt  e#     Replace the element at that index with -1.
  W-  e#     Remove -1 from the row.
}

1 নোট করুন যে সিজেএম খালি অ্যারে এবং খালি স্ট্রিংগুলির মধ্যে পার্থক্য করতে পারে না, যেহেতু স্ট্রিংগুলি কেবল অ্যারে যার উপাদানগুলি অক্ষর। সুতরাং, খালি অ্যারে এবং খালি দুটি স্ট্রিংয়ের স্ট্রিং প্রতিনিধিত্ব ""

2 উইকিপিডিয়ায় পৃষ্ঠায় প্রদর্শিত অ্যালগরিদমের সময় জটিলতা এন × এম ম্যাট্রিক্সের জন্য ও (এনএম) হওয়া উচিত, তবে এটির কমপক্ষে ও (এম এন ) হয়



দুঃখের বিষয়, এটি দ্বিতীয় পরীক্ষার ক্ষেত্রে কাজ করবে না। আমি এই সম্পর্কে দুটি সপ্তাহ আগে একটি বাগ রিপোর্ট দায়ের করেছি ।
ডেনিস

5

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

l=length
f a@(b:c)=snd$maximum$(zip=<<map(sum.concat))$map(zipWith((uncurry((.drop 1).(++)).).flip splitAt)a)$iterate((\e@(f:_)->[f-1:e,f:e,min(f+1)(l b-1):e])=<<)[[y]|y<-[0..l b-1]]!!l c

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

*Main> f [[1,4,3,5,2],[3,2,5,2,3],[5,2,4,2,1]]
[[4,3,5,2],[3,5,2,3],[5,4,2,1]]

*Main> f [[1],[2],[3]]
[[],[],[]]

*Main> f [[1,2,3,4,5]]
[[2,3,4,5]]

এটি কীভাবে কাজ করে, সংক্ষিপ্ত সংস্করণ: প্রতিটি পথের (1) প্রতিটি পাথের একটি তালিকা তৈরি করুন: সংশ্লিষ্ট উপাদানগুলি (2) সরান এবং বাকী সমস্ত উপাদান (3) যোগ করুন। বৃহত্তম যোগফল (4) সহ আয়তক্ষেত্রটি নিন।

দীর্ঘ সংস্করণ:

Input parameters, assigned via pattern matching:
a = whole input, e.g. [[1,2,4],[2,5,6],[3,1,6]]
b = first line, e.g. [1,2,4]
c = all lines, except first, e.g. [[2,5,6],[3,1,6]]

Step (1), build all paths:

iterate((\e@(f:_)->[f-1:e,f:e,min(f+1)(l b-1):e])=<<)[[y]|y<-[0..l b-1]]!!l c

     [[y]|y<-[0..l b-1]]           # build a list of single element lists
                                   # for all numbers from 0 to length b - 1
                                   # e.g. [[0],[1],[2]] for a 3 column input.
                                   # These are all possible start points

     \e@(f:_)->[f-1:e,f:e,min(f+1)(l b-1):e]
                                   # expand a list of paths by replacing each
                                   # path with 3 new paths (up-left, up, up-right)

     (...)=<<                      # flatten the list of 3-new-path lists into
                                   # a single list

     iterate (...) [...] !! l c    # repeatedly apply the expand function to
                                   # the start list, all in all (length c) times.


Step (2), remove elements

map(zipWith((uncurry((.drop 1).(++)).).flip splitAt)a)

     (uncurry((.drop 1).(++)).).flip splitAt
                                   # point-free version of a function that removes
                                   # an element at index i from a list by
                                   # splitting it at index i, and joining the
                                   # first part with the tail of the second part

      map (zipWith (...) a) $ ...  # per path: zip the input list and the path with
                                   # the remove-at-index function. Now we have a list
                                   # of rectangles, each with a path removed

Step (3), sum remaining elements

zip=<<map(sum.concat)             # per rectangle: build a pair (s, rectangle)
                                  # where s is the sum of all elements


Step (4), take maximum

snd$maximum                      # find maximum and remove the sum part from the
                                 # pair, again.

3

IDL 8.3, 307 বাইট

মেহ, আমি নিশ্চিত যে এটি জিতবে না কারণ এটি দীর্ঘ, তবে এখানে একটি সহজ সমাধান রয়েছে:

pro s,a
z=size(a,/d)
if z[0]lt 2then return
e=a
d=a*0
u=max(a)+1
for i=0,z[1]-2 do begin
e[*,i+1]+=min([[u,e[0:-2,i]],[e[*,i]],[e[1:*,i],u]],l,d=2)
d[*,i]=l/z[0]-1
endfor
v=min(e[*,-1],l)
r=intarr(z[1])+l
for i=z[1]-2,0,-1 do r[0:i]+=d[r[i+1],i]
r+=[0:z[1]-1]*z[0]
remove,r,a
print,reform(a,z[0]-1,z[1])
end

Ungolfed:

pro seam, array
  z=size(array, /dimensions)
  if z[0] lt 2 then return
  energy = array
  ind = array * 0
  null = max(array) + 1
  for i=0, z[1]-2 do begin
    energy[*, i+1] += min([[null, energy[0:-2,i]], [energy[*,i]], [energy[1:*,i], null]], loc ,dimension=2)
    ind[*, i] = loc / z[0] - 1
  endfor
  void = min(energy[*,-1], loc)
  rem = intarr(z[1]) + loc
  for i=z[1]-2, 0, -1 do rem[0:i] += ind[rem[i+1], i]
  rem += [0:z[1]-1]*z[0]
  remove, rem, array
  print, reform(array, z[0]-1, z[1])
end

আমরা পুনরাবৃত্তভাবে শক্তি অ্যারে তৈরি করি এবং সিমটি কোন দিকে চলে যায় তা ট্র্যাক করি, তারপরে আমরা চূড়ান্ত অবস্থানটি জানার পরে একটি অপসারণের তালিকা তৈরি করি const 1D ইনডেক্সিংয়ের মাধ্যমে সীমটি সরান, তারপরে নতুন মাত্রা সহ অ্যারেটিতে পুনরায় সংস্কার করুন।


3
ওহ godশ্বর ... আমি মনে করি আমি কেবল আইডিএল (আবার) দেখলাম up আমি ভেবেছিলাম যে আমি স্নাতক হওয়ার পরেও তা শেষ করে দিয়েছি ...
কাইল কানোস

এটি বলেছিল, আমি সন্দেহ করি এটি জিডিএল এর পক্ষেও কাজ করে, যাতে জনগণ একক ব্যবহারকারীর লাইসেন্সের জন্য $ 1 বিলিয়ন ডলার দিতে আগ্রহী হয় না এটি পরীক্ষা করতে পারে?
কাইল কানোজ

আমি কখনই জিডিএল ব্যবহার করি নি, তাই আমি বলতে পারি না (সত্যই আমি ভুলে গিয়েছিলাম এটি বিদ্যমান ছিল)। সমস্যাটি হতে পারে কেবলমাত্র যদি জিডিএল সিনট্যাক্সের অ্যারে তৈরি পরিচালনা করতে না পারে [0:n]; এটাই যদি সত্যি হয়, তাহলে এটি প্রতিস্থাপন করা সহজ r+=[0:z[1]-1]*z[0]সঙ্গে r+=indgen(z[1]-1)*z[0]
sirpercival

এছাড়াও, আমি আমার গল্ফগুলির জন্য অজগরটি ব্যবহার করার সময়, অন্য কেউ আইডিএল করে না তাই আমি এক্সডির অবদান রাখতে বাধ্য বোধ করি। এছাড়াও, এটি খুব ভাল কিছু কাজ করে।
sirpercival

3
আমি আমাকে খুব ভালভাবে
ক্রিঞ্জ

3

জাভাস্ক্রিপ্ট ( ES6 ) 197 209 215

উইকিপিডিয়া অ্যালগরিদমের ধাপে ধাপে প্রয়োগ।

সম্ভবত আরও ছোট করা যেতে পারে।

ফায়ারফক্সে স্নিপেট চালানোর পরীক্ষা করুন।

// Golfed

F=a=>(u=>{for(r=[i=p.indexOf(Math.min(...p))];l--;i=u[l][i])(r[l]=[...a[l]]).splice(i,1)})
(a.map(r=>[r.map((v,i)=>(q[i]=v+~~p[j=p[i+1]<p[j=p[i-1]<p[i]?i-1:i]?i+1:j],j),q=[++l]),p=q][0],p=[l=0]))||r

// LESS GOLFED

U=a=>{
  p = []; // prev row
  u = a.map( r => { // in u the elaboration result, row by row
      q=[];
      t = r.map((v,i) => { // build a row for u from a row in a
        j = p[i-1] < p[i] ? i-1 : i; // find position of min in previous row
        j = p[i+1] < p[j] ? i+1 : j;
        q[i] = v + ~~p[j]; // values for current row
        // ~~ convert to number, as at first row all element in p are 'undefined'
        return j;//  position in u, row by row
      });
      p = q; // current row becomes previous row 
      return t;
  });
  n = Math.min(...p) // minimum value in the last row
  i = p.indexOf(n); // position of minimum (first if there are more than one present)
  r = []; // result      
  // scan u bottom to up to find the element to remove in the output row
  for(j = u.length; j--;)
  {
    r[j] = a[j].slice(); // copy row to output
    r[j].splice(i,1); // remove element
    i = u[j][i]; // position for next row
  }
  return r;
}

// TEST        
out=x=>O.innerHTML += x + '\n';        

test=[
  [[1,4,3,5,2],[3,2,5,2,3],[5,2,4,2,1]],
  [[1,2,3,4,5]],
  [[1],[2],[3],[4]]
];  

test.forEach(t=>{
  out('Test data:\n' + t.map(v=>'['+v+']').join('\n'));
  r=F(t);
  out('Golfed version:\n' + r.map(v=>'['+v+']').join('\n'))      
  r=U(t);
  out('Ungolfed version:\n' + r.map(v=>'['+v+']').join('\n'))
})  
<pre id=O></pre>


1

পিপ, 91 বাইট

এটি কোনও পুরস্কার জিতবে না, তবে এতে কাজ করে আমি মজা পেয়েছি। হোয়াইটস্পেস কেবল প্রসাধনী কারণে এবং বাইট গণনা অন্তর্ভুক্ত করা হয় না।

{
 p:{(zaj-1+,3RMv)}
 z:a
 w:,#(a0)
 Fi,#a
  Fjw
   Ii
    z@i@j+:MN(pi-1)
 s:z@i
 Ti<0{
  j:s@?MNs
  a@i@:wRMj
  s:(p--i)
 }
 a
}

এই কোড একটি বেনাম ফাংশন সংজ্ঞায়িত করে যার যুক্তি এবং ফেরতের মান নেস্টেড তালিকা। এটি উইকিপিডিয়া পৃষ্ঠা থেকে অ্যালগরিদম প্রয়োগ করে: a(যুক্তি) হল লাল সংখ্যা, এবং zকালো সংখ্যা numbers

পরীক্ষার জোতা সহ একটি সংস্করণ এখানে:

f:{p:{(zaj-1+,3RMv)}z:aw:,#(a0)Fi,#aFjwIiz@i@j+:MN(pi-1)s:z@iTi<0{j:s@?MNsa@i@:wRMjs:(p--i)}a}
d:[
 [[1 4 3 5 2]
  [3 2 5 2 3]
  [5 2 4 2 1]]
 [[1 2 3 4 5]]
 [[1]
  [2]
  [3]]
 ]
Fld
 P(fl)

ফলাফল:

C:\> pip.py minSumSeam.pip -p
[[4;3;5;2];[3;5;2;3];[5;4;2;1]]
[[2;3;4;5]]
[[];[];[]]

এবং পাইথন 3 এর মোটামুটি সমতুল্য এখানে যদি কেউ পাইপ কোডের আরও ভাল ব্যাখ্যা চান তবে কেবল মন্তব্যে জিজ্ঞাসা করুন।

def f(a):
    z = [row.copy() for row in a]
    w = range(len(a[0]))

    for i in range(len(a)):
        for j in w:
            if i:
                z[i][j] += min(z[i-1][max(j-1,0):j+2])
    s = z[i]
    while i >= 0:
        j = s.index(min(s))
        del a[i][j]
        i -= 1
        s = z[i][max(j-1,0):j+2]
    return a
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.