การแจกแจง N-Dimensions เวกเตอร์


17

รับจำนวนเต็มบวกk > 1และไม่ใช่จำนวนเต็มลบiสร้างk-tuple (หรือk-dimensional vector) ของจำนวนเต็มไม่เป็นลบ ทุกkแผนที่จากℕเพื่อℕ k , ต้อง bijective นั่นคือทุกการป้อนข้อมูลiควรผลิต tuple ที่แตกต่างกันและทุก tuple iเป็นไปได้ที่จะต้องมีการผลิตโดยการป้อนข้อมูลบางส่วน

คุณสามารถเขียนโปรแกรมหรือฟังก์ชั่น, รับอินพุตผ่าน STDIN (หรือทางเลือกที่ใกล้เคียงที่สุด), อาร์กิวเมนต์บรรทัดคำสั่งหรืออาร์กิวเมนต์ของฟังก์ชันและส่งผลลัพธ์ผ่าน STDOUT (หรือทางเลือกที่ใกล้เคียงที่สุด), ค่าส่งคืนของฟังก์ชันหรือพารามิเตอร์

คุณสามารถใช้รูปแบบรายการแบบแบนที่สะดวกและไม่คลุมเครือสำหรับเอาท์พุท

วิธีการแก้ปัญหาของคุณควรกำหนดไม่มีการ จำกัด เทียมkและiแต่คุณอาจคิดว่าพวกเขาพอดีกับขนาดจำนวนเต็มภาษาพื้นเมือง อย่างน้อยที่สุดคุณต้องสนับสนุนค่าถึง255แม้ว่าขนาดจำนวนเต็มดั้งเดิมของคุณจะเล็กกว่านั้น

สำหรับการใด ๆ1 < k < 32, รหัสของคุณควรสร้างผลลัพธ์ในเรื่องของการวินาที (แน่นอนถ้าคำตอบของคุณไม่สนับสนุนว่าเนื่องจากขนาดใหญ่เพื่อการปกครองก่อนหน้านี้ จำกัด การปรับเปลี่ยนตาม) นี้ควรจะไม่มีปัญหา: มันเป็นไปได้ที่จะแก้ปัญหาความท้าทายเช่นนี้ว่ามันทำงานได้ถึง 2 128ในไม่กี่วินาที แต่วงเงินที่จะมีการหลีกเลี่ยงการตอบที่จริงสำทับจากการที่จะหาผลi < 231i0i

โปรดระบุคำอธิบายเกี่ยวกับการทำแผนที่ที่คุณเลือกและคำตอบว่าทำไมมันถึงเป็น bijective (ไม่จำเป็นต้องพิสูจน์อย่างเป็นทางการ)

นี่คือรหัสกอล์ฟคำตอบที่สั้นที่สุด (เป็นไบต์) ชนะ

ความท้าทายที่เกี่ยวข้อง

คำตอบ:


5

Pyth, 15 12 ไบต์

ms+0_%Q>_zdQ

ชุดทดสอบ

การแปลงของฉันคล้ายกับหนึ่งใน xnor's แต่อยู่ในฐาน 10 ซึ่งทำงานโดยการคลายซิปอินพุตเป็น k แยกตัวเลข:

n = 21003034
k = 3

21003034
 1  3  4    134
2  0  3     203
  0  0        0

ตัวเลขจะถูกจัดเรียงในตำแหน่งที่ลดลงของหลักขวาสุดเพื่อให้การเรียงลำดับทั้งหมดของกลุ่มใด ๆ เป็นไปได้

วิธีการทำงานของรหัสคือเราย้อนกลับอินพุตจากนั้นตัด0, 1, ... k-1ตัวเลขหลักสุดท้ายจากนั้นนำทุก ๆkหลักกลับมาอีกครั้งติด0ที่จุดเริ่มต้นและแปลงเป็น int


4

CJam, 20 ไบต์

q~({4b2fmd2/z2fb~p}*

การทำแผนที่เป็น bijective เนื่องจากมันใช้การทำแผนที่จากคำตอบนี้ k - 1ครั้ง

i kโปรแกรมอ่านอินพุตเป็น ลองใช้ออนไลน์ในล่าม CJam

ความคิด

เราสามารถสร้างการทำแผนที่ bijective f: N → N 2โดยการกำหนดf (i)ดังนี้:

  • แปลงiเป็นอาร์เรย์ของเลขฐานสอง

  • ส่ง0ไปที่อาร์เรย์นี้หากมีจำนวนหลักคี่

  • Deinterleave ปล่อยอาร์เรย์ผลลัพธ์ขึ้นรูปใหม่ในกระบวนการ

  • แปลงอาร์เรย์เหล่านั้นจากฐาน 2 เป็นจำนวนเต็ม กำหนดf 1 (i)และf 2 (i)เป็นผลลัพธ์

เพื่อให้ได้การทำแผนที่ bijective g: N → N 3เราสามารถกำหนดg (n): = (f 1 (i), f 1 (f 2 (i)), f 2 (f 2 (i))) (i)))

เพื่อให้ได้การทำแผนที่ bijective h: N → N 4เราสามารถกำหนดh (i): = (g 1 (i), g 2 (i), f 1 (g 3 (i)), f 2 (g 3 ( ผม)))ฉัน)))

ต่อจากกระบวนการข้างต้นในที่สุดเราก็มาถึงแผนที่ bijective N → N k k

รหัส

q~      e# Read and evaluate all input. This pushes i and k.
({      e# Do k-1 times:
  4b    e#   Convert the integer on the stack (initially i) to base 4.
  2fmd  e#   Replace each base-4 digit d by d/2 and d%2.
  2/    e#   Split into the chunks [d/2 d%2].
  z     e#   Transpose. This collects all quotients in one array and all
        e#   residues in another one.
  2fb   e#   Convert each array from base 2 to integer.
  ~     e#   Dump both integers on the stack.
  p     e#   Print the topmost one.
}*      e#

ความคิดของ xnor ยังให้ 20 ไบต์ (หรือน้อยกว่าถ้าคุณเล่นกอล์ฟได้ดีกว่าที่ฉันเคยทำ): q~2bW%1$Te]/zWf%2fbp(ตรงกันข้ามกับลำดับอินพุต)
Martin Ender

3

CJam, 18 ไบต์

q~({)2bW%_1#p))b}*

มันใช้สูตรที่โง่กว่า

ลองที่นี่ลองได้ที่นี่

คำอธิบาย

q~          e# Read input.
({          e# Repeat k-1 times:
    )       e# Increment the current integer (initially i), to make it positive.
    2b      e# Convert to binary.
    W%      e# Reverse the binary.
            e# The result can be any non-empty binary string without trailing 0s.
    _1#     e# Find the position of the first 1, or the number of initial 0s.
    p       e# Print.
    )       e# Extract the final bit, which is always 1.
            e# An array that can be any binary string is left in the stack.
    )       e# Increment the 1 to make it 2.
    b       e# Convert the binary string to a number using base 2.
            e# Only the number of initial 0s doesn't affect the result,
            e# which is exactly what is printed before.
}*          e# The final integer is printed automatically when the program ends.

โดยสรุปมันแม็พจำนวนเต็มบวกกับ:

  1. จำนวนศูนย์ต่อท้าย
  2. จำนวนเต็มที่เป็นค่าเริ่มต้นที่มีค่าศูนย์ต่อท้ายถูกลบออกย้อนกลับและส่วนท้าย (เริ่มแรกเริ่ม) ลบ 1

3

Python 2, 62

lambda z,k:[int('0'+bin(z)[~i:1:-k][::-1],2)for i in range(k)]

รหัสนี้น่าเกลียดและเล่นกอล์ฟได้ แต่ความคิดนั้นง่ายมาก

แพ็คkการขยายฐานสองให้เป็นหนึ่งเดียวโดยการอ่านkตัวเลขทุกตัวที่มีออฟเซ็ตต่างกัน ตัวอย่างเช่นด้วยk=3อินพุต357จะจับคู่กับ(3,0,7):

101100101 <- 357
  1  0  1 -> 5
 0  0  0  -> 0
1  1  1   -> 7

การบีบอัดตัวเลขกลับเข้าด้วยกันจะทำให้มันกลับด้าน ในการทำเช่นนั้นให้คิดถึงการขยายแบบไบนารีที่มีเลขศูนย์นำหน้า


3

J, 38 28 27 ไบต์

(({.,g^:_1@}.)g=:_ q:>:)~<:

นี่คือคำกริยาโดยปริยาย dyadic ที่ใช้iและkเป็นอาร์กิวเมนต์ซ้ายและขวา ลองมันออนไลน์กับJ.js

ความคิด

เรากำหนดแผนที่f: N → N kโดย f (i): = (α 1 , …α k-1 , p 1 α k … p 2 α k + 1 … - 1)โดยที่⟨p nคือ ลำดับของจำนวนเฉพาะและi + 1 = p 1 α 1 p 2 α 2 .

โดยทฤษฎีบทการคำนวณพื้นฐาน, แผนที่g: N → N ωนิยามโดยg (i): = (α 1 , α 2 , …) (เลขชี้กำลังของการแยกตัวประกอบเฉพาะของi + 1 ) คือ bijective

ตั้งแต่f (i) = (g 1 (i), … g k-1 (i), g -1 (g k (i), g k + 1 (i), …))แผนที่fเป็น bijective เช่น ดี.

รหัส

                            Left argument: i -- Right argument: k
                         <: Decerement k.
(                      )~   Reverse the order of the arguments and apply the
                            dyadic verb inside the parentheses to k-1 and i.
              g=:            Define a monadic helper verb g:
                     >:       Increment its right argument.
                 _ q:         Calculate the exponents of the prime factorization.
                             (implicit) Apply g to i.
(            )               Apply the dyadic verb inside the parentheses to k-1
                             and (g i).
           }.                 Drop the first k-1 elements of (g i)...
          @                   and...
     g^:_1                    apply the inverse of g to the result.
  {.                          Take the first k-1 elements of (g i).
    ,                         Append the rightmost result to the leftmost one.

ทำไมฟังค์ชั่น bijective ของคุณคืออะไร?
xnor

@xnor อย่างน้อยที่สุดสิ่งที่ฉันอธิบายไม่ได้เป็นเพราะฉันได้เปลี่ยนดัชนีสองสามครั้งโดยไม่ได้ตั้งใจ ฉันได้เพิ่มภาพร่างหลักฐาน
เดนนิส

1

Python 2, 72

q=lambda z:z and z%2+2*q(z/4)
g=lambda z,k:1/k*[z]or[q(z)]+g(q(z/2),k-1)

ฟังก์ชั่นqทำหน้าที่เกี่ยวกับตัวเลขไบนารีโดยการบิตทุกวินาทีเริ่มต้นจากจุดสิ้นสุด เป็นผลq(z), q(z>>1)ให้ตัวเลขสองตัวที่มีเลขฐานสองให้สลับzกัน ตัวอย่างเช่น 594 แยกเป็น 12 และ 17

1001010010   <- 594
 0 1 1 0 0   ->  12
1 0 0 0 1    ->  17

นี่เป็นความผิดเพราะเราสามารถรวมตัวเลขกลับเข้าด้วยกันเพื่อกู้คืนหมายเลขเดิม

ฟังก์ชั่นgนี้ใช้k-1เวลาbijection นี้โดยขยายจากองค์ประกอบเดี่ยวไปเป็นคู่ถึงสามเท่า ... ถึงk-tuple แต่ละครั้งองค์ประกอบสุดท้ายจะขยายออกเป็นสององค์ประกอบ สิ่งนี้ทำซ้ำโดยการแมปอินพุตกับคู่ผ่าน bijection การรับองค์ประกอบแรกของคู่สำหรับรายการแรกของเอาต์พุตและใช้ฟังก์ชันซ้ำกับk-1องค์ประกอบที่สองเพื่อสร้างรายการที่เหลือ


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