คำนวณค่า p-adic norm ของจำนวนตรรกยะ


11

คำนวณค่า p-adic norm ของจำนวนตรรกยะ

เขียนฟังก์ชั่นหรือโปรแกรมที่ใช้จำนวนเต็ม 3 จำนวนm,n,p(ซึ่งpเป็นจำนวนเฉพาะที่เป็นค่าบวก) เป็นอินพุตซึ่งส่งเอาต์พุต p-adic norm (แทนด้วย|m/n|_p) เป็นส่วน (ลดลงอย่างสมบูรณ์) แฟร์มาต์เป็นที่รู้จักกันว่ามีกำไรเพียงเล็กน้อยเท่านั้น แต่สิ่งที่ไม่เป็นที่รู้จักคือเขามีหน้าจอคอมพิวเตอร์ขนาดเล็กมาก ดังนั้นพยายามทำให้รหัสสั้นที่สุดเท่าที่จะเป็นไปได้เพื่อให้พอดีกับหน้าจอของแฟร์มาต์!

คำนิยาม

กำหนดที่สำคัญpทุกส่วนm/nสามารถเขียนได้โดยไม่ซ้ำกัน (ไม่สนใจสัญญาณ) เป็น(a/b)* p^eเช่นที่eเป็นจำนวนเต็มและpแบ่งค่ามิได้a บรรทัดฐาน p- อำนวยการของการมี มีกรณีพิเศษคือถ้าส่วนเป็น 0:bm/np^-e|0|_p = 0

รูปแบบผลลัพธ์จะต้องx/y(เช่น1/3สำหรับจำนวนเต็มทั้งสอง10หรือเท่ากัน10/1ได้รับอนุญาตสำหรับจำนวนลบจะต้องมีเครื่องหมายลบนำหน้าเช่น-1/3)

รายละเอียด

โปรแกรมจะต้องใช้ stdin / stdout หรือเพียงแค่ประกอบด้วยฟังก์ชั่นที่ส่งกลับจำนวนเหตุผลหรือสตริง คุณต้องสมมติว่าอินพุตm/nไม่ได้ลดลงอย่างสมบูรณ์ คุณสามารถสันนิษฐานว่าpเป็นนายก โปรแกรมจะต้องสามารถประมวลผลจำนวนเต็มตั้งแต่-2^28ถึง2^28และไม่ควรใช้เวลามากกว่า 10 วินาที

ไม่อนุญาตให้สร้างการแยกตัวประกอบและฟังก์ชันตรวจสอบเฉพาะเช่นเดียวกับที่สร้างขึ้นในการแปลงฐานและฟังก์ชันในตัวที่คำนวณค่า p-adic หรือบรรทัดฐาน

ตัวอย่าง (ถูกขโมยจากวิกิพีเดีย ):

x = m/n = 63/550 = 2^-1 * 3^2 * 5^-2 * 7 * 11^-1
|x|_2 = 2
|x|_3 = 1/9
|x|_5 = 25
|x|_7 = 1/7
|x|_11 = 11
|x|_13 = 1

เรื่องไม่สำคัญที่น่าสนใจ

(ไม่จำเป็นต้องรู้ / อ่านสำหรับความท้าทายนี้ แต่อาจจะดีในการอ่านเป็นแรงจูงใจ)

(โปรดแก้ไขให้ฉันด้วยถ้าฉันใช้คำผิดหรืออย่างอื่นไม่ถูกต้องฉันไม่คุ้นเคยกับการพูดภาษาอังกฤษ)

หากคุณพิจารณาสรุปตัวเลขเป็นเขตข้อมูลแล้วบรรทัดฐาน p- d_p(a,b) = |a-b|_pอำนวยการเจือจางเมตริก จากนั้นคุณสามารถกรอกข้อมูลในฟิลด์นี้โดยคำนึงถึงตัวชี้วัดนี้ซึ่งหมายความว่าคุณสามารถสร้างฟิลด์ใหม่ที่ลำดับ cauchy ทั้งหมดมาบรรจบกันซึ่งเป็นสมบัติเชิงทอพอโลยีที่ดี (ซึ่งเช่นหมายเลขที่ไม่มีเหตุผล แต่ไม่มี reals ทำ) ตัวเลข p-adicเหล่านี้เป็นตามที่คุณอาจเดาได้ใช้ทฤษฎีจำนวนมาก

ผลลัพธ์ที่น่าสนใจอีกอย่างคือทฤษฎีบทของ Ostrowskiซึ่งโดยพื้นฐานแล้วบอกว่าค่าสัมบูรณ์ใด ๆ (ตามที่นิยามไว้ด้านล่าง) ในจำนวนตรรกยะคือหนึ่งในสามของดังต่อไปนี้:

  • เรื่องไม่สำคัญ: |x|=0 iff x=0, |x|=1 otherwise
  • มาตรฐาน (ของจริง): |x| = x if x>=0, |x| = -x if x<0
  • p-adic (ตามที่เรากำหนดไว้)

ค่าสัมบูรณ์ / ตัวชี้วัดเป็นเพียงทั่วไปของสิ่งที่เราพิจารณาเป็นระยะ ค่าสัมบูรณ์เป็น|.|ไปตามเงื่อนไขต่อไปนี้:

  • |x| >= 0 and |x|=0 if x=0
  • |xy| = |x| |y|
  • |x+y| <= |x|+|y|

โปรดทราบว่าคุณสามารถสร้างเมตริกได้อย่างง่ายดายจากค่าสัมบูรณ์และในทางกลับกัน: |x| := d(0,x)หรือd(x,y) := |x-y|ดังนั้นจึงเกือบจะเหมือนกันถ้าคุณสามารถเพิ่ม / ย่อ / ขยาย / คูณ (นั่นคือในโดเมนที่สมบูรณ์) แน่นอนคุณสามารถกำหนดเมตริกในชุดทั่วไปเพิ่มเติมโดยไม่มีโครงสร้างนี้


ฉันคิดว่าPadicNormฟังก์ชั่นของ Mathematica นั้นออกมาแล้วเช่นกัน? : P
Alex A.

คุณถือว่าถูกต้อง / เหมือนกัน (อันไหนถูกใช้ที่นี่?)
ข้อบกพร่อง

เว้นแต่ว่าส่วนคุณสมบัติที่น่าสนใจนั้นมีประโยชน์สำหรับการทำสิ่งที่ท้าทายให้เสร็จฉันก็บอกได้เลยว่ามันดีกว่าที่จะเชื่อมโยงไปยังข้อมูลนั้นสำหรับผู้ที่สนใจ มิฉะนั้นจะทำให้กลุ่มโพสต์ไม่จำเป็น
Alex A.

เพื่อให้ชัดเจนผลลัพธ์ควรเป็นอะไร|x|_11 = 11ใช่ไหม หรือไม่11เป็นไร และมันต้องจัดการกับx=0คดีนี้หรือไม่?
เกลน O

@GlenO ที่ถูกต้องก็ไม่ต้องจัดการกับx=0กรณีเช่นนี้คุณสามารถส่งออก11เช่นเดียวกับแต่คุณจะได้ไม่ต้องพิมพ์11/1 |x|_11
ข้อบกพร่อง

คำตอบ:


3

Julia, 94 80 75 ไบต์

f(m,n,p)=(k=gcd(m,n)
g(m)=m%p>0?g(m÷p)p:1
m!=0?print(g(n÷k),/,g(m÷k)):0)

หมายเหตุ: การใช้ linefeeds แทนเครื่องหมายอัฒภาคเพื่อการอ่าน - จะทำงานเหมือนกัน

นี้จะค่อนข้างง่าย - The g(m,n)ฟังก์ชั่นใช้เรียกซ้ำและส่วนที่เหลือ ( %) เพื่อแยกp^nปัจจัยจากการป้อนข้อมูลmด้วยn=1เป็นค่าเริ่มต้นแล้วคูณด้วยในขั้นตอนของการเรียกซ้ำในแต่ละเพื่อให้การส่งออกจะได้รับp p^nรหัสนี้ใช้กับn/gcd(m,n)และจากนั้นm/gcd(m,n)จะได้รับการแสดงออกที่เหมาะสม k=gcd(m,n)ใช้เพื่อหลีกเลี่ยงการคำนวณgcd(m,n)สองครั้งเพื่อบันทึกอักขระ m!=0เป็นการทดสอบเพื่อจัดการกรณีที่x=0คือการทดสอบที่จะจัดการกับกรณีที่

เอาท์พุทเป็นรูปแบบN/1หรือ1/Nตามความเหมาะสมที่จะเป็นNp^e


1

J, 35 34 ไบต์

(,'/'&,)&":/@(%+./)@(]<.^+.|.@])x:

นี่คือคำกริยาไบนารีที่ใช้ไพร์มpเป็นอาร์กิวเมนต์ซ้ายของมันและอาร์เรย์m nเป็นอาร์กิวเมนต์ที่ถูกต้อง มันก็จะพิมพ์เฉือน/และผลตอบแทนถ้า0/1 m = 0ใช้มันแบบนี้:

  f =: (,'/'&,)&":/@(%+./)@(]<.^+.|.@])x:
  5 f 63 550
25/1

คำอธิบาย

การx:เปิดใช้ความแม่นยำที่เพิ่มขึ้นเนื่องจากเราจัดการกับตัวเลขที่มีขนาดใหญ่ ส่วนที่เหลือของรหัสทำงานดังนี้:

(,'/'&,)&":/@(%+./)@(]<.^+.|.@])
                        ^         Power: this gives the array p^n p^m
                         +.       Take element-wise GCD with
                           |.@]   the rotated array n m; this gives
                                  the largest powers of p that divide n and m
                      <.          Take element-wise minimum with
                     [            The array m n to handle the m=0 case correctly
              %+./                Divide this array by its GCD to get it to lowest terms
        &":/                      Convert both elements to strings
 ,'/'&,                           Insert the slash '/' between them

0

CJam, 42 ไบต์

q~)\_:*g_sW<o@*28#f{{{_@\%}h;}:G~}_~Gf/'/*

เสร็จสิ้นการนี้กับข้อผิดพลาด (หลังจากพิมพ์ 0) สำหรับการป้อนข้อมูล 0. ลองออนไลน์ในล่าม CJam


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.