หมายเลขปันส่วนบวก


14

ตัวเลขเชิงบวกสามารถแสดงให้เห็นว่าสามารถนับได้ด้วยกระบวนการต่อไปนี้:

  1. ศูนย์มีลำดับ 0
  2. จัดเรียงตัวเลขอื่น ๆ ในตารางเพื่อให้แถว a คอลัมน์ b มี / b
  3. พล็อตเส้นทแยงมุมซิกแซกด้านบนขวาไปซ้ายล่าง
  4. ดำเนินการนับตัวเลขที่ไม่ซ้ำกันพบตาม zig-zag

นี่คือรูปภาพของซิกแซก:

เริ่มต้นที่ 1/1 เลื่อนไปทางขวาก่อน

ดังนั้นตัวเลขที่พบเป็นไปตามลำดับ

1/1, 2/1, 1/2, 1/3, 2/2, 3/1, 4/1, 3/2, 2/3, 1/4, 1/5, 2/4, 3/3, 4/2, 5/1, 6/1, 5/2, 4/3, 3/4, 2/5, 1/6, 1/7, 2/6, 3/5, 4/4, 5/3 ...

และตัวเลขที่เรียบง่ายและไม่เหมือนใครที่พบก็คือ

1, 2, 1/2, 1/3, 3, 4, 3/2, 2/3, 1/4, 1/5, 5, 6, 5/2, 4/3, 3/4, 2/5, 1/6, 1/7, 3/5, 5/3, ...

ท้าทาย:

  • ให้pและqจำนวนเต็มมากกว่าศูนย์สองเอาท์พุทหมายเลขลำดับของ p / q
  • p และ q ไม่จำเป็นต้องเป็นแบบ co-prime
  • รหัสที่สั้นที่สุดชนะ
  • ช่องโหว่มาตรฐานเป็นสิ่งต้องห้าม

กรณีทดสอบ:

นี่คือจำนวนตรรกติ 24 ตัวแรกที่พบและผลลัพธ์ที่ต้องการสำหรับแต่ละ:

1/1: 1
2/1: 2
1/2: 3
1/3: 4
2/2: 1
3/1: 5
4/1: 6
3/2: 7
2/3: 8
1/4: 9
1/5: 10
2/4: 3
3/3: 1
4/2: 2
5/1: 11
6/1: 12
5/2: 13
4/3: 14
3/4: 15
2/5: 16
1/6: 17
1/7: 18
2/6: 4
3/5: 19

และสำหรับกรณีทดสอบเพิ่มเติมต่อไปนี้คือจำนวนตรรกยะเชิงบวก 200 ลำดับแรก:

1, 2, 1/2, 1/3, 3, 4, 3/2, 2/3, 1/4, 1/5, 
5, 6, 5/2, 4/3, 3/4, 2/5, 1/6, 1/7, 3/5, 5/3, 
7, 8, 7/2, 5/4, 4/5, 2/7, 1/8, 1/9, 3/7, 7/3, 
9, 10, 9/2, 8/3, 7/4, 6/5, 5/6, 4/7, 3/8, 2/9, 
1/10, 1/11, 5/7, 7/5, 11, 12, 11/2, 10/3, 9/4, 8/5, 
7/6, 6/7, 5/8, 4/9, 3/10, 2/11, 1/12, 1/13, 3/11, 5/9, 
9/5, 11/3, 13, 14, 13/2, 11/4, 8/7, 7/8, 4/11, 2/13, 
1/14, 1/15, 3/13, 5/11, 7/9, 9/7, 11/5, 13/3, 15, 16, 
15/2, 14/3, 13/4, 12/5, 11/6, 10/7, 9/8, 8/9, 7/10, 6/11, 
5/12, 4/13, 3/14, 2/15, 1/16, 1/17, 5/13, 7/11, 11/7, 13/5, 
17, 18, 17/2, 16/3, 15/4, 14/5, 13/6, 12/7, 11/8, 10/9, 
9/10, 8/11, 7/12, 6/13, 5/14, 4/15, 3/16, 2/17, 1/18, 1/19, 
3/17, 7/13, 9/11, 11/9, 13/7, 17/3, 19, 20, 19/2, 17/4, 
16/5, 13/8, 11/10, 10/11, 8/13, 5/16, 4/17, 2/19, 1/20, 1/21, 
3/19, 5/17, 7/15, 9/13, 13/9, 15/7, 17/5, 19/3, 21, 22, 
21/2, 20/3, 19/4, 18/5, 17/6, 16/7, 15/8, 14/9, 13/10, 12/11, 
11/12, 10/13, 9/14, 8/15, 7/16, 6/17, 5/18, 4/19, 3/20, 2/21, 
1/22, 1/23, 5/19, 7/17, 11/13, 13/11, 17/7, 19/5, 23, 24, 
23/2, 22/3, 21/4, 19/6, 18/7, 17/8, 16/9, 14/11, 13/12, 12/13, 
11/14, 9/16, 8/17, 7/18, 6/19, 4/21, 3/22, 2/23, 1/24, 1/25 

ส่งเสียงคำถามผกผันที่การย้ายครั้งแรกไม่ทำงานดังนั้นคุณไม่สามารถใช้คำตอบเพื่อสร้างกรณีทดสอบเพิ่มเติม


ฉันสงสัยว่ามีรูปแบบการกำหนดหมายเลขทางเลือกอื่นที่ทำให้รหัสสั้นลง
qwr

1
ตัวเศษของเศษส่วน: oeis.org/A157807ตัวส่วน: oeis.org/A157813ไม่ตรงกับลำดับของลำดับ: oeis.org/ …
qwr

ฉันเห็น. คุณต้องลดเศษส่วนแล้วนับ ไม่ใช่ซิกแซกเท่านั้น
ดอนจ้า

คำตอบ:


4

เยลลี่ ,  21  20 ไบต์

อาจเป็นไปได้ที่จะเอาชนะได้ด้วยจำนวนไบต์โดยใช้คณิตศาสตร์ที่ฉลาดบางอย่าง ...

:g/
ǵSRRUĖ€UÐeẎÇ€Qi

การเชื่อมโยงเอกยอมรับรายการซึ่งจะส่งกลับจำนวนธรรมชาติที่ได้รับมอบหมาย[p,q]p/q

ลองออนไลน์! หรือดูการทดสอบในตัว

อย่างไร?

โน้ตตัวแรกที่N THเส้นทแยงมุมพบมีทั้งหมดของตัวเลขเหตุผลของตารางซึ่งผลรวมของเศษและส่วนเท่ากับN + 1ได้รับเพื่อให้ฟังก์ชั่นซึ่งจะช่วยลดเป็น[p,q]คู่รูปแบบที่ง่าย ( [p/gcd(p,q),q/gcd(p,q)]) เราสามารถสร้างเส้นทแยงมุมเท่า ต้องการ *, ลดรายการทั้งหมด, ไม่ต้องทำซ้ำและค้นหาดัชนีของอินพุตที่ง่ายขึ้น

* อันที่จริงอีกหนึ่งที่นี่เพื่อบันทึกไบต์

:g/ - Link 1, simplify a pair: list of integers, [a, b]
  / - reduce using:
 g  - Greatest Common Divisor -> gcd(a, b)
:   - integer division (vectorises) -> [a/gcd(a,b), b/gcd(a,b)]

ǵSRRUĖ€UÐeẎÇ€Qi - Main Link: list of integers, [p, q]
Ç                - call last Link as a monad (simplify)
 µ               - start a new monadic chain (call that V)
  S              - sum -> the diagonal V will be in plus one
   R             - range -> [1,2,3,...,diag(V)+1]
    R            - range (vectorises) -> [[1],[1,2],[1,2,3],...,[1,2,3,...,diag(V)+1]]
     U           - reverse each       -> [[1],[2,1],[3,2,1],[diag(V)+1,...,3,2,1]]
      Ė€         - enumerate €ach     -> [[[1,1]],[[1,2],[2,1]],[[1,3],[2,2],[3,1]],[[1,diag(V)+1],...,[diag(V)-1,3],[diag(V),2],[diag(V)+1,1]]]
         Ðe      - apply only to the even indexed items:
        U        -   reverse each     -> [[[1,1]],[[2,1],[1,2]],[[1,3],[2,2],[3,1]],[[4,1],[3,2],[2,3],[1,4]],...]
           Ẏ     - tighten            -> [[1,1],[2,1],[1,2],[1,3],[2,2],[3,1],[4,1],[3,2],[2,3],[1,4],...]
            Ç€   - for €ach: call last Link as a monad (simplify each)
                 -                    -> [[1,1],[2,1],[1,2],[1,3],[1,1],[3,1],[4,1],[3,2],[2,3],[1,4],...]
              Q  - de-duplicate       -> [[1,1],[2,1],[1,2],[1,3],[3,1],[4,1],[3,2],[2,3],[1,4],...]
               i - index of V in that list

3

Perl 6 ,  94  90 ไบต์

->\p,\q{(({|(1…($+=2)…1)}…*)Z/(1,{|(1…(($||=1)+=2)…1)}…*)).unique.first(p/q,:k)+1}

ทดสอบมัน

{(({|(1…($+=2)…1)}…*)Z/(1,{|(1…(($||=1)+=2)…1)}…*)).unique.first($^p/$^q):k+1}

ทดสอบมัน

สิ่งนี้จะสร้างลำดับของค่าทั้งหมดและจะหยุดเมื่อพบการแข่งขัน

ขยาย:

{  # bare block lambda with placeholder parameters $p,$q

  (
      ( # 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
  .first( $^p / $^q ) # find the first one that matches the input
  :k                  # get the index instead (0 based)
  + 1                 # add one               (1 based)
}

({1…($+=2)…1}…*)สร้างลำดับที่ไม่มีที่สิ้นสุดของตัวเลข ( |(…)ใช้ด้านบนเพื่อทำให้แบน)

(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)

3

Python 2 , 157 144 137 134 126 125 ไบต์

def f(p,q):a=[((j-i)/(i+1.))**(j%-2|1)for j in range(p-~q)for i in range(j)];return-~sorted(set(a),key=a.index).index(p*1./q)

ลองออนไลน์!

บันทึก 4 ไบต์เนื่องจากMr. Xcoder ; 1 ไบต์จากJonathon Frech

ดังที่นาย Xcoder กล่าวไว้เราสามารถทำได้ดีขึ้นเล็กน้อยใน Python 3 ตั้งแต่สิ่งอื่น ๆ ค่าเริ่มต้นของการแบ่งจำนวนเต็มเพื่อผลการลอยตัวและเราสามารถแตกไฟล์ได้ง่ายขึ้นlist:

Python 3 , 117 ไบต์

def f(p,q):a=[((j-i)/-~i)**(j%-2|1)for j in range(p-~q)for i in range(j)];return-~sorted({*a},key=a.index).index(p/q)

ลองออนไลน์!


128 ไบต์ (-6)โดยการแลกเปลี่ยนส่วนและการใช้และ**(j%-2|1) p-~q
นาย Xcoder

@นาย. Xcoder: วันนี้คุณเกี่ยวกับโมดูโลเชิงลบในวันนี้! :) ฉันคิดว่าฉันยังคงต้องการ+1ที่สิ้นสุดตั้งแต่1,1'ต้อง' ให้ไม่ได้1 0
Chas Brown

125 ไบต์
Jonathan Frech

124 ไบต์ :) ใช่โมดูโลเชิงลบจะเป็นประโยชน์จริง ๆ !
นาย Xcoder

ที่จริงแล้ว117 ไบต์ใน Python 3
Mr. Xcoder

3

งูหลาม 3 ,157, 146, 140, 133 ไบต์

def f(p,q):a=[(i+i-abs(j-i-i))/(abs(j-i-i+.5)+.5)for i in range(p+q)for j in range(4*i)];return sorted(set(a),key=a.index).index(p/q)

ลองออนไลน์!

ได้รับรางวัล 11 ไบต์ขอบคุณJonathan Frech

ได้รับรางวัลอีก 6 ไบต์และ 7 ขอบคุณChas Brown


1
146 ไบต์
Jonathan Frech

140 ไบต์
Chas Brown

@bobrobbob: ยินดีต้อนรับสู่ PPCG! ฉันไม่แน่ใจว่าอัลกอริทึมของคุณทำงานอย่างไร (แม้ว่าจะชัดเจน); แต่การทดลองดูเหมือนว่าคุณสามารถบันทึกไบต์บางมากขึ้นโดยการแทนที่ด้วยrange(max(p,q)+1) range(p+q)
Chas Brown

1
คุณสามารถบันทึกไบต์บางมากขึ้นโดยใช้แทน{*a} set(a)
นาย Xcoder

2

J, 41 , 35 , 30 ไบต์

-11 ไบต์ขอบคุณ FrownyFrog

%i.~0~.@,@,[:]`|./.[:%/~1+i.@*

ลองออนไลน์!

โพสต์ 41 ไบต์ต้นฉบับพร้อมคำอธิบาย

%>:@i.~[:([:~.@;[:<@|.`</.%"1 0)~(1+i.@*)

ungolfed

% >:@i.~ [: ([: ~.@; [: <@|.`</. %"1 0)~ 1 + i.@*

คำอธิบาย

                  +
                  | Everything to the right of this
                  | calculates the list
p (left arg)      |                                      create the
divided by q      |                                      diagonals.  yes,
      (right)     |                                     +this is a         +create this list
   |              |        ++ finally rmv ^alternately  |primitive ADVERB  |1..(p*q), and pass
   |   + the index          | the boxes,  |box, or      |in J              |it as both the left
   |   | of that  |         | and remove  |reverse and  |                  |and right arg to the
   |   | in the   |         | any dups    |box, each    |                  |middle verb, where each
   |   | list on  |         |             |diagonal     |                  |element will divide the
   |   | the right|         |             |             |       +----------+entire list, producing
   |   | plus 1   |         |             |             |       |          |the undiagonalized grid
   |   |          |         |             |             |       |          |
   |   |          |         |             |             |       |          |
   |   |          +         |             |             |       |          |
  ┌+┬──|──────────┬─────────|─────────────|─────────────|───────|──────────|─────────────┐
  │%│┌─+───────┬─┐│┌──┬─────|─────────────|─────────────|───────|────────┬─|────────────┐│
  │ ││┌──┬─┬──┐│~│││[:│┌────|─────────────|─────────────|───────|─────┬─┐│┌+┬─┬────────┐││
  │ │││>:│@│i.││ │││  ││┌──┬|───────┬─────|─────────────|───────|────┐│~│││1│+│┌──┬─┬─┐│││
  │ ││└──┴─┴──┘│ │││  │││[:│+──┬─┬─┐│┌──┬─|─────────────|─┬─────|───┐││ │││ │ ││i.│@│*││││
  │ │└─────────┴─┘││  │││  ││~.│@│;│││[:│┌|───────────┬─+┐│┌─┬─┬+──┐│││ │││ │ │└──┴─┴─┘│││
  │ │             ││  │││  │└──┴─┴─┘││  ││+────────┬─┐│/.│││%│"│1 0││││ ││└─┴─┴────────┘││
  │ │             ││  │││  │        ││  │││┌─┬─┬──┐│<││  ││└─┴─┴───┘│││ ││              ││
  │ │             ││  │││  │        ││  ││││<│@│|.││ ││  ││         │││ ││              ││
  │ │             ││  │││  │        ││  │││└─┴─┴──┘│ ││  ││         │││ ││              ││
  │ │             ││  │││  │        ││  ││└────────┴─┘│  ││         │││ ││              ││
  │ │             ││  │││  │        ││  │└────────────┴──┘│         │││ ││              ││
  │ │             ││  │││  │        │└──┴─────────────────┴─────────┘││ ││              ││
  │ │             ││  ││└──┴────────┴────────────────────────────────┘│ ││              ││
  │ │             ││  │└──────────────────────────────────────────────┴─┘│              ││
  │ │             │└──┴──────────────────────────────────────────────────┴──────────────┘│
  └─┴─────────────┴──────────────────────────────────────────────────────────────────────┘

ลองออนไลน์!


35:1+~.@;@([:<@|.`</.%~/~)@(1+i.@*)i.%
FrownyFrog

ขอบคุณมาก ๆ! ฉันจะอัปเดตอย่างเต็มที่ในภายหลังเนื่องจากต้องมีการทำคำอธิบายซ้ำ ...
Jonah

และ 30:%i.~0~.@,@,[:]`|./.[:%/~1+i.@*
FrownyFrog

มันฉลาดใช้ 0 และ ~ เพื่อหลีกเลี่ยงการชกมวยและการเพิ่มฉันรักมัน
Jonah

2

Python 3, 121 ไบต์

import math
def o(x,y):
 p=q=n=1
 while x*q!=p*y:a=p+q&1;p+=1+a*~-~-(p<2);q+=1-~-a*~-~-(q<2);n+=math.gcd(p,q)<2
 return n

2

สนิม 244 ไบต์

ฉันสร้างสูตรง่ายๆที่จะหา "ธรรมดา" ลำดับของ "ธรรมดา" ที่คดเคี้ยวไปมาโดยไม่มีข้อ จำกัด ของปริศนาโดยใช้หมายเลขสามเหลี่ยมสูตร: https://www.mathsisfun.com/algebra/triangular-numbers.html สิ่งนี้ได้รับการดัดแปลงด้วย modulo 2 เพื่ออธิบายการเคลื่อนที่ของซิกแซกในแต่ละทิศทางของเส้นทแยงมุมในปริศนา นี่คือฟังก์ชั่น h ()

จากนั้นสำหรับเคล็ดลับหลักของปริศนานี้: วิธีการ 'ไม่นับ' ค่าการทำซ้ำบางอย่างเช่น 3/3 เทียบกับ 1/1, 4/2 เทียบกับ 2/1 ในเส้นทางซิกแซก ฉันวิ่งไปที่ตัวอย่าง 1-200 และสังเกตเห็นความแตกต่างระหว่างตัวนับสามเหลี่ยมซิกแซกธรรมดาและปริศนาที่ต้องการมีรูปแบบ รูปแบบของตัวเลข "หายไป" คือ 5, 12, 13, 14, 23, ฯลฯ ซึ่งส่งผลให้ OEIS ได้รับความนิยม มันเป็นสิ่งหนึ่งที่อธิบายโดย Robert A Stump ที่ https://oeis.org/A076537เพื่อให้หมายเลข "deduplicate" เช่น 3/3, 4/2 และ 1/1 คุณสามารถตรวจสอบว่า GCD> 1 สำหรับ x, y ของลำดับก่อนหน้า "ทั้งหมด" ในซิกแซก นี่คือลูป 'for' และ g () ซึ่งเป็น gcd

ฉันเดาด้วย gd builtin มันจะสั้นกว่า แต่ฉันไม่สามารถหาได้ง่ายมาก (ฉันเป็นประเภทใหม่ที่ Rust and Integer สับสนฉัน) และฉันชอบความจริงที่ว่าอันนี้ใช้เลขคณิตเลขจำนวนเต็มตรง และไม่มีบิลด์หรือไลบรารีใด ๆ

fn f(x:i64,y:i64)->i64 {
        fn h(x:i64,y:i64)->i64 {let s=x+y;(s*s-3*s+4)/2-1+(s+1)%2*x+s%2*y}
        fn g(x:i64,y:i64)->i64 {if x==0 {y} else {g(y%x,x)}}
        let mut a=h(x,y);
        for i in 1..x+y {for j in 1..y+x {if h(i,j)<h(x,y) && g(i,j)>1 {a-=1;}}}
        a
}


0

Javascript, 79 ไบต์

a=(p,q)=>p*q==1?1:1+((p+q)%2?q==1?a(p-1,q):a(p+1,q-1):p==1?a(p,q-1):a(p-1,q+1))

(ฉันใหม่กับการตีกอล์ฟดังนั้นนี่อาจปรับปรุงได้อย่างง่ายดาย)

คำอธิบาย

let a = (p, q) => p * q == 1 // If they are both 1
    ? 1
    // Do a recursive call and increment the result by 1
    : 1 + (
        (p + q) % 2 // If on an even-numbered diagonal
        ? q == 1 // If at the beginning of the diagonal
            ? a(p - 1, q) // Go to previous diagonal
            : a(p + 1, q - 1) // Go one back
        : p == 1 // rougly the same
            ? a(p, q - 1)
            : a(p - 1, q + 1)
    )

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