英文:
Find the unknown element "c3" value in a triangle of dependent integers
问题
I understand your question. You're looking for a more efficient method to reduce the number of iterations in your code. One approach you can consider is using binary search to narrow down the possible values of c3
instead of iterating through all possible values from 1 to Variable^No_In_1_Group
.
Here's a simplified example of how you can use binary search:
def find_c3(Variable, No_In_1_Group, c1, c2, c4_final, t1_final):
left = 1
right = Variable**No_In_1_Group
while left <= right:
mid = (left + right) // 2
f1 = Distance_Calculation(Variable, No_In_1_Group, c1, c2)
f2 = Distance_Calculation(Variable, No_In_1_Group, c2, mid)
f3 = Distance_Calculation(Variable, No_In_1_Group, mid, c4_final)
s1 = Distance_Calculation(Variable, No_In_1_Group, f1, f2)
s2 = Distance_Calculation(Variable, No_In_1_Group, f2, f3)
t1 = Distance_Calculation(Variable, No_In_1_Group, s1, s2)
if t1 == t1_final:
return mid
elif t1 < t1_final:
left = mid + 1
else:
right = mid - 1
return -1 # If no valid c3 is found
# Call this function with your input values to find c3
result = find_c3(Variable, No_In_1_Group, c1, c2, c4_final, t1_final)
This binary search approach should significantly reduce the number of iterations and provide a more efficient solution for finding the value of c3
.
英文:
I have a triangle with four integer values at the top between 1 to 256. The values below it are all determined by the "distance" between the two values immediately above them. That distance is the subtraction of the left-hand "parent" from the right-hand parent, plus 1. It this result would be 0 or negative, then 256 is added to the result, so it is guaranteed to be between 1 and 256.
Example
49 52 158 201
\ / \ / \ /
4 107 44
\ / \ /
104 194
\ /
91
Explanation
The top row is the input. The other rows are derived:
The second row starts with 52 - 49 + 1 = 4, then follows 158 - 52 + 1 = 107, ...etc.
The second value in the third row needs the additional 256: it is 44 - 107 + 1 + 256 = 194
The actual challenge
For the actual challenge, we don't have the third input value, but instead the final value at the bottom, and we need to find out what the third value should be. Also, the range of the values is not always 1..256, but 1..Variable<sup>No_In_1_Group</sup>, where these are inputs too. In the above example, Variable = 2
and No_In_1_Group = 8
So we have this pattern:
c1 c2 c3 c4
\ / \ / \ /
f1 f2 f3 (f: first level distance)
\ / \ /
s1 s2 (s: second level distance)
\ /
t1 (t: third level distance)
Given input: Variable, No_In_1_Group, c1, c2, c4, t1
Required output: c3
For Example:
Input: c1 = 49, c2 = 52, c4 = 201, t1 = 91, Variable = 2, No_In_1_Group = 8
Output: c3 = 158
49 52 ? 201
\ / \ / \ /
. . .
\ / \ /
. .
\ /
91
Attempt
I have a function Distance_Calculation
:
def Distance_Calculation(Variable, No_In_1_Group, Comb_1, Comb_2):
"""This function gives the value of "*Direct_Distance*" if Comb_1 & Comb_2 are known."""
if (Comb_2 >= Comb_1):
return Comb_2 - Comb_1 + 1
else:
return pow(Variable, No_In_1_Group) - Comb_1 + Comb_2 + 1
So I could call it like this, provided I already gave the values of the arguments:
f1 = Distance_Calculation(Variable, No_In_1_Group, c1, c2) or
s2 = Distance_Calculation(Variable, No_In_1_Group, f2, f3) or
t1 = Distance_Calculation(Variable, No_In_1_Group, s1, s2)
But I would need sometimes to derive a sibling value from a child value. For that I have this function:
"""If Comb_1 & Direct_Distance are known, then Comb_2 will be calculated using this function"""
def Reverse_Distance_Calculation(Variable, No_In_1_Group, Comb_1, Direct_Distance):
if (Comb_1+Direct_Distance-pow(Variable, No_In_1_Group)-1 <= 0 and Direct_Distance-1 >= 0):
return Comb_1 + Direct_Distance - 1
else:
return Comb_1 + Direct_Distance - pow(Variable, No_In_1_Group) - 1
In a similar fashion, all f
and s
values are calculated with the following code:
def get_unknown_element(c1, c2, c4_final, t1_final):
c4 = c4_final
base_reminder_index = Variable**No_In_1_Group
for i in range(1,base_reminder_index+1):
c3 = i
f1 = Distance_Calculation(Variable, No_In_1_Group, c1, c2)
f2 = Distance_Calculation(Variable, No_In_1_Group, c2, c3)
f3 = Distance_Calculation(Variable, No_In_1_Group, c3, c4)
s1 = Distance_Calculation(Variable, No_In_1_Group, fld1, fld2)
s2 = Distance_Calculation(Variable, No_In_1_Group, fld2, fld3)
t1 = Distance_Calculation(Variable, No_In_1_Group, sld1, sld2)
if (t1 == t1_final):
return i
return -1
Problem and question
The above method is not very efficient as it takes a max of 256 iterations in every single run and I have run this code more than 1000 times to get my desired result. Is there an efficient method where iterations can be reduced drastically?
答案1
得分: 1
我首先会将Variable
和No_In_1_Group
视为一个输入m
,类似于你示例中的m=256
。
计算在结果变为负数时添加了256(即值m
)。这对应于模运算。当c2小于c1或等于c1时,我们应该得到m + (c2 - c1 + 1)
,但这等同于c2 - c1 (mod m) + 1
,在Python中,你可以使用模运算符来获得:(c2 - c1) % m + 1
。由于值在范围0..m-1
而不是1..m
,所以+ 1
被从模运算中省略了。
可以将计算从上到下扩展,始终考虑表达式应视为模m
(如上所述):
c1 c2 c3 c4
\ / \ / \ /
(c2-c1+1) (c3-c2+1) (c4-c3+1)
\ / \ /
(c3-2c2+c1) (c4-2c3+c2)
\ /
(c4-3c3+3c2-c1+1)
底部表达式必须等于t1 - 1 (mod m) + 1
,因此为了将其重写为关于c3(未知数)的表达式:
3c3 = c4 + 3c2 - c1 - t1 (mod m) + 1
由于左边的系数3,我们实际上有3个解决这个方程的候选:
c3 = [c4 + 3c2 - c1 - t1 (mod m) + 1] / 3
or [c4 + 3c2 - c1 - t1 (mod m) + 1 + m] / 3
or [c4 + 3c2 - c1 - t1 (mod m) + 1 + 2m] / 3
将此重写为Python:
def solve(c1, c2, c4, t1, m):
triple_c3 = (c4 + 3*c2 - c1 - t1) % m + 1
if triple_c3 % 3:
triple_c3 += m
if triple_c3 % 3:
triple_c3 += m
if triple_c3 % 3:
return None # 无解
return (triple_c3 // 3 - 1) % m + 1 # 映射到1..m范围
c3 = solve(49, 52, 201, 91, 256)
print(c3) # 158
这段Python代码解决了方程并返回c3的值。
英文:
I would first consider Variable
and No_In_1_Group
as one input m
, like m=256
in your example.
The calculation adds 256 (ie. the value m
) when a result would become negative. This corresponds to modular arithmetic. When c2 would be less than c1 or equal), we should get m + (c2 - c1 + 1)
, but that is c2 - c1 (mod m) + 1
, which in Python you get with the modulo operator: (c2 - c1) % m + 1
. The + 1
is left out of the modulo operation as you don't values in the range 0..m-1
, but 1..m
The calculation can be expanded from top to bottom as follows, always considering that the expressions are to be considered modulo m
(as explained above):
c1 c2 c3 c4
\ / \ / \ /
(c2-c1+1) (c3-c2+1) (c4-c3+1)
\ / \ /
(c3-2c2+c1) (c4-2c3+c2)
\ /
(c4-3c3+3c2-c1+1)
The bottom expression must equal t1 - 1 (mod m) + 1
, so to rewrite that in terms of c3 (the unknown):
3c3 = c4 + 3c2 - c1 - t1 (mod m) + 1
Because of the coefficient 3 at the left side we actually have 3 candidates to solve this equation:
c3 = [c4 + 3c2 - c1 - t1 (mod m) + 1] / 3
or [c4 + 3c2 - c1 - t1 (mod m) + 1 + m] / 3
or [c4 + 3c2 - c1 - t1 (mod m) + 1 + 2m] / 3
To rewrite this in Python:
def solve (c1, c2, c4, t1, m):
triple_c3 = (c4 + 3*c2 - c1 - t1) % m + 1
if triple_c3 % 3:
triple_c3 += m
if triple_c3 % 3:
triple_c3 += m
if triple_c3 % 3:
return None # No solution
return (triple_c3 // 3 - 1) % m + 1 # map to 1..m range
c3 = solve(49, 52, 201, 91, 256)
print(c3) # 158
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论