আসুন একটি রেস কার ট্র্যাক তৈরি করি!


19

ভূমিকা

আমার ভাগ্নী একটি রেস গাড়ি ট্র্যাক করতে চায়। তার কাঠের অংশ রয়েছে যা ট্র্যাক গঠনের জন্য একসাথে ফিট করে। প্রতিটি অংশ বর্গক্ষেত্র আকৃতির এবং পৃথক আকার ধারণ করে। আমি উদাহরণস্বরূপ পাইপ অঙ্কনের অক্ষরগুলি ব্যবহার করব:

  • : যে রাস্তাটি উল্লম্বভাবে যায়
  • : রাস্তাটি অনুভূমিকভাবে যায়
  • : রাস্তাগুলি যে দিকে ঘুরিয়ে দেয়
  • : একটি আন্ডারপাস সহ একটি ব্রিজ

কৌতূহলজনকভাবে, কোনও টি-জংশনের টুকরা নেই।

এখানে সম্ভাব্য রেস কার ট্র্যাকের একটি উদাহরণ রয়েছে:

┌─┐
│ │┌─┐
│ └┼─┘
└──┘

বৈধ রেস কার ট্র্যাকের নিয়মগুলি নীচে রয়েছে:

  • কোথাও যেতে পারে এমন কোনও রাস্তা থাকতে পারে না।
  • এটি অবশ্যই একটি লুপ তৈরি করবে (এবং সমস্ত টুকরা অবশ্যই একই লুপের অংশ হওয়া উচিত)।
  • সেতুগুলি / আন্ডারপাসগুলিতে, আপনি ঘুরতে পারবেন না (যাতে আপনার মাধ্যমে সরাসরি যেতে হবে)।

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

ইনপুট বিবরণ

আমরা চাই যে ইনপুটটি এসটিডিআইএন, কমান্ড লাইন আর্গুমেন্ট, ফাইল রিডিং বা কোনও ব্যবহারকারী ইনপুট ফাংশন (যেমন raw_inputবা prompt) এর মাধ্যমে আসতে পারে। ইনপুটটি ফর্মে কমা দ্বারা পৃথক হওয়া ইতিবাচক পূর্ণসংখ্যা

│,─,┌,┐,└,┘,┼

যেখানে প্রত্যেকেই আমাদের সেই নির্দিষ্ট টুকরোটির পরিমাণ উপস্থাপন করে। উদাহরণস্বরূপ ইনপুট:

1,1,1,1,1,1,1

এর অর্থ হ'ল আমাদের প্রতিটি টুকরার একটি ছিল।

আউটপুট বিবরণ

উপরে তালিকাভুক্ত পাইপ অঙ্কন অক্ষর ব্যবহার করে একটি রেস গাড়ী ট্র্যাক আউটপুট। রেস কার ট্র্যাকের ইনপুটটিতে উল্লিখিত প্রতিটি টুকরার ঠিক সংখ্যাটি ব্যবহার করা উচিত - আর নেই, এবং কমও নয়। প্রতিটি ইনপুট জন্য কমপক্ষে একটি বৈধ রেস গাড়ী ট্র্যাক থাকবে।

উদাহরণ ইনপুট এবং আউটপুট

ইনপুট: 3,5,2,2,2,2,1

একটি সম্ভাব্য আউটপুট:

┌─┐
│ │┌─┐
│ └┼─┘
└──┘

ইনপুট: 0,0,1,4,4,1,3

একটি সম্ভাব্য আউটপুট:

 ┌┐
 └┼┐
  └┼┐
   └┼┐
    └┘

আউটপুট দেওয়ার দরকার কি? বা কেবলমাত্র তাত্ত্বিকভাবে আউটপুট দেওয়ার দরকার আছে?
সুমুরাই 8

@ সুমুরাই 8 "তাত্ত্বিকভাবে" আউটপুট দেওয়ার অর্থ কী? আপনি কি এমন কোনও প্রোগ্রাম বোঝাতে চান যা চূড়ান্ত দীর্ঘ সময়ের জন্য শেষ হয় না তবে শেষ পর্যন্ত আউটপুট দেয়?
সোমরস

1
রেস টুকরোগুলি এবং খালি স্কোয়ারগুলি পূর্ণ nxn স্কোয়ারের একটি ক্ষেত্র তৈরি করতে সক্ষম হতে পারে, যেখানে আপনি রেস ট্র্যাকের কোনও কিছু না পাওয়া পর্যন্ত আপনি ক্রমগতি তৈরি করতে পারবেন। এটি কয়েক টাইলের চেয়ে আরও বেশি কিছু জন্য চিরকাল নেবে।
সুমুরাই 8

4
@ সুমুরাই 8 আহ ঠিক আছে, আমি এখন বুঝতে পারছি। আমি পছন্দ করবো যে আমি যে চ্যালেঞ্জটিতে দেখিয়েছি তার স্বল্পমূল্যের ইনপুটগুলির জন্য মহাবিশ্বের তাপ মৃত্যুর আগে প্রোগ্রামগুলি একটি আউটপুট দেবে।
সোমরস

4
আপনার ভাগ্নী যথেষ্ট ধৈর্য না! : পি
সুমুরাই 8

উত্তর:


4

রুবি 664 671 677 687 701 (678 বাইট)

_={│:[1,4],─:[2,8],┌:[4,8],┐:[4,2],└:[1,8],┘:[1,2],┼:[1,4,2,8]}
s=->a,l,b{l==[]&&a==[]?b:(l.product(l).any?{|q,r|q,r=q[0],r[0];(q[0]-r[0])**2+(q[1]-r[1])**2>a.size**2}?!0:(w,f=l.pop
w&&v=!a.size.times{|i|y=_[x=a[i]]
f&&y&[f]==[]||(k=l.select{|p,d|w!=p||y&[d]==[]}
(y-[f]).map{|d|z=[w[0]+(d<2?-1:(d&4)/4),w[1]+(d==2?-1:d>7?1:0)]
g=d<3?d*4:d/4
b[z]?_[b[z]]&[g]!=[]||v=0:k<<[z,g]}
v||r=s[a[0...i]+a[i+1..-1],k,b.merge({w=>x})]
return r if r)}))}
c=eval"[#{gets}]"
r=s[6.downto(0).map{|i|[_.keys[i]]*c[i]}.flatten,[[[0,0],nil]],{}]
h=j=k=l=0
r.map{|w,_|y,x=w
h>x&&h=x
j>y&&j=y
k<x&&k=x
l<y&&l=y}
s=(j..l).map{|_|' '*(k-h+1)}
r.map{|w,p|y,x=w
s[y-j][x-h]=p.to_s}
puts s

এটি যে সংক্ষিপ্ততম প্রোগ্রামটি নিয়ে আসতে পেরেছি তা নয়, তবে মৃত্যুদণ্ড কার্যকর করার গতির জন্য আমি কিছুটা উত্সর্গের ত্যাগ করেছি।

আপনি প্রোগ্রামটি এখানে পরীক্ষা করতে পারেন । নোট করুন যে আইডিয়নের একটি নির্বাহের সময়সীমা থাকে, সুতরাং প্রায় 12 টিরও বেশি সংখ্যক সমন্বিত ইনপুটগুলির জন্য, প্রোগ্রামটি সম্ভবত সময় শেষ করবে।

প্রোগ্রামটির জন্য একটি পরীক্ষার স্যুটও রয়েছে । নোট করুন যে শেষ দুটি পরীক্ষা উপরে বর্ণিত সময়সীমার কারণে আদর্শের উপর অক্ষম রয়েছে। এই পরীক্ষাগুলি সক্ষম করতে, x_তাদের নাম থেকে উপসর্গ মুছুন ।

প্রোগ্রামটি গভীরতা-প্রথম অনুসন্ধান ব্যবহার করে একটি সমাধান খুঁজে বের করে; এটি একবারে একটি করে টুকরো রাখে এবং আলগা প্রান্তের ট্র্যাক রাখে। আর কোনও আলগা (সংযোগযুক্ত) শেষ না হওয়া এবং সমস্ত টুকরো স্থাপন করা হলে অনুসন্ধান বন্ধ হয়ে যায়।

এটি অসম্পূর্ণ প্রোগ্রাম:

N, W, S, E = 1, 2, 4, 8

# given a direction, find the opposite
def opposite (dir)
  dir < 3 ? dir * 4 : dir / 4
end

# given a set of coordinates and a direction,
# find the neighbor cell in that direction
def goto(from, dir)
  y, x = from

  dx = case dir
  when W then -1
  when E then 1
  else 0
  end

  dy = case dir
  when N then -1
  when S then 1
  else 0
  end

  [y+dy, x+dx]
end

CONNECTIONS = {
  ?│ => [N, S],
  ?─ => [W, E],
  ?┌ => [S, E],
  ?┐ => [S, W],
  ?└ => [N, E],
  ?┘ => [N, W],
  ?┼ => [N, S, W, E], 
}

BuildTrack =-> { 
  piece_types = CONNECTIONS.keys
  piece_counts = gets.split(?,).map &:to_i

  pieces = 6.downto(0).map{|i|piece_types[i]*piece_counts[i]}.join.chars

  def solve (available_pieces, loose_ends=[[[0,0],nil]], board={})

    return board if loose_ends==[] and available_pieces==[]

    # optimization to avoid pursuing expensive paths
    # which cannot yield a result.
    # This prunes about 90% of the search space
    c = loose_ends.map{ |c, _| c }
    not_enough_pieces = c.product(c).any? { |q, r| 
      ((q[0]-r[0])**2+(q[1]-r[1])**2) > available_pieces.size**2
    }
    return if not_enough_pieces

    position, connect_from = loose_ends.pop

    return unless position

    available_pieces.size.times do |i|
      piece = available_pieces[i]

      remaining_pieces = available_pieces[0...i] + available_pieces[i+1..-1]

      piece_not_connected_ok = connect_from && CONNECTIONS[piece] & [connect_from] == []
      next if piece_not_connected_ok

      new_loose_ends = loose_ends.select  { |pos, dir| 
        # remove loose ends that may have been 
        # fixed, now that we placed this piece
        position != pos || CONNECTIONS[piece] & [dir] == []
      }

      invalid_placement = false

      (CONNECTIONS[piece]-[connect_from]).map do |dir|
        new_pos = goto(position, dir)
        new_dir = opposite(dir)

        if board[new_pos]
          if CONNECTIONS[board[new_pos]] & [new_dir] != []
            # do nothing; already connected
          else
            # going towards an existing piece
            # which has no suitable connection
            invalid_placement = true
          end
        else
          new_loose_ends << [new_pos, new_dir]
        end
      end

      next if invalid_placement

      new_board = board.merge({position => piece})

      result = solve(remaining_pieces, new_loose_ends, new_board)
      return result if result
    end
    nil
  end

  def print_board board
    min_x = min_y = max_x = max_y = 0

    board.each do |position, _|
      y, x = position
      min_x = [min_x, x].min
      min_y = [min_y, y].min
      max_x = [max_x, x].max
      max_y = [max_y, y].max
    end

    str = (min_y..max_y).map{|_|
      ' ' * (max_x - min_x + 1)
    }

    board.each do |position, piece|
      y, x = position
      str[y-min_y][x-min_x] = piece
    end
    puts str
  end

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