পরিবার ট্রি সলভার


22

ক্যালভিনের শখের দ্বারা সম্প্রদায়টির জন্য এটি বেশ কয়েকটি চ্যালেঞ্জ ।

ফর্মের রেখাগুলি সহ একটি "পারিবারিক ট্রি বর্ণনা করে" ফাইলটি নিন:

[ID] [mother ID] [father ID] [gender] [full name]

যেমন এটি http://en.wikedia.org/wiki/Cousin- এ প্রথম পরিবারের গাছ বর্ণনা করে :

1 ? ? M Adam
2 ? ? F Agatha
3 ? ? M Bill
4 2 1 F Betty
5 2 1 M Charles
6 ? ? F Corinda
7 3 4 M David
8 6 5 F Emma

একটি প্রোগ্রাম বা ফাংশন লিখুন যা ফাইলের নাম এবং দুটি আইডি গ্রহণ করে এবং সম্পর্কের জন্য সাধারণ ইংরেজি নাম ব্যবহার করে কীভাবে সহজ লোকের সাথে এই লোকেরা রক্ত ​​সম্পর্কিত related ইনপুটটি STDIN, ARGV বা ফাংশন আর্গুমেন্টের মাধ্যমে হতে পারে তবে আউটপুটটি STDOUT এ হওয়া উচিত should

নোট

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

রক্তের সম্পর্ক

সম্পর্কের নিম্নলিখিত সংজ্ঞা R নির্ধারণ যদি কোনো ব্যক্তি একজন হয় আর বা ব্যক্তি বিআর এর দুটি ভেরিয়েন্ট তালিকাভুক্ত করা থাকলে প্রথমটি মহিলা এ এর এবং দ্বিতীয়টি পুরুষ এ এর জন্য । এগুলির সব বাস্তবায়ন করা দরকার। যদি একাধিক সংজ্ঞা মিলে যায় তবে আগেরটি ব্যবহার করতে হবে। বন্ধনীতে শর্তাদি লিঙ্গ-নিরপেক্ষ শর্তাদি, যা প্রয়োগ করার প্রয়োজন হয় না তবে আরও সংজ্ঞাতে আবার ব্যবহার করা হবে। এন এবং এম জড়িত সংজ্ঞায় , এন> 1 এবং এম> 0 ধরে নিন

  • কন্যা / ছেলেঃ একটি তালিকা বি পারেন পিতা বা মাতা হিসাবে।
  • মা / বাবা (পিতা বা মাতা): বি তালিকা একটি পারেন পিতা বা মাতা হিসাবে।
  • বোন / ভাই (ভাইবোন): এবং বি একই মা বাবার তালিকান।
  • অর্ধ-বোন / অর্ধ ভাই (সহোদর): এবং বি একই মাতা বা একই পিতার তালিকাবদ্ধ।
  • ভাইঝি / ভাতিজা: একটি তালিকা একটি পিতা বা মাতা যারা সহোদর হল বি
  • খালা / চাচা: বি হ'ল এক ভাগ্নী বা ভাগ্নে।
  • নাতনী / নাতি (নাতি): একটি এমন একটি পিতামাতাকে তালিকাভুক্ত করে যারা বি কে তাদের পিতামাতার তালিকা করে।
  • দাদী / নানা (পিতামহ): বি হল একটি 'র নাতি।
  • দারুণ-ভাইঝি / মহান-ভাইপো: একজন এর নাতি হয় সি যারা সহোদর হল বি
  • গ্রেট-মাসি / গ্রেট-মামা: বি হ'ল এক বড় ভাগ্নি বা ভাগ্নে।
  • নাতি-নাতনী / পুত্র (প্রথম পিতামহ): সি এর এক নাতি -নাতনি যারা বি কে তাদের পিতামাতার তালিকাভুক্ত করে ।
  • মহান-নানী / পিতা (1 ম মহান-পিতামহ): বি হল একটি 'র 1 ম মহান-নাতি।
  • নবম নাতি -নাতনী / পুত্র ( নবম নাতি -নাতি): সি এর একটি (এন -১) তম নাতি, যিনি বি কে তাদের পিতামাতার তালিকাভুক্ত করেন ।
  • নবম দাদী / পিতা (Nth গ্রেট-পিতামহ): বি হ'ল এর Nth বড়-নাতি।
  • নবম গ্রেতি-ভাগ্নী / ভাগ্নে: হ'ল সি -এর (এন -১) তম নাতি-নাতি যিনি বি- এর ভাই-বোন ।
  • N তম মহান-মাসিমা / চাচা: বি হল একটি 'র N তম N তম মহান ভাগ্নের মহান-ভাইঝি।
  • খালাতো ভাই: হ'ল সি এর নাতনি যারা বি এর পিতামহ ।
  • N তম চাচাত ভাই: একটি (এন -1) এর ম নাতি হয় সি কে (এন -1) এর ম পিতামহ বি
  • চাচাত ভাই, এম বার সরানো হয়েছে: একটি এর নাতি হয় সি যারা Mth পিতামহ হয় বি বা একটি এর Mth নাতি হয় সি যারা পিতামহ হয় বি
  • নবম মামাতো ভাই, এম বার সরানো: হ'ল সি এর পঠতম নাতি-নাতনি যিনি বি এর চতুর্থ পিতামহ , কোথায় N = min(P,Q) + 1এবং M = |P-Q|

জন্য Nth, লেখার 2nd, 3rd, 4th, 5thইত্যাদি

জন্য M times, লেখার once, twice, thrice, 4 times, 5 timesইত্যাদি

উদাহরণ

ধরে নিন যে নিম্নলিখিত ফাইলটি ব্যবহৃত হয়েছে (আপনি একাধিক স্পেস মোকাবেলা করতে সক্ষম হবেন না, তবে আমি এগুলি যথাযথতার জন্য যুক্ত করেছি):

 1  ?  ? F Agatha
 2  ?  ? M Adam
 3  ?  ? F Betty
 4  1  2 M Bertrand
 5  1  2 F Charlotte
 6  ?  ? M Carl
 7  ?  ? F Daisy
 8  3  4 M David
 9  5  6 F Emma
10  ?  ? M Edward
11  ?  ? F Freya
12  7  8 M Fred
13  9 10 F Grace
14  ?  ? M Gerald
15  ?  ? F Hillary
16 11 12 M Herbert
17 13 14 F Jane
18  ?  ? M James
19 15 16 F Kate
20 17 18 M Larry
21  ? 18 F Mary

তারপরে ইনপুট আইডিগুলির আউটপুটগুলিতে ম্যাপ করা উচিত:

 1  2 --> Agatha is not a blood relative to Adam.
 8  3 --> David is the son of Betty.
 9 13 --> Emma is the mother of Grace.
 4  5 --> Bertrand is the brother of Charlotte.
 9  4 --> Emma is the niece of Bertrand.
 5  8 --> Charlotte is the aunt of David.
16  7 --> Herbert is the grandson of Daisy.
 1  9 --> Agatha is the grandmother Emma.
12  5 --> Fred is the great-nephew of Charlotte.
 4 13 --> Bertrand is the great-uncle of Grace.
16  3 --> Herbert is the great-grandson of Betty.
 6 17 --> Carl is the great-grandfather of Jane.
19  2 --> Kate is the 3rd great-granddaughter of Adam.
 1 17 --> Agatha is the 2nd great-grandmother of Jane.
20  4 --> Larry is the 3rd great-nephew of Bertrand.
 5 16 --> Charlotte is the 2nd great-aunt of Herbert.
 8  9 --> David is the cousin of Emma.
19 20 --> Kate is the 4th cousin of Larry.
16  9 --> Herbert is the cousin, twice removed, of Emma.
12 17 --> Fred is the 2nd cousin, once removed, of Jane.
21 20 --> Mary is the half-sister of Larry.

আমি এগুলি হাতে লিখে দিয়েছি তাই যদি আপনার কোনও ভুল চিহ্নিত হয় তবে আমাকে জানান।

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

 1  ?  ? F Berenice I of Egypt
 2  ?  ? M Ptolemy I Soter
41  1  2 F Arsinoe II of Egypt
 3  1  2 M Ptolemy II Philadelphus
 4  ?  ? F Arsinoe I of Egypt
 5  ?  ? M Philip
 6  4  3 M Ptolemy III Euergetes
 7  1  5 F Magas of Cyrene
 8  7  ? F Berenice II
 9  8  6 M Ptolemy IV Philopator
10  8  6 F Arsinoe III of Egypt
11 10  9 M Ptolemy V Epiphanes
12  ?  ? F Cleopatra I of Egypt
13 12 11 M Ptolemy VI Philometor
14 12 11 F Cleopatra II
15 12 11 M Ptolemy VIII Physcon
19  ?  ? F Eirene
16 14 13 M Ptolemy VII Neos Philopator
17 14 13 F Cleopatra III
18 14 15 M Ptolemy Memphites
20 19 15 M Ptolemy Apion
21 17 15 F Cleopatra IV
22 17 15 M Ptolemy IX Lathyros
23 17 15 F Cleopatra Selene I
24 17 15 M Ptolemy X Alexander I
25 23 22 F Berenice III of Egypt
26 23 24 M Ptolemy XI Alexander II
27 21 22 M Ptolemy XII Auletes
28 25 24 F Cleopatra V of Egypt
29 28 27 F Cleopatra VI of Egypt
30 28 27 F Berenice IV of Egypt
31 28 27 M Ptolemy XIII Theos Philopator
32 28 27 F Cleopatra VII Thea Philopator
33 28 27 M Ptolemy XIV
34 28 27 F Arsinoe IV of Egypt
35  ?  ? M Julius Caesar
37 32 35 M Ptolemy XV Caesarion
36  ?  ? M Mark Anthony
38 32 36 M Alexander Helios
39 32 36 M Ptolemy XVI Philadelphus
40 32 36 F Cleopatra Selene II

উত্তর:


3

ইসমাস্ক্রিপ্ট 6, 886

শূন্য দ্বারা বিভাজন একটি দুর্দান্ত জিনিস।

একবার এই ব্যবহারসমূহ আপাতদৃষ্টিতে লিটারেল (যা ফায়ারফক্স 33 বা Node.js বাস্তবায়িত হয় না, কিন্তু হয় রাত্রিকালীন Firefox এর তৈরী করে পাওয়া)। আধা আক্ষরিক ব্যবহৃত:

`
`

"\n"আপনি যেগুলি ব্যবহার করছেন সেগুলির জন্য যদি সমর্থনগুলির অভাব থাকে তবে এটির সাথে প্রতিস্থাপন করা যেতে পারে ।

এই স্ক্রিপ্টটি লোকের তালিকা থেকে একটি গাছ তৈরি করে, পিতা-মাতা এবং শিশু উভয়কেই সঞ্চয় করে। ব্যক্তি A থেকে বি বি পর্যন্ত প্রতিটি পাথ চেষ্টা করা হয় এবং সর্বোত্তম পথটি সংরক্ষণ করা হয়। কোনও পাথ কেবলমাত্র একবার গাছের নীচে যাওয়ার থেকে পরিবর্তিত হলে তা বৈধ হিসাবে বিবেচিত হবে। বিপরীত পরিবর্তন অনুমোদিত নয় - যদি কোনও সন্তানের কাছে নীচে যেতে হয় এবং কোনও পথ খুঁজে পেতে অন্য পিতামাতার কাছে ফিরে যেতে হয় তবে এই দুটি ব্যক্তি রক্তের আত্মীয় নয়। ( UUUUUDDDবৈধ, UUDUUUনিখুঁত নয়। Uমানে উপরে উঠুন (পিতামাতার কাছে)), Dমানে নীচে যান (একটি সন্তানের কাছে))।

গল্ফযুক্ত বাছাই করুন:

R=(a,b)=>{F="forEach",C='';p=[],g=[],c={},n=[],e=m=1/0;y=i=>i+(k=i%10,k&&k<4&&~~(i%100/10)-1?[,'st ','nd ','rd '][k]:'th ');q=(a,b,s,$)=>!($=$.slice())|!a|~$.indexOf(a)||a-b&&$.push(a)|[p,c][F]((M,N)=>M[a][F](j=>q(j,b,s+N,$)))||(z=(s.match(/0/g)||[]).length,r=s.length-z,_=e+m-z-r,s.indexOf(10)<0&_>0|!_&m>r&&(e=z,m=r));I.split(`
`)[F](V=>{P=V.split(' ');D=+P[0];p[D]=[+P[1],+P[2]];g[D]=P[3]<'L';n[D]=P.slice(4).join(' ');c[D]=[]});p[F]((V,I)=>V[F](Y=>Y&&c[Y].push(I)));q(a,b,C,[]);U=e>m?m:e,V=e>m?e:m;alert(n[a]+' is '+(e/m+1?'the '+(U*V---1?U<2?(V<3?C:y(V-1))+(V<2?C:'great-')+(V*!U?'grand':C)+'son0father0nephew0uncle0daughter0mother0niece0aunt'.split(0)[g[a]*4+2*U+(U==e)]:(V-=--U,(U<2?C:y(U))+'cousin'+(V?', '+(V>3?V+' times':[,'on','twi','thri'][V]+'ce')+' removed,':C)):(p[a].join()==p[b].join()?C:'half-')+(g[a]?'sister':'brother'))+' of ':'not a blood relative to ')+n[b]+'.')}

অবহেলিত (ধরণের):

// function for running.
R=(a,b)=>{
F="forEach",C='';
p=[], g=[], c={}, n=[], e=m=1/0;
// returns suffixed number (1->1st, 2->2nd, etc)
y= i=>i+(k=i%10,k&&k<4&&~~(i%100/10)-1?[,'st ','nd ','rd '][k]:'th ');
// this looks for the shortest path up/down the family tree between a and b.
q=(a,b,s,$)=>
  // copy the array of visited people
  !($=$.slice())
  // check if a is invalid
  | !a
  // check to make sure we are not visiting a for a second time
  | ~$.indexOf(a)
  // if a != b
  || a-b 
  // add a to visited, and call q(...) on all parents and children
  && $.push(a) |
   [p,c][F]((M,N)=>M[a][F](j=>q(j,b,s+N,$)))
  || (
    // a == b
    // get number of ups and downs
    z=(s.match(/0/g)||[]).length,
    r=s.length-z,

    _=e+m-z-r,
    // if DU: path is invalid.
    // if _>0: path is shorter
    // if _==0: check m > r to see if new path should replace old 
    s.indexOf(10)<0 & _>0|!_&m>r && (e=z,m=r));
// load list of people into arrays
I.split(`
`)[F](V=>{
  P=V.split(' ');
  // ID
  D=+P[0];
  // parents: NaN if not given
  p[D]=[+P[1],+P[2]];
  // gender: 1 if female, 0 if male
  g[D]=P[3]<'L';
  // merge the rest of the array to get name
  n[D]=P.slice(4).join(' ');
  // empty children array..for now
  c[D]=[]
});
// push current ID to parents' children array.
p[F]((V,I)=>V[F](Y=>Y&&c[Y].push(I)));

// get shortest path
q(a,b,C,[]);

U=e>m?m:e,V=e>m?e:m;
G=(a,b,c,d)=>(a<3?C:y(a-1))+(a<2?C:'great-')+(a*!b?'grand':C)+'son0father0nephew0uncle0daughter0mother0niece0aunt'.split(0)[g[d]*4+2*b+(b==c)];


// output
alert(n[a]+' is '+(e/m+1?'the '+(U*V---1?
    U<2?
        G(V,U,e,a)
    :(V-=--U,
     (U<2?C:y(U))+'cousin'+
     (V?
        ', '+(V>3?V+' times':[,'on','twi','thri'][V]+'ce')+' removed,'
     :C)
     )
:(p[a].join()==p[b].join()?C:'half-')+(g[a]?'sister':'brother'))+' of ':'not a blood relative to ')+n[b]+'.')
}

নোট:

  • লোকের তালিকাটি একটি পরিবর্তনশীল I(একক স্পেস এবং নিউলাইন সহ স্ট্রিং হিসাবে) স্থাপন করা উচিত ।
  • কল করার জন্য: R(a,b)যেখানে aএবং bদুটি মানুষের ID- র তুলনা করা হয়েছে।

5

কোবরা - 932

আমি কোবরাতে যে সমস্ত চ্যালেঞ্জের জবাব দিয়েছি, তার মধ্যে এটি এটি কী করতে পারে তার সেরা উদাহরণ এটি।

সম্পাদনা: এটি এখন একটি ফাংশন, তবে জেডের জন্য স্বাক্ষরের দ্বারা অবশ্যই উপস্থাপিত হওয়া উচিত (চর গণনায় অন্তর্ভুক্ত)।

sig Z(m,n=nil,r=nil)as String?
def f(f='',u='',v='')
    d={:}
    for l in File.readAllLines(f)
        w=l.trim.split
        i,j,k,p=w[:4]
        q=w[4:].join(' ')
        if i==u,x,g=q,if(p<'M',1,0)
        if i==v,y=q
        d.add(i,[j,k])
    o as Z=do(n,m,r)=if(n>1,"[n][if(0<n%10<4and not 10<n%100<14,'stndrd'[n%10-1:n%10+2],'th')] ",'')
    z as Z=do(m,n,r)
        h,a,b=n
        if m[0]==m[1]
            if if(b<1or 0<b<3and a>b,s=2,s=0),a,b=b,a
            r="the [if(a,if(a<2,if(b<2,if(not'?'in'[c=d[u]][e=d[v]]'and c==e,'','half-')+['brother','sister'][g],if(b<3,'',o(b-2)+'great-')+['uncle','aunt','nephew','neice'][s+g]),o(a-1)+'cousin'+if(b>a,', '+if((b-=a)<4,['on','twi','thri'][b-1]+'ce','[b] times')+' removed,','')),if(b,if(b<3,'',o(b-2)+'great-')+'grand','')+['father','mother','son','daughter'][s+g])] of"
        for t in d[m[h]],if'?'<>h,r?=if(h,z([m[0],t],[1,a,b+1]),z(m,[1,a,0])?z([t,v],[0,a+1,0]))
        return r to String?
    print x+" is [z([u,v],[0,0,0])?'not a blood relative to'] [y]."

মন্তব্য করা হয়েছে: (পুরানো, কিন্তু এখনও একই কোড-প্রবাহ)

class F
    # Initilaise link dict
    var d={'?':@[''][:0]}
    # Gender bool
    var g
    def main
        # Initilaise name dict
        d={'?':@[''][:0]}
        # Take args
        f,a,b=CobraCore.commandLineArgs[1:]
        # For line in file
        for l in File.readAllLines(f)
            # Split line
            i=l.split
            # Add links to link dict
            .d.add(i[0],i[1:3])
            # Add names to name dict
            d.add(i[0],i[3:])
        # Get gender
        .g=if(d[a][0]=='F',1,0)
        # Print result
        print _
            '[d[a][1]] is '+ _ # Name A
                .r(@[1,0,0],@[a,a,b,b]) _ # If link found, link
                ? _ # Else
                'not a blood relative'+ _ # Not related
            ' of [d[b][1]].' # Name B
    def r(n as int[],m as String[])as String?
        # Recurse through the links at each level from A (A1), climbing when no links are found to B
        # For each level incremented for A, search upwards to the end of all nodes from B (B1), looking for A1
        r=nil
        # Check if we're done searching/climbing
        if m[1]==m[2]
            a,b=n[1:]
            s=if(b<1or b in[1,2]and a>b,1,0)
            if s,a,b=b,a
            # Take the A and B distance and translate them into a phrase
            return'the '+ _ 
                if(a, _
                    if(a<2, _
                        if(b<2, _
                            if('?'not in'[.d[m[0]]][.d[m[3]]]'and.d[m[0]]==.d[m[3]], _
                                '', _
                                'half-' _
                            )+['brother','sister'][.g], _
                            if(b<3, _
                                '', _
                                .o(b-2)+'great-' _
                            )+[['uncle','aunt'],['nephew','neice']][s][.g] _
                        ), _
                        .o(a-1)+'cousin'+if(b>a, _
                            ', '+if((b-=a)<4, _
                                ['once','twice','thrice'][b-1], _
                                '[b] times' _
                            )+' removed,', _
                            '' _
                        ) _
                    ), _
                    if(b, _
                        if(b<3, _
                            '', _
                            '[.o(b-2)]great-' _
                        )+'grand', _
                        '' _
                    )+[['father','mother'],['son','daughter']][s][.g] _
                )
        # Check if we're climbing
        if n[0]
            # For each link in the current A-level
            for x in.d[m[1]]
                r?= _
                    .r(@[0,n[1],0],m) _ # Start a search
                    ? _ # If the search failed
                    .r(@[1,n[1]+1,0],@[m[0],x,m[3],m[3]]) # Climb again
        # Check if we're searching
        else
            # For each link in the current B-level
            for x in.d[m[2]]
                # Search up one level from the current B-level
                r?=.r(@[0,n[1],n[2]+1],@[m[0],m[1],x,m[3]])
        return r
    def o(n as int)as String
        # Get ordinal string for the number
        return if(n>1,'[n][if(0<n%10<4and not 10<n%100<14,['st','nd','rd'][n%10-1],'th')] ','')

3

সি - ungolfed

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

typedef enum {
    MALE,
    FEMALE
} gender_t;

typedef enum {
    VISITED_A,
    VISITED_B,
    NOT_VISITED
} visited_t;

struct node {
    int id;
    int mother;
    int father;
    char *name;
    int height;
    gender_t gender;
    visited_t visited;
};

struct queue_item {
    void *item;
    struct queue_item *next;
    struct queue_item *previous;
};

struct queue {
    struct queue_item *first;
    struct queue_item *last;
};

void queue_push(struct queue *q, struct node *n)
{
    struct queue_item *i = malloc(sizeof(*i));
    i->item = (void *)n;
    i->next = q->last;
    i->previous = NULL;
    q->last = i;
    if(i->next != NULL) {
        i->next->previous = i;
    } else {
        q->first = i;
    }
}

void queue_pop(struct queue *q)
{
    struct queue_item *temp = q->first;
    if(temp) {
        q->first = q->first->previous;
        if(q->first == NULL) {
            q->last = NULL;
        } else {
            q->first->next = NULL;
        }
        free(temp);
    }
}

struct node *queue_front(struct queue *q)
{
    if(q->first) {
        return (struct node *)q->first->item;
    } else {
        return NULL;
    }
}

void queue_free(struct queue *q) {
    while(queue_front(q) != NULL) {
        queue_pop(q);
    }

    free(q);
}

struct node *find_shortest_path(struct node **nodes, struct node *a, struct node *b)
{

    struct queue *q = malloc(sizeof(*q));
    q->first = NULL;
    q->last = NULL;

    a->visited = VISITED_A;
    queue_push(q, a);
    b->visited = VISITED_B;
    queue_push(q, b);

    struct node *n, *father, *mother;

    while((n = queue_front(q)) != NULL) {
        if(n->visited == VISITED_A) {
            if(n->father != 0) {
                father = nodes[n->father-1];
                if(father->visited == VISITED_B) {
                    a->height = n->height + 1;
                    b->height = father->height;
                    n = father;
                    goto exit_queue_free;
                } else  if(father->visited == NOT_VISITED) {
                    father->visited = VISITED_A;
                    father->height = n->height+1;
                    queue_push(q, father);
                }
            }
            if(n->mother != 0) {
                mother = nodes[n->mother-1];
                if(mother->visited == VISITED_B) {
                    a->height = n->height + 1;
                    b->height = mother->height;
                    n = mother;
                    goto exit_queue_free;
                } else  if(mother->visited == NOT_VISITED) {
                    mother->visited = VISITED_A;
                    mother->height = n->height+1;
                    queue_push(q, mother);
                }
            }
        } else if (n->visited == VISITED_B) {
            if(n->father != 0) {
                father = nodes[n->father-1];
                if(father->visited == VISITED_A) {
                    b->height = n->height + 1;
                    a->height = father->height;
                    n = father;
                    goto exit_queue_free;
                } else  if(father->visited == NOT_VISITED) {
                    father->visited = VISITED_B;
                    father->height = n->height+1;
                    queue_push(q, father);
                }
            }
            if(n->mother != 0) {
                mother = nodes[n->mother-1];
                if(mother->visited == VISITED_A) {
                    b->height = n->height + 1;
                    a->height = mother->height;
                    n = mother;
                    goto exit_queue_free;
                } else  if(mother->visited == NOT_VISITED) {
                    mother->visited = VISITED_B;
                    mother->height = n->height+1;
                    queue_push(q, mother);
                }
            }
        }

        queue_pop(q);
    }

exit_queue_free:
    queue_free(q);
    return n;
}

int main(int argc, char *argv[]) {

    if(argc != 4) {
        return -1;
    }

    FILE *file = fopen(argv[1], "r");
    int id_1 = strtol(argv[2], NULL, 0);
    int id_2 = strtol(argv[3], NULL, 0);

    char name[128];
    char id[128];
    char id_father[128];
    char id_mother[128];
    char gender;

    struct queue *read_queue = malloc(sizeof(*read_queue));
    read_queue->first = NULL;
    read_queue->last = NULL;
    int nr_nodes = 0;

    while(fscanf(file, "%s %s %s %c %s",
        id, id_mother, id_father, &gender, name) == 5) {

        struct node *n = malloc(sizeof(*n));
        if(strcmp(id, "?") == 0) {
            n->id = 0;
        } else {
            n->id = strtol(id, NULL, 0);
        }

        if(strcmp(id_mother, "?") == 0) {
            n->mother = 0;
        } else {
            n->mother = strtol(id_mother, NULL, 0);
        }

        if(strcmp(id_father, "?") == 0) {
            n->father = 0;
        } else {
            n->father = strtol(id_father, NULL, 0);
        }

        if(gender == 'M') {
            n->gender = MALE;
        } else {
            n->gender = FEMALE;
        }

        n->name = malloc(strlen(name)+1);

        strcpy(n->name, name);

        n->visited = NOT_VISITED;
        n->height = 0;

        queue_push(read_queue, n);

        nr_nodes++;
    }

    struct node **nodes = malloc(sizeof(*nodes) * nr_nodes);
    struct node *temp;
    while((temp = queue_front(read_queue)) != NULL) {
        nodes[temp->id-1] = temp;
        queue_pop(read_queue);
    }

    queue_free(read_queue);

    struct node *a = nodes[id_1-1], *b = nodes[id_2-1];

    temp = find_shortest_path(nodes, a, b);

    if(temp) {
        if(a->height == b->height) {
            if(a->height == 1) {
                if((a->father == b->father) &&
                    (a->mother == b->mother)) {
                    printf("%s is the %s of %s.\n", a->name,
                        a->gender == MALE ?
                        "brother" : "sister",
                        b->name);
                } else {
                    printf("%s is the half-%s of %s.\n",
                        a->name,
                        a->gender == MALE ?
                        "brother" : "sister",
                        b->name);
                }
            } else if (a->height == 2) {
                printf("%s is the cousin of %s.\n", a->name,
                    b->name);
            } else if (a->height == 3){
                printf("%s is the 2nd cousin of %s.\n", a->name,
                    b->name);
            } else if (a->height == 4) {
                printf("%s is the 3rd cousin of %s.\n", a->name,
                    b->name);
            } else {
                printf("%s is the %dth cousin of %s.\n", a->name,
                    a->height-1,b->name);
            }
        } else if (a->height == 0) {
            if(b->height == 1) {
                printf("%s is the %s of %s.\n", a->name,
                    a->gender == MALE ? "father" :
                    "mother", b->name);
            } else if (b->height == 2) {
                printf("%s is the grand%s of %s.\n", a->name,
                    a->gender == MALE ? "father" :
                    "mother", b->name);
            } else if (b->height == 3) {
                printf("%s is the great-grand%s of %s.\n",
                    a->name, a->gender == MALE ?
                    "father" : "mother", b->name);
            } else if (b->height == 4) {
                printf("%s is the 2nd great-grand%s of %s.\n",
                    a->name, a->gender == MALE ?
                    "father" : "mother", b->name);
            } else if (b->height == 5) {
                printf("%s is the 3rd great-grand%s of %s.\n",
                    a->name, a->gender == MALE ?
                    "father" : "mother", b->name);
            } else if (b->height == 6) {
                printf("%s is the %dth great-grand%s of %s.\n",
                    a->name, b->height-2,
                    a->gender == MALE ? "father" :
                    "mother", b->name);
            }
        } else if (b->height == 0) {
            if(a->height == 1) {
                printf("%s is the %s of %s.\n", a->name,
                    a->gender == MALE ? "son" :
                    "daughter", b->name);
            } else if (a->height == 2) {
                printf("%s is the grand%s of %s.\n", a->name,
                    a->gender == MALE ? "son" :
                    "daughter", b->name);
            } else if (a->height == 3) {
                printf("%s is the great-grand%s of %s.\n",
                    a->name, a->gender == MALE ?
                    "son" : "daughter", b->name);
            } else if (a->height == 4) {
                printf("%s is the 2nd great-grand%s of %s.\n",
                    a->name, a->gender == MALE ?
                    "son" : "daughter", b->name);
            } else if (a->height == 5) {
                printf("%s is the 3rd great-grand%s of %s.\n",
                    a->name, a->gender == MALE ?
                    "son" : "daughter", b->name);
            } else {
                printf("%s is the %dth great-grand%s of %s.\n",
                    a->name, a->height - 2,
                    a->gender == MALE ? "son" :
                    "daughter", b->name);
            }
        } else if (a->height == 1) {
            if(b->height == 2) {
                printf("%s is the %s of %s.\n", a->name,
                    a->gender == MALE ? "uncle" :
                    "aunt", b->name);
            } else if(b->height == 3) {
                printf("%s is the great-%s of %s.\n", a->name,
                    a->gender == MALE ? "uncle" :
                    "aunt", b->name);
            } else if(b->height == 4) {
                printf("%s is the 2nd great-%s of %s.\n", a->name,
                    a->gender == MALE ? "uncle" :
                    "aunt", b->name);
            } else if(b->height == 5) {
                printf("%s is the 3rd great-%s of %s.\n", a->name,
                    a->gender == MALE ? "uncle" :
                    "aunt", b->name);
            } else {
                printf("%s is the %dth great-%s of %s.\n",
                    a->name, b->height - 2,
                    a->gender == MALE ? "uncle" :
                    "aunt", b->name);
            }
        } else if (b->height == 1) {
            if(a->height == 2) {
                printf("%s is the %s of %s.\n", a->name,
                    a->gender == MALE ? "nephew" :
                    "niece", b->name);
            } else if(a->height == 3) {
                printf("%s is the great-%s of %s.\n", a->name,
                    a->gender == MALE ? "nephew" :
                    "niece", b->name);
            } else if(a->height == 4) {
                printf("%s is the 2nd great-%s of %s.\n", a->name,
                    a->gender == MALE ? "nephew" :
                    "niece", b->name);
            } else if(a->height == 5) {
                printf("%s is the 3rd great-%s of %s.\n", a->name,
                    a->gender == MALE ? "nephew" :
                    "niece", b->name);
            } else {
                printf("%s is the %dth great-%s of %s.\n",
                    a->name, a->height - 2,
                    a->gender == MALE ? "nephew" :
                    "niece", b->name);
            }
        } else {
            int m = a->height > b->height ? a->height - b->height :
                b->height - a->height;
            int n = a->height > b->height ? b->height - 1:
                a->height - 1;

            printf("%s is the ", a->name);
            if(n == 2) printf("2nd ");
            if(n == 3) printf("3rd ");
            if(n > 3) printf("%dth ", n);
            printf(" cousin, ");
            if (m == 1) printf("once");
            if (m == 2) printf("twice");
            if (m == 3) printf("thrice");
            if (m > 3) printf("%d times", m);
            printf(" removed, of %s.\n", b->name);
        }
    } else
        printf("%s is not a blood relative to %s.\n", a->name, b->name);



    int i;
    for(i = 0; i < nr_nodes; i++) {
        free(nodes[i]->name);
        free(nodes[i]);
    }

    free(nodes);

    fclose(file);

    return 0;
}

এটি কি ডিজকস্ট্রার সবচেয়ে ছোট পথ অ্যালগরিদমের মাঝখানে লুকিয়ে আছে?
স্কট লিডলি

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

3

রুবি - 1892 1290 1247

হিসাবে চালান ruby relation.rb ID1 ID2 relationship_file

P=Struct.new(:i,:m,:f,:s,:n,:c)
def f u,v,w,x,y,z
t=[y,z,v]
return t if v=='?'||x.include?(v)||v==w
r=x+[v];p=u[v]
p.c.each{|o|s=f(u,o,w,r,y,z+1);return s if s.last==w}
return t if z>0
[:m,:f].each{|i|s=f(u,p[i],w,r,y+1,z);return s if s.last==w}
t;end
def g j,a,r,b;puts"#{j[a].n} is the #{r} of #{j[b].n}.";end
def k n;n<2?'':n<3?'2nd':n<4?'3rd':"#{n}th";end
def h n;n<2?'':n<3?'great-':"#{k(n-1)} great-";end
def e n;s=n<2?'once':n<3?'twice':n<4?'thrice':"#{n} times";", #{s} removed,";end
def d u,a,b,x;y,z=x
if y==1&&z==1
w=u[a];v=u[b]
g(u,a,((w.f==v.f&&w.m==v.m)?'':'half-')+((w.s=='F')?'sister':'brother'),b)
elsif y<1||z<1
t=[y,z].max
g(u,a,h(t-1)+(t>=2?'grand':'')+(u[a].s=='F'?y>0?'daughter':'mother':y>0?'son':'father'),b)
elsif y==1||z==1
t=[y,z].max
g(u,a,h(t-1)+(u[a].s=='F'?y==1?'aunt':'niece':y==1?'uncle':'nephew'),b)
else
s=[y,z].min
g(u,a,(s-1>1?"#{k(s-1)} ":'')+'cousin'+((y==z)?'':e((z-y).abs)),b)
end;end
A,B=$*.shift(2);j={}
ARGF.each_line{|l|a=l.scan(/\s*(\d+)\s+(\d+|\?)\s+(\d+|\?)\s+([MF])\s+([\w\s]*\w+)\s*/).flatten;j[a[0]]=P.new(a[0],a[1],a[2],a[3],a[4],[])}
j.each{|k,i|[:f,:m].each{|l|j[i[l]].c<<k if i[l]!='?'}}
a=f(j,A,B,[],0,0)
if a.pop==B
d(j,A,B,a)
else
puts"#{j[A].n} is not a blood relative to #{j[B].n}."

অরোগল্ফড সংস্করণ - 5251 3416 (একই কল ট্রি, সবে প্রচুর কোড ফোল্ডিং হয়েছে)

Person = Struct.new( :id, :mother, :father, :sex, :name, :children )

#       Find a path between "start" and "finish". To reflect human consanguinity
# rules, either travel down through descendants or up through ancestors with a
# possible down leg through their descendants.
#
# Use depth-first search until forced to improve.
# If start up, path allowed one inflection point.
# Once start down, path must continue down.
# returns [stepsUp, stepsDown, trialResult],
#   shortest path found if trialResult == finish
def findRelationship(people, start, finish, pathSoFar, stepsUp, stepsDown)
  trialResult = [stepsUp, stepsDown, start]
  #     Return success or failure.
  return trialResult if start == '?' || pathSoFar.include?(start) || start == finish
  #     If success or failure not known, explore further.
  pathNext = pathSoFar + [start]
  person = people[start]
  #     Follow descendants.
  person[:children].each do |child|
    trial = findRelationship(people, child, finish, pathNext, stepsUp, stepsDown+1)
    return trial  if trial.last == finish
  end
  #     Already past inflection point?
  return trialResult  if stepsDown > 0
  #     Follow ancestry.
  [:mother, :father].each do |parent|
    trial = findRelationship(people, person[parent], finish, pathNext, stepsUp+1, stepsDown)
    return trial  if trial.last == finish
  end
  return trialResult
end

def printRelationship(people, a, relationship, b)
  puts "#{people[a][:name]} is the #{relationship} of #{people[b][:name]}."
end

def formatNth(n)
  return n<2?'':n<3?'2nd':n<4?'3rd':"#{n}th"
end

def formatGenerations(n)
  return n<2?'':n<3?'great-':"#{formatNth(n-1)} great-"
end

def formatRemoves(n)
  s=n<2?'once':n<3?'twice':n<4?'thrice':"#{n} times"
  return ", #{s} removed,"
end

def describeRelationship(people, a, b, legLengths)
  down = legLengths.pop
  up = legLengths.pop
  if up==1 && down==1
    who = people[a]
    what = people[b]
    printRelationship(people, a,
        (who[:father] == what[:father]  &&  who[:mother] == what[:mother] ? '' : 'half-') +
          ((who[:sex] == 'F') ? 'sister' : 'brother'),
        b)
  elsif up<1 || down<1
    pathLength = [up, down].max
    printRelationship(people, a,
        formatGenerations(pathLength-1) + ((pathLength>=2) ? 'grand' : '') +
          (up>0 ?
            people[a][:sex] == 'F' ? 'daughter' : 'son'  :
            people[a][:sex] == 'F' ? 'mother': 'father'
          ),
        b)
  elsif up==1 || down==1
    pathLength = [up, down].max
    printRelationship(people, a,
        formatGenerations(pathLength-1) +
          (up==1 ?
            people[a][:sex] == 'F' ? 'aunt': 'uncle'  :
            people[a][:sex] == 'F' ? 'niece': 'nephew'
          ),
        b)
  else
    shortestLeg = [up, down].min
    printRelationship(people, a,
        (shortestLeg-1>1 ? "#{formatNth(shortestLeg-1)} " : '') +
          'cousin' +
          (up==down ? '' : formatRemoves((down-up).abs)),
        b)
  end
end

A = $*.shift
B = $*.shift
#       Meet and greet.
people = {}
ARGF.each_line do |line|
  a = line.scan(/\s*(\d+)\s+(\d+|\?)\s+(\d+|\?)\s+([MF])\s+([\w\s]*\w+)\s*/).flatten
  people[a[0]] = Person.new( a[0], a[1], a[2], a[3], a[4], [] )
end
#       Build lineage.
people.each do |key, individual|
  [:father, :mother].each do |l|
      people[individual[l]][:children] << key  if individual[l] != '?'
  end
end
#       How are A and B related?
a = findRelationship(people, A, B, [], 0, 0)
if a.pop == B
  describeRelationship(people, A, B, a)
else
  puts "#{people[A][:name]} is not a blood relative to #{people[B][:name]}."
end

নিম্নলিখিত পরীক্ষার স্যুটটি পাস করে:

#!/usr/bin/env perl
#
use strict;
use warnings;
require File::Temp;
use File::Temp qw( tempfile tempdir );

use Test::More qw(no_plan);
# use Test::More tests => 38;


#       solution executable
my $solver='ruby relation.rb';


#       "happy" path
my $dir = tempdir( CLEANUP => 1 );
my ($fh, $filename) = tempfile( DIR => $dir );
my $testData = <<'END_TEST_DATA';
 1  ?  ? F Agatha
 2  ?  ? M Adam
 3  ?  ? F Betty
 4  1  2 M Bertrand
 5  1  2 F Charlotte
 6  ?  ? M Carl
 7  ?  ? F Daisy
 8  3  4 M David
 9  5  6 F Emma
10  ?  ? M Edward
11  ?  ? F Freya
12  7  8 M Fred
13  9 10 F Grace
14  ?  ? M Gerald
15  ?  ? F Hillary
16 11 12 M Herbert
17 13 14 F Jane
18  ?  ? M James
19 15 16 F Kate
20 17 18 M Larry
21  ? 18 F Mary
END_TEST_DATA
print $fh  $testData;
close($fh);

is( `$solver 1  2 $filename 2>&1`, "Agatha is not a blood relative to Adam.\n", 'OP example #1,  1  2');
is( `$solver 8 3 $filename 2>&1`, "David is the son of Betty.\n", 'OP example #2,  8  3');
is( `$solver 9 13 $filename 2>&1`, "Emma is the mother of Grace.\n", 'OP example #3,  9 13');
is( `$solver 4 5 $filename 2>&1`, "Bertrand is the brother of Charlotte.\n", 'OP example #4,  4  5');
is( `$solver 9 4 $filename 2>&1`, "Emma is the niece of Bertrand.\n", 'OP example #5,  9  5');
is( `$solver 5 8 $filename 2>&1`, "Charlotte is the aunt of David.\n", 'OP example #6,  5  8');
is( `$solver 16 7 $filename 2>&1`, "Herbert is the grandson of Daisy.\n", 'OP example #7, 16  7');
is( `$solver 1 9 $filename 2>&1`, "Agatha is the grandmother of Emma.\n", 'OP example #8,  1  9 (amended)');
is( `$solver 12 5 $filename 2>&1`, "Fred is the great-nephew of Charlotte.\n", 'OP example #9, 12  5');
is( `$solver 4 13 $filename 2>&1`, "Bertrand is the great-uncle of Grace.\n", 'OP example #10,  4 13');
is( `$solver 16 3 $filename 2>&1`, "Herbert is the great-grandson of Betty.\n", 'OP example #11, 16  3');
is( `$solver 6 17 $filename 2>&1`, "Carl is the great-grandfather of Jane.\n", 'OP example #12,  6 17');
is( `$solver 19 2 $filename 2>&1`, "Kate is the 3rd great-granddaughter of Adam.\n", 'OP example #13, 19  2 (amended)');
is( `$solver 1 17 $filename 2>&1`, "Agatha is the 2nd great-grandmother of Jane.\n", 'OP example #14,  1 17 (amended)');
is( `$solver 20 4 $filename 2>&1`, "Larry is the 3rd great-nephew of Bertrand.\n", 'OP example #15, 20  4');
is( `$solver 5 16 $filename 2>&1`, "Charlotte is the 2nd great-aunt of Herbert.\n", 'OP example #16,  5 16');
is( `$solver 8 9 $filename 2>&1`, "David is the cousin of Emma.\n", 'OP example #17,  8  9');
is( `$solver 19 20 $filename 2>&1`, "Kate is the 4th cousin of Larry.\n", 'OP example #18, 19 20');
is( `$solver 16 9 $filename 2>&1`, "Herbert is the cousin, twice removed, of Emma.\n", 'OP example #19, 16  9');
is( `$solver 12 17 $filename 2>&1`, "Fred is the 2nd cousin, once removed, of Jane.\n", 'OP example #20, 12 17');
is( `$solver 21 20 $filename 2>&1`, "Mary is the half-sister of Larry.\n", 'OP example #21, 21 20');


#       "sad" path
# none!


#       "bad" path
# none!


exit 0;

2

জাভাস্ক্রিপ্ট, 2292

for(var r=prompt().split("\n"),n=[{m:"",f:""}],t=1;t<r.length;t++){var e=r[t].split(" ");n[+e[0]]={m:"?"==e[1]?-1:+e[1],f:"?"==e[2]?-1:+e[2],s:e[3],n:e[4]}}var f=function(r,t){return r=n[r],t=n[t],~r.m&&r.m==t.m&&~r.f&&r.f==t.f?"M"==r.s?"brother":"sister":void 0},i=function(r,t){return r=n[r],t=n[t],~r.m&&r.m==t.m||~r.f&&r.f==t.f?"M"==r.s?"half-brother":"half-sister":void 0},o=function(r){var n=("0"+r).slice(-2),t=n[0];return n=n[1],r+(1==t?"th":1==n?"st":2==n?"nd":3==n?"rd":"th")+" "},a=function(r){return 1==r?"once":2==r?"twice":3==r?"thrice":r+" times"},h=function(r,t){var e,f,i=[t],a=[n[t].m,n[t].f];for(e=0;e<n.length&&!~a.indexOf(r);e++){i=a.slice(),a=[];for(var h=0;h<i.length;h++)i[h]>=0&&a.push(n[i[h]].m,n[i[h]].f)}if(!(e>=n.length))return f="M"==n[r].s?"father":"mother",e>0&&(f="grand"+f),e>1&&(f="great-"+f),e>2&&(f=o(e-1)+f),f},u=function(r,t){var e=h(t,r);return e?e.slice(0,-6)+("M"==n[r].s?"son":"daughter"):void 0},s=function(r){for(var t=[],e=1;e<n.length;e++)f(r,e)&&e!=r&&t.push(e);return t},l=function(r){return r=r.slice(0,-6),""==r?r:"grand"==r?"great ":"great-grand"==r?"2nd great ":o(+r.split(" ")[0].slice(0,-2)+1)+"great "},v=function(r,t){for(var e,f=s(r),i=0;i<f.length&&!(e=h(f[i],t));i++);return e?l(e)+("M"==n[r].s?"uncle":"aunt"):void 0},c=function(r,t){var e=v(t,r);return e?(e.split(" ").slice(0,-1).join(" ")+("M"==n[r].s?" nephew":" niece")).trim():void 0},g=function(r,n){for(var t=0;t<r.length;t++)if(~n.indexOf(r[t]))return!0},m=function(r,t){r=n[r],t=n[t];for(var e=[[r.m,r.f]],f=[[t.m,t.f]],i=0;i<n.length;i++){for(var h=e[i],u=f[i],s=[],l=0;l<h.length;l++){var v=0,c=0;-1!=h[l]&&(v=n[h[l]].m,c=n[h[l]].f),v>0&&s.push(v),c>0&&s.push(c)}for(var m=[],l=0;l<u.length;l++){var v=0,c=0;-1!=u[l]&&(v=n[u[l]].m,c=n[u[l]].f),v>0&&m.push(v),c>0&&m.push(c)}if(!s.length&&!m.length)break;e.push(s),f.push(m)}for(var i=1;i<Math.min(e.length,f.length);i++){var h=e[i],u=f[i];if(g(h,u))return(i>1?o(i):"")+"cousin"}for(var i=1;i<e.length;i++)for(var h=e[i],l=1;l<f.length;l++){var u=f[l];if(g(h,u)){var p=Math.min(i,l);return(p>1?o(p):"")+"cousin, "+a(Math.abs(i-l))+" removed,"}}},e=prompt().split(" "),p=+e[0],d=+e[1],M=u(p,d)||h(p,d)||f(p,d)||i(p,d)||c(p,d)||v(p,d)||m(p,d);alert(n[p].n+" is "+(M?"the "+M+" of ":"not a blood relative to ")+n[d].n+".\n"

আমি নিশ্চিত যে এটি আরও গল্ফ করা যেতে পারে, আমি যা কিছু করেছি তা একটি মিনিফায়ারের মাধ্যমে একটি অদম্য সংস্করণ রাখা হয়েছিল।

আপনি জেএসফিডেলে এখানে অসম্পূর্ণ সংস্করণটি চালাতে পারেন । উদাহরণস্বরূপ ডেটার জন্য আউটপুট এখানে দেওয়া হল:

1 2 Agatha is not a blood relative to Adam.
8 3 David is the son of Betty.
9 13 Emma is the mother of Grace.
4 5 Bertrand is the brother of Charlotte.
9 4 Emma is the niece of Bertrand.
5 8 Charlotte is the aunt of David.
16 7 Herbert is the grandson of Daisy.
1 9 Agatha is the grandmother of Emma.
12 5 Fred is the great nephew of Charlotte.
4 13 Bertrand is the great uncle of Grace.
16 3 Herbert is the great-grandson of Betty.
6 17 Carl is the great-grandfather of Jane.
19 1 Kate is the 3rd great-granddaughter of Agatha.
2 17 Adam is the 2nd great-grandfather of Jane.
20 4 Larry is the 3rd great nephew of Bertrand.
5 16 Charlotte is the 2nd great aunt of Herbert.
8 9 David is the cousin of Emma.
19 20 Kate is the 4th cousin of Larry.
16 9 Herbert is the cousin, twice removed, of Emma.
12 17 Fred is the 2nd cousin, once removed, of Jane.
21 20 Mary is the half-sister of Larry.

2

পাইথন 3: 1183

def D(i):
 if i==a:return 0
 r=[D(c)for c in t[i][4]]
 if r:return min(x for x in r if x is not None)+1
def A(i):
 if i=="?":return None
 r=D(i)
 if r is not None:return 0,r
 m,f=map(A,t[i][:2])
 return(f[0]+1,f[1])if not m or(f and sum(f)<sum(m))else(m[0]+1,m[1])if f else None
def P(r):print("%s is %s of %s"%(t[a][3],r,t[b][3]))
O=lambda n:"%d%s "%(n,{2:"nd",3:"rd"}.get(n,"th"))
G=lambda n:(O(n-2)if n>3 else"")+("great-"if n>2 else"")
GG=lambda n:G(n)+("grand"if n>1 else"")
f,a,b=input().split()
t={}
for l in open(f):
 i,m,f,g,n=l.strip().split(maxsplit=4)
 t[i]=(m,f,g,n,[])
for i,(m,f,g,n,c)in t.items():
 if m in t:t[m][4].append(i)
 if f in t:t[f][4].append(i)
g=t[a][2]=="M"
r=A(b)
if r:
 u,d=r
 if u==d==1:P("the "+("half-"if t[s][0]!=t[e][0]or t[s][1]!=t[s][1]else"")+["sister","brother"][g])
 elif u==0:P("the "+GG(d)+["daughter","son"][g])
 elif d==0:P("the "+GG(u)+["mother","father"][g])
 elif u==1:P("the "+G(d)+["niece","nephew"][g])
 elif d==1:P("the "+G(u)+["aunt","uncle"][g])
 else:
  n,m=min(u,d)-1,abs(u-d);P("the "+(O(n)if n>1 else"")+"cousin"+(" %s removed"%{1:"once",2:"twice",3:"thrice"}.get(m,"%d times"%m)if m else""))
else:
 P("not a blood relative")

বর্ণিত লোকগুলির ফাইলের নাম এবং আইডিগুলি একটি লাইনে স্ট্যান্ডার্ড ইনপুট থেকে পড়ে।

কোডের উপরের অংশটি হ'ল ফাংশন সংজ্ঞা। স্ক্রিপ্টটি অর্ধেক নীচে শুরু হয়, এবং প্রথমে ইনপুট প্রক্রিয়াজাতকরণ (ফাইলটি বিশ্লেষণ, তারপর তাদের দ্বিতীয় পর্বে শিশুদের তাদের পিতামাতার কাছে বরাদ্দ) কাজ করে।

ডেটা সেট আপ হওয়ার পরে, আমরা Aপুনরাবৃত্ত অনুসন্ধান বন্ধ করার জন্য একবার ফাংশনটি কল করি । ফলাফল সম্পর্কের সংজ্ঞা দেয়।

বাকী কোডটি ইংরেজিতে সেই সম্পর্কটি বর্ণনা করার জন্য উত্সর্গীকৃত। ভাইবোন এবং কাজিনরা জটিল (এবং দীর্ঘ লাইন ব্যবহার করুন), বাকিগুলি বেশ সোজা এগিয়ে straight

উদাহরণ রান (দ্বিতীয় লাইনটি আমার ইনপুট):

C:\>Python34\python.exe relations.py
relations.txt 20 4
Larry is the 3rd great-nephew of Bertrand

ফাংশন এবং ভেরিয়েবল নাম কী:

  • f: ফাইলের নামটি থেকে পরিবারের ডেটা পড়া হয়।
  • a: আমরা যার নামকরণ করছি তার সম্পর্কের আইডি The
  • b: সম্পর্কের সাথে সম্পর্কিত ব্যক্তির আইডি সংজ্ঞায়িত হয়।
  • t: পারিবারিক বৃক্ষ নিজেই, অভিধানের ম্যাপ হিসাবে আইডি থেকে মায়ের আইডি, বাবার আইডি, লিঙ্গ, নাম এবং বাচ্চাদের তালিকার একটি 5-টুপল ম্যাপিং।
  • g: একটি বুলিয়ান মান ব্যক্তির লিঙ্গ প্রতিফলিত করে a। এটা Trueযদি তারা একটি পুরুষ আছে।
  • uথেকে প্রজন্মের সংখ্যা bসাধারণ পূর্বপুরুষ থেকে aএবং b(অথবা 0 যদি bহয় aএর পূর্বপুরুষ)।
  • dথেকে প্রজন্মের সংখ্যা aসাধারণ পূর্বপুরুষ থেকে aএবং b(অথবা 0 যদি aহয় bএর পূর্বপুরুষ)।
  • D(i): Recursively ব্যক্তির সন্তান অনুসন্ধান iব্যক্তির জন্য a। গভীরতা aপাওয়া গেছে, বা এটি না পাওয়া সন্ধান পেলে ফিরিয়ে দিন।
  • A(i): পুনরাবৃত্তভাবে অনুসন্ধান করুন iএবং iএর বংশধরদের অনুসন্ধান করুন , তবে যদি এটির সন্ধান না পাওয়া যায় তবে iতাদের পূর্বপুরুষদের (এবং তাদের বংশধরদের )ও অনুসন্ধান করুন । একটি 2-টিপল ফেরত দেয়, যার মানগুলি uএবং dউপরে বর্ণিত। যদি পিতা-মাতার উভয়ের মধ্যেই কোনও সম্পর্ক খুঁজে পাওয়া যায়, তবে সর্বনিম্ন সংখ্যক প্রজন্মের পদক্ষেপের সাথে একটিকে u+dঅগ্রাধিকার দেওয়া হয়। ব্যক্তি যদি aব্যক্তি কোন রক্ত সম্পর্ক রয়েছে i, A(i)আয় None
  • P(r): মুদ্রণ ফলাফল স্ট্রিং rব্যক্তি aএবং এর নাম দ্বারা বন্ধনীযুক্ত b
  • O(n): প্রদত্ত সংখ্যার জন্য একটি অর্ডিনাল স্ট্রিং ফিরিয়ে দিন n। কেবল সমর্থন করে 1 < n < 21
  • G(n): n-1"গ্রেটস" (যেমন "2nd great-"এন = 2` এর সমতুল্য) এর সমতুল্য একটি উপসর্গের স্ট্রিং ফেরান। এন <= 1 এর জন্য একটি খালি স্ট্রিং ফিরে আসবে।
  • GG(n): nপ্রজন্মের জন্য উপযুক্ত হিসাবে "Nth দুর্দান্ত-" এবং "গ্র্যান্ড" সহ একটি উপসর্গের স্ট্রিং প্রদান করে । এন <= 1 এর জন্য একটি খালি স্ট্রিং ফিরে আসবে।

আমি সংক্ষিপ্ত কোডের নামে কয়েকটি শর্টকাট নিয়েছি যা বৃহত বংশানুক্রমে আরও ভাল (বা কিছুটা আরও সঠিক) পারফরম্যান্সের জন্য সংশোধন করা যেতে পারে। Aফাংশন যা (যুক্তিসঙ্গত আকারের পরিবারের জন্য যদিও সম্ভবত এখনও যথেষ্ট দ্রুত) ধীর করে তোলে প্রয়োজনীয় তুলনায় শিশু গাছ recursing ইতিমধ্যে হয়েছে অনুসন্ধান এড়াতে কোনো চেষ্টা দেখা যায় না। Oফাংশন সঠিকভাবে ordinals হ্যান্ডেল নেই চেয়ে বড় 20 (এটি একটি সব পেতে চতুর বিট 11th, 21stএবং 101stঠিক আছে, কিন্তু আমার খসড়া সংস্করণ এক আমি 25 সম্পর্কে অতিরিক্ত বাইটে তা)। যদি আপনি খুব পুরানো এবং বিখ্যাত পরিবারগুলির সাথে ডিল না করেন (উদাহরণস্বরূপ ইউরোপের কিছু রাজপরিবার) আমি নিশ্চিত নই যে আমি কোনও বংশপরিচয়টির যথার্থতার উপর নির্ভর করব যা যেভাবেই ফিরে গেছে।

অন্যদিকে, আমি কয়েকটি জায়গাগুলিও ছেড়ে দিয়েছি যেখানে আমি কয়েকটি বাইট শেভ করতে পারি। উদাহরণস্বরূপ, আমি GGএকটি অক্ষরের নাম পরিবর্তন করে 3 বাইট সংরক্ষণ করতে পারি , তবে নামটি বন্ধ great-grandকরে দেওয়া আমার কাছে বেশি মূল্যবান মনে হয়েছিল।

আমি বিশ্বাস করি যে কোডে সমস্ত সাদা স্থান প্রয়োজন, তবে এটি সম্ভব যে কিছু এড়িয়ে যেতে পারে এবং আমি কেবল এগুলি মিস করেছি (এই উত্তরটি টাইপ করার সময় আমি যুক্তি তালিকায় বিপথগামী ফাঁকা জায়গা খুঁজেছি, তবে আমি মনে করি আমি ') এখনই সব পেয়ে গেছেন)।

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

সমস্যাটি প্রকাশ করে এমন একটি ডেটাসেটের উদাহরণ এখানে:

1 ? ? F Alice
2 1 ? M Bob
3 1 2 F Claire
4 3 ? F Danielle

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


0

একটি পরীক্ষার স্যুট। এটি টি / রিলেশন.টিতে স্টাফ করুন এবং "প্রমাণ" বা "পার্ল টি / রিলেশন.টি" চালান। এটি বর্তমানে ধরে নেয় প্রোগ্রাম ফাইলটি "রিলেশন.আরবি"।

এটি সম্প্রদায়ের উইকি, তাই পরীক্ষাগুলি যোগ করতে নির্দ্বিধায়। আপনি যদি এটি পরিবর্তন করেন তবে আমি মনে করি একটি টাইমস্ট্যাম্প (বা অন্য কোনও স্পষ্ট পতাকা) ক্রমযুক্ত হবে। ইচ্ছেতালিকা:

  1. একটি "খারাপ ছেলে" পরীক্ষা যা সম্পূর্ণ অনুসন্ধান কৌশলকে শাস্তি দেবে
#
#       S. Leadley, Wed Aug 27 20:08:31 EDT 2014
use strict;
use warnings;
require File::Temp;
use File::Temp qw( tempfile tempdir );

use Test::More qw(no_plan);
# use Test::More tests => 38;


#       solution executable
my $solver='ruby relation.rb';


#       "happy" path
my $dir = tempdir( CLEANUP => 1 );
my ($fh, $filename) = tempfile( DIR => $dir );
my $testData = <<'END_TEST_DATA';
 1  ?  ? F Agatha
 2  ?  ? M Adam
 3  ?  ? F Betty
 4  1  2 M Bertrand
 5  1  2 F Charlotte
 6  ?  ? M Carl
 7  ?  ? F Daisy
 8  3  4 M David
 9  5  6 F Emma
10  ?  ? M Edward
11  ?  ? F Freya
12  7  8 M Fred
13  9 10 F Grace
14  ?  ? M Gerald
15  ?  ? F Hillary
16 11 12 M Herbert
17 13 14 F Jane
18  ?  ? M James
19 15 16 F Kate
20 17 18 M Larry
21  ? 18 F Mary
END_TEST_DATA
print $fh  $testData;
close($fh);

is( `$solver 1  2 $filename 2>&1`, "Agatha is not a blood relative to Adam.\n", 'OP example #1,  1  2');
is( `$solver 8 3 $filename 2>&1`, "David is the son of Betty.\n", 'OP example #2,  8  3');
is( `$solver 9 13 $filename 2>&1`, "Emma is the mother of Grace.\n", 'OP example #3,  9 13');
is( `$solver 4 5 $filename 2>&1`, "Bertrand is the brother of Charlotte.\n", 'OP example #4,  4  5');
is( `$solver 9 4 $filename 2>&1`, "Emma is the niece of Bertrand.\n", 'OP example #5,  9  5');
is( `$solver 5 8 $filename 2>&1`, "Charlotte is the aunt of David.\n", 'OP example #6,  5  8');
is( `$solver 16 7 $filename 2>&1`, "Herbert is the grandson of Daisy.\n", 'OP example #7, 16  7');
is( `$solver 1 9 $filename 2>&1`, "Agatha is the grandmother of Emma.\n", 'OP example #8,  1  9 (amended)');
is( `$solver 12 5 $filename 2>&1`, "Fred is the great-nephew of Charlotte.\n", 'OP example #9, 12  5');
is( `$solver 4 13 $filename 2>&1`, "Bertrand is the great-uncle of Grace.\n", 'OP example #10,  4 13');
is( `$solver 16 3 $filename 2>&1`, "Herbert is the great-grandson of Betty.\n", 'OP example #11, 16  3');
is( `$solver 6 17 $filename 2>&1`, "Carl is the great-grandfather of Jane.\n", 'OP example #12,  6 17');
is( `$solver 19 2 $filename 2>&1`, "Kate is the 3rd great-granddaughter of Adam.\n", 'OP example #13, 19  2 (amended)');
is( `$solver 1 17 $filename 2>&1`, "Agatha is the 2nd great-grandmother of Jane.\n", 'OP example #14,  1 17 (amended)');
is( `$solver 20 4 $filename 2>&1`, "Larry is the 3rd great-nephew of Bertrand.\n", 'OP example #15, 20  4');
is( `$solver 5 16 $filename 2>&1`, "Charlotte is the 2nd great-aunt of Herbert.\n", 'OP example #16,  5 16');
is( `$solver 8 9 $filename 2>&1`, "David is the cousin of Emma.\n", 'OP example #17,  8  9');
is( `$solver 19 20 $filename 2>&1`, "Kate is the 4th cousin of Larry.\n", 'OP example #18, 19 20');
is( `$solver 16 9 $filename 2>&1`, "Herbert is the cousin, twice removed, of Emma.\n", 'OP example #19, 16  9');
is( `$solver 12 17 $filename 2>&1`, "Fred is the 2nd cousin, once removed, of Jane.\n", 'OP example #20, 12 17');
is( `$solver 21 20 $filename 2>&1`, "Mary is the half-sister of Larry.\n", 'OP example #21, 21 20');


#       "sad" path
# none!


#       "bad" path
is( `$solver 1 32 $filename 2>&1`, "person with ID 32 does not exist\n", 'not required, not in the spec');


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