On iki bozuk para sorunu


14

Arka fon

On iki bozuk para sorunu, iş görüşmelerinde yaygın olarak kullanılan klasik bir denge bulmacasıdır . Bulmaca ilk olarak 1945'te ortaya çıktı ve annemle evlenmek istediğinde büyükbabam tarafından babama gönderildi! Bulmacada, biri diğerinden daha ağır veya daha hafif olan on iki para vardır (hangisini bilmediğiniz). Sorun, benzersiz parayı belirlemek için üç kez bir denge skalası kullanmaktır. Bazı varyasyonlarda, madalyonun daha ağır veya daha hafif olup olmadığını belirlemek gerekir.

Buradaki görev , en kötü durumda mümkün olan en az ağırlığı kullanarak, n jeton içeren genel sorunun çözülmesini içerir . Madalyonun daha ağır mı yoksa daha hafif mi olduğunu tanımlamak gerekli değildir, sadece hangisi olduğunu. Ayrıca, verilen setin dışında ek paralara erişemezsiniz (bu, merakla bir fark yaratır).

K tartımlarının (3 ^ k-1) / 2 jetona kadar yeterli olduğu ortaya çıkıyor (bu nedenle bu varyasyondaki 4 tartım aslında 13 jetonu işleyebilir). Ayrıca (ve şaşırtıcı bir şekilde), gelecekteki tartımların geçmiş sonuçlara bağlı olmasını değil, tüm tartım setini önceden seçmek mümkündür (ancak burada gerekli değildir). İki olası çözümün açıklaması için bu makaleye ve Quora cevabına bakın .

Görev

STDIN, komut satırı bağımsız değişkeni veya işlev bağımsız değişkeni yoluyla girdi olarak n tamsayısını alarak , en kötü durumda mümkün olan en az ağırlığı kullanarak n sikke sorununu çözen bir işlev veya program yazın . Program:

  • 1,2,3-4,5,6Terazinin her iki yanındaki bozuk para listelerini belirtmek için tartımları STDOUT biçiminde yazdırın . Tartılmayan herhangi bir bozuk para belirtilmemelidir. Paralar dolaylı olarak 1'den n'ye kadar numaralandırılmıştır ve sayısal sırayla basılmasına gerek yoktur (yani 2,1-3,4ile aynıdır 1,2-3,4).
  • Her tartımdan sonra, program STDIN üzerinden <, =ya >da ölçeğin sol tarafının sağ taraftan daha hafif, aynı mı yoksa daha ağır mı olduğunu gösteren bir girişi beklemelidir .
  • Son tartım sonucundan sonra, program benzersiz parayı yazdırmalı veya iade etmelidir.
  • Program, kullanıcıdan gelen tutarsız sonuç girişlerini işlemek zorunda değildir.
  • Programın n'den küçük olması gerekmez .

Örnek çıktılar

>> 3
1-2
>> =
1-3
>> <
3

# using Quora algorithm
>> 13
1,2,3,4-5,6,7,8
>> <
1,2,5-3,4,6
>> >
3-4
>> <
3

# using paper algorithm
>> 13
1,2,3,4-5,6,7,8
>> <
2,6,7,9-3,8,10,11
>> >
6,8,10,12-4,5,7,11
>> =
3

puanlama

En kısa kod kazanır. Standart kurallar geçerlidir.

Yanıtlar:


2

Python 3: 497 bayt

I=lambda a,b:input(",".join(a)+"-"+",".join(b)+"\n>> ")
def A(a,b):
 l,L=len(a),len(b)
 if l+L==1:return(a or b)[0]
 m=(2*l+1-L)//3;M=m+L-l;x,y,X,Y=a[:m],a[m:2*m],b[:M],b[M:2*M];r=I(x+X,y+Y);return A(a[2*m:],b[2*M:])if r=="="else A(x,Y)if r=="<"else A(y,X)
def B(a,n=[]):
 if len(a)==1:return a[0]
 m=len(n);l=(len(a)+1+m)//3;x,y,z=a[:l],a[l:2*l-m],a[2*l-m:];r=I(x,y+n);return B(z,a[:1])if r=="="else A(x+z[:1-m],y)if r=="<"else A(y+z[:1-m],x)
print(B(list(map(str,range(1,int(input("N= "))+1)))))

Bunun biraz daha daraltılabileceğinden şüpheleniyorum, ancak artık belirgin bir yer görmüyorum (her işlevin yaklaşık 5 farklı sürümünden sonra).

Kod, üç işlev kullanarak bu sayfadan algoritmanın biraz değiştirilmiş bir sürümünü uygular . IFonksiyon IO (yazdırma seçeneklerini ve kullanıcının tepkisini dönen) yapar. AVe Bişlevleri algoritmanın ana uygularlar. Aboyut olarak tam olarak bir öğe ile farklılık gösteren iki liste alır (her iki liste de daha büyük olabilir): bir madeni para anormalden daha açık veya bir madeni para bdaha ağır olabilir. Bçifte görev yapar. Bir jeton listesi ave isteğe bağlı olarak doğru ağırlık olduğu bilinen tek bir jetonla ikinci bir liste alır . Uzunluk yuvarlama davranışının iki vaka arasında farklı olması gerekir, bu da baş ağrısının sona ermesine neden olmaz.

İki algoritma işlevi k, aşağıdaki boyutlara kadar girişler verilen ağırlıklarda olağandışı ağırlıklı parayı bulabilir :

  • A: 3^kİki listesine bölünür toplam paralar, (3^k-1)/2ve (3^k+1)/2.
  • B: (3^k + 1)/2iyi bilinen bir bozuk para verilirse bozuk paralar (3^k - 1)/2 .

Soru kümesindeki kötü jeton bulmak çözebilir yüzden, başlangıçta herhangi bilinen iyi paralar yok burada belirliyorsa poz (3^k - 1)/2içinde ktartım.

Kodumun sahte tartım istemediğinden veya olması gereken tartım sayısından daha fazlasını kullanmadığından emin olmak için yazdığım bir test işlevi:

def test(n):
    global I
    orig_I = I
    try:
        for x in range(3,n+1):
            max_count = 0
            for y in range(x*2):
                count = 0
                def I(a, b):
                    assert len(a) == len(b), "{} not the same length as {}".format(a,b)
                    nonlocal count
                    count += 1
                    if y//2 in a: return "<"if y%2 else ">"
                    if y//2 in b: return ">"if y%2 else "<"
                    return "="
                assert B(list(range(x)))==y//2, "{} {} not found in size {}".format(['heavy','light'][y%2], y//2+1, x)
                if count > max_count:
                    max_count = count
            print(x, max_count)
    finally:
        I = orig_I

Bu, her bozuk para ve kötü ağırlık (ağır veya hafif) kombinasyonuyla test ettikten sonra belirli bir set için en kötü tartım sayısını yazdırır.

125'e kadar setler için test çıktısı:

>>> test(150)
3 2
4 2
5 3
6 3
7 3
8 3
9 3
10 3
11 3
12 3
13 3
14 4
15 4
16 4
17 4
18 4
19 4
20 4
21 4
22 4
23 4
24 4
25 4
26 4
27 4
28 4
29 4
30 4
31 4
32 4
33 4
34 4
35 4
36 4
37 4
38 4
39 4
40 4
41 5
42 5
43 5
44 5
45 5
46 5
47 5
48 5
49 5
50 5
51 5
52 5
53 5
54 5
55 5
56 5
57 5
58 5
59 5
60 5
61 5
62 5
63 5
64 5
65 5
66 5
67 5
68 5
69 5
70 5
71 5
72 5
73 5
74 5
75 5
76 5
77 5
78 5
79 5
80 5
81 5
82 5
83 5
84 5
85 5
86 5
87 5
88 5
89 5
90 5
91 5
92 5
93 5
94 5
95 5
96 5
97 5
98 5
99 5
100 5
101 5
102 5
103 5
104 5
105 5
106 5
107 5
108 5
109 5
110 5
111 5
112 5
113 5
114 5
115 5
116 5
117 5
118 5
119 5
120 5
121 5
122 6
123 6
124 6
125 6

Kesme noktaları tam olarak beklediğiniz yerde (3^k - 1)/2ve arasındadır (3^k + 1)/2.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.