ゼロに隣接する最大数を見つける


38

チャレンジ:

ベクトル/整数のリストを入力として受け取り、ゼロに隣接する最大数を出力します。

仕様:

  • いつものように、オプションの入力および出力形式
  • 少なくとも1つのゼロ要素と、少なくとも1つの非ゼロ要素があると想定できます。

テストケース:

1 4 3 6 0 3 7 0
7

9 4 9 0 9 0 9 15 -2
9

-4 -6 -2 0 -9
-2

-11 0 0 0 0 0 -12 10
0

0 20 
20

幸運と幸せなゴルフ!


4番目のようなテストケースを追加する必要がありますが、結果が負の場合(リストには正の数があります)。
mbomb007

Retinaでこれを試してみるつもりでしたが、ネガティブがあることに気付きました。網膜はネガが嫌いです。
mbomb007

2
網膜にできることとできないことを指示させないでください。責任を持って、あなたがボスです!
スチューイーグリフィン

回答:



19

MATL、10バイト

t~5BZ+g)X>

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

説明

入力[-4 -6 -2 0 -9]を例としてみましょう。

t     % Input array. Duplicate
      %   STACK: [-4 -6 -2 0 -9],  [-4 -6 -2 0 -9]
~     % Logical negate. Replaces zeros by logical 1, and nonzeros by logical 0
      %   STACK: [-4 -6 -2 0 -9],  [0 0 0 1 0]
5B    % Push logical array [1 0 1] (5 in binary)
      %   STACK: [-4 -6 -2 0 -9], [0 0 0 1 0], [1 0 1]
Z+    % Convolution, maintaining size. Gives nonzero (1 or 2) for neighbours of
      % zeros in the original array, and zero for the rest
      %   STACK: [-4 -6 -2 0 -9], [0 0 1 0 1]
g     % Convert to logical
      %   STACK: [-4 -6 -2 0 -9], [0 0 1 0 1]
)     % Use as index into original array
      %   STACK: [-2 -9]
X>    % Maximum of array.
      %   STACK: -2
      % Implicitly display

x(~~(dec2bin(5)-48))。それを実装するのは誰のアイデアですか?非常に賢く、論理配列に役立ちます!:) いい答えだ!
スチューイーグリフィン

1
よろしくお願いします!私はdec2bin()-'0'MATLABで何百回も使用していたので、MATLにいる必要があることを知っていました:
ルイス・メンドー

5
ちなみに、すべての操作の後にスタックのコンテンツを含めたという事実は、賛成だけの価値があります。それはそんなに簡単にMATL =)を理解(そしておそらく学ぶ)することができます
Stewieグリフィン

2
畳み込みロック。+1
スーバー

10

05AB1E、9バイト

ü‚D€P_ÏOZ

説明

ü‚         # pair up elements
  D        # duplicate
   €P      # product of each pair (0 if the pair contains a 0)
     _     # logical negate, turns 0 into 1 and everything else to 0
      Ï    # keep only the pairs containing at least 1 zero
       O   # sum the pairs
        Z  # take max

オンライン通訳では機能しませんが、オフラインで機能します。


これはすごいです!ジャストインタイム:p。
アドナン

1
これらの演算子の1つを実装しましたか?:)
Stewieグリフィン

1
@WeeingIfFirst:ü昨日追加されました:)
エミグナ

2
0実際の答えが否定的な場合、これは戻りませんか?ゼロを捨てる必要があると思います。
リン

1
@Lynnナイスキャッチ!これは、簡単に交換することによって固定することができる˜O(合計)。
アドナン

9

ハスケル、63の 43バイト

f x=maximum[a+b|(a,b)<-tail>>=zip$x,a*b==0]

4バイトの@MartinEnderに感謝します!


a*b==0代わりに使用できると思います||
マーティンエンダー

zipを使用して以前のバージョンに戻る必要があります。ここで、aとbeはもはや隣接していません
ダミアン

ここではlambdabotは必要ありません。これは「通常の」ハスケル
ダミアン

8

Pyth、12 11 10バイト

eSsM/#0,Vt

ペアを形成し、ゼロメンバーでフィルタリングし、合計でソートし、最大を返します。


,Vt(暗黙的QQ)は、と同じペアを返します.:Q2が、ペアは反転されます。ただし、動作するはずです。
-PurkkaKoodari

f}0Tis/#0
isaacg

7

JavaScript(ES6)、59 57 56バイト

let f =
    
l=>l.map((n,i)=>m=l[i-1]==0|l[i+1]==0&&n>m?n:m,m=-1/0)|m

console.log(f([1, 4, 3, 6, 0, 3, 7, 0]));       // 7
console.log(f([9, 4, 9, 0, 9, 0, 9, 15, -2]));  // 9
console.log(f([-4, -6, -2, 0, -9]));            // -2
console.log(f([-11, 0, 0, 0, 0, 0, -12, 10]));  // 0
console.log(f([3, 0, 5]));                      // 5
console.log(f([28, 0, 14, 0]));                 // 28

編集:Huntroのおかげで2バイトを節約
編集:ETHproductionsのおかげで1バイトを節約


1
==代わりに===
Huntro

1
いくつかの場所で数バイトを節約できますl=>l.map((n,i)=>m=l[i-1]*l[i+1]==0&n>m?n:m,m=-1/0)|m
。– ETHproductions

エラー:{「メッセージ」:「構文エラー」、「ファイル名」:「stacksnippets.net/js」、「lineno」:15、「colno」:3}
-RosLuP

@RosLuP-これには、矢印機能をサポートするES6が必要であり、すべてのブラウザーで機能しません(Edgeの前のすべてのIEバージョン、v10未満のすべてのSafariバージョンなどを含む)
Arnauld

6

JavaScript(ES6)、53バイト

a=>(m=-1/0,a.reduce((l,r)=>(m=l*r||l+r<m?m:l+r,r)),m)

を使用するのが好きだからreduceです。代替ソリューション、53バイト:

a=>Math.max(...a.map((e,i)=>e*a[++i]==0?e+a[i]:-1/0))


4

Ruby、51バイト

->a{a.each_cons(2).map{|a,b|a*b!=0?-1.0/0:a+b}.max}

使用法

f=->a{a.each_cons(2).map{|a,b|a*b!=0?-1.0/0:a+b}.max}
p f[gets.split.map(&:to_i)]

括弧を必要とは思わないa+b
マーティンエンダー

@Martin Ender構文エラーが発生する... ideone.com/F6Ed4B
cia_rana

Ruby 2.3で動作します。(たとえば、ここで利用可能:repl.it/languages/ruby
マーティンエンダー

@Martin Ender「==」の代わりに「!=」を使用すると、機能します。アドバイスをしてくれてありがとう!ideone.com/F6Ed4B
cia_rana

バグがそこにあります。:( -3 -2 0リターンは0私が交換すると思います。...?0:...とは...?-1.0/0:...5バイトを追加し、それを修正する必要があります。
M-chrzan

4

PHP、77 68 71バイト

匿名から-3バイト、 MartinEnderから-4および-2

preg_match_all("#(?<=\b0 )\S+|\S+(?= 0)#",$argv[1],$m);echo max($m[0]);

と走る php -r '<code>' '<space separated values>'


2
\Kこれまでのマッチを破棄するために使用することは、後読みを使用するよりも短くなります。
user59178

2
入力にスペース区切りを使用して\S+から、符号付き整数の照合に使用することもできます。おそらくを使用\b0,する必要があるので、を追加する必要はありません,
マーティンエンダー

1
これは次のような入力に対して機能します4 0 0 5か?
トンホスペル

@TonHospelいいえ。\K代替品では動作しませんか?理由は不明ですが、2番目の選択肢はを返すため、の前に一致するものは0 0もうありません。修正済み、ありがとう。05
タイタス

register_globalsを使用して他のPHPソリューションを見てください
ヨルグヒュルサーマン

4

Java 7、118 105 106バイト

int d(int[]a){int i=0,m=1<<31,c;for(;++i<a.length;m=a[i]*a[i-1]==0&(c=a[i]+a[i-‌​1])>m?c:m);return m;}

代わりに算術アプローチを使用することで、@ cliffrootのおかげで13バイト節約されました。バグを発見した後、@ mrcoに1バイト追加しました(追加したテストケース2, 1, 0はの2代わりに戻ります1)。

未ゴルフ&テストコード:

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

class M{
  static int c(int[] a){
    int i,
        m = a[i=0],
        c;
    for(; ++i < a.length; m = a[i] * a[i-1] == 0 & (c = a[i] + a[i - 1]) > m)
                           ? c
                           : m);
    return m;
  }

  public static void main(String[] a){
    System.out.println(c(new int[]{ 1, 4, 3, 6, 0, 3, 7, 0 }));
    System.out.println(c(new int[]{ 9, 4, 9, 0, 9, 0, 9, 15, -2 }));
    System.out.println(c(new int[]{ -4, -6, -2, 0, -9 }));
    System.out.println(c(new int[]{ -11, 0, 0, 0, 0, 0, -12, 10 }));
    System.out.println(c(new int[]{ 0, 20 }));
    System.out.println(c(new int[]{ 2, 1, 0 }));
  }
}

出力:

7
9
-2
0
20
1

1
算術を使用するわずかに異なるアプローチが機能しているようですint d(int[]a){int i,m=a[i=0],c;for(;++i<a.length;m=a[i]*a[i-1]==0&(c=a[i]+a[i-1])>m?c:m);return m;}
クリフルート

3
最初の数値が0に隣接していないが、0に隣接している任意の数値よりも大きい場合、出力は間違っています。テストケース{2、1、0}で再現可能です。これを修正するには、iを0で直接初期化し、mを1 << 31(全体で+1)で初期化します。
-mrco


3

Image Processing Toolboxを備えたMATLAB、32バイト

@(x)max(x(imdilate(~x,[1 0 1])))

これは匿名関数です。テストケースの使用例:

>> f = @(x)max(x(imdilate(~x,[1 0 1])))
f =
  function_handle with value:
    @(x)max(x(imdilate(~x,[1,0,1])))

>> f([1 4 3 6 0 3 7 0])
ans =
     7

>> f([9 4 9 0 9 0 9 15 -2])
ans =
     9

>> f([-4 -6 -2 0 -9])
ans =
    -2

>> f([-11 0 0 0 0 0 -12 10])
ans =
     0

>> f([0 20])
ans =
    20

3

Dyalog APL、14 バイト

⌈/∊2(+↑⍨0∊,)/⎕

⌈/ 最大の

平坦化された( " e nlisted"

2(... )/ペアワイズ

+ 合計(ゼロと何かが何か)

↑⍨ 取られた場合

0 ゼロ

のメンバーです

, ペア(点灯。左側の番号と右側の番号の連結)

TryAPLオンライン!


3

R、48 47バイト

編集:@Vloのおかげでエラーを修正し、標準入力から入力を読み取るように変更し、パラセシスを割り当てwてスキップすることで1バイトを保存しました。

function(v)sort(v[c(w<-which(v==0)-1,w+1)],T)[1]

v=scan();w=which(v==0);sort(v[c(w-1,w+1)],T)[1]

ネストされていない説明

  1. ベクトルvが値0をとるインデックスを見つけます。w <- which(v == 0)
  2. インデックスを含む新しいベクトルを作成+-1w-1w+1
  3. インデックスに一致する要素を抽出しw-1w+1
  4. 降順でソートし、最初の要素を抽出します

の最後または最初の要素がvゼロの場合、w+-1v[length(v)+1]返すことを意味するベクトルの長さ以外のインデックスを効果的にフェッチすることに注意してくださいNA。これは一般に問題ではありませんが、オプションを指定しない限り、ベクトルにオカレンスmax()NAあれば関数は不便に戻りますna.rm=T。したがって、を使用するよりも最初の要素をソートして抽出する方が2バイト短くなりますmax()。例:

max(x,na.rm=T)
sort(x,T)[1]

1
余分な括弧は、それ以外の場合は、最大で0などの右側にあるすべてのテストケース失敗する必要c(1, 4, 3, 6, 0, 10, 7, 0) c((w<-which(v==0))-1,w+1)TADは、スキャンと短いビットもsort((v<-scan())[c(w<-which(v==0)-1,w+1)],T)[1]
VLO

@Vlo明らかなエラーを指摘してくれてありがとう、+ 1。あなたの提案された解決策では、あなたも忘れました();)。コードを更新し、v事前の操作を割り当てました。
ビリーウォブ

3

Mathematica、46 43バイト

@MartinEnderにより3バイトを節約しました

Max[Tr/@Partition[#,2,1]~Select~MemberQ@0]&

匿名関数。入力として整数のリストを受け取り、出力として整数を返します。Rubyソリューションに基づいています。


2

Perl、42バイト

+1を含む -p

STDINの行に番号を付けます

largest0.pl <<< "8 4 0 0 5 1 2 6 9 0 6"

largest0.pl

#!/usr/bin/perl -p
($_)=sort{$b-$a}/(?<=\b0 )\S+|\S+(?= 0)/g

2

ジュリア、56 55バイト

f(l)=max(map(sum,filter(t->0 in t,zip(l,l[2:end])))...)

近傍値のタプルを作成し、0を含むタプルを取得し、タプル値を合計して最大値を見つけます


1

Python 2、74バイト

def f(x):x=[9]+x;print max(x[i]for i in range(len(x)) if 0in x[i-1:i+2:2])

0現在の要素の左または右のいずれかの位置にaがある場合、すべての要素を循環させ、ジェネレーターに含めてから実行しますmax。リストに非0数字を埋め込む必要があります。スライス[-1:2:2]には何も含まれないため、含まれません。


1

T-SQL、182バイト

ゴルフ:

DECLARE @x varchar(max)='1 5 4 3 6 1 3 17 1 -8 0 -7'

DECLARE @a INT, @b INT, @ INT WHILE @x>''SELECT @a=@b,@b=LEFT(@x,z),@x=STUFF(@x,1,z,''),@=IIF(@a=0,IIF(@b<@,@,@b),IIF(@b<>0 or @>@a,@,@a))FROM(SELECT charindex(' ',@x+' ')z)z PRINT @

ゴルフをしていない:

DECLARE @x varchar(max)='1 5 4 3 6 1 3 17 1 -8 0 -7'

DECLARE @a INT, @b INT, @ INT
WHILE @x>''
  SELECT 
   @a=@b,
   @b=LEFT(@x,z),
   @x=STUFF(@x,1,z,''),
   @=IIF(@a=0,IIF(@b<@,@,@b),IIF(@b<>0 or @>@a,@,@a))
  FROM(SELECT charindex(' ',@x+' ')z)z 
PRINT @

フィドル


1

PowerShell v3 +、62バイト

param($n)($n[(0..$n.count|?{0-in$n[$_-1],$n[$_+1]})]|sort)[-1]

他の回答よりも少し長いですが、気の利いたアプローチです。

入力を受け取ります$n。次にインデックスをループ0..$n.countし、Where-Object|?{...})を使用して配列の前または次の項目があるインデックスを引き出し0、それらを配列スライスにフィードバックします$n[...]。次に、|sortこれらの要素を使用して、最大のものを取得し[-1]ます。

PS C:\Tools\Scripts\golfing> @(1,4,3,6,0,3,7,0),@(9,4,9,0,9,0,9,15,-2),@(-4,-6,-2,0,-9),@(-11,0,0,0,0,0,-12,10)|%{""+$_+" --> "+(.\largest-number-beside-a-zero.ps1 $_)}
1 4 3 6 0 3 7 0 --> 7
9 4 9 0 9 0 9 15 -2 --> 9
-4 -6 -2 0 -9 --> -2
-11 0 0 0 0 0 -12 10 --> 0

PS C:\Tools\Scripts\golfing> @(0,20),@(20,0),@(0,7,20),@(7,0,20),@(7,0,6,20),@(20,0,6)|%{""+$_+" --> "+(.\largest-number-beside-a-zero.ps1 $_)}
0 20 --> 20
20 0 --> 20
0 7 20 --> 7
7 0 20 --> 20
7 0 6 20 --> 7
20 0 6 --> 20

1

q、38バイト

{max x where 0 in'x,'(next x),'prev x}

最大値が0の後に来る場合、これは機能しないようです。また、私はqの専門家ではありませんが{}、関数を作成するにはコードを囲む必要があると思います。
デニス

1

J、18バイト

[:>./2(0&e.\#+/\)]

説明

[:>./2(0&e.\#+/\)]  Input: array A
                 ]  Identity. Get A
     2              The constant 2
      (         )   Operate on 2 (LHS) and A (RHS)
               \    Get each subarray of size 2 from A and
             +/       Reduce it using addition
           \        Get each subarray of size 2 from A and
       0&e.           Test if 0 is a member of it
            #       Filter for the sums where 0 is contained
[:>./               Reduce using max and return

1

Perl 6、53バイト

{max map ->$/ {$1 if !$0|!$2},(1,|@_,1).rotor(3=>-2)}

拡張:

# bare block lambda with implicit signature of (*@_)
{
  max

    map

      -> $/ {           # pointy lambda with parameter 「$/」
                        # ( 「$0」 is the same as 「$/[0]」 )
        $1 if !$0 | !$2 # return the middle value if either of the others is false
      },

      ( 1, |@_, 1 )     # list of inputs, with added non-zero terminals
      .rotor( 3 => -2 ) # grab 3, back-up 2, repeat until less than 3 remain
}

1

PHP、66バイト

foreach($a=$argv as$k=>$v)$v||$m=max($m,$a[$k-1],$a[$k+1]);echo$m;

とても簡単です。入力を反復、及び数である場合0、それはセット$m2つのに隣接する数字の最大数までの以前の値$m

次のように実行します(-d美学のためにのみ追加):

php -d error_reporting=30709 -r 'foreach($a=$argv as$k=>$v)$v||$m=max($m,$a[$k-1],$a[$k+1]);echo$m;' -- -4 -6 -2 0 -9;echo

1

C#76 74バイト

using System.Linq;i=>i.Zip(i.Skip(1),(a,b)=>a*b==0?1<<31:a+b).Max(‌​);

説明:

zipを使用して配列自体を結合しますが、2番目の参照の最初の値をスキップして、アイテム0がアイテム1に結合するようにします。aにbを掛けます。結果がゼロの場合、そのうちの1つはゼロで、a + bを出力する必要があります。それ以外の場合は、言語で可能な最小の整数を出力します。常にゼロと非ゼロを持っているという仮定を考えると、この最小値が最大値として出力されることはありません。

使用法:

[TestMethod]
public void LargestFriend()
{
    Assert.AreEqual(7, F(new int[] { 1, 4, 3, 6, 0, 3, 7, 0 }));
    Assert.AreEqual(9, F(new int[] { 9, 4, 9, 0, 9, 0, 9, 15, -2 }));
    Assert.AreEqual(-2, F(new int[] { -4, -6, -2, 0, -9 }));
    Assert.AreEqual(0, F(new int[] { -11, 0, 0, 0, 0, 0, -12, 10 }));
    Assert.AreEqual(20, F(new int[] { 0, 20 }));
}

こんにちは。でスペースを削除できますint[]i) {。また、現在のコードで75バイトをカウントします(スペースを削除した場合は74バイト)。
ケビンCruijssen

三元を反転させることで4バイト節約できると思います。– a?b?i.Min()).Max():a:b
Titus

プラスusing System.Linq;、いいえ?
pinkfloydx33

確かに、この質問は完全なプログラムではなくメソッドを要求しただけSystem.Linq;で、デフォルトの新しいクラステンプレートの一部です。
Grax32

@Graxどちらにしてもusing、バイトカウントにステートメントを含める必要があります
-TheLethalCoder

1

R、48 54バイト

s=scan()

w=which;max(s[c(w(s==0)+1,w(s==0)-1)],na.rm=T)

コンソール入力からベクトルを読み取り、0に隣接するすべての値の最大値を取得します。

編集:境界で生成されたNAをキャッチ、rturnbullに感謝!


私は間違っていますか?pastebin.com/0AA11xcw
manatwork

20 0、などの場合、これは失敗しs[w(s==0)+1]ます。なぜならNAmaxのデフォルトの処理NAはを返すからです 引数を追加することで修正するna.rm=Tか、使用するコードを作り直すことができますsort(上記のRの回答を参照)。
rturnbull

すべてを1行に凝縮できますか?Rでコーディングする方法はわかりませんが、できると思います。
clismique

@ Qwerp-Derp:私の知る限りではありません。scan()は、コンソール入力がベクトルを読み込むのを待機し、空の行を入力することで入力ストリームが閉じられます。2本の線を1本として実行する場合、2番目の部分はベクトルsへの入力として少なくとも部分的に認識されます。
ヘッドクラッシュ

0

ラケット183バイト

(λ(k)(let*((lr(λ(l i)(list-ref l i)))(l(append(list 1)k(list 1)))(m(for/list((i(range 1(sub1(length l))))
#:when(or(= 0(lr l(sub1 i)))(= 0(lr l(add1 i)))))(lr l i))))(apply max m)))

詳細バージョン:

(define f
 (λ(k)
    (let* ((lr (λ(l i)(list-ref l i)))
           (l (append (list 1) k (list 1)))
           (m (for/list ((i (range 1 (sub1(length l))))
                         #:when (or (= 0 (lr l (sub1 i)))
                                    (= 0 (lr l (add1 i))) ))
                (lr l i) )))
      (apply max m) )))

テスト:

(f (list 1 4 3 6 0 3 7 0))
(f (list 9 4 9 0 9 0 9 15 -2))
(f (list -4 -6 -2 0 -9))
(f (list -11 0 0 0 0 0 -12 10))
(f (list 0 20 ))

出力:

7
9
-2
0
20

0

C 132バイト

mainの戻りコードを使用した出力:

int main(int a,char**_){int i,m=0;_[0]=_[a]="1";for(i=1;i<a;++i){m=(*_[i-1]-48||*_[i+1]-48?m>atoi(_[i])?m:atoi(_[i]):m);}return m;}

atoi呼び出しの1つを保存することで数バイトを保存できるはずですが、効率的な方法を見つけることができませんでした。(,tプラスt=プラス,プラスt2回は長すぎます)。また、これは技術的に未定義の動作(_ [a]を "1"に設定)を使用しますが、私が知っているすべてのコンパイラはデフォルトで許可しています。

戦略:配列の開始と終了を1で埋めてから、内部セクションをループして各近傍をチェックします。


0

PHP 69 64バイト

JörgHülsermannとTitusからのオンとオフのバイト。=(-5)

register_globalsを有効にする必要があります。使用法:http://localhost/notnull.php?i[]=9&i[]=-5i[]=...

$x=$_GET['i'];
$y=0;
foreach($x as $j){
if($y<abs($j)){
$y=$j;
}
}
echo $y;

ゴルフ:

$x=$_GET['i'];$y=0;foreach($x as $j)if($y<abs($j))$y=$j;echo $y;

入力を配列として直接使用しないのはなぜですか。json_encodeの理由がわかりませんでした。
ヨルクヒュルサーマン

デフォルト以外の設定の場合、設定変更の完全な長さをバイトカウントに追加する必要があります。(meta.codegolf.stackexchange.com/q/4778#4778を参照)この場合、+ 21バイト-d register_globals=1(またはregister_globalsがデフォルトで有効になっているバージョンを指定)
Titus

しかしjson_decode、いいアイデアです。
タイタス

@Titus私の平均で?id[]=1&id[]=2&id[]=3 、その後$_GET["id"]、アレイをバック与えます。json_decodeが私のためには意味がありません。このため
イェルクHülsermann

@JörgHülsermannバイトはかかりますが、それでもいいアイデアです。
タイタス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.