海で迷子になって助けて!


11

前書き

今日、私はカヌーと一緒に一人で釣りに行きました。残念なことに、私は眠りに落ち、小川が私を連れ去り、オールを失いました。海岸が見えないので遠くに行かなければなりません!

私は携帯電話を持っていますが、塩水で濡れたために故障しています。マイクと電話のスピーカーが壊れているため、何も話せず、聞こえませんが、海岸のビーチにいる友人にSMSを送信できます!

私の友人は非常に強力なトーチを持っていて、彼は正しい方向を示すために竹の杖の上にそれを上げましたが、私はオールを持っていないのでrowいできません。キャッチ!

友人は、トーチを海面の11.50メートルに維持していると言ったので、地平線のすぐ上に光が見えます。今、私は学校から地球の半径が海面で6371 Kmであるべきだと覚えているだけです。そして、私はカヌーに座っているので、私の目も海面にあると仮定できます。

仕事

潮流が刻々と私を動かしているので、私の友人は時々トーチを上げています(現在は12.30メートルです)。私の友人の位置からの距離を計算するのに役立つ完全なプログラムまたは関数を書いてください!

以下に図を示します(縮尺どおりではありません)。

ここに画像の説明を入力してください

ラベルの付いたオレンジ色の点Mは私、ラベルの付いた赤い点Tはトーチです。緑の線は、Mとの間の直線距離ですT

入力

標準入力からh、水平線の真上にあるトーチの高さをメートル単位で取得します。 0から100の範囲が含まれます。

出力

緑色の線のユークリッド長を1 cmの精度で返す必要があります。たとえば、メートル単位で出力する場合は、小数点以下2桁にする必要があります(少なくとも)。出力はメートルまたはキロメートルのいずれかですが、精度を尊重します。

テストケース:

すべての値はメートルです。

11.5 > 12105.08
13.8 > 13260.45

ルール

最短のコードが優先されます。


結果は数学的に正しいものである必要がありますか、または最初の2桁が問題ない場合は問題ありませんか?hxhは2xRxhに比べて小さく、短い距離では無視できることを意味します。(Rは地球の半径で、hはトーチの高さです)。
-Osable

@メートルで出力する場合、最初の2桁の小数でも問題ありません
マリオ

入力範囲はどのくらいですか?
2016年

@Osableは、入力が0〜100(この場合は必要以上に多すぎる)であると見なすことができます。
マリオ

1
コーストガードスタックエクスチェンジを試してみるべきです-コードゴルファーは海から抜け出すのを助けることができません、男!
corsiKa

回答:


4

05AB1E13 12 10バイト

Emignaのおかげで2バイト節約されました。

地球が局所的に平面であるというOPの仮定を使用して呼び出される三角関数がないため、05AB1Eソリューションを作成することが可能になります。

•1#oC•+¹*t

           For understanding purposes input is referred to as 'h'
•1#oC•     Push 12742000 [ = 2*R, where R is the radius of earth]
      +    Compute 2*R+h
       ¹*  Multiply by h. Result is (2*R*+h)*h
         t Take the square root of it and implicitly display it

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


1
12742000ように書くことができます•1#oC•
エミグナ

:参考のために、それは9つのバイトだったでしょう•1#oC•+*t2sable
Emigna

で囲まれた文字列は...ベース214の数字を表しますか?05AB1Eには、このような特殊機能に関するドキュメントが不足している場合があります。素敵な2sableの回答も。数日前にそれを知りましたが、この質問にそれを使用することを考えていませんでした。
-Osable

正しい。これは、ベース214に符号化されたベース10数である
Emigna

結果は三角法でも達成できますが、おそらくもっと長いでしょう。
マリオ

4

Python、34 26バイト:

Osableのおかげで-8バイト!

lambda i:(i*(i+12742))**.5

匿名のラムダ関数。キロメートル単位で入力を受け取り、キロメートル単位で出力します。として呼び出しますprint(<Function Name>(<Input>))


lambda i:(i*(i+12742))**.5さらに短くなります。
-Osable

@Osableナイス!私はちょうどそれをやろうとしていました。:)
R. Kap

不一致の間に与えられた数学の公差がある場合、iおよび12742は、表現を短縮することができるので、:(i*12742)**.5
Osable

結果が間違っています。11.5m->〜12kmではなく〜380km
GB

@GBプログラムは、入力をキロメートルとして読み取ります。
2016年

4

PHP、34バイト

<?=sqrt((12742e3+$h=$argv[1])*$h);

壊す

   r^2+x^2=(r+h)^2      # Pythagoras base
   r^2+x^2=r^2+2rh+h^2  # right term distributed
       x^2=    2rh+h^2  # -r^2
       x =sqrt(2rh+h^2) # sqrt

これまでのところ、これは古いMathematicaの答えと同じです

sqrt(2*6371e3*$h+$h*$h) # to PHP
sqrt(14742e3*$h+$h+$h)  # constants combined
sqrt((14742e3+$h)*$h)   # conjugation to save a byte
((14742e3+$h)*$h)**.5   # same size

あとは、入力=$argv[1]と出力を追加するだけです<?=-完了


4

dc、16 11バイト:

?d12742+*vp

コマンドラインからの入力をキロメートル単位で要求し、距離をキロメートル単位で出力します。

説明

?           # Prompt for input
 d          # Duplicate the top-of-stack value
  12742     # Push 12,742 onto the stack
       +    # Pop the top 2 values of the stack and push their sum
        *   # Pop top 2 values of the stack and push their product
         v  # Pop the remaining value and push the square root
          p # Output the result to STDOUT

これは次の利点を活用します。

((6371+h)**2-6371**2)**.5 
=> ((6371**2+12742h+h**2)-6371**2)**0.5 
=> (h**2+12742h)**0.5 
=> (h*(h+12742))**0.5


4

Haskell、22バイト

d h=sqrt$h*(h+12742e3)

使用法:

Prelude> d 11.5
12105.087040166212

ポイントフリー:(23バイト)

sqrt.((*)=<<(+12742e3))


2

Mathematica、16バイト

これらのいずれかは、キロメートル単位の入力と出力の両方で機能します。

(12742#+#*#)^.5&
((12742+#)#)^.5&

これは、問題に対するピタゴラスの単純なアプリケーションです。

   x*x + R*R = (R+h)*(R+h)
=> x*x = (R+h)*(R+h) - R*R
       = R*R + 2*R*h + h*h - R*R
       = 2*R*h + h*h
=>   x = √(2*R*h + h*h)

2

Jelly、Jellyのコードページの9バイト

私はゴルフ言語でプログラムを書くことに挑戦することにしました。私は実際に他の人が使用しているものよりも効率的なアルゴリズムを見つけました(少なくとも問題のような短い距離で)が、それはジェリーが圧縮できないように見えるリテラル浮動小数点数を必要とするので、ピタゴラスそうです。

+“Ȯịż’×µ½

説明:

 “Ȯịż’     12742000, compressed base-250
+          add to argument
      ×    multiply with original argument
       µ   separator to avoid what would otherwise be a parsing ambiguity
        ½  square root everything seen so far
           implicit output at EOF

µセパレータの必要性は私をいらいらさせますが、それは避けられないと思います。Jellyは、多くのコマンドに必要な引数を推測できるため、すでに05AB1Eを超えるバイトを保存していますが、この場合、最後まで正しく推測できないため、ヒントを提供する必要がありました。

Jelly、Jellyのコードページの7バイト

דȮịż’½

私の他の答えで説明したように、ピタゴラス近似の級数近似は、実際には質問に含まれる長さよりも優れた結果を生成し(少なくとも、例の出力に近い)、より短い式も持っています。執筆中に、12742000の平方根を事前に計算する代わりに、最初に12742000を掛け、次に両方を同時に平方根にできることに気付きました。これは基本的に、追加なしの他の式と同等であり、追加を削除することで以前のプログラムから生成できます。これにより、2バイトが節約されます。これは、今では明確に解析されるため、µこれ以上必要ありません。


hの範囲を指定してセンチメートル(要求された出力を参照)を見ると同じ値を生成しないため、この最適化を使用しないことにしました。また、05AB1Eに2バイトを保存します。
2016年

最適化により、12105.081577585506および13260.452480967608の出力が得られます。これらはテストケースの出力に非常に近く、それらに丸められます。なしでは、12105.087040166212と13260.459661716106が得られますが、これらはさらに遠くにあります(後者はセンチメートル単位で不正確で、13260.46に丸められます)。他の答えで述べたように、最適化は、最適化されたコードよりも正しい値に近くなります。これは、キャンセルするものがないだけでなく、互いに大きく相殺する2つのエラーが含まれているためです。

レビューキューで「オープンのままにする」に投票しただけなので、コメントで明確化を要求した質問への回答を知っていると思われると思います。したがって、質問が明確になるように編集してください。
ピーターテイラー

1
質問は明確です。著者は、ナビゲートを支援するために友人までの距離を知る必要があります。彼は、トーチの位置を0.1メートルの精度で決定できます(これは、語られたストーリーから決定できます)。これにより、必然的に現在の距離での出力から約1メートルの不確実性が得られます(注:作者は漂流しているため、非常に速く移動することはほとんどありません...)。許容できる。問題の一部は、この状況でどれほど正確である必要があるかを判断することです!

1
要求された出力は、メートルで2桁の小数を示します。したがって、精度は1センチメートルになると予想されます。質問へのコメントの中で、OPはhが100まで上がる可能性があると述べました。h= 100では、元のアルゴリズムと14センチメートルの不一致があります。
2016年

2

ルビー、23

23バイト、Km単位

->h{(h*h+h*12742)**0.5}

25バイト、m

->h{(h*h+h*12742e3)**0.5}

1

Tcl、49バイト:

set A [get stdin];puts [expr ($A*($A+12742))**.5]

まあ、私はTclが初めてなので、これをゴルフで打つためのヒントは大歓迎です。私の他の答えと同様に、コマンドライン入力をキロメートル単位で、出力をキロメートル単位で求めます。本質的には既存dcpython回答のTcl適応です。


そこにある取得に不足しているS
sergiol

1

x86_64 + SSEマシンコード、16バイト

プログラムのバイトは左側(16進数)にあり、右側に逆読みがあり、読みやすくなっています。これは、単精度浮動小数点数を受け取って返す関数の通常のx86_64規則に従う関数です(%xmm0で引数を取り、同じレジスターで回答を返し、%xmm1と%eaxを一時的に使用します;これらCプログラムが使用するのと同じ呼び出し規約であり、そのため、Cプログラムから関数を直接呼び出すことができます。

b8 80 19 5f 45          mov    $0x455f1980,%eax
66 0f 6e c8             movd   %eax,%xmm1
0f 51 c0                sqrtps %xmm0,%xmm0
0f 59 c1                mulps  %xmm1,%xmm0
c3                      retq

ただし、分解しても、これには説明が必要です。まず、式を議論する価値があります。ほとんどの人は地球の曲率を無視し、ピタゴラスの式を使用して距離を測定しています。私もやっていますが、級数展開近似を使用しています。入力の最初のパワーに関連する用語のみを使用し、3、5、7などのパワーは無視します。これらはすべて、この短い距離では非常に小さな影響しか与えません。(さらに、ピタゴラス近似は低い値を与えますが、シリーズ展開の後半の用語は値を減らすのに役立ちます。そのため、間違った方向に近似をプッシュするのに役立つ小さな要因を無視することで、実際により正確でない式を使用することにより、より正確な結果が得られます。)式は√12742000×√hであることが判明しました。0x455f1980

次に人々を混乱させる可能性があるのは、平方根と乗算にベクトル命令を使用している理由です。%xmm0そして%xmm1、各4つの単精度浮動小数点数を保持することができ、私はすべての4つの上で動作しています。ここでの推論は実に簡単です。それらのエンコードは、対応するスカラー命令のエンコードよりも1バイト短くなります。したがって、典型的なゴルフ言語アルゴリズムに非常によく似た方法で、2バイトを節約するために、FPUに多くの余分な作業を平方根とゼロの乗算を行わせることができます。(x86アセンブラーは、しばらく前からチャットでアセンブラーのゴルフ言語と呼ばれていましたが、それについてはまだ考えていません。)

そこから、アルゴリズムの非常にシンプル:ロード%xmm1経由√12742000と%eax(メモリからロードよりも、バイト単位で短いだろう)、平方根引数(三ゼロ)、の乗算対応する要素%xmm1%xmm0(我々は唯一のケア最初の要素について)、戻ります。


1

Minkolang v0.15、22バイト

ndd*$r'12742000'*+1MN.

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

n                               gets input in the form of a number
 dd                             duplicates it twice
   *                            multiplies 2 of the duplicates with each other
                                STACK: [h, h*h]
    $r                          swap top two stack values
                                STACK: [h*h, h]
      '12742000'*               push this number and multiply the original input by it
                                STACK: [h*h, h*12742000]
                 +1M            adds the two values and takes their square root
                                STACK: [sqrt(h*h+h*12742000)]
                    N.          output as a number and end program

1

JavaScript(ES6)、31 25バイト

値をメートル単位で表示します

//the actual code 
f=h=>(h*h+12742e3*h)**0.5


console.log(f(11.5));
console.log(f(13.8));

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