3,5,7,11,13 sayılarını toplama, çıkarma, çarpma ve bölme işlemlerinin herbirini ve istediğimiz kadar parantez kullanarak 64 sonucunu elde ediniz.
sorunum şu parantezler işi karıştıryor
Eğer dört işlem kullan deseydi sadece sonucu bu şekilde bulurdum,sizce ne yapılabilir yardımcı olurmusunuz?
Altda yerdeğiştirme dikkate alınmamıştır
from itertools import permutations
işlemler='+-*/'
permutasyonlar=permutations(işlemler,4)
for i in permutasyonlar:
sonuç='3{}5{}7{}11{}13'.format(i[0],i[1],i[2],i[3])
if eval(sonuç)==64:
print(sonuç)
Buda bir işlemin birden fazla kullanıldığı durum bunu zaten istemiyor bizden ve
Burada yerdeğiştirme dikkate alınmadı
from itertools import product
işlemler='+-*/'
permutasyonlar=product(işlemler,repeat=4)
for i in permutasyonlar:
sonuç='3{}5{}7{}11{}13'.format(i[0],i[1],i[2],i[3])
if eval(sonuç)==64:
print(sonuç)
En baştaki sayının önüne -
gelebiliyor mu?
Hayır işaretler arada kalmalı
Parantezler için bir algoritma düşünmemiz lazım.
evet haklısınız ama ben daha belirleyemedim
Sayıların sıralaması önemli mi?
Evet onu atlamışım sıra önemli değil yer değişebilir
Algoritmasını kurdum şuan kodu yazıyorum.
Bu infix (4 * (2 + 3)
) ifadelerle ilgili bir sorun; prefix (* 4 + 2 3
) veya postfix (2 3 + 4 *
) ifadeler kullandigimizda bu sorun ortadan kalkiyor.
Daha once expression tree yaratmak gerektigini soylemistim; bu tur sorularin genel cozumu bu.
(Uc ifade de ayni islem agacini temsil ediyor.)
şöyle bir şey yapmayı denedim
tek parantez için sonuç veriyor
from itertools import permutations
a=[3,5,7,11,13,'(',')','+','*']
istenenler=permutations(a,9)
liste=[]
for i in istenenler:
boş=''
for j in i:
boş+=str(j)
liste.append(boş)
sonuçlar=[]
for i in liste:
try:
sonuçlar.append(eval(i))
except :
pass
print(sonuçlar)
ama sorun şu ki
<string>:1: SyntaxWarning: 'int' object is not callable; perhaps you missed a comma?
bu yazıda ekrana geliyor
işlem sayısı artıkça zaman uzuyor
birde ekrana gelen yazının sebebi nedir?
dediğiniz şekilde yapılırsa parantez kullanımına gerek kalmaz
nasıl o yazım şeklini yapabiliriz?
:1: SyntaxWarning: ‘int’ object is not callable; perhaps you missed a comma?
Bu sorum burada yetim kalmış
Neden böyle bir durum oluşmuştur?
Bana hic bir sey katmadiklari ve gercek dunyada kullanim alanlari olmadigi icin eval
'li cozumleri okumuyorum.
eval
edilen string’lerin birinde sentaks hatasi oldugu icin olusmustur.
Merhabalar,
Aşağıdaki algoritmayı inceleyin lütfen, mümkün olan parantez koşullarını oluşturuyor.
Burada önce hedef sayılarla ve operatörlerle bir kartezyen çarpım yapılır.
Daha sonra bu çarpımdan ürettiğimiz her bir ürün için, bracket_combinations
fonksiyonu ile, mümkün parantez grupları iç içe listeler kullanılarak oluşturulur.
Sonra da oluşan her bir ifadeye operatörler SyntaxError
vermeyecek şekilde yerleştirilir. Ama belli ifadeler ZeroDivisionError
hatası verebilir.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
def product(*iterables):
if not iterables:
yield []
return
for i in iterables[0]:
for p in product(*iterables[1:]):
yield [i, *p]
def find_numbers(s):
return list(map(int, "".join(map(lambda i: i if i.isnumeric() else " ", s)).split()))
def find_chars(s):
return list(filter(lambda i: not i.isnumeric(), s))
def unique_append(result, item):
if item not in result:
result.append(item)
def bracket_combinations(numbers):
def side_brackets(result, select, left, mid, right):
unique_append(result, [left, mid, *right] if select == left else [*left, mid, right])
for bracket in brackets(select):
if select == left:
unique_append(result, [bracket, mid, *right])
unique_append(result, [*bracket, mid, *right])
else:
unique_append(result, [*left, mid, bracket])
unique_append(result, [*left, mid, *bracket])
def brackets(n):
step = 2
result = [n]
while step < len(n):
for i in range(len(n) - 1):
left = n[:i]
mid = n[i: i + step]
right = n[i + step:]
unique_append(result, [*left, mid, *right])
if len(left) >= 2:
side_brackets(result, left, left, mid, right)
if len(right) >= 2:
side_brackets(result, right, left, mid, right)
for bracket in brackets(mid):
unique_append(result, [*left, bracket, *right])
step += 1
return result
return brackets(numbers)
def insert_operators(group, chars):
expr = ""
for i in range(len(group)):
if isinstance(group[i], list):
expr += "(" + insert_operators(group[i], chars) + ")"
try:
if expr[-1] != group[i + 1]:
expr += next(chars)
except IndexError:
pass
else:
expr += str(group[i])
if i != len(group) - 1:
try:
expr += next(chars)
except StopIteration:
pass
return expr
def get_products(ops, numbers):
products = []
for i in range(len(numbers)):
if i == len(numbers) - 1:
products += [[numbers[i]]]
else:
products += [[numbers[i]]] + [ops]
return products
def find_expression(ops, numbers, target):
for p in product(*get_products(ops, numbers)):
stmt = "".join(map(str, p))
chars = find_chars(stmt)
for bracket_comb in bracket_combinations(find_numbers(stmt)):
expr = insert_operators(bracket_comb, iter(chars))
try:
res = eval(expr)
if res == target:
return expr, res
except ZeroDivisionError:
pass
def main():
ops = "+-*/"
numbers = [3, 5, 7, 11, 13]
targets = [64, 32, 16, 125]
for target in targets:
expr = find_expression(ops, numbers, target)
print(expr)
main()
Değişik toplamlar için ifadeler otomatik olarak üretilir.
('(3-5*7)*(11-13)', 64)
('(3+5)*7-(11+13)', 32)
('3+(5+7-11)*13', 16)
('3*(5*7+11)-13', 125)
Algoritmanın dayandığı mantığı aşağıdaki açılımda gördüğüm örüntü yoluyla oluşturuyorum. İzninizle, dört sayıya kadar olan parantez olasılıklarını açayım:
"""
i: sayıları temsil eden değişken
?: operatörleri temsil eden değişken
i ? i:
1. i ? i
i ? i ? i:
1. i ? i ? i
2. (i ? i) ? i
3. i ? (i ? i)
i ? i ? i ? i:
1. i ? i ? i ? i
2. (i ? i) ? i ? i
3. i ? (i ? i) ? i
4. i ? i ? (i ? i)
5. (i ? i) ? (i ? i)
6. (i ? i ? i) ? i
7. ((i ? i) ? i) ? i
8. (i ? (i ? i)) ? i
9. i ? (i ? i ? i)
10. i ? ((i ? i) ? i)
11. i ? (i ? (i ? i))
"""
Yukardaki parantezleri bracket_combinations
fonksiyonuyla oluşturabiliriz:
c = 0
nums = [3, 5, 7, 11, 13]
for bracket_comb in bracket_combinations(nums):
c += 1
print(c, bracket_comb)
Çıktı:
1 [3, 5, 7, 11, 13]
2 [[3, 5], 7, 11, 13]
3 [[3, 5], [7, 11, 13]]
4 [[3, 5], [[7, 11], 13]]
5 [[3, 5], [7, 11], 13]
6 [[3, 5], [7, [11, 13]]]
7 [[3, 5], 7, [11, 13]]
8 [3, [5, 7], 11, 13]
9 [3, [5, 7], [11, 13]]
10 [3, 5, [7, 11], 13]
11 [3, 5, 7, [11, 13]]
12 [[3, 5, 7], [11, 13]]
13 [[[3, 5], 7], [11, 13]]
14 [[3, [5, 7]], [11, 13]]
15 [[3, 5, 7], 11, 13]
16 [[[3, 5], 7], 11, 13]
17 [[3, [5, 7]], 11, 13]
18 [3, [5, 7, 11], 13]
19 [3, [[5, 7], 11], 13]
20 [3, [5, [7, 11]], 13]
21 [3, 5, [7, 11, 13]]
22 [3, 5, [[7, 11], 13]]
23 [3, 5, [7, [11, 13]]]
24 [[3, 5, 7, 11], 13]
25 [[[3, 5], 7, 11], 13]
26 [[[3, 5], [7, 11]], 13]
27 [[3, [5, 7], 11], 13]
28 [[3, 5, [7, 11]], 13]
29 [[[3, 5, 7], 11], 13]
30 [[[[3, 5], 7], 11], 13]
31 [[[3, [5, 7]], 11], 13]
32 [[3, [5, 7, 11]], 13]
33 [[3, [[5, 7], 11]], 13]
34 [[3, [5, [7, 11]]], 13]
35 [3, [5, 7, 11, 13]]
36 [3, [[5, 7], 11, 13]]
37 [3, [[5, 7], [11, 13]]]
38 [3, [5, [7, 11], 13]]
39 [3, [5, 7, [11, 13]]]
40 [3, [[5, 7, 11], 13]]
41 [3, [[[5, 7], 11], 13]]
42 [3, [[5, [7, 11]], 13]]
43 [3, [5, [7, 11, 13]]]
44 [3, [5, [[7, 11], 13]]]
45 [3, [5, [7, [11, 13]]]]
Yukardaki listeler insert_operators
fonksiyonuyla paranteze dönüştürülür ve ilgili yerlere operatörler eklenir.
c = 0
nums = [3, 5, 7, 11, 13]
for bracket_comb in bracket_combinations(nums):
c += 1
print(c, insert_operators(bracket_comb, iter("+-*/")))
Çıktı
1 3+5-7*11/13
2 (3+5)-7*11/13
3 (3+5)-(7*11/13)
4 (3+5)-((7*11)/13)
5 (3+5)-(7*11)/13
6 (3+5)-(7*(11/13))
7 (3+5)-7*(11/13)
8 3+(5-7)*11/13
9 3+(5-7)*(11/13)
10 3+5-(7*11)/13
11 3+5-7*(11/13)
12 (3+5-7)*(11/13)
13 ((3+5)-7)*(11/13)
14 (3+(5-7))*(11/13)
15 (3+5-7)*11/13
16 ((3+5)-7)*11/13
17 (3+(5-7))*11/13
18 3+(5-7*11)/13
19 3+((5-7)*11)/13
20 3+(5-(7*11))/13
21 3+5-(7*11/13)
22 3+5-((7*11)/13)
23 3+5-(7*(11/13))
24 (3+5-7*11)/13
25 ((3+5)-7*11)/13
26 ((3+5)-(7*11))/13
27 (3+(5-7)*11)/13
28 (3+5-(7*11))/13
29 ((3+5-7)*11)/13
30 (((3+5)-7)*11)/13
31 ((3+(5-7))*11)/13
32 (3+(5-7*11))/13
33 (3+((5-7)*11))/13
34 (3+(5-(7*11)))/13
35 3+(5-7*11/13)
36 3+((5-7)*11/13)
37 3+((5-7)*(11/13))
38 3+(5-(7*11)/13)
39 3+(5-7*(11/13))
40 3+((5-7*11)/13)
41 3+(((5-7)*11)/13)
42 3+((5-(7*11))/13)
43 3+(5-(7*11/13))
44 3+(5-((7*11)/13))
45 3+(5-(7*(11/13)))
Yazdim sonunda expression tree generator’i:
from dataclasses import dataclass
import operator
@dataclass
class Node:
value: str
children: ['Node']
def get_exptrees(bag):
def _get_subtrees(bag, holes):
leaves, ops = bag
if len(leaves) < holes:
return
for i in range(len(leaves)):
leaf = leaves[i]
rem_leaves = leaves[:i] + leaves[i+1:]
yield (Node(leaf, []), (rem_leaves, ops))
for i in range(len(ops)):
op = ops[i]
rem_ops = ops[:]
for left in _get_subtrees((leaves, rem_ops), holes+1):
left_st, rem_bag = left
for right in _get_subtrees(rem_bag, holes):
right_st, rem_bag = right
yield (Node(op, [left_st, right_st]), rem_bag)
for tree, rem in _get_subtrees(bag, 0):
yield tree
def eval_exptree(tree):
if len(tree.children) > 0:
return tree.value(*map(eval_exptree, tree.children))
else:
return tree.value
def print_infix(labels, t):
if len(t.children) > 0:
return f"({print_infix(labels, t.children[0])} {labels[t.value]} {print_infix(labels, t.children[1])})"
else:
return t.value
bag = ([3, 5, 7, 11, 13], [operator.add, operator.sub, operator.mul, operator.truediv])
labels = { ol[0]: ol[1] for ol in zip(bag[1], "+-*/") }
solutions = 0
for t in get_exptrees(bag):
try:
val = eval_exptree(t)
except:
continue
if val == 64:
solutions += 1
print(solutions, print_infix(labels, t), "=", eval(print_infix(labels, t)))
Hole mantigi biraz aceleye geldi. Gerekecegini onceden tahmin etseydim belki ugrasmazdim bile; recursion’i komplike bir hale getiriyor. (Arkada sonsuz delik birakip (? + (? + (? + (? + (? + ...
dipsiz kuyusuna inmesini engelliyor.) Daha guzel cozumlere acigim.
left/right’i da n-arity operatorlere genelleyecektim de, delik meselesiyle ugrasmaktan vaktim kalmadi.
Simetriler dahil 582 cozum buluyor. Simetrileri ayiklamak gerekse nasil yapilir bilemedim.
Birkac ornek:
1 (3 + (7 + ((5 * 13) - 11))) = 64
2 (3 + (7 + ((13 * 5) - 11))) = 64
3 (3 + (13 + ((5 * 11) - 7))) = 64
4 (3 + (13 + ((11 * 5) - 7))) = 64
5 (3 + ((7 - 11) + (5 * 13))) = 64
6 (3 + ((7 - 11) + (13 * 5))) = 64
7 (3 + ((13 - 7) + (5 * 11))) = 64
8 (3 + ((13 - 7) + (11 * 5))) = 64
9 (3 + (((5 * 11) - 7) + 13)) = 64
10 (3 + (((5 * 13) - 11) + 7)) = 64
573 ((11 - 7) * (13 + 3)) = 64
574 ((11 - 13) * (3 - (5 * 7))) = 64
575 ((11 - 13) * (3 - (7 * 5))) = 64
576 ((13 - 5) * (11 - 3)) = 64
577 ((13 - 11) * ((5 * 7) - 3)) = 64
578 ((13 - 11) * ((7 * 5) - 3)) = 64
579 ((13 - (7 / 3)) * (11 - 5)) = 64.0
580 (((5 * 7) - 3) * (13 - 11)) = 64
581 (((7 * 5) - 3) * (13 - 11)) = 64
582 (((7 / 3) - 13) * (5 - 11)) = 64.0