私の寸法は何ですか?


18

タスク:三角形の面積が与えられたら、その面積を持つヘロニアン三角形を見つけます。指定された面積を持つヘロニアン三角形はすべて許可されます。

ヘロニアン三角形は、整数の辺と整数の面積を持つ三角形です。ヘロンの公式により、辺の長さの三角形にa,b,cは面積があります

sqrt(s*(s-a)*(s-b)*(s-c))

どこs=(a+b+c)/2三角形の半分周囲はあります。これは次のように書くこともできます

sqrt((a+b+c)*(-a+b+c)*(a-b+c)*(a+b-c)) / 4

そのような三角形が存在しない場合は、一貫したfalsey値で出力します。

入力:三角形の面積を表す単一の正の整数。

出力:このような三角形の3辺の長さ、または偽の値。

例:

Input -> Output
6 -> 3 4 5
24 -> 4 15 13
114 -> 37 20 19
7 -> error

標準的な抜け穴が適用されます

これはコードゴルフで、バイト単位の最短回答が勝ちです。


6
あなたの挑戦でヘロン三角形の比較的簡潔な定義を書くことができますか?
Okx

1
@Okx:整数の辺と整数の面積を持つ三角形であることは明らかではありませんか?
ニールA.

@Okx:それがアイデアです。必要なのは、指定された領域が存在する場合、そのような例を1つ見つけることだけです。
ニールA.

ウィキペディアのリンクから:「ヘロニアンの三角形は、辺の長さと面積がすべて整数である三角形です。」
ニールA.

5
質問の定義について混乱を招くものを説明してください。
ニールA.

回答:


6

ゼリー17 16 バイト

Erik the outgolferのおかげで-1バイト(クイックを活用してください¥

SHð;_P
ṗ3Ç⁼¥Ðf²Ḣ

ヘロンの式のブルートフォースアプリケーション。

オンラインでお試しください!(114テストの場合は60秒のタイムアウトに達します。ローカルで3分30秒かかります-114 3 = 1,481,544トリプルをチェックします)

どうやって?

真のゴルフソリューション- との間の3つの整数のすべてのタプルをa見つけるエリアを指定すると(繰り返される三角形とエリアのないものでも)、そのエリアと目的のエリアのフィルターを取得します(すぐに停止することさえありません) 1つが見つかった場合、それらをすべて処理し、その後最初の結果をポップします)。存在しない場合は降伏します。1a0

SHð;_P - Link 1, get the square of the area of a triangle: list of sides
S      - sum the sides (get the perimeter)
 H     - halve
  ð    - dyadic chain separation (call that p)
    _  - subtraction (vectorises) =    [p-side1,  p-side2,  p-side3]
   ;   - concatenate              = [p, p-side1,  p-side2,  p-side3]
     P - product                  =  p*(p-side1)*(p-side2)*(p-side3)
                                  = the square of Heron's formula = area squared

ṗ3Ç⁼¥Ðf²Ḣ - Main link: number a (area)
ṗ3        - third Cartesian power (all triples of [1,area] : [[1,1,1],[1,1,2],[1,2,1],[1,2,2],[2,1,1],[2,1,2],[2,2,1],[2,2,2], ... ,[a,a,a]]
       ²  - square a
     Ðf   - filter keep if:
    ¥     -   last two links as a dyad:
  Ç       -     call last link (1) as a monad f(list of sides)
   ⁼      -     left (that result) equals right (square of a)?
        Ḣ - head - get the first one (an empty list yields 0, perfect for the falsey case)

誰かがこれをブルートフォースしようとするだろうと思いました。
ニールA.

@NeilA。ほとんどのゴルフの提出物は、この挑戦​​のためのブルートフォースになると思いますが、一部のものは、これよりもばかげて非効率的でありながら、なんとかゴルフをすることができます。
ジョナサンアラン

2行目を完全に置き換えçÇ⁼¥削除できます。
エリックアウトゴルファー

@EriktheOutgolferああ、おかげで、私はその...について移動する方法を思っていた
ジョナサン・アラン

5

JavaScriptの(ES7)、109の 102 100 98バイト

3つの整数の配列またはを返しますfalse。同様ゼリー答え、これはヘロンの公式をブルートフォース攻撃です。

A=>[...Array(A**3)].some((_,a)=>A*A/(r=[b=a/A%A|0,c=a/A/A|0,a%=A],p=a+b+c>>1)/(p-a)/(p-b)==p-c)&&r

テストケース


再帰バージョン、83バイト

3つの整数の配列を返すか、再帰エラーをスローします。悲しいことに、小さな入力に対してのみ機能します。

f=(A,n)=>A*A/(r=[a=n%A,b=n/A%A|0,c=n/A/A|0],p=a+b+c>>1)/(p-a)/(p-b)==p-c?r:f(A,-~n)

デモ


4

Haskell、69バイト

f a=take 1[t|t<-mapM(\_->[1..a])":-)",a*a==product[sum t/2-x|x<-0:t]]

オンラインでお試しください!

のような3つの三角形の辺のリストのシングルトンを出力し[[3.0,4.0,5.0]]ます。不可能な入力はを与え[]ます。技術的にFalseはHaskellのFalsey のみですが、Haskellはすべての可能な出力を同じタイプにする必要があるため、使用できません。エラーをFalseyとして使用できる場合、で[...]!!03バイト節約できますtake 1[..]

すべてのトリプル試みるt可能な辺の長さの範囲のそれぞれの1領域にはa。Heronの式は(s-0)(s-x)(s-y)(s-z)==a*a、where s=(x+y+z)/2is を介して領域が一致するかどうかを確認するために使用されsum t/2ます。積(s-0)(s-x)(s-y)(s-z)は、productから取得した要素0:t、つまりトリプルと0として表現されます。


ちょっとスヌーピーの場合でも、スマイリーフェイスの+1
Julian Wolf

2

F#、170 156 152バイト

let f(a,b,c)=
 let s=(a+b+c)/2.0
 s*(s-a)*(s-b)*(s-c)
let g A=[for a in 1.0..A do for b in a..A do for c in b..A do yield a,b,c]|>List.find(f>>(=)(A*A))

オンラインでお試しください!

「ゴルフなし」

let calculateArea (a, b, c) =
    let s = (a+b+c)/2.0
    s*(s-a)*(s-b)*(s-c)

let getTriangle A =
    [  for a in 1.0..A do
       for b in a..A do
       for c in b..A do yield a,b,c
    ]
    |> List.find(calculateArea>>(=)(A * A))

結果が見つからない場合、プログラムはエラーになります。これが望ましくない場合、私は交換する必要がList.findどちらかとList.filter(2バイト)の場合には空のリストを生成しますこれは何も見つからないか、されてList.tryFind何の三角形が見つからなかった場合はNoneを返していない、(3バイト)。

私はいつも、F#のゴルフバージョンは、まだ十分に読みやすいと感じています。


1
私はF#を知りませんが、私はあなたがなしで済ませてSystem.Math.Sqrt、結果の値と比較できると思いますA * Aか?
ショーン

@Seanもちろん!ヒントをありがとう:)
ブルナー

に置き換える1.0..A [...] 1.0..A [...] 1.0..A1.0..A [...] a..A [..] b..A、数バイト節約でき、速度が少し速くなります(機能する場合は、F#の経験は最小限です)。
CAD97

@ CAD97そうです!それを指摘してくれてありがとう。
ブルナー

2

Python 2(PyPy)131 123 118バイト

n=input()
t=n*3;r=i=c=0
while c<t:
 i+=1;a,b,c=i%t,i/t%t,i/t/t;s=a+b+c>>1
 if(s-a)*s*(s-b)*(s-c)==n**2:r=a,b,c
print r

オンラインでお試しください!

これはCPythonでも機能しますが、PyPyははるかに高速であり、TIOの制限時間で114​​の三角形を計算できます。

私のマシンからのタイミング:

$ echo 114 | time pypy2 d.py
        0.55 real         0.52 user         0.02 sys
$ echo 114 | time python2 d.py
       52.46 real        51.76 user         0.27 sys

1

Pyth-23バイト

/mu*G-/sd2Hd/sd2^UQ3^Q2

真実/偽の値を印刷する、または

fq^Q2u*G-/sT2HT/sT2^UQ3

考えられるすべての解決策を印刷し、大量の入力に対して恐ろしく遅いです。1つだけを出力するには、先頭に「h」を付けます。

説明:

fq^Q2u*G-/sT2HT/sT2^UQ3
                    UQ    # List of numbers from 0 to input-1
                   ^  3   # All triples of these numbers
f                         # Filter this by the following test (on variable T, based on Hero's formula)
     u*G-/sT2HT/sT2       # s*(s-a)*(s-b)*(s-c), where s is the sum of the triple over 2 (calclated as /sT2 )
 q^Q2                     # Test if equal to input ^2

それを試してみてください


1

Perl 6、54バイト

->\a{first {a*a==[*] .sum/2 «-«(0,|$_)},[X] ^a xx 3}

a入力エリアの1未満のすべての可能な辺のブルートフォース検索。

  • ^a0からの数値の範囲ですa - 1
  • [X] ^a xx 3は、クロス積によって、その範囲の3つのコピーを削減し、から(0, 0, 0)までのすべてのトリプレットを生成します(a - 1, a - 1, a - 1)
  • ヘロンの公式を使用して、firstそれらの辺を持つ三角形の面積が等しくなるようなトリプレットを探します。a

に与えられたコードブロック内first

  • $_トリプレットです。(x, y, z)ここで呼び出します。
  • (0,|$_)は同じトリプレットですが、0先頭に:が付きます(0, x, y, z)
  • .sum / 2は周囲の半分です(sヘロンの式の通常の表現で名前が付けられている量)。
  • .sum / 2 «-« (0, |$_)は、s左と(0, x, y, z)右の減算ハイパー演算子であり、を与え(s - 0, s - x, s - y, s - z)ます。
  • [*] 次に、その四つ子を乗算で減らし、面積の二乗を与えます。
  • a * a == 指定された領域の正方形に等しい正方形の領域を探します。

トリプレットが見つからない場合、Nil(falsey)が返されます。


1

Haskell、76バイト

f s=[[a,b,c]|a<-[1..s],b<-[1..a],c<-[1..b],a*a*c*c-(a*a+c*c-b*b)^2/4==4*s*s]

これは、ブルートフォースによって正しい領域を生成するすべての可能な整数サイズを含むリストのリストを出力します(存在しない場合は空のリストを出力します)。警告は、中央の分割のためにそれらをdoubleとして出力しますが、それらの小数部は常に0です。

何らかの理由でそれを取ることができない場合は、

f s=[[a,b,c]|a<-[1..s],b<-[1..a],c<-[1..b],4*a*a*c*c-(a*a+c*c-b*b)^2==16*s*s]

これにより、合計89 77バイトまたは13 1追加バイトの整数リストのリストとして回答が出力されます。(ニールに感謝)

必要な場合/最初の要素だけが必要な場合!!0は、最後に置くだけで、適用される数字がある場合は最初の要素のみが、3バイト以上ない場合はエラーが発生take 1し、最初にエラーなしで最初の要素が取得されますさらに6バイト。

オンラインでお試しください!


ダブルスを回避したい場合は、各側で方程式に4を掛けることはできませんか?
ニール

0

TI-Basic、70 69バイト

Prompt A
For(B,1,A
For(C,1,B
For(D,1,C
(B+C+D)/2
If A2=Ansprod(Ans-{B,C,D
Then
Disp B,C,D
Return
End
End
End
End
/

三角形がある場合は3辺の長さを表示し、ない場合は構文エラーをスローします(/最後に感謝します)。

-1バイト、異なる答えに対するショーンのコメントのおかげ


0

Mathematica、77バイト

数学のソルブで

s=(a+b+c)/2;d=Sqrt[s(s-a)(s-b)(s-c)];Solve[d==#&&0<a<b<c<#,{a,b,c},Integers]&

Mathematica、117バイト

強引な

s=(a+b+c)/2;l="error";(For[a=1,a<#,a++,For[b=1,b<a,b++,For[c=1,c<b,c++,If[Sqrt[s(s-a)(s-b)(s-c)]==#,l={a,b,c}]]]];l)&

1
Mathematicaには組み込み機能がありませんか?驚いた。
ニールA.

@ovsで1バイト節約することArea@SSSTriangle[a,b,c]もできます。
numbermaniac

0

実際には、22バイト

;╗R3@∙⌠;Σ½;)♀-π*╜²=⌡░F

オンラインでお試しください!

説明:

;╗R3@∙⌠;Σ½;)♀-π*╜²=⌡░F  (implicit input: A)
;╗                      store a copy of A in register 0
  R                     range(1, A+1)
   3@∙                  ternary Cartesian product (all triples with values in [1, A])
      ⌠;Σ½;)♀-π*╜²=⌡░   filter: take triples where function returns truthy
       ;Σ½                make a copy of the triple, compute s = (a+b+c)/2
          ;)              make a copy of s, move it to the bottom of the stack
            ♀-            subtract each value in the triple from s
              π*          product of those values and s (s*(s-a)*(s-b)*(s-c))
                ╜²        A*A
                  =       compare equality (does area of triangle with given dimensions equal input?)
                     F  take first triple that satisfies the filter (or empty list if none)

0

Casio Basic、123バイト

For 1⇒a To n
For 1⇒b To n
For 1⇒c To n
If(s*(s-a)*(s-b)*(s-c)|s=(a+b+c)/2)=n^2
Then
Print{a,b,c}
Stop
IfEnd
Next:Next:Next

標準的なブルートフォースソリューション。コード用の122バイトn、パラメーターとして指定する1バイト。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.