কোলাটজ স্টাইলে ডিম শিকার


11

গ্রেট এপিআই ইস্টার ডিম হান্ট দ্বারা অনুপ্রাণিত !

সারসংক্ষেপ

আপনার কাজটি হ'ল সম্ভাব্যতম পদক্ষেপটি ব্যবহার করে "কোলাটজ স্পেস" (পরে ব্যাখ্যা করার জন্য) একটি পূর্বনির্ধারিত পূর্ণসংখ্যার সন্ধান করা।

ভূমিকা

এই চ্যালেঞ্জটি বিখ্যাত কোলাটজ অনুমানের ভিত্তিতে যা আশা করি এখানে কমপক্ষে সকলেই শুনেছেন। এখানে সুপার কোলাটজ নম্বর মুদ্রণ করা থেকে একটি পুনরুদ্ধার করা আছে

Collatz সিকোয়েন্স (এছাড়াও 3x + 1 টি সমস্যা বলা হয়) যেখানে আপনি, কোনো ধনাত্মক পূর্ণসংখ্যা দিয়ে শুরু এই উদাহরণস্বরূপ আমরা 10 ব্যবহার করবে, এবং এটি করার জন্য পদক্ষেপ এই সেটটির প্রযোজ্য:

if n is even:
    Divide it by 2
if n is odd:
    Multiply it by 3 and add 1
repeat until n = 1

Collatz দূরত্ব C(m,n)দুটি সংখ্যার মধ্যে mএবং nএই প্রতিদ্বন্দ্বিতা করার উদ্দেশ্যে, দুটি সংখ্যার মধ্যে দূরত্ব Collatz গ্রাফ (ব্যবহার করছে:, যা সংজ্ঞায়িত করা হয় নিম্নরূপ (আমি এই ধারণা সম্পর্কে বলার জন্য @tsh করতে ক্রেডিট) 21এবং 13উদাহরণ হিসেবে ):

কোলাটজ ক্রমটি লিখুন m(এই ক্ষেত্রে 21):

21, 64, 32, 16, 8, 4, 2, 1

কোলাটজ ক্রমটি লিখুন n(এই ক্ষেত্রে 13):

13, 40, 20, 10, 5, 16, 8, 4, 2, 1

এখন কেবল একটি অনুক্রমের মধ্যে কতগুলি সংখ্যা উপস্থিত তা গণনা করুন। এটি এর মধ্যে mএবং এর মধ্যে কোলাটজ দূরত্ব হিসাবে সংজ্ঞায়িত করা হয়েছে n। এই ক্ষেত্রে 8, যথা,

21, 64, 32, 13, 40, 20, 10, 5

সুতরাং আমরা মধ্যে Collatz দূরত্ব আছে 21এবং 13যেমন C(21,13)=8

C(m,n) নিম্নলিখিত সুন্দর বৈশিষ্ট্য আছে:

C(m,n)=C(n,m)
C(m,n)=0 iff. m=n

আশা করি সংজ্ঞাটি C(m,n)এখন পরিষ্কার হয়ে গেছে। কোলাটজ স্পেসে ডিমের শিকার শুরু করা যাক!

গেমের শুরুতে, একটি নিয়ামক একটি ইস্টার ডিমের অবস্থান স্থির করে, যা তার এক-মাত্রিক সমন্বয় দ্বারা প্রকাশ করা হয়: বিরতিতে একটি পূর্ণসংখ্যা [p,q](অন্য কথায় , উভয় প্রান্তের মধ্যে একটি পূর্ণসংখ্যা pএবং qঅন্তর্ভুক্ত)।

পুরো খেলা জুড়ে ডিমের অবস্থান স্থির থাকে। আমরা এই সমন্বয় হিসাবে চিহ্নিত করব r

আপনি এখন প্রাথমিক অনুমান করতে পারেন 0 , এবং এটি নিয়ামক দ্বারা রেকর্ড করা হবে। এটি আপনার 0 তম রাউন্ড। আপনি যদি এত ভাগ্যবান হন যে আপনি এটি প্রথম স্থানে পেয়েছেন (যেমন একটি 0 = আর), খেলা শেষ হয় এবং আপনার স্কোর হয় 0(কম স্কোরটি তত ভাল)। অন্যথায়, আপনি 1 ম রাউন্ডে প্রবেশ করেন এবং আপনি একটি নতুন অনুমান 1 1 করেন , এটি ঠিক না হওয়া পর্যন্ত এটি চলতে থাকে, অর্থাত্ একটি এন = আর, এবং আপনার স্কোর হবে n

0 তম পরে প্রতিটি রাউন্ডের জন্য, নিয়ামক আপনাকে নীচের একটি ফিডব্যাক দেয় যাতে আপনি প্রদত্ত তথ্যের ভিত্তিতে আরও ভাল অনুমান করতে পারেন। ধরে নেওয়া যাক আপনি বর্তমানে nদ্বি রাউন্ডে আছেন এবং সুতরাং আপনার অনুমানটি একটি এন

  • "তুমি কি দেখেছো এটাকে!" যদি কোনও এন = আর হয়, সেক্ষেত্রে গেমটি শেষ হয় এবং আপনি স্কোর করেন n
  • "আপনি নিকটবর্তী হন :)" যদি সি (একটি এন , আর) <সি (একটি এন -1 , আর)
  • "আপনি ডিমের চারদিকে ঘুরছেন" যদি C (a n , r) = C (একটি n-1 , r)
  • "আপনি আরও দূরে রয়েছেন :(" সি (এ এন , আর)> সি (একটি এন -1 , আর)

কিছু বাইট সংরক্ষণ করতে, আমি উপরের উপস্থাপিত ক্রমে প্রতিক্রিয়াগুলিকে "ডান", "নিকটবর্তী", "সম", "আরও" বলে ডাকব।

এখানে সঙ্গে একটি উদাহরণ গেম p=1,q=15

  • a 0 = 10
  • a 1 = 11, প্রতিক্রিয়া: "নিকটবর্তী"
  • a 2 = 13, প্রতিক্রিয়া: "আরও"
  • একটি 3 = 4, প্রতিক্রিয়া: "আরও"
  • a 4 = 3, প্রতিক্রিয়া: "নিকটবর্তী"
  • a 5 = 5, প্রতিক্রিয়া: "একই"
  • a 6 = 7, প্রতিক্রিয়া: "ডান"

স্কোর: 6

চ্যালেঞ্জ

সেরা স্কোর সহ গেমটি খেলতে একটি নিয়ন্ত্রক কৌশল ডিজাইন করুন p=51, q=562

উত্তরগুলির अल्গরিদমগুলি বিশদভাবে বর্ণনা করা উচিত। আপনি যে কোনও কোড সংযুক্ত করতে পারেন যা অ্যালগরিদমকে ব্যাখ্যা করতে সহায়তা করে। এটি কোডগল্ফ নয় তাই আপনাকে সুস্পষ্ট কোড লিখতে উত্সাহ দেওয়া হবে।

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

চশমা

  • পুনরাবৃত্তি করতে, rঅন্তর অন্তর্ভুক্ত [51,562]
  • ডিফল্ট লুফোলস প্রয়োগ হয়।

অনুগ্রহ করে (প্রথম উত্তর পোস্ট করার পরে যুক্ত করা হয়েছে)

আমি ব্যক্তিগতভাবে এমন উত্তরের জন্য একটি অনুদানের প্রস্তাব দিতে পারি যেখানে [51,562]যথাযথভাবে কম খারাপ স্কোর থাকা সত্ত্বেও সমস্ত অনুমানগুলি সীমার মধ্যে করা হয় ।


তোমার কি নিয়ামক আছে?
ব্যবহারকারী 202729

মূল প্রশ্নটির মতো একটি নয়।
ওয়েইজুন চিউ

1
সি (মি, এন) কোলাটজ গ্রাফের মি, এন এর দূরত্ব ।
tsh

আমি নিজেই ধারণাটি নিয়ে এসেছি এবং কোলাটজ গ্রাফটি জানতাম না। আমাকে বলার জন্য আপনাকে ধন্যবাদ। আমি প্রশ্নের তথ্য অন্তর্ভুক্ত করব।
ওয়েজুন ঝোউ

উত্তর:


5

রুবি, 196

এটি এমনভাবে শক্ত ছিল যা আমি প্রথম দিকে ভেবেছিলাম। আমাকে প্রচুর অস্পষ্ট মামলা পরিচালনা করতে হয়েছিল এবং প্রচুর কুৎসিত কোড দিয়ে শেষ করতে হয়েছিল। তবে অনেক মজা ছিল! :)

কৌশল

প্রতিটি কোলাটজ সিকোয়েন্স শেষ হয় 2 এর শক্তির ক্রম দিয়ে (যেমন: [16, 8, 4, 2, 1])] 2 এর শক্তির সম্মুখীন হওয়ার সাথে সাথে আমরা 1 এ পৌঁছানোর আগে পর্যন্ত 2 কে বিভক্ত করে আসুন 2 এর প্রথম শক্তিটিকে একটি সিকোয়েন্সের নিকটতম পাওয়ার 2 তে কল করুন (কারণ এটি কোলাটজ দূরত্ব ব্যবহার করে আমাদের সংখ্যার 2 এর নিকটতম শক্তিও)। প্রদত্ত পরিসীমা (৫১-৫ For২) এর জন্য, সম্ভাব্য নিকটস্থ পাও 2 নম্বরগুলি হ'ল : [16, 64, 128, 256, 512, 1024]

সংক্ষিপ্ত সংস্করণ

অ্যালগরিদম সম্পাদন করে:

  • বর্তমান সংখ্যার নিকটতম শক্তি 2 বের করার জন্য একটি বাইনারি অনুসন্ধান
  • লক্ষ্য সংখ্যাটি আবিষ্কার না হওয়া অবধি ক্রমটিতে প্রতিটি পূর্ববর্তী উপাদান নির্ণয়ের জন্য একটি লিনিয়ার অনুসন্ধান।

বিস্তারিত সংস্করণ

লক্ষ্য নম্বর সহ একটি খেলা দেওয়া r, কৌশলটি নিম্নলিখিত:

  1. rযতটা সম্ভব কয়েকটি পদক্ষেপের নিকটতম 2 এর শক্তি বের করার জন্য বাইনারি অনুসন্ধান ব্যবহার করুন ।
  2. যদি 2 এর নিকটতম শক্তিটি পাওয়া যায় তবে এটি সমাধান হয়, বন্ধ করুন। অন্যথায় 3 অবিরত।
  3. যেহেতু 2 এর পাওয়ারটি পাওয়া গিয়েছিল এটি 2 এর প্রথম শক্তিটি ক্রমানুসারে ঘটছে, যদি এটি অনুসরণ করে যে একটি (* 3 + 1) অপারেশন করে এই মানটি পৌঁছেছে। (যদি এটি একটি / 2 অপারেশনের পরে আসে তবে পূর্ববর্তী সংখ্যাটি 2 এর শক্তিও হত)। বিপরীত অপারেশন (-1 এবং তারপরে / 3) করে ক্রমের পূর্ববর্তী সংখ্যাটি গুণান
  4. যদি সেই নম্বরটি লক্ষ্য হয় তবে থামুন। অন্যথায় 5 এ চালিয়ে যান।
  5. সিকোয়েন্স থেকে জানা বর্তমান নম্বরটি দেওয়া, এটির পিছনে ফিরে গিয়ে ক্রমটিতে পূর্ববর্তী নম্বরটি আবিষ্কার করা দরকার। বর্তমান নম্বরটি কোনও (/ 2) বা (* 3 +1) অপারেশনের মাধ্যমে এসেছিল কিনা তা জানা যায়নি, সুতরাং অ্যালগরিদম তাদের উভয়কেই চেষ্টা করে এবং লক্ষ্য করে যে কোনটি একটি সংখ্যার ফলাফল দেয় যা লক্ষ্য থেকে কাছাকাছি (কোল্টজ দূরত্ব হিসাবে) ।
  6. নতুন আবিষ্কৃত নম্বরটি যদি সঠিক হয় তবে থামুন।
  7. সদ্য আবিষ্কৃত নম্বরটি ব্যবহার করে, 5 ধাপে ফিরে যান।

ফলাফলগুলো

৫১-৫62২ পরিসরে সমস্ত সংখ্যার জন্য অ্যালগরিদম চালানো সাধারণ পিসিতে প্রায় এক সেকেন্ড সময় নেয় এবং মোট স্কোর 38665।

কোড

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

require 'set'

# Utility methods
def collatz(n)
  [].tap do |results|
    crt = n
    while true
      results << crt
      break if crt == 1
      crt = crt.even? ? crt / 2 : crt * 3 + 1
    end
  end
end

def collatz_dist(m, n)
  cm = collatz(m).reverse
  cn = collatz(n).reverse
  common_length = cm.zip(cn).count{ |x, y| x == y }
  cm.size + cn.size - common_length * 2
end



GuessResult = Struct.new :response, :score
# Class that can "play" a game, responding
# :right, :closer, :farther or :same when
# presented with a guess
class Game

  def initialize(target_value)
    @r = target_value
    @score = -1
    @dist = nil
    @won = false
  end
  attr_reader :score

  def guess(n)
    # just a logging decorator over the real method
    result = internal_guess(n)
    p [n, result] if LOGGING
    result
  end

  private

  def internal_guess(n)
    raise 'Game already won!' if @won
    @score += 1
    dist = collatz_dist(n, @r)
    if n == @r
      @won = true
      return GuessResult.new(:right, @score)
    end
    response = nil
    if @dist
      response = [:same, :closer, :farther][@dist <=> dist]
    end
    @dist = dist
    GuessResult.new(response)
  end

end

# Main solver code

def solve(game)
  pow2, won = find_closest_power_of_2(game)
  puts "Closest pow2: #{pow2}" if LOGGING

  return pow2 if won
  # Since this is the first power of 2 in the series, it follows that
  # this element must have been arrived at by doing *3+1...
  prev = (pow2 - 1) / 3
  guess = game.guess(prev)
  return prev if guess.response == :right

  solve_backward(game, prev, 300)
end

def solve_backward(game, n, left)
  return 0 if left == 0
  puts "***      Arrived at  ** #{n} **" if LOGGING
  # try to see whether this point was reached by dividing by 2
  double = n * 2
  guess = game.guess(double)
  return double if guess.response == :right

  if guess.response == :farther && (n - 1) % 3 == 0
    # try to see whether this point was reached by *3+1
    third = (n-1) / 3
    guess = game.guess(third)
    return third if guess.response == :right
    if guess.response == :closer
      return solve_backward(game, third, left-1)
    else
      game.guess(n) # reset to n...
    end
  end
  return solve_backward(game, double, left-1)
end


# Every Collatz Sequence ends with a sequence of powers of 2.
# Let's call the first occurring power of 2 in such a sequence
# POW2
#
# Let's iterate through the whole range and find the POW2_CANDIDATES
#
RANGE = [*51..562]
POWERS = Set.new([*0..15].map{ |n| 2 ** n })

POW2_CANDIDATES =
  RANGE.map{ |n| collatz(n).find{ |x| POWERS.include? x} }.uniq.sort
# Turns out that the candidates are [16, 64, 128, 256, 512, 1024]

def find_closest_power_of_2(game)
  min = old_guess = 0
  max = new_guess = POW2_CANDIDATES.size - 1
  guess = game.guess(POW2_CANDIDATES[old_guess])
  return POW2_CANDIDATES[old_guess], true if guess.response == :right
  guess = game.guess(POW2_CANDIDATES[new_guess])
  return POW2_CANDIDATES[new_guess], true if guess.response == :right
  pow2 = nil

  while pow2.nil?

    avg = (old_guess + new_guess) / 2.0

    case guess.response
    when :same
      # at equal distance from the two ends
      pow2 = POW2_CANDIDATES[avg.floor]
      # still need to test if this is correct
      guess = game.guess(pow2)
      return pow2, guess.response == :right
    when :closer
      if old_guess < new_guess
        min = avg.ceil
      else
        max = avg.floor
      end
    when :farther
      if old_guess < new_guess
        max = avg.floor
      else
        min = avg.ceil
      end
    end

    old_guess = new_guess
    new_guess = (min + max) / 2
    new_guess = new_guess + 1 if new_guess == old_guess
    # so we get next result relative to the closer one
    # game.guess(POW2_CANDIDATES[old_guess]) if guess.response == :farther
    guess = game.guess(POW2_CANDIDATES[new_guess])

    if guess.response == :right
      pow2 = POW2_CANDIDATES[new_guess]
      break
    end

    if min == max
      pow2 = POW2_CANDIDATES[min]
      break
    end

  end

  [pow2, guess.response == :right]

end



LOGGING = false

total_score = 0
51.upto(562) do |n|
  game = Game.new(n)
  result = solve(game)
  raise "Incorrect result for #{n} !!!" unless result == n
  total_score += game.score
end
puts "Total score: #{total_score}"

চিত্তাকর্ষক। একটি ছোটখাটো বিষয় রয়েছে: আমি বিশ্বাস করি যে কোনও একটি মন্তব্যে "নিখুঁত বর্গ" বলা উচিত নয়।
ওয়েজুন চাউ

1
@ উইজুনঝু আপনি ঠিক বলেছেন সংশোধন করা হয়েছে!
ক্রিশ্চিয়ান লুপাস্কু

আপনার সম্ভবত সমস্ত ক্ষেত্রে সবচেয়ে খারাপ স্কোরটি অন্তর্ভুক্ত করা উচিত, যা 196
ওয়েইজুন চিউ

3

সবচেয়ে খারাপ স্কোর: 11, যোগফল: 3986

সমস্ত অনুমান সীমার মধ্যে আছে [51,562]

আমার অ্যালগরিদম:

  1. প্রথমবার 512 অনুমান করুন এবং সম্ভাব্য ফলাফলের একটি সেট বজায় রাখুন vals, প্রাথমিকভাবে সেটটিতে পরিসরের সমস্ত সংখ্যা রয়েছে [51,562]
  2. প্রতিটি পদক্ষেপে, নিম্নলিখিতটি করুন:

    1. পরবর্তী অনুমান মান খুঁজুন guessসীমার মধ্যে [51,562]যেমন যে, যখন মান vals(ব্যতীত guessনিজেই) সম্ভাব্য ফলাফল সংশ্লিষ্ট 3 সেট বিভক্ত করা হয় Closer, Sameএবং Fartherসেই 3 সেট সর্বাধিক মাপ সর্বনিম্ন। উপরোক্ত সন্তুষ্ট করার জন্য
      যদি একাধিক সম্ভাব্য মান থাকে guessতবে সবচেয়ে ছোটটি চয়ন করুন।
    2. মান অনুমান করুন guess
    3. উত্তরটি যদি "ডান" হয়, হয়ে যায় (প্রোগ্রামটি থেকে প্রস্থান করুন)।
    4. সেটে সমস্ত মান মুছে ফেলুন valsযাতে তারা সম্ভবত ফলাফল দিতে পারে না।

সি ++ এবং বাশে লেখা আমার রেফারেন্স বাস্তবায়ন আমার মেশিনে প্রায় 7.6 সেকেন্ডে চলে এবং শিরোনামে বর্ণিত হিসাবে সবচেয়ে খারাপ স্কোর / যোগ স্কোর দেয়।

সমস্ত সম্ভাব্য প্রথম অনুমানের মান চেষ্টা করে আমার মেশিনে প্রায় 1.5 ঘন্টা সময় নেবে। আমি এটা করছেন বিবেচনা করতে পারেন।


(পি / এস: নন-কোড জমা দেওয়ার অনুমতি দেওয়া হয়েছে
you

তবে আপনি যদি কিছু কারণে এটি বাস্তবায়ন না করে সত্যই এটি কাজ করে দেখতে চান তবে অনলাইনে চেষ্টা করে দেখুন !
ব্যবহারকারী 202729

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