Bir işlem sorusu


Bu sorunun çözümünü buldum ama sizden de farklı yaklaşımlar bekliyorum :slight_smile:

Şö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 :slight_smile:

1 Beğeni

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ş :smiley:

1 Beğeni

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ı :slightly_smiling_face:
Zaten bu kod ile benimkini kıyaslayınca niçin bunun daha hızlı olduğu anlaşılıyor, a ve dnin 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.

2 Beğeni

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 :slight_smile:

Bu kullanımı bilseydim o kadar şeyi yapmaya ne hacet direk benim uzun yaptığım işi tek satırda bitiriyor :slight_smile:

Müsait olunca denersiniz :slightly_smiling_face:

>>> 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ü permutationsdan 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)
1 Beğeni

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 :slight_smile:

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.

2 Beğeni

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 :slight_smile:

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. :slight_smile:

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.)

2 Beğeni

Ters yazmisim, recursive kodu okumak yazmaktan daha zor.