距離mod Nの計算


13

Advanced Collecting Device Controller™から長い間データを収集しています。ログを確認すると、恐ろしいことに何かがひどく間違っていることがわかります。データには数字の最後のビットしか含まれていません。

幸いなことに、開始値がわかっていて、値が決して速く変化することはありません。つまり、スタート地点からの距離を見つけるだけで残りを回復できるということです。

チャレンジ

モジュラスNと中間値モジュロのリストを指定して、値が変化した量を計算するプログラムまたは関数を作成しますN

数値の各ペア間の変化は常により小さいためN/2、各テストケースに対して有効な回答は1つだけです。

入力として、N2を超える整数と値のリストが、選択した形式で提供されます。入力は、STDINまたはコマンドラインまたは関数の引数を介して指定できます。

元の値が変更された量である単一の整数を出力します。出力はSTDOUTに出力されるか、返されます。

ルール

  • プログラムは、未満の距離とモジュラスで機能する必要があり2^20ます。
  • あなたはそれを仮定するかもしれません:
    • Nは少なくとも3です。
    • リストには少なくとも2つの値があります。
    • リスト内のすべての値は、少なくとも0未満ですN
    • 数値のすべての変更は未満ですN/2
  • それ以外は無効な入力であり、プログラムは必要な処理を実行できます。
  • この正確な目的のための標準的な抜け穴、非標準ライブラリ、組み込み関数は禁止されています。
  • これはであるため、バイト単位の最短プログラムが優先されます。

テストケースの例

入力:

3
0 1 2 2 0 1 0 2 1 2 0 1 2 1 1

出力:

4

説明(値の例付き):

Value mod 3: 0 1 2 2 0 1 0 2 1 2 0 1 2 1 1
Value:       0 1 2 2 3 4 3 2 1 2 3 4 5 4 4

入力:

10
5 2 8 9 5

出力:

-10

説明(値の例付き):

Value mod 10:  5  2  8  9  5
Value:        15 12  8  9  5

無効な入力:

2
0 0 0 0 0

(モジュラスが小さすぎる)

6
2 5 4 2

(2と5の間の変化が大きすぎる)


あなたの選択の形式は滑りやすい斜面です。私のGolfScriptソリューションは、次のような入力リストに依存できます:^;[5 2 8 9 5](\ か?
リン

3
@Mauris通常、「...選択した形式」とは、通常「選択した言語での従来の表現」を意味すると想定されます。
マーティンエンダー

ただし、「10 5 2 8 9 5」または「10,5 2 8 9 5」または「10 5,2,8,9,5」のような入力リストに依存できます。
スパー

回答:


2

TI-BASIC、15バイト

Input N
sum(N/πtan⁻¹(tan(ΔList(πAns/N

からリストAnsとモジュラスを取得しInputます。

                       πAns/N    ; Normalize the list to [0,π)
                 ΔList(          ; Take differences, which are in the range (-π,π)
       tan⁻¹(tan(                ; Modulo, but shorter. Now elements are in (-π/2,π/2)
    N/π                          ; Multiply by N/π. These are displacements at each step.
sum(                             ; Add up all the displacements

9

Python 2、53バイト

lambda n,l:sum((b-a+n/2)%n-n/2for a,b in zip(l,l[1:]))

超簡単な答え。もっと短い方法があるのだろうか。


私はそのビットを逃しました。ありがとう。
リン

@ジャクベ私はすでにそれをしました-私は.:_2あなたの答えを見るまでペアを生成することを知りませんでした-私はzipを使用していました。
orlp

1
@ジャクベ19 :)
orlp

7

Mathematica、30バイト

Tr@Mod[Differences@#2,#,-#/2]&

これは、2つの引数を取る匿名関数です。使用例:

Tr@Mod[Differences@#2,#,-#/2]&[3, {0, 1, 2, 2, 0, 1, 0, 2, 1, 2, 0, 1, 2, 1, 1}]
(* 4 *)
Tr@Mod[Differences@#2,#,-#/2]&[10, {5, 2, 8, 9, 5}]
(* -10 *)

これは取ることによって動作Differences範囲にそれらを包む、連続する要素間-n/2+n/2有するMod次いで合計を取って、そのオフセットパラメータTr(マトリックストレース、対角要素の和)。


何もしなくてもたった43バイトです!

f[n_, l_] := Total[Mod[Differences[l], n, -n/2]]

@既に角括弧で関数を呼び出している場合は不要です。両方を持つことは構文エラーです。
デビッドチャン

@DavidZhangおっと、私の考えがわからない。Mathematicaを開かずに答えようとするのにぴったりです!
2012rcampion


4

Pyth、20 19バイト

sm-J/Q2%+-FdJQ.:vw2

.:_2ジャクベから盗んだ、マリスからのアイデア。


3

R、38バイト

function(n,v)sum((diff(v)+n/2)%%n-n/2)

これにより、入力として整数とベクトルを受け入れ、単一の整数を返す名前のない関数が作成されます。呼び出すには、名前を付けf=function(n,v)...ます。

Ungolfed +説明:

f <- function(n, v) {
    # Compute the differences between sequential elements of v
    d <- diff(v)

    # Add n/2 to the differences and get the result modulo n
    m <- (d + n/2) %% n

    # Subtract n/2 then sum the vector
    sum(m - n/2)
}

例:

> f(3, c(0, 1, 2, 2, 0, 1, 0, 2, 1, 2, 0, 1, 2, 1, 1))
[1] 4

> f(10, c(5, 2, 8, 9, 5))
[1] -10

3

MatLab、33バイト

@(x,y)sum(mod(diff(y)+x/2,x)-x/2)

申し訳ありませんが、これはこのウェブサイトでの最初の回答です。MatLabでこれを入力してから入力ans(modulus_value, [intermediate_values])を使用すると、要求された値が返されます。「modulus_value」はモジュラス値、「intermediate_values」はスペースまたはコンマで区切られた中間値のリストです。

例:

ans(3, [0 1 2 2 0 1 0 2 1 2 0 1 2 1 1])

無名関数は、MATLABのを利用してmoddiffsumの答えを計算するための関数。最初に、各中間値の差が計算されます。結果は、2で割ったモジュラスによってオフセットされ、[-modulus / 2 modus / 2]でバインドされた差分値のセットになります。結果はオフセットされ、再び合計されます。

これはもっとゴルフができると思います、私は更新ですぐに戻ってきます。@ 2012rcampionのアイデアに感謝します。

編集: Matlabのunwrap機能はほとんどここで機能しますが、ゴルフは難しいです。次のコードは、最後の値が最初の値が変更された量である配列を返します。 @(x,y)unwrap(y/x*2*pi)/2/pi*x-y(1)

中間値は、[-pi pi]の範囲にスケーリングされ、連続した値がpi以上離れないように「アンラップ」されます。次に、これらの値は再スケーリングおよびシフトされ、開始値からの距離の配列が生成されます。

興味深いが、この課題にはあまり実用的ではない:D


2

Pyth、29バイト

+sm**._K-Fdvz>y.aKvz.:Q2-eQhQ

オンラインで試す:Pyth Compiler / Executor


入力はコンマ区切りではなくスペース区切りです。あなたのプログラムはこれを処理していないようです。
リン

2
@Mauris「選択した形式の値のリスト」
ジャクベ

ああ、私の悪い!仕様のその部分を完全に見逃しました。
リン


2

ピップ、39バイト

Qn$+({a>n/2?a-na<-n/2?a+na}Mg@>1-g@<-1)

コマンドライン引数としてのデータのリストとSTDINのモジュラスが必要です。それが長すぎる場合は、5バイト以上のコマンドライン引数を2つ受け取るバージョンがあります。

説明:

                                         g is list of cmdline args (implicit)
Qn                                       Read n from stdin
                            g@>1         All but the first of the cmdline args
                                -g@<-1   ...minus all but the last of the cmdline args
                                         (i.e. a list of the differences of adjacent items)
     {                    }M             ...to which, map the following function:
      a>n/2?a-n                            If diff is too big, subtract n;
               a<-n/2?a+n                  else if too small, add n;
                         a                 else return unchanged
  $+(                                 )  Sum; print (implicit)

そして、このそれほど競争力のないスコアが私の言語よりもゴルフのスキルに反映していることを証明するために、30バイトのモーリスのPythonソリューションの移植版を以下に示します

Qn$+({(n/2-$-a)%n-n/2}MgZg@>1)

2

ゼリー、非競合

6 バイト この答えは、Jellyの作成よりも前の課題なので、競合しません。

Iæ%H}S

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

使い方

Iæ%H}S    Main link. Left input: A (list). Right input: N (integer).

I         Compute the increments (deltas of consecutive elements) of A.
   H}     Halve the right input (N).
 æ%       Mod the increments into (-N/2, N/2].
     S    Take the sum of all results.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.