Pyth, 92 ไบต์
I!%vzhK%2u?sm,ed-hd*ed/F<G2cG2@G1G+~Q,hQ_eQj9 2)J*L/vzhKtKeoSNm-VJ/RhK_*LdQsm+LdtM3/V*LhK_JQ
มันค่อนข้างเป็นสัตว์ประหลาด
ลองมันออนไลน์: สาธิต รูปแบบอินพุตคือc\n[a,b]
และรูปแบบเอาต์พุต[x,y]
และรูปแบบการออกเป็น
ในกรณีที่ไม่มีวิธีแก้ปัญหาจำนวนเต็มฉันจะไม่พิมพ์อะไรเลยและในกรณีที่ไม่มีวิธีแก้ปัญหาจำนวนเต็มโดยธรรมชาติฉันจะพิมพ์วิธีแก้ปัญหาจำนวนเต็มแบบสุ่ม
คำอธิบาย (ภาพรวมคร่าวๆ)
ตอนแรกฉันจะหาคำตอบจำนวนเต็มกับสมการax + by = gcd(a,b)
โดยใช้อัลกอริทึม Extended Euclidean
แล้วฉันจะปรับเปลี่ยนวิธีการแก้ปัญหา (คูณของฉันa
และb
มีc/gcd(a,b)
) ax + by = c
เพื่อให้ได้วิธีการแก้ปัญหาของจำนวนเต็ม ใช้งานได้ถ้าc/gcd(a,b)
เป็นจำนวนเต็ม มิฉะนั้นจะไม่มีวิธีแก้ปัญหา
ทั้งหมดโซลูชั่นจำนวนเต็มอื่น ๆ ที่มีรูปแบบa(x+n*b/d) + b(y-n*a/d) = c
ที่มีจำนวนเต็มd = gcd(a,b)
n
ใช้ทั้งสองความไม่เท่าเทียมกันx+n*b/d >= 0
และy-n*a/d >= 0
ผมสามารถกำหนดค่าที่เป็นไป 6 n
สำหรับ ฉันจะลองทั้ง 6 ตัวแล้วพิมพ์คำตอบด้วยค่าสัมประสิทธิ์ต่ำสุดสูงสุด
คำอธิบาย (รายละเอียด)
ax' + by' = gcd(a,b)
ขั้นตอนแรกคือการหาวิธีการแก้ปัญหาจำนวนเต็มสมการ สิ่งนี้สามารถทำได้โดยใช้อัลกอริทึมแบบยุคลิดแบบขยาย คุณสามารถได้รับความคิดในการทำงานที่วิกิพีเดีย ข้อแตกต่างคือว่าแทนที่จะใช้ 3 คอลัมน์ ( r_i s_i t_i
) ฉันจะใช้ 6 คอลัมน์ ( r_i-1 r_i s_i-1 s_i t_i-1 t_i
) วิธีนี้ฉันไม่ต้องเก็บสองแถวสุดท้ายไว้ในหน่วยความจำเพียงแถวสุดท้าย
K%2u?sm,ed-hd*ed/F<G2cG2@G1G+~Q,hQ_eQj9 2) implicit: Q = [a,b] (from input)
j9 2 convert 9 to base 2: [1,0,0,1]
+ Q add to Q => [a,b,1,0,0,1]
this is the initial row
u ) start with G = ^ and update G repeatedly
by the following expression, until
the value of G doesn't change anymore
? @G1 if G[1] != 0:
cG2 split G into parts of 2
m map the parts d to:
, the pair
ed d[1]
-hd*ed/F<G2 d[0]-d[1]*G[0]/G[1]
s unfold
else:
G G (don't change it, stop criterion for u)
%2 take every second element
we get the list [gcd(a,b),x',y']
K store this list in K
~Q,hQ_eQ afterwards change Q to [Q[0],-Q[1]] = [a,-b]
This will be important for the other parts.
ax + by = c
ตอนนี้ผมต้องการที่จะหาวิธีการแก้ c mod gcd(a,b) == 0
นี้เป็นไปได้เฉพาะเมื่อ ถ้าสมการนี้เป็นที่พอใจผมก็คูณด้วยx',y'
c/gcd(a,b)
I!%vzhK...J*L/vzhKtK implicit: z = c in string format (from input)
%vzhK evaluated(z) mod K[0] (=gcd(a,b))
I! if not ^ than:
/vzhK c/K[0]
*L tK multipy ^ to each element in K[1:] (=[x',y'])
J and store the result in J, this is now [x,y]
ax + by = c
เรามีวิธีการแก้ปัญหาสำหรับจำนวนเต็ม แจ้งให้ทราบว่าx
, y
หรือทั้งสองอาจจะเป็นเชิงลบ ดังนั้นเป้าหมายของเราคือเปลี่ยนสิ่งเหล่านี้ให้ไม่ใช่เชิงลบ
สิ่งที่ดีเกี่ยวกับสมการไดโอแฟนไทน์คือเราสามารถอธิบายการแก้ปัญหาทั้งหมดโดยใช้วิธีแก้ปัญหาเริ่มต้นเพียงหนึ่งเดียว หาก(x,y)
เป็นวิธีการแก้ปัญหานั้นโซลูชั่นอื่น ๆ ทั้งหมดอยู่ในรูปแบบ(x-n*b/gcd(a,b),y+n*a/gcd(a,b))
ของn
จำนวนเต็ม
ดังนั้นเราจึงต้องการที่จะหาn
ที่และx-n*b/gcd(a,b) >= 0
y+n*a/gcd(a,b >= 0
หลังจากการเปลี่ยนแปลงบางอย่างที่เราจบลงด้วยการที่ทั้งสองความไม่เท่าเทียมกันและn >= -x*gcd(a,b)/b
n >= y*gcd(a,b)/a
ขอให้สังเกตว่าสัญลักษณ์ความไม่เท่าเทียมกันอาจมีลักษณะไปในทิศทางอื่น ๆ เนื่องจากส่วนที่มีศักยภาพเชิงลบหรือa
b
ฉันไม่สนใจเรื่องนั้นมากนักฉันเพียงแค่บอกว่าจำนวนหนึ่งของ-x*gcd(a,b)/b - 1, -x*gcd(a,b)/b, -x*gcd(a,b)/b + 1
ความไม่เท่าเทียมกันแน่นอน 1 และy*gcd(a,b)/a - 1, y*gcd(a,b)/a, y*gcd(a,b)/a + 1
ความพึงพอใจของความไม่เท่าเทียมกันจำนวนหนึ่ง2. มันมีn
ที่ตอบสนองความไม่เท่าเทียมกัน
แล้วฉันจะคำนวณโซลูชั่นใหม่(x-n*b/gcd(a,b),y+n*a/gcd(a,b))
สำหรับค่าที่เป็นไปได้ทั้งหมด n
6 และฉันพิมพ์โซลูชันด้วยค่าต่ำสุดสูงสุด
eoSNm-VJ/RhK_*LdQsm+LdtM3/V*LhK_JQ
_J reverse J => [y,x]
*LhK multiply each value with K[0] => [y*gcd,x*gcd]
/V Q vectorized division => [y*gcd/a,-x*gcd/b]
m map each d of ^ to:
tM3 [-1,0,1]
+Ld add d to each ^
s unfold
these are the possible values for n
m map each d (actually n) of ^ to:
*LdQ multiply d to Q => [a*n,-b*n]
_ reverse => [-b*n,a*n]
/RhK divide by K[0] => [-b*n/gcd,a*n/gcd]
-VJ vectorized subtraction with J
=> [x+b*n/gcd,y-a*n/gcd]
oSN order the solutions by their sorted order
e print the last one
เรียงลำดับตามสิ่งที่เรียงลำดับของพวกเขาทำงานด้วยวิธีต่อไป ฉันใช้ตัวอย่าง2x + 3y = 11
ฉันเรียงลำดับโซลูชันทั้ง 6 รายการ (เรียกว่าคีย์) และเรียงลำดับโซลูชันต้นฉบับตามคีย์:
solutions: [1, 3], [4, 1], [7, -1], [-5, 7], [-2, 5], [1, 3]
keys: [1, 3], [1, 4], [-1, 7], [-5, 7], [-2, 5], [1, 3]
sort by key:
solutions: [-5, 7], [-2, 5], [7, -1], [1, 3], [1, 3], [4, 1]
keys: [-5, 7], [-2, 5], [-1, 7], [1, 3], [1, 3], [1, 4]
วิธีนี้จะเป็นการแก้ปัญหาที่ไม่เป็นลบทั้งหมดต่อท้าย (ถ้ามี)