কোলাটজ চাচাত ভাইদের গণনা করা হচ্ছে


21

ধনাত্মক পূর্ণসংখ্যা n এর জন্য ক্রিয়াটি f (n) সংজ্ঞায়িত করুন :

  • n / 2 , যদি n হয় হয়
  • 3 * n + 1 , যদি n বিজোড় হয়

যদি আপনি বারবার 0 টির চেয়ে বড় এন- তে এই ফাংশনটি প্রয়োগ করেন তবে ফলাফলটি সর্বদা 1 তে রূপান্তরিত হয় বলে মনে হয় (যদিও কেউ এখনও এটি প্রমাণ করতে সক্ষম হয়নি)। এই সম্পত্তিটি কোলাটজ কনজেকচার হিসাবে পরিচিত ।

একটি পূর্ণসংখ্যা এর নির্ধারণ বাঁধন সময় যতবার হিসাবে আপনি Collatz ফাংশন মাধ্যমে এটি পাস করতে হবে আগেই পৌঁছে 1. এখানে প্রথম 15 পূর্ণসংখ্যার বাঁধন বার আছেন:

1  0
2  1
3  7
4  2
5  5
6  8
7  16
8  3
9  19
10 6
11 14
12 9
13 9
14 17
15 17

একই থামার সময় কোলাটজ চাচাত ভাইদের সাথে কোনও সংখ্যার সেট কল করুন । উদাহরণস্বরূপ, 5 এবং 32 হ'ল কোলাটজ চাচাতো বোন, 5 এর বিরতি সময় রয়েছে।

আপনার টাস্ক: এমন একটি প্রোগ্রাম বা ফাংশন লিখুন যা একটি ননজেগটিভ পূর্ণসংখ্যার গ্রহণ করে এবং কোলাটজ চাচাতো ভাইয়ের সেট তৈরি করে যার বিরতি সময় সেই সংখ্যার সমান।

ইনপুট

STDIN, ARGV বা ফাংশন আর্গুমেন্টের মাধ্যমে প্রদত্ত একটি nonnegative পূর্ণসংখ্যা এস।

আউটপুট

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

আবশ্যকতা

আপনার জমা দিতে অবশ্যই যে কোনও এস ≤ 30 এর জন্য সঠিক ফলাফল দিতে হবে It এটি কয়েক ঘন্টা বা দিন নয়, সেকেন্ড বা মিনিটে শেষ হওয়া উচিত।

উদাহরণ

0  -> 1
1  -> 2
5  -> 5, 32
9  -> 12, 13, 80, 84, 85, 512
15 -> 22, 23, 136, 138, 140, 141, 150, 151, 768, 832, 848, 852, 853, 904, 906, 908, 909, 5120, 5376, 5440, 5456, 5460, 5461, 32768

এস = 30 এর আউটপুটটির একটি সংক্ষিপ্তসার এখানে ।

এটি : বাইট জেতে সংক্ষিপ্ততম প্রোগ্রাম। শুভকামনা!


চক্র কি? আমি চক্র এড়ানোর কোনও উল্লেখ দেখিনি। কারণ এস = 5 এর জন্য এখানে 3 টি মান রয়েছে [4, 5, 32] কারণ আপনি "1 - 2 - 4 - 1 - 2- 4" যেতে পারেন
জেপিএমসি

1
@ জেপিএমসি চক্র এড়ানো বিরত থাকা সংজ্ঞা দিয়ে বোঝানো হয়েছে। 4 এর থামার সময়টি 2 নয়, 5 নয়, কারণ 2 "এটি কোল্টজ ফাংশনটি 1 এ পৌঁছানোর আগেই আপনাকে পাস করতে হবে তার সংখ্যা" "
DLosc

আহ, আমাকে ক্ষমা করুন আমি ভাবছিলাম যে কোনও সংখ্যার একাধিক থামার সময় থাকতে পারে, যেহেতু একাধিক পাথ এটির দিকে নিয়ে যেতে পারে। তবে এটি 1 থেকে তৈরি করার বিষয়ে ছিল, এন থেকে কাজ করা হয়নি that সে সম্পর্কে দুঃখিত Sorry
জেপিএমসি

1
@DLosc পাইথ অবশ্যই
isaacg

1
সম্পর্কিত, তবে গল্ফ করা হয়নি: math.stackexchange.com/q/470782/20792 এবং math.stackexchange.com/q/1243841/20792
পিওরেফেরেট

উত্তর:


7

পাইথ, 26 24 21 বাইট

Su+yMG-/R3fq4%T6G1Q]1

এই কোডটি তাত্ক্ষণিকভাবে চলে S=30। নিজে চেষ্টা করে দেখুন: বিক্ষোভ

5 বাইট বাঁচানোর জন্য @ আইস্যাচকে ধন্যবাদ

ব্যাখ্যা

আমার কোডটি 1কোলাটজ ফাংশন দিয়ে শুরু এবং পূর্বাবস্থায় ফিরে আসে। এটা সব সংখ্যার মানচিত্র dএর S-1পদক্ষেপ 2*dএবং (d-1)/3। সর্বশেষে সর্বদা বৈধ নয় যদিও।

                        implicit: Q = input number
                   ]1   start with G = [1]
 u                Q     apply the following function Q-times to G:
                          update G by
   yMG                      each number in G doubled
  +                       +
          fq4%T6G           filter G for numbers T, which satisfy 4==T%6
       /R3                  and divide them by 3
      -          1          and remove 1, if it is in the list
                            (to avoid jumping from 4 to 1)
S                       sort the result and print

এটি একটি সুন্দর ব্যবহার -F
isaacg

1
আপনি যদি - ... 1হ্রাসের ভিতরে যোগফলটি প্রায় রাখেন তবে আপনার কমানোর দরকার হবে .uনা, -Fবাইরেও। 2 টি অক্ষর সংরক্ষণ করে।
isaacg

ধন্যবাদ আমি আসলে এটি পূর্ববর্তী সংস্করণে পেয়েছি, কিন্তু একটি ত্রুটি ডিবাগ করার সময় এটি সরিয়ে ফেলেছি।
জাকুব

3
আমি আমার নিজের উত্তরের জন্য @ আইস্যাকের bণ নিয়েছি। সদৃশ অপসারণের জন্য আমি সংক্ষিপ্ততম কোডটি সন্ধান করার জন্য কয়েক ঘন্টা ব্যয় করেছি, তবে এটি এখন পর্যন্ত সবচেয়ে মার্জিত সমাধান। এছাড়াও, আমি অবৈধ ভাগফলগুলি ফেলে দেওয়ার জন্য আপনাকে টিউলের ব্যবহার সত্যিই পছন্দ করি। দুঃখের বিষয়, সিজেমের টিউপলস নেই, তবে আমি অবৈধ ভাগফলের মানচিত্র 1 এ পরিচালনা করতে পেরেছি
ডেনিস

@ জাকুব q4%d6সমতুল্য !%hhd6, তবে 1 টি অক্ষর ছোট।
isaacg

8

গণিত, 98 92 89 বাইট

এই সমাধান S = 30অবিলম্বে সমাধান :

(p={0};l={1};Do[l=Complement[##&@@{2#,Mod[a=#-1,2]#~Mod~3~Mod~2a/3}&/@l,p=p⋃l],{#}];l)&

এটি একটি নামবিহীন ফাংশন Sএটির একমাত্র পরামিতি হিসাবে গ্রহণ এবং কোলাটজ চাচাত ভাইদের একটি তালিকা ফেরত।

অ্যালগরিদম হল একটি সাধারণ প্রস্থের প্রথম অনুসন্ধান। একটি প্রদত্ত জন্য Collatz ভাই Sসব পূর্ণসংখ্যার যে জন্য Collatz ভাই থেকে পৌঁছে যাবে হয় S-1মাধ্যমে 2*nবা বিজোড় নম্বরগুলির মাধ্যমে পৌঁছে যাবে যে (n-1)/3। আমাদের এটিও নিশ্চিত করতে হবে যে আমরা কেবলমাত্র সেই পূর্ণসংখ্যার উত্পাদন করেছি যা পদক্ষেপের পরে প্রথমবারের মতো পৌঁছেছিল S, তাই আমরা পূর্ববর্তী সমস্ত কাজিনকে ট্র্যাক করে রাখি pএবং ফলাফলগুলি থেকে সরিয়ে ফেলি । যেহেতু আমরা যাইহোক এটি করছি, আমরা কিছু বাইট সংরক্ষণের জন্য পূর্ববর্তী সকল কাজিনের (কেবল তাদের থেকে নয় S-1) পদক্ষেপগুলি গণনা করে কয়েকটি বাইট সংরক্ষণ করতে পারি (এটি এটি কিছুটা ধীর করে তোলে তবে প্রয়োজনীয়তার জন্য লক্ষ্যণীয় নয় S)।

এখানে আরও কিছুটা পাঠযোগ্য সংস্করণ:

(
  p = {0};
  l = {1};
  Do[
    l = Complement[
      ## & @@ {2 #, Mod[a = # - 1, 2] #~Mod~3~Mod~2 a/3} & /@ l,
      p = p ⋃ l
    ]~Cases~_Integer,
    {#}
  ];
  l
) &

5

পাইথন 2, 86 83 75 73 71 বাইট

f=lambda n,k=1:sorted([k][n:]or(k>4==k%6and f(n-1,k/3)or[])+f(n-1,k*2))

কল করুন f(30)n = 30বেশ তাত্ক্ষণিক।

( kচাচাত ভাইদের তালিকার চেয়ে কয়েকটি সংখ্যা এবং কয়েকটা বাইট করে পুনরাবৃত্তি করার ধারণার জন্য @ ডিএলসকে ধন্যবাদ জানাই ~-। বাদ দেওয়ার জন্য @ আইস্যাককে ধন্যবাদ ।)

এই রূপটি খুব খাটো, তবে দুর্ভাগ্যক্রমে ক্ষতিকারক শাখার কারণে খুব বেশি সময় নেয়:

f=lambda n,k=1:sorted([k][n:]or(k>4==k%6)*f(n-1,k/3)+f(n-1,k*2))

আকর্ষণীয় - আমার আসল সমাধানটি খুব অনুরূপ, তবে (আপনার কাছ থেকে কয়েকটা অপ্টিমাইজেশন নেওয়া) 2 বাইট সংক্ষিপ্ত: প্রকাশিত হয় f=lambda d,n=1:d and sorted(sum((c(d-1,x)for x in[n*2]+[~-n/3][:n>4==n%6]),[]))or[n]। এটি ফাংশন কলগুলির সাথে কম দক্ষ তবে এটি n = 30এক সেকেন্ডের মধ্যেও করে ।
DLosc

1
@DLosc আমি আপনার ধারণাটি পছন্দ করেছি এবং এটিকে আরও ভাল করে
দিয়েছি

নিস! এখানে আরও 2 বাইট বন্ধ রয়েছে:f=lambda n,k=1:sorted([k][n:]or(k>4==k%6and f(n-1,~-k/3)or[])+f(n-1,k*2))
DLosc

@DLosc আহা ধন্যবাদ আমি এখনও শপথ করছি আরও ভাল সংক্ষিপ্ত সার্কিট উপায় হতে পারে ...
Sp3000

আমি মনে করি এটি ~-অপ্রয়োজনীয় কারণ আপনি পূর্ণসংখ্যা বিভাগ ব্যবহার করছেন।
isaacg

5

সিজেম, 29 26 বাইট

Xari{{2*_Cmd8=*2*)}%1-}*$p

প্রতিটি পুনরাবৃত্তির পরে 1 টি অপসারণ করার জন্য তাঁর ধারণার জন্য ক্রেডিট @ আইস্যাকগের কাছে যায়, যা আমাকে দুটি বাইট সরাসরি এবং অপরটিকে পরোক্ষভাবে সংরক্ষণ করেছিল।

সিজেএম ইন্টারপ্রেটারে এটি অনলাইনে চেষ্টা করুন (এক সেকেন্ডেরও কম সময়ে শেষ করা উচিত)।

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

Xa       e# Push A := [1].
ri{      e# Read an integer from STDIN and do the following that many times:
  {      e# For each N in A:
    2*   e#     Push I := (N * 2) twice.
    _Cmd e#     Push (I / 12) and (I % 12).
     8=  e#     Push K := (I % 12 == 8).

         e#     (K == 1) if and only if the division ((N - 1) / 3) is exact and
         e#     yields an odd integer. In this case we can compute the quotient 
         e#     as (I / 12) * 2 + 1.

    *2*) e#     Push J := (I / 12) * K * 2 + 1.

         e#     This yields ((N - 1) / 3) when appropriate and 1 otherwise.
  }%     e# Replace N with I and J.
  1-     e# Remove all 1's from A.

         e# This serves three purposes:

         e# 1. Ones have been added as dummy values for inappropriate quotients.

         e# 2. Not allowing 1's in A avoids integers that have already stopped
         e#    from beginning a new cycle. Since looping around has been prevented,
         e#    A now contains all integers of a fixed stopping time.

         e# 3. If A does not contain duplicates, since the maps N -> I and N -> J
         e#      are inyective (exluding image 1) and yield integers of different
         e#      parities, the updated A won't contain duplicates either.

}*       e#
$p       e# print(sort(C))

4

সিজেম, 35 বাইট

1]ri{_"(Z/Y*"3/m*:s:~\L+:L-_&0-}*$p

ব্যাখ্যা শীঘ্রই আসছে। এটি "চমত্কার স্ট্রেইট ফরোয়ার্ড" পদ্ধতির চেয়ে অনেক দ্রুত সংস্করণ (এটি সম্পাদনা ইতিহাসে দেখুন)।

এটি এখানে অনলাইনে চেষ্টা করুনN = 30 যার জন্য অনলাইন সংস্করণে কয়েক সেকেন্ডের মধ্যে এবং তাত্ক্ষণিকভাবে জাভা সংকলকটিতে চলে


বৃহত্তর ইনপুটগুলির জন্য এটি কতক্ষণ সময় নিতে পারে? It should finish in seconds or minutes, not hours or days.
DLosc

আহ আমি দেখি. পাইথন সংস্করণটি আমি লিখেছিলাম N = 30 এর জন্য প্রায় 5 ঘন্টা সময় লাগবে
DLosc

সর্বশেষ সংস্করণ প্রায় তাত্ক্ষণিকভাবে চলমান।
অপ্টিমাইজার

6
আপনার কোডে একটি বাগ আছে। টেস্ট-কেস S=15কাজ করে না।
জাকুবে

3

জাভা 8, 123

x->java.util.stream.LongStream.range(1,(1<<x)+1).filter(i->{int n=0;for(;i>1;n++)i=i%2<1?i/2:3*i+1;return n==x;}).toArray()

যখন x30, প্রোগ্রাম 15 মিনিট এবং 29 সেকেন্ড সময় লাগে।

সম্প্রসারিত

class Collatz {
    static IntFunction<long[]> f =
            x -> java.util.stream.LongStream.range(1, (1 << x) + 1).filter(i -> {
                int n = 0;
                for (; i > 1; n++)
                    i = i % 2 < 1 ? i / 2 : 3 * i + 1;
                return n == x;
            }).toArray();

    public static void main(String[] args) {
        System.out.println(Arrays.toString(f.apply(15)));
    }
}

শুধু কৌতূহলী, এস = 30 এর জন্য এটি কতক্ষণ সময় নেয়?
জিওবিটস

এটি কেবল জাভা 8 এ কাজ করে, তাই না? javac 1.7.0_79উবুন্টু ব্যবহার করে আমার প্রচুর সিনট্যাক্স ত্রুটি হয়েছিল।
ডিএলসাস

@ ডিএলসকে সঠিক; আমি পোস্টে উল্লেখ করব।
Ypnypn

লুপ টার্মিনাল শর্তটিকে সীমাবদ্ধ করা i > 1 && ++n <= x( n++আপনিও ড্রপ করতে পারেন ) আমার আরও 5 টি অক্ষরের জন্য আরও দ্রুত বলে মনে হচ্ছে ... আমার কাছে এস = 30 এর জন্য প্রায় 3 মিনিট। .parallel()
এটিতে

1

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

ঠিক আছে, আমি অনুভব করেছি যে @ এসপি 3000 এর সমাধান দেখার পরে আমি সেরা পাইথন স্কোরটিতে পৌঁছতে পারব না। তবে এটি একটি মজাদার ছোট সমস্যার মতো মনে হয়েছিল, তাই আমি যাই হোক না কেন একটি স্বাধীন সমাধান চেষ্টা করতে চেয়েছিলাম:

s={1}
for k in range(input()):
 p,s=s,set()
 for t in p:s.add(2*t);t>4and(t-1)%6==3and s.add((t-1)/3)
print sorted(s)

হোয়াইটস্পেস বাদ দেওয়ার আগে একই জিনিস:

s={1}
for k in range(input()):
    p,s=s,set()
    for t in p:
        s.add(2 * t)
        t > 4 and (t - 1) % 6 == 3 and s.add((t - 1) / 3)
print sorted(s)

এটি প্রথম প্রস্থের অনুসন্ধানের একটি প্রত্যক্ষ বাস্তবায়ন। প্রতিটি পদক্ষেপে, আমরা সময় বাঁধন সঙ্গে সেট আছে k, এবং সময় বাঁধন সঙ্গে সেট আহরণ k + 1প্রতিটি মান সম্ভাব্য পূর্বসুরীদের যোগ করে tপদক্ষেপ থেকে সেটে k:

  • 2 * t সর্বদা সম্ভাব্য পূর্বসূরী।
  • যদি tএটি হিসাবে লিখিত হতে পারে 3 * u + 1, যেখানে uএকটি বিজোড় সংখ্যা যেখানে নেই 1, তবে uপাশাপাশি পূর্বসূরিও।

N = 30আমার ম্যাকবুক প্রোতে চলতে প্রায় 0.02 সেকেন্ড সময় নেয় ।


সাধারণভাবে, s.add(x)গল্ফে অপ্রয়োজনীয় যেহেতু আপনি সাধারণত s|={x}পরিবর্তে এটি করতে পারেন । এছাড়াও, বন্ধনীগুলিতে সংরক্ষণের ~-xপরিবর্তে ব্যবহার করা (x+1)। তবে অন্যথায়, ভাল কাজ :)
Sp3000

@ Sp3000 ধন্যবাদ আমি সহজেই দ্বিতীয়টি প্রতিস্থাপন করতে পারি না s.add()কারণ এটি একটি অ্যাসাইনমেন্ট হয়ে যায় এবং আর প্রকাশের অংশ হতে পারে না। এটি প্রথমটির জন্য কাজ করে। forকাউন্টারে উপর ভিত্তি করে লুপ সবসময় ধরনের বাগাড়ম্বরপূর্ণ হিসাবে ভাল আছেন। আমি ভেবেছিলাম আমি একটি whileলুপ ব্যবহার করে এটি সংক্ষিপ্ত করতে পারি তবে এটি একই দৈর্ঘ্যের হুবহু পরিণত হয়েছে।
রেটো কোড়াদি

একটি forলুপের পরিবর্তে , যেহেতু আপনি ইনপুটটি অন্য কোনও উপায়ে ব্যবহার করবেন না আপনি সম্ভবত এটি করতে পারেন exec"..."*input():)
স্প 3000

1

পিএইচপি 5.4+, 178 বাইট

কাজ

function c($s,$v=1,$p=[],&$r=[]){$p[]=$v;if(!$s--){return$r[$v][]=$p;}c($s,$v*2,$p,$r);is_int($b=($v-1)/3)&!in_array($b,$p)&$b%2?c($s,$b,$p,$r):0;ksort($r);return array_keys($r);}

পরীক্ষা এবং আউটপুট

echo "0 - ".implode(',',c(0)).PHP_EOL;
// 0 - 1
echo "1 - ".implode(',',c(1)).PHP_EOL;
// 1 - 2
echo "5 - ".implode(',',c(5)).PHP_EOL;
// 5 - 5,32
echo "9 - ".implode(',',c(9)).PHP_EOL;
// 9 - 12,13,80,84,85,512
echo "15 - ".implode(',',c(15)).PHP_EOL;
// 15 - 22,23,136,138,140,141,150,151,768,832,848,852,853,904,906,908,909,5120,5376,5440,5456,5460,5461,32768

এস (30) 0.24 সেকেন্ডে রান করে * , 732 উপাদান ফেরত দেয়। এক দম্পতি হলেন

86,87,89,520,522,524,525,528, [ ... ] ,178956928,178956960,178956968,178956970,1073741824

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

কারও কাছে অতিরিক্ত অতিরিক্ত বাইট ছাড়াই একবার মাত্র সঠিক প্রক্রিয়াকরণ পাওয়ার কোনও চতুর উপায় থাকলে, দয়া করে আমাকে জানান! (আমি আমার সংখ্যাগুলি অ্যারে কী হিসাবে সংরক্ষণ করি, তাই এর ব্যবহার array_keysএবং ksort)


0

সি ভাষা

#include <stdio.h>
#include <limits.h>    
const int s = 30;

bool f(long i)
{
    int r = 0;
    for(;;)
        if (i < 0 || r > s) return false;
        else if (i == 1) break;
        else{r ++;i = i % 2 ? 3*i + 1 : i/2;}
    return (r==s);
}

void main(){
    for(long i = 1; i < LONG_MAX; i++) if (f(i)) printf("%ld ", i);
}

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

{}আপনার কোডটি ফর্ম্যাট করতে আপনি বোতামটি টিপতে পারেন, যা আমি আপনার জন্য করেছি। তবে অ্যালেক্স যেমন বলেছেন, দয়া করে ভাষার নাম (সি?) যুক্ত করুন এবং এটি গল্ফ করার চেষ্টা করুন :) তবে স্বাগতম!
Sp3000

বিন্যাস কোড সাহায্য করার জন্য @ Sp3000 ধন্যবাদ
ঝড়ো

ফাংশনটি fসঠিকভাবে আচরণ করছে না। সহ s=5, আমি একগুচ্ছ ভুল ফলাফল পেয়েছি। if (r == s)return true;হওয়া উচিত return (r==s), যেহেতু fকখনই কোনও অর্থবোধের অর্থ ফেরত দেয় না (r < s)। এছাড়াও, আমার মনে হয় আপনি ঘোষণা করা উচিত iমধ্যে fযেমন long, যেহেতু এটি কিছু মান জন্য বেশ দ্রুত ওভারফ্লো হবে।
ডেনিস

@ ডেনিস ধন্যবাদ :) এটি হওয়া উচিতreturn (r==s);
বাতাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.