Şöyle bir çözüm ürettim, mantığı oldukça basit:
from algoritmalar import ayır, permutations
formül = "(({} - ({} / {}) * ({} - {}) * {}) + {})"
sayılar = "123456789"
sonuç = 0
for i in permutations(sayılar):
for j in ayır("".join(i), 6):
if sonuç < (yeni := eval(formül.format(*j))):
sonuç = yeni
sonuç_formül = j
print(sonuç)
print(formül.format(*sonuç_formül))
sizin kod 56779 çıktısı veriyor
ama ben ((76-2/4)*(85-1)*9)+3=57081 buldum
gerçi sizin koddaki mantıkda doğru ama sonuç neden farklı
parantezlemede ufak bir hatanız olmuş ordan kaynaklanmış sorun orayı düzeltince cevap geldi.
Ayıraç fonksiyonu çok kullanışlı oldu bu arada
Birde ben böyle yazmıştım çok daha hızlı ama çok daha uzun kodlar mevcut.
Sizce hız mı yoksa okunaklı ve kısa kodmu ? Kesinlikle sizin yazdığınız kod daha şık ama yazdığım kodun hızıda cezbediyor.
liste=[]
for i in range(1,10):
for j in range(1,10):
if j!=i:
for k in range(1,10):
if k!=j and k!=i:
for l in range(1,10):
if l!=i and l!=j and l!=k:
for m in range(1,10):
if m!=i and m!=j and m!=k and m!=l:
for n in range(1,10):
if n!=i and n!=j and n!=k and n!=l and n!=m:
for o in range(1,10):
if o!= i and o!= j and o!= k and o!= l and o!= m and o!= n:
for p in range(1,10):
if p != i and p != j and p != k and p != l and p != m and p != n and p!=o:
for r in range(1,10):
if r != i and r != j and r != k and r != l and r != m and r != n and r != o and r!=p:
a=float(str(i)+str(j))
d=float(str(l)+str(k))
b=float(str(m))
c=float(str(n))
e=float(str(o))
f=float(str(p))
g=float(str(r))
x=((a-(b/c))*(d-e)*f)+g
liste.append(x)
print(max(liste))
Ben bir sıkıntı göremiyorum. Bence çok güzel bir merdiven olmuş
Kodunuz zaten çok kötü durumda, ama iyi hale getirmek zor değil:
from itertools import permutations
liste = []
for i, j, k, l, m, n, o, p, r in permutations("123456789"):
a=int(i+j)
d=int(l+k)
b=int(m)
c=int(n)
e=int(o)
f=int(p)
g=int(r)
x=((a-(b/c))*(d-e)*f)+g
liste.append(x)
print(max(liste))
Tamamen aynı işi yapıyor, hem de daha hızlı
Zaten bu kod ile benimkini kıyaslayınca niçin bunun daha hızlı olduğu anlaşılıyor, a
ve d
nin iki basamaklı olması gerektiği varsayımına dayanıyor, olasılıkların çoğunu kontrol bile etmiyor.
Bir de tüm sonuçları listeye eklemeniz hafızada kaplanan yeri arttırıyor, benim gibi anlık kontrol yapmanız en iyisi.
For döngüsünün böyle kullanımı yeni öğreniyorum hangi durumlarda birden fazla elemanlarla bir nesne üzerinde dönebiliyoruz?
Ve burada o elemanlar neden eşit olmuyor .
Kanımca tupplelarda uzunluk kadar elemanlarla dönebiliyoruz peki daha az elemanla dönsek ne olur?
Diyeceksiniz ki dene gör ama dışardayım PC başında değil
Bu kullanımı bilseydim o kadar şeyi yapmaya ne hacet direk benim uzun yaptığım işi tek satırda bitiriyor
Müsait olunca denersiniz
>>> a, b = 1, 2
>>> a
1
>>> b
2
Kullanımla çok alakası yok aslında, sizin aklınıza permutations
gelmemiş sanırım. Çünkü permutations
dan geri dönen değeri de indexleyebilirdiniz.
Şöyle bir kullanımla eşdeğer:
>>> from itertools import permutations
>>> p = permutations("abc")
>>> l = next(p)
>>> l
('a', 'b', 'c')
>>> i, j, k = l
>>> i
'a'
>>> j
'b'
>>> k
'c'
>>> i, j, k = next(p)
>>> i
'a'
>>> j
'c'
>>> k
'b'
Tabii uzunuklarının aynı olması lazım:
>>> i, j, k = (1,2,3)
>>> i, j, k = (1,2,3,4)
Traceback (most recent call last):
File "<pyshell#17>", line 1, in <module>
i, j, k = (1,2,3,4)
ValueError: too many values to unpack (expected 3)
>>> i, j, k = (1,2)
Traceback (most recent call last):
File "<pyshell#18>", line 1, in <module>
i, j, k = (1,2)
ValueError: not enough values to unpack (expected 3, got 2)
Evet bu kalıpta sorularla ilk ilgilendiğimde itertools modülünü bilmiyordum
Daha sonrada farklı bir yöntem düşünmek aklıma gelmedi nede olsa bu kalıpta her soruya yanıt veriyordu kod
import functools
import itertools
import operator
def groupings(sum_):
if sum_ == 0:
return [()]
else:
return [(i,) + subg for i in range(1, sum_ + 1) for subg in groupings(sum_ - i)]
groupings_with_length = lambda s, l: list(filter(lambda g: len(g) == l, groupings(s)))
def assign_elements(grouping, elements, fold_op=operator.add):
element_gen = iter(elements)
return tuple(functools.reduce(fold_op, itertools.islice(element_gen, g)) for g in grouping)
assign_digits = functools.partial(assign_elements, fold_op=lambda x, y: x*10 + y)
assert list(groupings(4)) == [(1, 1, 1, 1), (1, 1, 2), (1, 2, 1), (1, 3), (2, 1, 1), (2, 2), (3, 1), (4,)]
assert list(groupings_with_length(6, 3)) == [(1, 1, 4), (1, 2, 3), (1, 3, 2), (1, 4, 1), (2, 1, 3), (2, 2, 2), (2, 3, 1), (3, 1, 2), (3, 2, 1), (4, 1, 1)]
assert assign_elements((2, 1, 3, 4), "abcdefghij") == ("ab", "c", "def", "ghij")
assert assign_digits((1, 3, 1, 4), [1,2,3,4,5,6,7,8,9]) == (1, 234, 5, 6789)
##
def evaluate(nums):
A, B, C, D, E, F, G = nums
return ((A - (B/C)) * (D-E) * F) + G
assigned = [assign_digits(g, digits) for g in groupings_with_length(9, 7) for digits in itertools.permutations(range(1, 10))]
print(sorted([(nums, evaluate(nums)) for nums in assigned], key=lambda n_e: n_e[1], reverse=True)[0])
((76, 2, 4, 85, 1, 9, 3), 57081.0)
Fonksiyonlar dursun, bu tur sorularda kullaniriz.
Güzel olmuş elinize sağlık, bunları da giste ekliyorum.
Özyinelemede ne yapmak istediğinizi anlayamıyorum ne yapmam gerekir ?
Bu sonuçların çıkacağını nasıl öngörüyorsunuz
İnternette ki örnekler bunların yanında çok basit kalıyor
Fonksiyonun sonuçlarını bulmanın pratik ve anlaşılır bir yolu varmı
Biraz geç oldu biliyorum ama rica etsem ayır fonksiyonunu burada paylaşabilir misiniz?
Burada çok kullandığımız fonksiyonları bir dosyada toplamaya karar vermiştim, bakabilirsiniz:
Teşekkürler…
Benim deneyimimde, ozyinelemeli kod yazmak okumaktan daha kolay
Profosyonel hayatta bu tur kod orneklerini okuma geregi pek duyulmuyor. Duyulacaksa, daha okunakli bir sekilde tekrardan yaziliyor. Ilk bakista her seyiyle anlasilmayan bir kodu okumanin manasi yok—dogrulamak icin okumanin bir manasi yok cunku dogrulama yapan kisi kodu yanlis okuyabilir. Dogru calistigindan emin olmak icin okumanin bir manasi yok cunku bu isi testler yapiyor. Asagidaki assert
’leri okuyup anlamak yeterli olacaktir. (Kendileri ornek ve test olarak cift gorev goruyorlar.)
Kodu daha anlasilabilir yapmak icin herhalde list comprehension’i hede = []; for ...: for ...: hede.append(x)
seklinde acmak gerekiyor. Bunu odev olarak veriyorum.
Onun disinda sum_ == 0
olan base case’den geriye dogru cagrilari ve pasladiklari/dondurdukleri degerleri takip etmek lazim.
Bu aslinda 2 boyutlu bir dynamic programming fonksiyonu. Onlari gorsellestirmeyi anlatan soyle guzel bir makale de var. (“2 boyutlu” lafim da oradan geliyor olsa gerek; terim degil.)
Ters yazmisim, recursive kodu okumak yazmaktan daha zor.