ฟังก์ชั่นการนับเหตุผล


11

สร้างฟังก์ชั่นที่รับจำนวนธรรมชาติ (เริ่มต้นจาก 0 รวม) และส่งกลับคู่ของจำนวนเต็มบวกซึ่งเป็นตัวเศษและส่วนตามลำดับ ใช้การสำรวจเส้นทางในแนวทแยง หมายเลขที่นับก่อนหน้านี้จะต้องข้าม (คุณสามารถจดจำชุดของค่าที่ข้ามได้)

แผนภาพ:

ป้อนคำอธิบายรูปภาพที่นี่

สีแดงเป็นค่าที่ข้าม

ค่า:

  • f (0) = 1, 1
  • f (1) = 2, 1
  • f (2) = 1, 2
  • f (3) = 1, 3
  • f (4) = 3, 1 (สังเกตการข้าม)
  • f (5) = 4, 1
  • f (6) = 3, 2
  • f (7) = 2, 3
  • f (8) = 1, 4
  • f (9) = 1, 5
  • f (10) = 5, 1 (สังเกตการข้าม)

คุณอาจใช้โครงสร้างข้อมูล Rational และการดำเนินการหากมี รหัสที่สั้นที่สุดชนะ


1
จำนวนของจำนวนตรรกยะที่นับได้ในแต่ละเส้นทแยงมุมคือฟังก์ชัน totient ของผลรวมทั่วไปของเส้นทแยงมุมนั้น
Leun Nun

ฉันรู้ว่าความท้าทายนี้เก่า แต่มีคำตอบสั้นกว่าคำตอบที่ยอมรับดังนั้นคุณอาจต้องการยอมรับอีกครั้ง
แยกผลไม้

คำตอบ:


4

J, 41 36 ตัวอักษร

รับจำนวนเต็มและคืนค่าเวกเตอร์ที่ประกอบด้วยจำนวนเต็มสองจำนวน วิธีแก้ปัญหาแรกของฉันที่ไม่ได้มีนัยใด ๆ

{3 :'~.;<`(<@|.)/.(,%+.)"0/~1+i.1+y'

นี่คือโซลูชันที่มีการเว้นวรรคแทรกตามความเหมาะสม:

{ 3 : '~. ; <`(<@|.)/. (, % +.)"0/~ 1 + i. 1 + y'

คำอธิบาย:

  1. x (, % +.) y- เวกเตอร์ที่มีความยาว 2 แสดงถึงเศษส่วนที่มีตัวเศษxและตัวyส่วนลดให้เหลือตัวเล็กที่สุด
  2. 1 + i. 1 + y–a เวกเตอร์ของจำนวนเต็มตั้งแต่1ถึงy + 1
  3. (, % +.)"0/~ 1 + i. 1 + yเมทริกซ์ -a เศษส่วนลดลงทั้งหมดที่มีการยกเลิกการลดส่วนและเศษในช่วงจากไป1y + 1
  4. <`(<@|.)/. y- อาเรย์ของเส้นทแยงมุมเอียงของเมทริกซ์yซึ่งกันและกันในแนวทแยงพลิก
  5. ~. ; y- อาร์เรย์ diagonals ยุบลงในเวกเตอร์ขององค์ประกอบโดยลบรายการที่ซ้ำกัน
  6. x { y- รายการที่อยู่xในตำแหน่งy
  7. (u v) y-The y u v yเดียวกับ ในกรณีการใช้งานเฉพาะนี้uคือ{และvเป็น3 : '~. ; <`(<@|.)/. (, % +.)"0/~ 1 + i. 1 + y'


8

Haskell, 78 ตัวอักษร

q(r,f)=[(r-b,b)|b<-f[1..r-1],r`gcd`b==1]
d=reverse:id:d
f=((zip[2..]d>>=q)!!)

วิ่งตัวอย่าง:

> map f [0..10]
[(1,1),(2,1),(1,2),(1,3),(3,1),(4,1),(3,2),(2,3),(1,4),(1,5),(5,1)]
> f 100
(17,1)
> f 1000
(3,55)

  • แก้ไข: (100 → 87) โง่ฉันแค่ทดสอบ gcd ก็พอ!
  • แก้ไข: (87 → 85) เคล็ดลับที่ชาญฉลาดด้วยcycleและฟังก์ชั่นเพื่อสลับแถว
  • แก้ไข: (85 → 82) แทนที่cycleด้วยรายการที่ไม่มีที่สิ้นสุดที่สร้างขึ้นด้วยมือd
  • แก้ไข: (82 → 78) ใช้gcdข้อมูลประจำตัวที่แนะนำโดยMatías

ตามคำจำกัดความgcd (r-b) b == gcd r bและคุณสามารถโกนอักขระได้อีกสี่ตัว
Matías Giovannini

3

Python 144 ตัวอักษร

def F(i):
 r,d,z=[1],1,[]
 while z[:i]==z:z+=[(x,y)for x,y in zip(r[::d],r[::-d])if all(x%j+y%j for j in r[1:])];d=-d;r+=[r[-1]+1]
 return z[i]


2

OCaml + แบตเตอรี่182 168 ตัวอักษร

นี่คือสิ่งที่จะเป็นธรรมชาติใน Haskell แต่แทบจะเป็นไปไม่ได้ใน OCaml:

open LazyList
let rec r(i,j)=lazy(let a,b=if(i+j)mod 2=0then i,j else j,i in
Cons((a,b),filter(fun(c,d)->a*d<>c*b)(r(if j=1 then 1,i+1else i+1,j-1))))
let f=nth(r(1,1))

แก้ไข:เส้นทแยงมุมไม่จำเป็น


0

Perl 6 , 75 ไบต์

{(({|(1…($+=2)…1)}…*)Z/(1,{|(1…(($||=1)+=2)…1)}…*)).unique[$_]}

ทดสอบมัน

สิ่งนี้จะสร้างลำดับของค่าที่มีเหตุผลทั้งหมดโดยทั่วไปจะหยุดเมื่อมีการสร้างค่าดัชนีเท่านั้น

(ขึ้นอยู่กับความท้าทายของฉันในการเล่นกอล์ฟ )

ขยาย:

{  # bare block lambda with implicit parameter $_

  (
      ( # sequence of numerators

        {
          |( # slip into outer sequence (flatten)

            1      # start at one
            
            (
              $    # state variable
              += 2 # increment it by two each time this block is called
            )
            
            1      # finish at one
          )

        }
         * # never stop generating values
      )


    Z/   # zip using &infix:« /  » (generates Rats)


      ( # sequence of denominators

        1,  # start with an extra one

        {
          |( # slip into outer sequence (flatten)

            1
            
            (
              ( $ ||= 1 ) # state variable that starts with 1 (rather than 0)
              += 2        # increment it by two each time this is called
            )
            
            1
          )
        }
         * # never stop generating values
      )


  ).unique                # get only the unique values
  .[ $_ ]                 # index into the sequence
}

({1…($+=2)…1}…*)สร้างลำดับอนันต์ของ numerators ( |(…)จะใช้ดังกล่าวข้างต้นให้เรียบ)

(1 2 1)
(1 2 3 4 3 2 1)
(1 2 3 4 5 6 5 4 3 2 1)
(1 2 3 4 5 6 7 8 7 6 5 4 3 2 1)
(1 2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 3 2 1)

(1,{1…(($||=1)+=2)…1}…*) สร้างลำดับของตัวส่วน

1
(1 2 3 2 1)
(1 2 3 4 5 4 3 2 1)
(1 2 3 4 5 6 7 6 5 4 3 2 1)
(1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 1)
(1 2 3 4 5 6 7 8 9 10 11 10 9 8 7 6 5 4 3 2 1)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.