ค้นหาว่ารายการเป็น ABC-triple หรือไม่


16

จำนวนเต็มบวก A, B, C เป็น ABC-triple ถ้าเป็น coprime โดยมี A <B และสร้างความสัมพันธ์ที่น่าพอใจ: A + B = C

ตัวอย่าง :

  • 1, 8, 9 เป็น ABC-triple เนื่องจากเป็น coprime 1 <8 และ 1 + 8 = 9
  • 6, 8, 14 ไม่ใช่เพราะพวกเขาไม่ใช่ coprime
  • 7, 5, 12 ไม่ใช่เพราะ 7> 5

คุณสามารถดูการนำเสนอ Frits Beukers 2005สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับ ABC-triples

Input / Output

จำนวนเต็มสามจำนวน, เขียนทศนิยม อาจเป็นค่าหรือรายการที่คั่น ผลลัพธ์จะต้องเป็นค่าความจริง / ค่าเท็จไม่ว่าจะเป็นจำนวนเต็มสามตัวคือ ABC-triple

หมายเหตุ: สิ่งสำคัญคือต้องเคารพลำดับของจำนวนเต็มในรายการตัวอย่าง: 1, 8, 9ไม่ถือว่าเป็นรายการเดียวกัน9, 1, 8หรือหรือการรวมกันอื่น ๆ อย่างแรกคือ ABC-triple และ Second ไม่ใช่

ดังนั้น A คือองค์ประกอบแรกของรายการ B ที่สองและ C ที่สาม

กรณีทดสอบ

แต่ละรายการต่อไปนี้ควรส่งออกค่าความจริง

[1, 8, 9]
[2, 3, 5]
[2, 6436341, 6436343]
[4, 121, 125]
[121, 48234375, 48234496]

แต่ละรายการต่อไปนี้ควรส่งออกค่าเท็จ

[1, 1, 2]
[1, 2, 5]
[1, 9, 8]
[4, 12872682, 12872686]
[6, 8, 14]
[7, 5, 12]

เอาต์พุตต้องมีเพียงหนึ่งในสองค่าหรือเราสามารถส่งออกค่าความจริง / เท็จต่างกันสำหรับอินพุตที่แตกต่างกันได้หรือไม่?
Luis Mendo

ฉันคิดว่ามันควรจะสอดคล้องกัน: โค้ดของคุณจะต้องแสดงค่าความจริง / ค่าเท็จประเภทใดก็ตามที่อินพุต แต่คู่สัจธรรม / คู่หมั้นอาจเป็นสิ่งที่คุณต้องการเท่าที่ทำงาน: แยกรายการ
david

หากเรารับอินพุตเป็นรายการค่าสามค่าอินพุตจะต้องอยู่ในลำดับ[A,B,C]หรือเราได้รับอนุญาตให้รับอินพุตตามลำดับ[C,B,A]หรือ[C,A,B]ไม่
Kevin Cruijssen

คุณต้องเคารพคำสั่งเนื่องจาก <B เป็นเกณฑ์ในการท้าทาย
David

1
ฉันไม่คิดว่าต้องมีการสั่งซื้อรายการโดยเฉพาะอย่างยิ่งเข้ากันได้กับการอนุญาตให้ป้อนข้อมูลเพื่อนำมาเป็นค่าที่แยกจากกันเป็นค่าแยกเรียงลำดับโดยเนื้อแท้และอาจจะเป็นรายการ
Dennis

คำตอบ:


8

เยลลี่ , 10 9 ไบต์

Ṫ=S×</=g/

ลองออนไลน์!

มันทำงานอย่างไร

Ṫ=S×</=g/  Main link. Argument: [a, b, c] (positive integers)

Ṫ          Tail; pop and yield c.
  S        Take the sum of [a, b], yielding (a + b).
 =         Yield t := (c == a + b).
    </     Reduce by less than, yielding (a < b).
   ×       Multiply, yielding t(a < b).
       g/  Reduce by GCD, yielding gcd(a, b).
      =    Check if t(a < b) == gcd(a, b).

8

Haskell , 48 38 29 ไบต์

-10 ไบต์เนื่องจากเคล็ดลับของTFeldgcd !

-7 ไบต์ขอบคุณHPWizสำหรับการปรับปรุงการทดสอบแบบ co-primality และการตรวจจับพื้นที่ที่ไม่จำเป็น!

-2 ไบต์ต้องขอบคุณnimiสำหรับการแนะนำตัวดำเนินการมัด -!

(a!b)c=a<b&&a+b==c&&gcd a b<2

ลองออนไลน์!

คำอธิบาย

สองเงื่อนไขแรกa < bและa + b == cค่อนข้างชัดเจนส่วนที่สามใช้gcd(a,b)=gcd(a,c)=gcd(b,c) :

การเขียนgcd(a,c)=Ua+Vcโดยใช้ข้อมูลประจำตัวของBézoutและการแทนที่c=a+bให้:

Ua+V(a+b)=(U+V)a+Vb

ตั้งแต่GCDเป็นวิธีการแก้ปัญหาในเชิงบวกน้อยที่สุดเพื่อตัวตนให้เป็นไปตามที่GCD ( , B ) = GCD ( , C ) อีกกรณีหนึ่งคือสมมาตร gcdgcd(a,b)=gcd(a,c)


1
นอกจากนี้ผมเชื่อว่าคุณต้อง gcd a b==1แต่เพียงว่า ตั้งแต่แบ่งgcd a b a+b=ciegcd(gcd a b)c=gcd a b
H.PWiz

@HPWiz: อ่าใช่แน่นอนขอบคุณ! จะแก้ไขในภายหลังเมื่อไม่ได้อยู่บนมือถือ ..
ბიმო

7

Perl 6, 33 32 bytes

-1 ไบต์ต้องขอบคุณ nwellnhof

{(.sum/.[2]/2*[<] $_)==[gcd] $_}

Try it online!

Anonymous code block that takes a list of three numbers and returns True or False.

คำอธิบาย

{                              }  # Anonymous code block
                       [gcd] $_   # Is the gcd of all the numbers
 (                  )==           # Equal to
  .sum        # Whether the sum of numbes
      /       # Is equal to
       .[2]/2 # The last element doubled
             *[<] $_   # And elements are in ascending order



4

ทุบตี, 61 ไบต์

factor $@|grep -vzP '( .+\b).*\n.*\1\b'&&(($1<$2&&$1+$2==$3))

ลองออนไลน์!

อินพุตเป็นอาร์กิวเมนต์บรรทัดรับคำสั่งเอาต์พุตในโค้ดออก (ยังสร้างเอาต์พุตบน stdout เป็นผลข้างเคียง แต่สามารถละเว้นได้)

ส่วนที่สอง (เริ่มต้นจาก&&(() ค่อนข้างมาตรฐาน แต่สิ่งที่น่าสนใจคือการทดสอบ coprime:

factor $@      # produces output of the form "6: 2 3\n8: 2 2 2\n14: 2 7\n"
|grep -        # regex search on the result
v              # invert the match (return truthy for strings that don't match)
z              # zero-terminated, allowing us to match newlines
P              # perl (extended) regex
'( .+\b)'      # match one or more full factors
'.*\n.*'       # and somewhere on the next line...
'\1\b'         # find the same full factors

สุดท้าย&&สามารถเปลี่ยนเป็น&เพราะความสำคัญ
Nahuel Fouilleul

4

Java 10, 65 64 ไบต์

(a,b,c)->{var r=a<b&a+b==c;for(;b>0;a=b,b=c)c=a%b;return r&a<2;}

-1 ไบต์ขอบคุณ@Shaggy

ลองออนไลน์

คำอธิบาย:

(a,b,c)->{        // Method with three integer parameters and boolean return-type
  var r=          //  Result-boolean, starting at:
        a<b       //   Check if `a` is smaller than `b`
        &a+b==c;  //   And if `a+b` is equal to `c`
  for(;b>0        //  Then loop as long as `b` is not 0 yet
      ;           //    After every iteration:
       a=b,       //     Set `a` to the current `b`
       b=c)       //     And set `b` to the temp value `c`
    c=a%b;        //   Set the temp value `c` to `a` modulo-`b`
                  //   (we no longer need `c` at this point)
  return r        //  Return if the boolean-result is true
         &a<2;}   //  And `a` is now smaller than 2

a==1-> a<2เพื่อบันทึกไบต์
Shaggy

@Shaggy ขอบคุณ!
Kevin Cruijssen

4

05AB1E , 12 11 10 bytes

บันทึก 1 ไบต์ขอบคุณKevin Cruijssen

ÂÆ_*`\‹*¿Θ

ลองออนไลน์! หรือเป็นชุดทดสอบ

คำอธิบาย

ÂÆ           # reduce a reversed copy of the input by subtraction
  _          # logically negate
   *         # multiply with input
    `        # push the values of the resulting list separately to stack
     \       # remove the top (last) value
      ‹      # is a < b ?
       *     # multiply by the input list
        ¿    # calculate the gcd of the result
         Θ   # is it true ?

อ๊ะ .. ลบความคิดเห็นของฉัน .. >> ดังนั้นอีกครั้ง:. คุณสามารถบันทึกไบต์โดยใช้หลายแทนการแลกเปลี่ยนกับผลิตภัณฑ์: RÆ_*`\‹*¿Θ Test Suite
Kevin Cruijssen

@KevinCruijssen: ขอบคุณ! ใช่ปกติเมื่อคุณมีการแลกเปลี่ยนหลายครั้งคุณกำลังทำสิ่งผิดปกติ: P
Emigna

3

Python 2 , 69 67 63 62 55 ไบต์

lambda a,b,c:(c-b==a<b)/gcd(a,b)
from fractions import*

ลองออนไลน์!


Python 3 , 58 51 ไบต์

lambda a,b,c:(c-b==a<b)==gcd(a,b)
from math import*

ลองออนไลน์!


-7 ไบต์ขอบคุณ H.PWiz


เป็นgcdในgcdเคล็ดลับที่ถูกต้อง? เกิดอะไรขึ้นถ้าaไม่ใช่ coprime ด้วยc?
Jo King

2
@ jo-king ถ้า p หาร a และ c มันควรแบ่ง ca so b
david

2
@JoKing: It is in this case, but not in general (you can prove it via Bezout's identity).
ბიმო

You can take it one step further and use gcd(a,b), since gcd(a,b) divides a+b
H.PWiz

@H.PWiz Thanks :)
TFeld

3

Japt, 16 14 13 11 bytes

<V¥yU «NÔr-

Try it

                :Implicit input of integers U=A, V=B & W=C
<V              :Is U less than V?
  ¥             :Test that for equality with
   yU           :The GCD of V & U
      «         :Logical AND with the negation of
       N        :The array of inputs
        Ô       :Reversed
         r-     :Reduced by subtraction

Here is another 11 byte solution, though on closer inspection it isn't much different from yours in its actual logic.
Kamil Drakari

@KamilDrakari, had a variation on that at one stage, too. It could be 10 bytes if variables were auto-inserted when > follows ©.
Shaggy

3

JavaScript (ES6),  54 43 42  40 bytes

Thanks to @Shaggy for pointing out that we don't need to compute gcd(a,c). Saved 11 bytes by rewriting the code accordingly.

Takes input as 3 separate integers. Returns true for an ABC-triple, or either 0 or false otherwise.

f=(a,b,c)=>c&&a/b|a+b-c?0:b?f(b,a%b):a<2

Try it online!


1
I don't think you need to test gcd(c,a).
Shaggy

@Shaggy Thanks! I've rewritten the code entirely.
Arnauld

3

Wolfram Language 24 30 28 26 bytes

With 2 bytes shaved by Doorknob. A further 2 bytes shaved off by @jaeyong sung

#<#2&&GCD@##==1&&#+#2==#3&

I think you should also be able to use CoprimeQ@## to save 2 bytes.
Doorknob

@Doorknob, If the first and second numbers are coprime, are they necessarily coprime with their sum?
DavidC

They are, but the original definition actually states that A, B, and C should be coprime. Most answers check only A and B just because it's usually shorter.
Doorknob

I think GCD@##==1 would save 2 bytes
jaeyong sung

2

C# (Visual C# Interactive Compiler), 90 bytes

n=>new int[(int)1e8].Where((_,b)=>n[0]%++b<1&n[1]%b<1).Count()<2&n[0]+n[1]==n[2]&n[0]<n[1]

Runs for numbers up to 1e8, takes about 35 seconds on my machine. Instead of calculating the gcd like others, the function just instantiate a huge array and filter the indexes that aren't divisors of a or b, and check how many elements are left. Next it check if element one plus element two equals element three. Lastly, it checks if the first element is less than the second.

Try it online!



2

ECMAScript Regex, 34 bytes

Input is in unary, in the domain ^x*,x*,x*$ (repeated xs delimited by ,).

^(?!(xx+)\1*,\1+,)(x*)(,\2x+)\3\2$

Try it online! (.NET regex engine)
Try it online! (SpiderMonkey regex engine)

# see /codegolf/178303/find-if-a-list-is-an-abc-triple
^
(?!                # Verify that A and B are coprime. We don't need to include C in the
                   # test, because the requirement that A+B=C implies that A,B,C are
                   # mutually comprime if and only if A and B are coprime.
    (xx+)\1*,\1+,  # If this matches, A and B have a common factor \1 and aren't coprime.
)
(x*)(,\2x+)\3\2$   # Verify that A<B and A+B=C. The first comma is captured in \3 and
                   # reused to match the second comma, saving one byte.

The question does say "Three integers, decimal written", so this might not qualify (as it takes input in unary), but it makes for such an elegant pure regex that I hope it will at least be appreciated.

However, note that if the phrasing is to be literally interpreted, lambda and function submissions that take integer arguments are to be disqualified too, as to strictly adhere to the question's specification they would need to take the input in the form of a string.








1

Mathematica 35 bytes

CoprimeQ @@ # && #[[1]] + #[[2]] == #[[3]] & 

if order is important:

CoprimeQ @@ # && Sort[#]==# && #[[1]] + #[[2]] == #[[3]] & 

or...

And[CoprimeQ @@ #, Sort@# == #, #[[1]] + #[[2]] == #[[3]]] &

1

Retina 0.8.2, 42 41 bytes

\d+
$*
A`^(11+)\1*,\1+,
^(1+)(,1+\1)\2\1$

Try it online! Link includes test cases. Edit: Saved 1 byte thanks to @Deadcode. Explanation:

\d+
$*

Convert to unary.

A`^(11+)\1*,\1+,

Check that A and B have no common factor.

^(1+)(,1+\1)\2\1$

Check that A < B and A + B = C.


1
There appears to be a bug in your program. [121, 48234375, 48234496] is returning false.
Deadcode

1
@Deadcode Fixed, thanks for letting me know.
Neil

As with my regex, you can drop 1 byte by changing ^(1+),(1+\1),\1\2$ to ^(1+)(,1+\1)\2\1$.
Deadcode

1
@Deadcode Thanks! It's a shame that my use of Retina's A operation doesn't actually save me any bytes.
Neil

1
@Deadcode I'm using Retina's behaviour of turning the last regex into a positive assertion (actually a (count of) match stage) so moving the antigrep would cost me 5 bytes.
Neil

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