nから最大n桁離れた位置を見つける


29

この質問の続編。

仕事

正の整数の配列が与えられた場合、次の最大要素kを見つけます。

存在するいくつかの正の整数距離Nは、アレイ内の要素が配置ように、n個  の場所は、左または右からkが等しいN

配列には、この条件を満たす少なくとも1つの要素が含まれていることが保証されています。

最短のコード(バイト単位)が優先されます。好きなI / O形式を選択できます。

与えられた入力

[4, 6, 7, 9, 3, 6, 5, 7, 2]

適格な値は次のとおりです。

  • 4あるように、7その右側に位置する7位に
  • 最初に63その右側に3つの位置があるため
  • 3あるように、4その左に位置する4つの位置が
  • 5あるように、2その右側に位置する2つの位置が
  • 2番目7は、3左側に3つの位置があるためです。

これらの値のうち、最大値は7です。

テストケース

[1, 13] → 13
[2, 9, 8, 3, 72, 2] → 8
[5, 28, 14, 5, 6, 3, 4, 7] → 14
[1, 3, 5, 15, 4, 1, 2, 6, 7, 7] → 7
[5, 1, 3, 5, 2, 5, 5, 8, 5, 1, 5, 1, 2, 3] → 5
[5, 12, 2, 5, 4, 7, 3, 3, 6, 2, 10, 5, 5, 5, 4, 1, 8, 5] → 10

この例では、さらに2つ(わずかに冗長ですが)のケースがあります。最初の6つ(これも)右側に5〜5つの位置があるためです。または、2番目の7(再び)が6から6ポジション残っているためです。
ジョナサンアラン

1.私の電話では、タイトルは「から最大数の位置を見つける」と表示されます。2.述べられている条件は、次のようなkが存在することです(kに依存しないプロパティ)。間違いであるに違いありません。
ピーターテイラー

「this要素」の@PeterTaylor「this」はkを指します。
Taemyr

1
@Taemyr、これは2つの理由で意味がありません。まず、kが要素であると述べられていないためです。第二に、条件満たす最大の要素を見つける」ように求められているため、この要素」には条件外の前件があります。
ピーターテイラー

2
「そのような最大の要素kを見つける」と言って、すべての混乱を避けてから、定義でこの要素の代わりにkを使用できますか
マーティンエンダー

回答:


3

ゼリー、9 バイト

Jạþ`=ḅa¹Ṁ

オンラインでお試しください!または、すべてのテストケースを確認します

使い方

Jạþ`=ḅa¹Ṁ  Main link. Argument: A (array)

J          Indices; yield [1, ..., len(A)].
   `       Use the previous return value as left and right argument:
 ạþ        Absolute difference table; take the absolute value of the difference
           of each pair of indices, yielding a 2D array.
    =      Compare each absolute difference with the corresponding item of A.
     ḅ     Base; convert each Boolean list from base i to integer, where i is the
           corresponding item of A. The value of i is not important; we only care
           if the list contains a 1, which will result in a non-zero integer.
       ¹   Identity; yield A.
      a    Logical AND; replace non-zero values with the corresponding items of A.
        Ṁ  Take the maximum.

1
うーん、これに関するポリシーが何であるかはわかりませんが、同じユーザーが同じプログラム言語で、別々の回答で2つの異なるアプローチを使用できるようになりました。9バイトと10バイトの両方のスニペットを同じ答えに入れる方が賢明ではないでしょうか。なぜなら、それは同じプログラミング言語であり、あなたも両方だからです。私は複数のユーザーが同じプログラミング言語で複数の答えを理解できますが、個人的には同じプログラミング言語で同じユーザーが異なるアプローチを行う方が編集に適していると思います。ただ私の意見。
ケビンCruijssen

5
それが私の最初のメタ質問であり、コンセンサスは異なるアプローチが異なる回答に投稿されるべきであると思われました。この場合、私のアプローチには最後の最大値以外に共通点がないため、別の投稿に行きました。
デニス

8

05AB1E、21バイト

vyN+Ny-})¹gL<Ãv¹yè})Z

説明

v      }               # for each num in input
 yN+                   # push index + num
    Ny-                # push index - num
        )              # wrap stack in a list
         ¹gL<Ã         # remove indices outside the range of input
              v¹yè})   # get list of elements in input at the remaining indices
                    Z  # get max

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


おそらく常にそれを使用しますが、私は「リストでスタックをラップする」ことに気付いただけです。きちんとした。
GreenAsJade

@GreenAsJade:ええ、それは私が最もよく使うコマンドの1つです:)
Emigna

7

Haskell、61 57 55バイト

f x=maximum[a|(n,a)<-x,(i,b)<-x,b==abs(n-i)]
f.zip[0..]

使用例:(f.zip[0..]) [5,28,14,5,6,3,4,7]-> 14

(多かれ少なかれ)の定義の直接の実装:各インデックスのn入力リストのxキープをa := x!!nインデックスがあるかどう等しいが。最大値を見つけます。ib := x!!iabs(n-i)

編集:@xnorは2バイトを保存しました。ありがとう!


使用していないのでx、で関数を定義しz、で作成する方が短くなりますzip[0..]
XNOR

6

ゼリー、10 バイト

,N+JFfJị¹Ṁ

オンラインでお試しください!または、すべてのテストケースを確認します

使い方

,N+JFfJị¹Ṁ  Main link. Argument: A (array)

,N          Pair A with -A (element-wise negative).
   J        Yield the indices of A [1, ..., len(A)].
  +         Add the elements of A (and their negatives) with the corr. indices.
    F       Flatten the resulting 2D array.
     fJ     Filter indices; remove invalid indices (not in [1, ..., len(A)]) from
            the generated array. The result is the list of all indices of eligible
            elements of A.
       ị¹   Retrieve the corresponding elements of A.
         Ṁ  Take the maximum.


5

EXCEL:32 30バイト

=MAX(IF(A:A-ROW(A:A)<0,A:A,0))

こんなに短かったとはまだ信じられません...

使用方法:
これを列Aのセルを除く任意のセルに貼り付けます。貼り付けた後、編集中にcontrol+ shift+ enterを押して正しく入力します。
列Aに値を入力します(セルごとに1つの値(CSVエントリごと))。

これがどのように機能するかを知りたい場合、Excelでのゴルフのヒントに関する質問に追加のヒントを投稿しました。


私はこれらの優れたゴルフを愛しています-誰だと思います!!
GreenAsJade

4

JavaScript(ES6)、61バイト

a=>Math.max(...a.filter((_,i)=>a.some((e,j)=>e==i-j|e==j-i)))

4

Perl、45バイト

+2を含む -ap

STDINの行に番号を付けます。

largest.pl <<< "5 12 2 5 4 7 3 3 6 2 10 5 5 5 4 1 8 5"

largest.pl

#!/usr/bin/perl -ap
($_)=sort{$b-$a}map@F[$^P=$n-$_,$n+++$_],@F

^Pリテラル制御文字で置き換えることでもう1バイト取得できますが、最近のperlのSTDERRで警告が発生します。

想定 largest number + array length < 2^32


3

Pyth、19 17バイト

-2バイトの@ Pietu1998に感謝

eS@LQ@UQs.e,-kb+b

STDINのリストの入力を受け取り、結果を出力するプログラム。

オンラインで試す

使い方

eS@LQ@UQs.e,-kb+b  Program. Input: Q
         .e        Map over Q (implicit input fill) with elements as b and indices as k:
            -kb     k-b
               +b   k+b (Implicit fill with k)
           ,        2-element list of those (possible indices)
        s          Flatten that
      UQ           Yield [0, 1, 2, 3..., len(Q)-1]
     @             Filter the flattened list by presence in the above, removing invalid
                   indices
  @LQ              Index into Q at those indices
 S                 Sort that
e                  Yield the last element of that, giving the maximum
                   Implicitly print

}#はと同じ@です。また、最後のビットを再配置すると、Pythが自動挿入,-kb+bkするため、最後のビットを削除できますk
PurkkaKoodari

@ Pietu1998ありがとう。列挙の暗黙の塗りつぶしについては知りませんでした。それは他のマップタイプの関数で機能しますか?
TheBikingViking

任意のラムダで動作し、残りのラムダを最初のラムダ変数で自動入力します。
PurkkaKoodari

3

MATL、13バイト

ttn:tYTq=a)X>

入力は列ベクトルでなければなりません。つまり、入力は[1; 2; 3]のようにセミコロンで区切られるか、または[1,2,3] 'のように転置目盛りでコンマで区切られます。

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

すべてのテストケース:(A)(B)(C)(D)(E)(F)

MATLチャットルームで 2文字を節約するための提案をしてくれたSueverに感謝します。

説明:

全体的な戦略は、Octave / MATLABの答えと同じです。ここでは、基本的な概念が説明されています:https : //codegolf.stackexchange.com/a/94161/42247

このMATL回答の特定のコードは、次のように構築されています。

この方法の中核は、ij番目のエントリがabs(ij)であるテプリッツ行列の構築です。最初に、次のようにMATLのtoeplitzコマンドYTを使用してエントリabs(i-1)+1でToeplitz行列を作成します。

n:tYT % Equivalent to @(v)toeplitz(1:length(v))

これがどのように機能するかを見るために、このコードスニペット「v」への入力ベクトルを呼び出しましょう。「n」はvの長さを見つけ、「:」はベクトル1:length(v)を構築します。次に、「t」はスタック上に1:length(v)の別のコピーを作成します。この余分なコピーは、MATLのYT関数の既知のバグ(toeplitz()と同等のMATL)のために必要です。この場合、入力の1の代わりに2つのコピーが必要です。次に、YTはこのベクトルの2つのコピー1 :length(v)をスタックから取り除き、それらからabs(ij)+1 Toeplitz行列を作成します。

次に、この行列から1を減算して、エントリabs(ij)を含むテプリッツ行列を取得し、このabs(ij)テプリッツ行列が入力の列コピーを含むすべての列ベクトルの行列に等しいij位置を見つける必要があります。ベクトルv。これは次のように行われます。

t n:tYT q=
% t [code] q= is equivalent to @(v) [code](v)-1 == v

最初の「t」は入力の余分なコピーを作成し、スタックに保存します。「n:tYT」は、前述のようにテプリッツ行列を作成し、スタックに出力します。次に、「q」はテプリッツ行列から1を減算し、「=」はabs(ij)行列と列が入力のコピーであるベクトルとの間の要素ごとの等価比較を行います。列ベクトルを行列と比較することにより、MATLAB / MATLの演算子ブロードキャストルールを暗黙的に利用していることに注意してください(比較の列ベクトルは、コマンドを発行せずに行列を作成するためにコピーされます)。

最後に、上記で構築された行列差のij番目のエントリが1になるような列jがある行インデックスiを見つけ、これらのインデックスに対応する入力ベクトルの値を取得し、最大値を取る必要があります。これは、次の3つのステップで行います。

1)非ゼロを含む行のインデックスを検索します。

tn:tYTq= a
% [code] a is equivalent to @(v) any([code](v))

2)これらのインデックスに対応する入力ベクトルの要素を抽出します。

t tn:tYTq= a ) X>
% t [code] ) is equivalent to @(v) v([code](v)]

3)最大要素を見つけて返します:

t tn:tYTq= a ) X>
% [code] X> is equivalent to @(v) max(v).

機能の動作はリリース20.2.2でYT変更されました。現在では、デフォルトで1つの入力を使用します(これは一般により便利です)。ここで1バイト節約できます(t前に削除しますYT)が、言語の変更が課題を後回しにしているため、悪用することはできません。しかし、それはあなたの答えが新しいリリースではもはや有効ではないという効果があります。新しいリリースは現在TIOで公開されています
ルイスメンドー

リンクされたコードを編集してメモを残すか、古いリンクをサポートするMATLオンラインインタープリターへのこのリンクを使用できます。残念ながら、他のリンクも更新する必要があります。ご不便をおかけして申し訳ありません
ルイスメンドー

それに関係なく、次のように置き換えn:て1バイト節約f
ルイスメンドー

2

ルビー、66バイト

->a{i=-1;a.map{|e|i+=1;[a[j=i+e]||0,a[0>(k=i-e)?j:k]||0].max}.max}

2

オクターブ/ MATLAB、40バイト

@(v)max(v(any(toeplitz(1:nnz(v))-v==1)))

入力は列ベクトルでなければなりません。

3バイトの節約を提案してくれたLuis Mendoに感謝します(コメントを参照)

さらに4バイトを節約する提案をしてくれたSueverに感謝します(~~(sum())をany()に置き換えます)

説明:

入力ベクトルvが与えられた場合、この問題は次の離散方程式のすべての解i、jを見つけることと等価です。

abs(i-j) = v(i),   i,j both in 1..k,

ここで、abs()は絶対値関数です。この方程式が解かれる各v(i)は、最大化できる候補解の1つです。

iとjの離散関数として、左側のすべての可能性は、次のように見えるテプリッツ行列に配置できます。

[0, 1, 2, 3, 4]
[1, 0, 1, 2, 3]
[2, 1, 0, 1, 2]    <--- abs(i-j)
[3, 2, 1, 0, 1]
[4, 3, 2, 1, 0]

そして、右側はiに依存しないため、列のすべてが入力のコピーであるマトリックスに配置することができます。

[v(1), v(1), v(1), v(1), v(1)]
[v(2), v(2), v(2), v(2), v(2)]
[v(3), v(3), v(3), v(3), v(3)]   <--- v(i)
[v(4), v(4), v(4), v(4), v(4)]
[v(5), v(5), v(5), v(5), v(5)]

方程式のすべての解を見つけるために、これらの2つの行列を減算し、ゼロがある場所を見つけます。ゼロがある行は、abs(ij)= v(i)となるajがある場合の目的のインデックスiに対応します。

その他のトリック:

  • 絶対値関数に1を加えたabs(ij)+1を構築するために必要な文字数が少なくなり、真の(シフトされていない)絶対値関数を構築するのではなく、差が1である場所を確認します。
  • 自動演算子ブロードキャストを使用して、vの列コピーを暗黙的に作成します
  • length()の代わりにnnz()を介して入力の長さを取得します。これは、問題ステートメントで入力が正であると言われるため機能します。

入力形式はデフォルトで柔軟です。あなたはv列ベクトルとして取ることができます、答えでそれを述べてください。また、あなたは交換するfindことにより、~~さらに2つのバイトを保存するために
ルイスMendo

@LuisMendoありがとう、私はあなたの提案を組み込むために投稿を編集しました!
ニック・アルジェ

異なる言語(または同じ言語で大幅に異なるアプローチ)については、別の回答投稿してください。言語に関する質問がある場合は、MATLチャットルームがあります
ルイスメンドー

ところで、MATLのバグが原因でtoeplitzYT)、それはデフォルトでは二つの入力(ないもの)を使用しています
ルイスMendo

うんいいね。私はMATLにそれを翻訳し、ここでは別の答えを投稿:codegolf.stackexchange.com/a/94183/42247
ニック・アルジェ

1

Mathematica、69バイト

Max@MapIndexed[{If[#2[[1]]>#,a[[#2-#]],{}],a[[#2+#]]~Check~{}}&,a=#]&

匿名関数。整数のリストを入力として受け取り、整数を出力として返します。生成されたメッセージを無視します。


1

Scala、94バイト

a=>a.zipWithIndex.filter(p=>a.zipWithIndex.exists(x=>x._1==Math.abs(p._2-x._2))).unzip._1.max


1

Java 7、125 123バイト

int c(int[]a){int r=0,i=0,l=a.length,x;for(;i<l;r=l>(x=i+a[i])?a[x]>r?a[x]:r:r,r=(x=i-a[i++])>0?a[x]>r?a[x]:r:r);return r;}

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

Ungolfed(並べ替え)とテストコード:

ここで試してみてください。

class M{
  static int c(int[] a){
    int r = 0,
        i = 0,
        l = a.length,
        x;
    for(; i < l; r = l > (x = i + a[i])
                      ? a[x] > r
                         ? a[x]
                         : r
                      : r,
                 r = (x = i - a[i++]) > 0
                      ? a[x] > r
                         ? a[x]
                         : r
                      : r);
    return r;
  }

  public static void main(String[] a){
    System.out.println(c(new int[]{ 1, 13 }));
    System.out.println(c(new int[]{ 2, 9, 8, 3, 72, 2 }));
    System.out.println(c(new int[]{ 5, 28, 14, 5, 6, 3, 4, 7 }));
    System.out.println(c(new int[]{ 1, 3, 5, 15, 4, 1, 2, 6, 7, 7 }));
    System.out.println(c(new int[]{ 5, 1, 3, 5, 2, 5, 5, 8, 5, 1, 5, 1, 2, 3 }));
    System.out.println(c(new int[]{ 5, 12, 2, 5, 4, 7, 3, 3, 6, 2, 10, 5, 5, 5, 4, 1, 8, 5 }));
  }
}

出力:

13
8
14
7
5
10

1
xとyは必要ありません。それらの1つを再利用するだけです(-2)。また、左と右の両方のケースを常にテストする必要があるため、rを巨大な3進数で設定することはできないと思います。
-mrco

1
@mrcoありがとう,y。そして、私は確かに単一の三項ifに関して同じ結論に達しました。もちろん可能ですが、チェックを2回行うことで、さらに長くなります。
ケビンCruijssen


1

Python、58バイト

Tony S.のRubyの回答に基づいています。この回答はPython 2および3で機能します。ゴルフの提案を歓迎します。

lambda n:max([n[i+v]for i,v in enumerate(n)if i+v<len(n)])

アンゴルフ

def f(array):
    result = []
    for index, value in enumerate(array):
        if index + value < len(array):
            result.append(array[index + value])
    return max(result)

1

ルビー56バイト

私の最小のルビーソリューション。

->n{x=[];i=0;n.map{|v|x<<n[v+i]&&v+i<n.size;i+=1};x.max}

Railsコンソールでのテストは非常に簡単です

a = ->n{x=[];i=0;n.map{|v|x<<n[v+i]&&v+i<n.size;i+=1};x.max}
a[[1, 13]
=> 13
a[[2, 9, 8, 3, 72, 2]]
=> 8
a[[5, 12, 2, 5, 4, 7, 3, 3, 6, 2, 10, 5, 5, 5, 4, 1, 8, 5]]
=> 10

これは、63バイトから始まりました。それを減らすための提案に感謝します。


.map代わりに使用できます.each
16

(x) if (y)に置き換えることもできます(y)&&(x)
チョイス

あなたは使用することができますa<<b代わりにa+=[b]
Sherlock9

@ Sherlock9 <<を忘れました。a + = [b]の使用は、&&を使用したCyoceの提案では機能しませんでした。今では、感謝します!
トニーS.

1

実際には、17バイト

この回答は、実際にPythonの回答を移植したものです。ゴルフの提案を歓迎します。オンラインでお試しください!

;╗ñ♂Σ⌠╜l>⌡░⌠╜E⌡MM

アンゴルフ

         Implicit input L.
;╗       Duplicate L and save a copy of L to register 0.
ñ        enumerate() the other copy of L.
♂Σ       sum() all the pairs of [index, value of n]. Call this list Z.
⌠...⌡░   Push values of Z where the following function returns a truthy value. Variable v_i.
  ╜        Push L from register 0.
  l        Push len(L).
  >        Check if len(L) > v_i.
⌠...⌡M   Map the following function over Z_filtered. Variable i.
  ╜        Push L from register 0.
  E        Take the ith index of L.
M        max() the result of the map.
         Implicit return.

0

T-SQL(sqlserver 2016)、132バイト

ゴルフ:

;WITH C as(SELECT value*1v,row_number()over(order by 1/0)n FROM STRING_SPLIT(@,','))SELECT max(c.v)FROM C,C D WHERE abs(D.n-C.n)=D.v

ゴルフをしていない:

DECLARE @ varchar(max)='2, 9, 8, 3, 72, 2'

;WITH C as
(
  SELECT
    value*1v,
    row_number()over(order by 1/0)n
  FROM
    STRING_SPLIT(@,',')
)
SELECT
  max(c.v)
FROM
  C,C D
WHERE
  abs(D.n-C.n)=D.v

フィドル


0

JavaScript(ES6)、56 54バイト

let f =
    
l=>l.map((n,i)=>m=Math.max(m,l[i+n]|0,l[i-n]|0),m=0)|m

console.log(f([1, 13])); // → 13
console.log(f([2, 9, 8, 3, 72, 2])); // → 8
console.log(f([5, 28, 14, 5, 6, 3, 4, 7])); // → 14
console.log(f([1, 3, 5, 15, 4, 1, 2, 6, 7, 7])); // → 7
console.log(f([5, 1, 3, 5, 2, 5, 5, 8, 5, 1, 5, 1, 2, 3])); // → 5
console.log(f([5, 12, 2, 5, 4, 7, 3, 3, 6, 2, 10, 5, 5, 5, 4, 1, 8, 5])); // → 10


0

Clojure、68バイト

#(apply max(map(fn[i](get % i 0))(flatten(map-indexed(juxt - +)%))))

例えば、(map-indexed (juxt - +) [3 4 1 2])ある([-3 3] [-3 5] [1 3] [1 5])(インデックス+/-これらは元のベクトルからのルックアップ値に使用され、その値)(アウトオブレンジをデフォルト0)と最大値が見出されます。まだ少し冗長に感じますが、少なくとも私は使用するようになりましたjuxt:)

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