หารด้วย 1000003? ง่ายเพียงแค่คูณตัวเลขสุดท้ายด้วย 300001 และเพิ่ม!


16

กำหนดที่สำคัญPมากกว่า10โปรแกรมหรือการทำงานของคุณจะต้องคิดออกกฎหารของxกำหนดเป็นจำนวนเต็มกับค่าสัมบูรณ์ที่เล็กที่สุดที่ทำให้หลายนายกเดิมเมื่อคูณด้วยหลักสุดท้ายของนายกและเพิ่มในส่วนที่เหลือของเดิม สำคัญ

ตัวอย่าง

ได้รับการป้อนข้อมูล31ที่เป็นตัวเลขหลักสุดท้ายและส่วนที่เหลือของจำนวน1 3ดังนั้นโปรแกรมของคุณจะต้องพบกับจำนวนเต็มxกับค่าสัมบูรณ์ขั้นต่ำดังกล่าวว่ามีหลาย1*x + 3 31ในกรณีนี้การทำงานเพื่อให้โปรแกรมหรือฟังก์ชั่นจะกลับมาx=-3-3

ได้รับการป้อนข้อมูล1000003ที่เป็นตัวเลขหลักสุดท้ายและส่วนที่เหลือของจำนวน3 100000ดังนั้นโปรแกรมของคุณจะพบx=300001เพราะสิ่ง3*300001+100000 = 1000003ที่เป็นจำนวน1000003มาก

พื้นหลังทางคณิตศาสตร์

ค่าของxสามารถใช้เป็นการทดสอบการหารได้ หากตัวเลขNหารด้วยPแล้วการเพิ่มจำนวนxหลักสุดท้ายของNส่วนที่เหลือNจะให้ผลคูณของจำนวนPและถ้าหากNหารด้วยPในตอนแรก

สำหรับการP=11ที่เราได้รับx=-1ซึ่งจะเทียบเท่ากับกฎหารที่รู้จักกันดีสำหรับ11: หมายเลขคือหารด้วยความแตกต่างสลับหลักของมันคือการหารด้วย1111

กฎระเบียบ

  • เอาต์พุตอาจอยู่ในรูปแบบใด ๆ ที่เข้ารหัสทั้งสัญญาณและมูลค่าของเอาต์พุตอย่างชัดเจน
  • อินพุตที่สำคัญจะอยู่ระหว่าง 10 และ 2 ^ 30
  • คุณไม่จำเป็นต้องจัดการถ้าอินพุตไม่ใช่ไพร์มหรือไม่อยู่ในช่วง
  • คุณไม่จำเป็นต้องจัดการหากทั้งคู่xและ-xเป็นผลลัพธ์ที่ถูกต้อง (ไม่ควรเกิดขึ้น)
  • อนุญาตให้ใช้กำลังแบบเดรัจฉาน แต่ได้รับการยอมรับในการสร้างสรรค์โซลูชั่นมากขึ้น
  • นี่คือดังนั้นรหัสที่สั้นที่สุดในแต่ละภาษาชนะ! อย่าปล่อยให้คำตอบในภาษากอล์ฟกีดกันคุณจากการโพสต์ในภาษาอื่น ๆ

กรณีทดสอบ

Input   Output
11  -1
13  4
17  -5
19  2
23  7
29  3
31  -3
37  -11
41  -4
43  13
47  -14
53  16
59  6
61  -6
67  -20
71  -7
73  22
79  8
83  25
89  9
97  -29
101 -10
103 31
107 -32
109 11
113 34
127 -38
131 -13
1000003 300001
2000003 600001
2999999 300000
9999991 -999999

3
การทำให้เข้าใจง่ายที่มีประโยชน์: เรากำลังมองหาค่าที่เล็กที่สุดxในค่าสัมบูรณ์ซึ่ง10*x-1สามารถหารด้วยอินพุตได้
xnor

ใครสามารถให้คำใบ้ว่าทำไม(3 / (n % 5 * 2 - 5) * n + 1) / 10และ(n % 5 * 2 - 5^2) * n / 10 + 1สามารถหาค่าสัมบูรณ์แบบน้อยที่สุดสำหรับบางสิ่งเช่นนี้ได้หรือไม่? สัญชาตญาณแรกของฉันคือการคำนวณตัวคูณร่วมน้อยโดยใช้ตัวหารร่วมที่ยิ่งใหญ่ที่สุดซึ่งคำนวณด้วยอัลกอริทึมของ Euclid
David Foerster

1
รับจำนวน @DavidFoerster คุณสามารถลบหลักสุดท้ายคูณด้วยจำนวนเพิ่มขึ้นและยังคงได้รับหารจำนวนโดยx nถ้าเราแล้วคูณหมายเลขใหม่ 10 nและลบจำนวนเดิมก็ยังคงหารด้วย ความคิดเห็นของ xnor นั้นตามมาจากพีชคณิตบางตัว ขั้นตอนต่อไปคือการจัดเรียงสูตรเพื่อที่จะให้xในแง่ของn: x (k*n+1)/10= เราต้องการสัมบูรณ์ที่เล็กที่สุดxดังนั้นเราจึงต้องการสัมบูรณ์ที่เล็กที่สุดkและนี่ต้องเป็นอย่างใดอย่างหนึ่ง-3 , -1, 1หรือ3(ขึ้นอยู่กับn's หลักสุดท้าย) ที่ทำให้ส่วนที่แน่นอน
Neil

คำตอบ:


14

JavaScript (ES6) 32 25 23 ไบต์

f=
n=>(3/(n%5*2-5)*n+1)/10
<input type=number min=1 oninput=o.textContent=this.value%5*(this.value%2)?f(this.value):``><pre id=o>

3/(n%5*2-5)จะถูกเขียน9/n(mod -10)ถ้าฉันสามารถเข้าถึงส่วนโมดูโลที่สมดุล แก้ไข: บันทึก 2 ไบต์ด้วย @EgorSkriptunoff


3
คุณสามารถบันทึก 2 ไบต์โดยแทนที่n=>((n%10*2%14-3)*n+1)/10ด้วยn=>(3/(n%5*2-5)*n+1)/10
Egor Skriptunoff


@KevinCruijssen น่าจะเป็นภาษาพูดได้เกือบพลาดสำหรับ Java 8 ด้วย ... โอ้เดี๋ยวก่อนฉันเห็นคำตอบของคุณตอนนี้!
Neil

@Neil คุณพูดถูก ฉันมักจะโพสต์คำตอบ Java ดังนั้นฉันจึงทำงานบนพอร์ตของxnorเมื่อฉันเห็นคำตอบของคุณ โพสต์ไว้ทั้งทางเป็นพอร์ตที่น่าเบื่อให้เครดิตคุณ
Kevin Cruijssen

8

Python 2 , 27 ไบต์

lambda n:(n%5*2-5^2)*n/10+1

ลองออนไลน์!

การดำเนินการเสร็จจากซ้ายไปขวา: (((n%5)*2)-5)^2 .

ฉันใช้ตัวคำนวณสัตว์เดรัจฉานเลขคณิตของฉันเพื่อค้นหานิพจน์ n%5*2-5^2ในการดำเนิน{1:-1,3:3,2:-3,4:1}[k]การผกผันเชิงลบของพอควรตกค้าง 5 [-2..2]ลงในช่วง


นักคิดเลขคณิตตัวโกงนี้เปิดเผยต่อสาธารณะหรือไม่?
ลินน์

นั่นเป็นนิพจน์เดียวที่พบหรือพิมพ์เพียงความยาวแรกที่กำหนดหรือไม่ ( 3/(n%5*2-5)มีความยาวเท่า(n%5*2-5^2)กัน)
Neil

@ ลินน์ไม่ฉันอาจทำความสะอาดและโพสต์เมื่อมีเวลา
xnor

1
@Neil n%5*2-6^3มันพบเพียงเทียบเท่าเงินสดและ ฉันค้นหาความยาวถึงขนาดของการแสดงออกโดยไม่มี parens ในขณะที่3/(n%5*2-5)อีกสองตัวอักษรยาว แต่ประหยัดใน parens ด้านนอกเนื่องจากความสำคัญ การค้นหานิพจน์ที่มีความยาวนี้ควรใช้เวลาสักครู่ Use-case นี้แนะนำให้ใช้อ็อพชันเพื่อค้นหานิพจน์ที่สามารถใช้ในบริบทที่กำหนดผ่านการดำเนินการนอกสุดที่มีความสำคัญสูงพอ
xnor

6

เจลลี่ ,10 8 ไบต์

,N⁵æiAÞḢ

ลองออนไลน์!

คำอธิบาย

,N       Get [Input, -Input].
⁵æi      Modular inverse of 10 mod each of [Input, -Input].
AÞ       Sort by absolute value.
Ḣ        First.

+1 ฉันไม่เคยเห็นการส่ง Jelly ที่มีการลงทะเบียนซึ่งช่วยประหยัด bytes
Mr. Xcoder

@ Mr.Xcoder มันเป็นเพราะฉันเล่นกอล์ฟไม่เก่ง
jimmy23013


5

Python 2 , 69 54 53 ไบต์

แก้ไข: -15 ไบต์ขอบคุณ@ Mr.Xcoder

แก้ไข: -1 ไบต์โดยใช้การสอบถามซ้ำ

f=lambda a,x=-1:(a%10*x+a/10)%a and f(a,-x-(x>0))or x

ลองออนไลน์!


54 ไบต์ ฉันไม่เห็นว่าทำไมคุณถึงมีตัวแปรเหล่านั้นเมื่อคุณใช้เพียงครั้งเดียว
Mr. Xcoder

ใช่รีบร้อนเมื่อฉันเขียนมัน
Halvard Hummel


5

Japt , 16 9 ไบต์

วิธีที่บันทึกไว้มากเกินไปต้องขอบคุณการสังเกตโดย @xnor

_*AÉ vU}c

ทดสอบออนไลน์! อาจใช้เวลาสองสามวินาทีในการป้อนข้อมูลขนาดใหญ่

คำอธิบาย

_  *AÉ  vU}c    Implicit: U = input integer
Z{Z*A-1 vU}c    Ungolfed
Z{        }c    Loop through each integer Z in [0, -1, 1, -2, ...] and yield the first where
  Z*A             Z times 10
     -1           minus 1
        vU        is divisible by the input.
                Implicit: output result of last expression

2

Java 8, 23 21 ไบต์

n->3/(n%5*2-5)*++n/10

JavaScrip (ES6)พอร์ตของ@Neilตอบกลับ แต่ -2 ไบต์ขอบคุณ@Nevayเนื่องจากการปูพื้นโดยนัยของจำนวนเต็ม

ลองที่นี่


1
21 ไบต์:n->3/(n%5*2-5)*++n/10
2560

1
@Nevay Even when I create a port of the top answer, you still have to golf me.. xD (Read: Thanks and nice job!)
Kevin Cruijssen



1

Python 2, 44 43 bytes

(Crossed out 44 is still 44.) Thanks to Fireflame241 for saving a byte!

P=input();i=P/3
while i*10%P-1:i-=1
print i

Try it online!

There is exactly one number between 0 and P-1 which is an inverse of 10. But if that inverse u happens to be greater than P/2, then (u-P) is also an inverse, and has a smaller absolute value than u. So it turns out that we're really looking for the unique number x between -P/2 and P/2 which is an inverse of 10.

The code above does exactly that, starting at (the floor of) P/2, and stepping downward until an inverse is reached. This must happen for some number greater than -P/2 so long as P is a prime greater than 10. More precisely, it will terminate if and only if P is coprime to 10.

Edit: It actually turns out that x is guaranteed to be between -P/3 and P/3, so the current version starts at P/3 and steps down from there. See the section labeled Improved Bound for an explanation of this.

Mathematical explanation

It was not immediately obvious to me why the divisibility test worked. Here's an explanation, in case anyone else was wondering.

อนุญาตPเป็นสำคัญมากกว่าซึ่งหลักสุดท้ายคือ10 bดังนั้น

P = 10a + b

ที่และa > 0 0 <= b < 10ในความเป็นจริงbเป็นอย่างใดอย่างหนึ่ง1, 3, 7หรือ9เพราะมากขึ้นที่สำคัญกว่า10ปลายต้องอยู่ในหนึ่งในตัวเลขเหล่านี้

bx + a = 0 (mod P)คิดว่าตอนนี้ แล้วก็

a = -bx (mod P)

10a + b = 10(-bx) + b (mod P)

0 = 10(-bx) + b (mod P)

0 = b(1 - 10x) (mod P)

ตั้งแต่Pเป็นนายกจำนวนเต็มmod Pเป็นโดเมนหนึ่ง ดังนั้นทั้งหรือb = 0 (mod P)1 - 10x = 0 (mod P)

เรารู้0 <= b < 10 < Pดังนั้นหากแล้วb = 0 (mod P) b = 0แต่เราบอกว่าbเป็นอย่างใดอย่างหนึ่ง1, 3, 7หรือ9ดังนั้นนี้เป็นไปไม่ได้ ดังนั้นเพื่อให้1 - 10x = 0 (mod P) 10x = 1 (mod P)ในคำอื่น ๆxเป็นสิ่งที่ตรงกันข้ามของ10, Pโมดูโล

Now suppose N is a nonnegative integer whose last digit is d, so N = 10c + d. We have a chain of equivalent statements:

10c + d = 0 (mod P)

<==> 10xc + dx = 0 (mod P)

<==> c + dx = 0 (mod P)

QED.

Usefulness?

ฉันยังสงสัยด้วยว่าการทดสอบการหาร (ให้N = 10c + d, แทนที่Nด้วยdx + c) จริง ๆ แล้วจะมีประสิทธิผลในทางปฏิบัติหรือไม่ หรืออย่างน้อยมันก็น่าเชื่อถือแทนที่Nด้วยจำนวนที่น้อยกว่าN(ในค่าสัมบูรณ์)?

สมมติว่าN = 10c + dที่และc >= 0 ดังนั้น0 <= d < 10 10c = N - d <= Nโดยความไม่เสมอภาคของสามเหลี่ยม

|c + dx| <= |c| + |dx| = c + d|x| <= N/10 + d|x|

< N/10 + 10|x| <= N/10 + 10P/2 = N/10 + 5P

ดังนั้นถ้า5P <= 9N/10อย่างนั้น|c + dx| < Nแล้ว

โดยเฉพาะอย่างยิ่งถ้าแล้วN >= 6P |c + dx| < Nดังนั้นให้Pเราเริ่มต้นด้วยการคำนวณ2P, 3P, ... , พร้อมกับ6P xจากนั้นให้Nเราเรียกใช้การทดสอบหารซ้ำ ๆ จนกว่าจะถึงจำนวนน้อยกว่าหรือเท่ากับ6Pและตรวจสอบว่าผลที่ได้คือตัวเลขใด0, P, 2P, ... ,6P ,

(แน่นอนเมื่อใดก็ตามที่เราไปถึงจำนวนลบเราจะแทนที่ด้วยค่าสัมบูรณ์ของมันซึ่งใช้ได้เนื่องจากถ้าqหารด้วยPif และเพียงถ้า(-q)เป็นเท่านั้น)

ปรับปรุงขอบเขต

ผมสังเกตเห็นว่าไม่เคยดูเหมือนจะใกล้เคียงกับ|x|/P 1/2ในความเป็นจริงมันดูเหมือนว่ามันก็มักจะน้อยกว่า1/3... หรือเมื่อตรวจสอบอย่างใกล้ชิดมันมักจะมากใกล้เคียงกับอย่างใดอย่างหนึ่งหรือ1/10 3/10ที่ยิ่งใหญ่ที่สุดเท่าที่เคยมีมาดูเหมือนจะเป็น4/13(ซึ่งเกิดขึ้นเมื่อใดP=13และx=4 ) ทำไมถึงเป็นเช่นนี้?

ให้uเป็นจำนวนเต็มและคิดว่า10u = kP + 1สำหรับจำนวนเต็มบางส่วนkเพื่อuเป็นค่าผกผันของ10, Pโมดูโล จากนั้นเราก็ยังไม่ทราบว่าkเป็นความสำคัญที่จะ10ตั้งแต่k(-P)เทียบเท่ากับโมดูโล110

Now, we know that the inverses of 10 modulo P all differ by multiples of P, so we can take the integer u and either add or subtract multiples of P at will, and the result will always still be an inverse of 10 modulo P. Suppose we choose to subtract P from u: we get

10(u - P) = 10u - 10P = kP + 1 - 10P

10(u - P) = (k - 10)P + 1

In other words, decreasing (respectively, increasing) u by P corresponds to decreasing (increasing) k by 10. We wish to add/subtract multiples of P from u until the left-hand side is minimized in absolute value; but the left-hand side is minimized exactly when the right-hand side is minimized, and so we want to add/subtract 10 from k until the right-hand side is minimized in absolute value.

แต่เรารู้ว่าเรื่องนี้จะเกิดขึ้นเมื่อkอยู่ระหว่าง-5และ5และดังนั้นจึง (ตั้งแต่kค่อนข้างสำคัญในการ10) วิธีนี้kเป็นทั้ง-3, -1, หรือ1 3(นี่คือเนื้อหาของความคิดเห็นของ @ Neil ภายใต้ OP ขอบคุณ Neil! )

ดังนั้นเมื่อ|u|จะลดลง (กล่าวคือu=x) เราจะมีx/P = u/P = k/10 + 1/(10P)ที่kเป็นทั้ง-3, -1, หรือ1 ดังนั้น3 |x|/P <= 3/10 + 1/(10P)อย่างเท่าเทียมกัน, |x| <= (3P + 1)/10.

นอกจากนี้ความไม่เท่าเทียมกันนี้เป็นที่เข้มงวดที่P=11เพราะที่P=11เรามีและx=-1 k=-1ขนาดเล็กที่สุดPซึ่งความเสมอภาคถือเป็นP=13(ที่ไหนx=4และk=3)

Therefore the largest that |x|/P ever gets is 3/10 + 1/(10*13), because P=13 is the first prime for which we have k=3, and among those with k=3, the 1/(10P) term is largest when P is smallest (i.e., at P=13). Therefore, for all P, we also have |x|/P <= 3/10 + 1/130 = 4/13 < 1/3. This explains why in the above code we can initialize at i = P/3 rather than having to start at P/2.

Further, the bounds in the Usefulness section above can now be improved.

Lemma: Let N = 10c + d where c > 0 and 0 <= d <= 9. Then c + d|x| < N/10 + 9(3P + 1)/10. (Note the strict inequality.)

Proof of Lemma: by cases. Case I: d = 0, so N = 10c. Then c + d|x| = c = N/10 < N/10 + 9(3P + 1)/10.

Case II: 0 < d <= 9. Then 10c = N - d < N, so c < N/10. Therefore c + d|x| < N/10 + d|x| <= N/10 + 9|x| <= N/10 + 9(3P + 1)/10. QED.

Thus, if N > 3P (and N = 10c + d as before), then

3P + 1 <= N

9(3P + 1)/10 <= 9N/10

N/10 + 9(3P + 1)/10 <= N

c + d|x| < N/10 + 9(3P + 1)/10 <= N

So, if N > 3P then c + d|x| < N.

Therefore, we only have to find P, 2P and 3P, along with x. Given N > 0, while N > 3P, we replace N by |c + dx|, which decreases N. Eventually we'll get N <= 3P; at that point we stop and check whether N is equal to any of the numbers 0, P, 2P, or 3P.

We can't do better than 3P in general. For example suppose P = 13 and N = 39, so x = 4. Then replacing N by dx + c = 9(4) + 3 leaves N unchanged.


Very nice explanation! You can save a byte by moving -1 outside the parenthesis: 43 bytes
fireflame241

@fireflame241 Thank you very much! I could claim that I left it at 44 just so I could cross it out (though this would be a lie).
mathmandan

1

Whitespace, 92 bytes

Note that this language's syntax consists of only whitespace, so each whitespace character has been prefixed here with S, T, or L (corresponding to Space, Tab, and Linefeed, respectively). These can be removed without losing functionality, but they are included here in order to display it correctly.

S S S L
T   L
T   T   S S S L
T   T   T   S L
S S S S T   T   L
T   S S L
S L
T   S S S T S T L
T   S T T   S L
S T S S S S S S T   S T L
T   S S T   T   S T S S S S T   L
T   S S S S S S T   S T S L
T   S T S T L
S T L
L
L
.

Try it online!




0

Excel, 27 bytes

=0.3/(MOD(A1,5)*2-5)*A1+0.1

Could be entered into Cell as

=.3/(MOD(A1,5)*2-5)*A1+.1

for 25 bytes, but Excel auto-updates.


Actually I think you're allowed to claim the number of bytes you need to enter (but I'm too lazy to check meta).
Neil
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.