私のマトリックスアローヘッドですか?


33

定義

矢印行列はあるマトリックスのすべてのエントリに等しいた0主対角、一番上の行と一番左の列にものを除きます。つまり、マトリックスは次のようになります。

* * * * * *
* * 0 0 0 0
* 0 * 0 0 0
* 0 0 * 0 0
* 0 0 0 * 0
* 0 0 0 0 *

*はゼロ以外のエントリです。

仕事

非負の整数の正方行列が与えられた場合、上記の定義に従って矢じりかどうかを確認します。

配列に相当する言語がポインターや長さ(Cなど)のようなものでない限り、入力として行列のサイズを使用することはできません。常に少なくとも3 x 3になります。

各言語のバイト単位の最短コードが優先れます

入出力

入力を受信するために、次の形式のいずれかを選択できます。

  • ネイティブマトリックスタイプのマトリックス(言語にマトリックスがある場合)
  • 2D配列1(それぞれが1行に対応する1D配列の配列)
  • 1D配列(行列は常に正方形であるため)
  • 文字列(スペースを選択しましたが、これを悪用しないでください)。

出力の提供に関しては、標準の決定問題の定義に従って真実/偽の値を報告するか、2つの異なる一貫した値を選択できます。

さらに、これらの抜け穴はデフォルトで禁止されていることに注意しながら、任意のプログラミング言語で、任意の標準メソッドを介して入力および出力を行うことができます。他の形式を選択したい場合、または何かについて不明な点がある場合は、コメントでお問い合わせください。

1:またはあなたの言語に相当するもの(リスト、ベクターなど)

次の例を見てみましょう。

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

これは矢印の行列です(プログラムは真の値を報告する必要があります)。なぜなら、主対角線上の要素1 1 1 1はで1 2 2 2あり、最上行の要素はであり、左端の列の要素はであるため1 2 3 4です。他のすべてのエントリは0であるため、これはすべての条件を満たします。

3 5 6
7 1 0
8 0 0

主対角線上に0があるため、この行列は矢印ではありません

9 9 9 9
9 9 0 0
9 7 9 0
9 0 0 9

0の代わりに7が含まれているため、これ矢印ではありません

より多くのテストケース

真実:

[[1、1、1]、[1、1、0]、[1、0、1]]
[[1、2、3、4]、[1、1、0、0]、[1、0、1、0]、[1、0、0、1]]
[[1、2、2、2]、[2、1、0、0]、[3、0、1、0]、[4、0、0、1]]
[[34、11、35、5]、[56、567、0、0]、[58、0、679、0]、[40、0、0、7]]

偽物:

[[3、5、6]、[7、1、0]、[8、0、0]]
[[9、9、9、9]、[9、9、0、0]、[9、7、9、0]、[9、0、0、9]]
[[1、0、3、4]、[1、1、0、0]、[1、0、1、0]、[1、0、0、1]]
[[1、6、3、4]、[13、2、0、6]、[29、0、1、0]、[2、0、0、4]]

1
マトリックスに負の数を含めることは可能ですか
ザカリー

2
@Zacharýいいえ、それらはすべて負でないと仮定できます。
ミスターXcoder

Pedant:2次元配列と行列は同じものではなく、配列の配列と同じでもありません。選択した言語が多次元配列をサポートできるほど文明化されている場合、2次元配列としての入力は受け入れられますか?
イアンブッシュ

@IanBushはい、2D配列はまったく問題ありません。
ミスターXcoder

9
矢印は、任意の方向を指すことができればMr.Xcoderこれは十分に異なると興味深い課題だろう@
dylnan

回答:


15

Javascript(ES6)、48 47バイト

edc65のおかげで1バイト節約

m=>m.some((r,y)=>r.some((c,x)=>(x*y&&x!=y)^!c))

false矢印行列とtrue非矢印行列の戻り値(trueとfalseを表すために任意の2つの異なる値を使用できるため許可されます)

テストケース:


これは本当に賢いアプローチです!
ミスターXcoder

1
これは機能しますか?f=m=>m.some((r,y)=>r.some((c,x)=>(x*y&&x!=y)^!c))
edc65

@ edc65なしf=のコースの;-)
ニール

11

J21 20 19 17 15バイト

@GalenIvanovのおかげで-4バイト。

*-:1,1,.=&/:@}.

入力を行列(ランク2配列)として受け取ります。

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

説明

編集履歴は、ゴルフをしないと同時にあなたに説明を書くという教訓にしましょう。

* -: 1, 1,. = & /: @ }.  Let m be the input matrix.
            = & /: @ }.  Identity matrix 1 smaller than m.
                     }.    Behead (m without its first row).
                   @       Composed with.
                /:         Grade up (get len(m) - 1 unique elements)
              &            Composed with.
            =              Self-classify (compare equality with
                           unique elements)
        1,.              Prepend a column of 1s
     1,                  Prepend a row of 1s
*                        Signum (0 becomes 0, n > 0 becomes 1)
  -:                     Does it match the generated arrowhead matrix?

視覚的説明

これはREPLで行われることに注意してください(入力は3つのスペースで始まり、出力は先行スペースなしで与えられます)。そのため、のようなI時々オミット組成の関数@&REPL上のものからは、右から左に評価されている(機能はより複雑です)。

次のサンプルマトリックスがあるとします。

   ] m =. 4 4 $ 1 2 3 4 1 1 0 0 1 0 1 0 1 0 0 1
1 2 3 4
1 1 0 0
1 0 1 0
1 0 0 1

最初に、@ GalenIvanovの非常に巧妙な単位行列の生成方法を説明します(そして叫びます)=&/:@}.

最初に、入力行列(}.)を削除します。

   }. m
1 1 0 0
1 0 1 0
1 0 0 1

次に、/:-grade up を使用してソートされた行の各行に含まれるインデックスを取得します。

   /: }. m
2 1 0

結果のインデックスは一意であることに注意してください。リストには重複する要素がありません(そして、なぜそうなるのでしょうか?配列内の同じ位置に2つの要素を配置する方法はありません)。

最後に、ニッチですが有用な=自己分類を使用します。このモナドは、各一意の要素を配列内の他のすべての要素と比較します。結果のインデックスが一意であることが重要であると述べたことを覚えていますか?以来=-self-分類はユニークな要素がリストに表示される順序で比較を行います(この理由は、結果の出力は、独自の入力のための単位行列になります=@i.あなたが与えられた長さの単位行列を作ることができる方法です)。

   = /: }. m
1 0 0
0 1 0
0 0 1
   NB. This is what is happening
   (2 = 2 1 0) , (1 = 2 1 0) ,: (0 = 2 1 0)
1 0 0
0 1 0
0 0 1

恒等行列ができたら、それは非常に簡単に行われます(1つの行と1つの列を追加するだけです,) :

   1,. (=&/:@}. m)
1 1 0 0
1 0 1 0
1 0 0 1
   1, (1,. =&/:@}. m)
1 1 1 1
1 1 0 0
1 0 1 0
1 0 0 1

次に、生成された矢じり行列を入力行列の符号と単純に比較します。

   * m
1 1 1 1
1 1 0 0
1 0 1 0
1 0 0 1
   (* m) -: (1, 1,. =&/:@}. m)
1

2
(17バイトの)*代わりに十分ではありません0@<か?試してください
ガレンイワノフ

1
@GalenIvanov良いキャッチ、私はそう思う。ありがとう!説明を再編集する時間ですlol。
コール

1
アイデンティティマトリックスを生成する新しい方法を見つけたと思います。=&/:それをに結合したとき、15バイトで}.これを取得しました。オンラインで試してみてください。*-:1,1,.=&/:@}.
ガレンイワノフ

1
@GalenIvanov素晴らしいアプローチ(/:-gradeと}.-beheadの両方を使用)、ありがとうございます!編集します。
コール

うーん、実際には*-:1,1,.=@}.うまく機能します-恒等行列を見つけるための凝った方法は不要です 単純に正方行列自体から単位行列を生成でき=ます。したがって}.、で1行削除し、で単位行列を= 作成し、で行と列を追加1します。
ガレンイワノフ

9

Wolfram言語(Mathematica)、47バイト

Clip@#==Array[If[1<#!=#2>1,0,1]&,{1,1}Tr[1^#]]&

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

説明:Clip@#1S有するマトリックス内のすべての非ゼロ数字を置き換え、その後、我々は寸法を有するアレイにこれを比較{1,1}Tr[1^#]= {Length@#, Length@#}位置に0を有するi,j場合1 < i != j > 1、および1別段。

Urielの回答にほぼ基づいています。)

16バイト長いもう1つのアイデアを次に示します。ゴルフをすることができれば、気軽に盗んでください。

Union@@Array[{1,#}~Tuples~2&,Length@#]==Most@Keys@ArrayRules@#&

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


8

APL(Dyalog Classic)19 16 15 13バイト

@ErikTheOutgolferのおかげで-1バイト

⎕IO←0

×≡(∧=⌊)/¨∘⍳∘⍴

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

@ngnと@ H.PWizのおかげで-2バイト

どうやって?

(2D入力行列S

  • ×≡Sが正であるかどうかを確認する...
  • (∧=⌊ ...対角線または一番上の行と左の列...
  • )/¨∘⍳∘⍴...のS

⍳∘⍴デカルト積のための素晴らしい利用。
ウリエル

×≡(=/∨1∊⊢)¨∘⍳∘⍴
エリックアウトゴルファー

1
(=/∨1∊⊢)->(~≠⌊⌊)/
ngn

2
@ngnさらに良い:(∧=⌊)/もちろん、両方とも必要です⎕IO←0
H.PWiz

7

PowerShellの112の 108バイト

param($a)$o=+!(0-in$a[0]);1..($x=$a.count-1)|%{$i=$_;0..$x|%{$o*=(!($y=$a[$i][$_]),$y)[!$_-or$_-eq$i]}};!!$o

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

入力を受け取り、配列の配列として操作します。これは、PowerShellが行列をサポートしていないためです(.NET Direct3D変換行列のサポート以外は、まったく異なるものです)。

アルゴリズム全体は、PowerShellでは非ゼロの数値が真実であり、ゼロが偽であるという事実に基づいており、乗算を使用してそれらの真実/偽の値を決定します。

まず、最初の行を取る$a[0]、とするかどうかをチェックし0ている-in私たちに、店をことをその配列$output変数。その行のいずれかがゼロである$o場合、それもゼロです。それ以外の場合は、1になります。+です。

次に、から1までループし$a.count-1ます設定$x、途中ます。各行を1つずつループします。

繰り返しごとにヘルパー変数を設定$iして、現在の行を追跡し、から0にループして$xこの行の各要素を繰り返します。内側のループ内では$o、今回はタプル設定から疑似三項演算子として選択することにより、を乗算しています。

タプルの条件付きは!$_-or$_-eq$i、「0番目の列にある場合、または列が行(つまり、主対角線)に一致する場合」と言い、真の場合はタプルの後半を、偽の場合は前半を選択します。タプルはで構成され!($y=$a[$i][$_]), $yます。前半セット$yゴルフをしますが、いずれにしても現在の要素を選択します。前半はブール否定を行い、後半は要素をそのまま使用します。したがって、0番目の列にもメインの対角線にもない場合は、ブールのNOTを使用して要素がゼロであることを確認します。同様に、単純に0番目の列または主対角がゼロでないことを確認します。

マトリックス内のすべての要素を反復処理$oしたので0、一部の要素が正しくなかった場合、または矢印のマトリックスの場合はゼロ以外の整数になります。どちらかFalseまたはTrueそれぞれを取得し、出力の一貫性を保つために、ブール演算ではなく、ブール演算を行います。これは、印刷が暗黙的に行われるパイプラインに残されます。


+= [int]?いいですね。
ルート


7

ゼリー14 12バイト

ŒDµḢ;Ḣ€Ȧ>FẸ$

-Pietu1998から2バイト

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

説明

[[9,7,1],
 [7,1,0],
 [7,0,1]]

上記のマトリックスを入力例として使用します。

ŒDµḢ;Ḣ€Ȧ>FẸ$
ŒD              Diagonals → [[9, 1, 1], [7, 0], [1], [7], [7, 0]]
  µ             New monadic link
   Ḣ            Head → [9, 1, 1]. Alters diagonals list.
    ;Ḣ€         Append with the head of each of the other diagonals → [9, 1, 1, 7, 1, 7, 7]
       Ȧ        Logical all → 1
         FẸ$    Flatten what's left in diagonals then take logical any → [[0],[],[],[0]] → [0,0] → 0
        >       Matrix is an arrowhead iff result of Ȧ > result of Ẹ

@ wizzwizz4どういう意味かわからない
ディルナン

@ wizzwizz4 このコードは、マトリックスの要素がどのように再グループ化されるかを示しています。上、左、メインの対角線を取ります。これはあなたが意味したものですか?
ディルナン

説明で提供したコードの実際の視覚的表現を意味します。私は面白くしようとしていたが、明らかにうまくいかなかった。これらのコメントを整理します。
wizzwizz4


6

MATL、15バイト

gtZyXy,!llY(]X=

入力は行列です(;行区切りとして使用)。それ以外の場合1、出力は矢印用0です。

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

説明

g        % Implicit input. Convert to logical values (nonzero becomes true and
         % zero becomes false)
t        % Duplicate
Zy       % Size
Xy       % Identity matrix of that size
,        % Do twice
  !      %   Transpose
  ll     %   Push 1 twice
  Y(     %   Write 1 at all entries of row 1
]        % End
X=       % Are the two matrices (input and constructed) equal? Implicit display

1
Indeityマ​​トリックスとは正確には何ですか?
エリックアウトゴルファー

13
@EriktheOutgolferは明らかに神を含む行列です。
コール

5
@coleおそらくエリシアンフィールド上にマトリックスに関連
JLD

5

C(gcc)80 75バイト

i;f(A,n)int*A;{for(i=0;i<n*n;i++)n=A[i]>0^(i<n||i%n<1||i/n==i%n)?0:n;n=!n;}

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

scottinetのおかげで5バイト節約されました!

この回答のテストコードを再利用しました。

不正な値がないか配列を線形にスキャンし、矢印の行列の場合は0を返し、そうでない場合は1を返します。排他的または特定の位置のアイテムがゼロであるかどうか、およびその位置が矢印上にあるかどうかを計算して確認します。

2D配列の情報を1次元にエンコードすると、かなり単純な条件のセットになります。聞かせたらin次元配列への0から始まるインデックスとするi<n、最初の行を記述します。同様にi%n==0、最初の列をi/n==i%n説明し、対角線を説明します。

戻り値を処理するために見つけた最善のトリックは、エラーが発生したときにディメンションをゼロに設定することです。これにより、ループはすぐに終了し、ディメンションの論理否定を返すと、2つの異なる値のいずれかが返されます。scottinetは、GCCがそれをよりうまく返すようにする方法を見つけました。


-2バイト、さらにいくつかのゴルフ
スコティネット

gccの値を返す方法を悪用して追加の-4バイト
スコチネット

@scottinetありがとう!私はそのトリックを使用するためにどの値を設定する必要があるかを理解するのに苦労していた。
FryAmTheEggman

実際、あなたの最初のゴルフは信じられません。最初の位置にゼロがなかったため、テストケースに合格しました。ケースを追加し、その変更を元に戻しました。
FryAmTheEggman

int test0 [] = {0、1、1、1、1、0、1、0、1}; printf( "%d \ n"、f(test0、3)); a [0,0]は0であるため、1ではなく0を返す必要があります(3x3 matrx 011 110 101の場合)
RosLuP

5

Python 2、75バイト

lambda m,E=enumerate:all((x[j]>0)-(i>0<j!=i)for i,x in E(m)for j,y in E(m))

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

Python 2 2、85バイト

配列を1Dマトリックスとして取得する:

def f(m):s=len(m)**.5;print all((v<1)^(0in(p>s,p%s,p//s-p%s))for p,v in enumerate(m))

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


最上位のソリューションで「1Dマトリックス」を意味しましたか?
ニコニール

@NikoNyrhおっと、修正
FlipTack

5

R78 70 69 68 54 53バイト

function(m){d=diag(nrow(m))
d[1,]=d[,1]=1
all(d!=!m)}

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

ルイスメンドーの移植の答えは、以前のアプローチよりもはるかに短いです。

バグを指摘し、1バイトをゴルフしてくれたrturnbullに感謝します!

古い回答、68バイト:

function(m,i=which(!m,T))all(i[,1]-i[,2],i!=1,sum(m>0)==3*nrow(m)-2)

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

duckmayrの答えは、対角線と最初の行を取得するための優れた計算を使用して、メインの対角線と最初の行/列(m[i])のすべてのエントリがゼロ以外で残り(m[-i])がゼロであることをテストします。

ただし、この回答では、(1)ゼロエントリがメインの対角線または最初の行/列にないこと、および(2)n x nマトリックスが存在すること、3*n-2ゼロ以外のエントリがあることを確認します。

which入力がであるインデックスを返し、TRUEオプションでarr.ind=Tあるインデックスを返します。、各配列次元(この場合は2)のインデックスの配列を返します。

したがってany(i[,1]==i[,2])、対角線上にゼロが存在する場合、およびany(i==1)ゼロが存在し、の場合、最初の行または最初の列にゼロが存在します。

最後に、非ゼロエントリの数がなければならないことを少し演算を示し3*n-2n最初の列から、n-1対角線から、そしてn-1最初の行から。


これは、値が1でない矢印行列では機能しないようです。all(!m==!d)最後の行で意味しましたか?
rturnbull

@rturnbullああ!ありがとうございました。R演算子の構文はとても奇妙です。私は本当に意味(!!m)==dがあり!ますが、より低い優先順位を持ってい==ます。d==!!mしかし、私はトリックを行うべきだと思います。
ジュゼッペ

d!=!m同じように見えますが、1バイト少なくなります。pryr::fシンタックスを使用するよりfunctionも、別のバイトを保存できます。
rturnbull

私はそれをゴルフしようとしましたが、私ができる最善はまだ53です。
JayCe

@JayCeはあなたの答えも私のものも52にゴルフすることができます、そして、それが以前に私に起こらなかった理由がわかりません。1行のアプローチは非常に優れており、さらに改善の余地があるかもしれません。
ジュゼッペ


3

Haskell、62バイト

Xcoder氏のおかげで-3バイト。user28667のおかげで-13バイト。Zgarbのおかげで-5バイト。

z=zip[0..]
f m=and[(i==j||i*j<1)==(a>0)|(i,r)<-z m,(j,a)<-z r]

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


1
80バイト ....ほとんどの場合<1、そのようなトリックを忘れますか?:P
ミスターXcoder

1
(x==y||x==0||y==0)==(m!!y!!x/=0)短くする必要があります
user28667

1
インデックスを作成する代わりにzipして62バイトx*y<1
Zgarb



2

Pyth、22 21バイト

これは間違いなく行列操作用の言語ではありません。

.As.e+!MWk.Db,0k,@bkh

各行についてb、そのインデックスk行列内の(.e)は、第1及びグラブkと番目のエントリ(左側及び対角線)を,@bkhし、(+他のすべてのエントリ).Db,0k。場合k(0でない最初の行に対応するようにされWk、その後、)!ではありませんM、それらのエントリのすべてで。それらのすべてを選択したら、それらがすべて正しいことを確認します。(.As)あるべきでない場所に0がある場合、対応する場所はそのまま!つかまれ、混乱します。また、あるべきでない場所にゼロ以外がある場合、0に記録されます。また偽。

テストスイート。

注文を入れ替えるために-1バイト。


1
Wow this solution is really nice given that Pyth is quite parallel with matrix manipulation. Probably up for another Pyth duel tomorrow :P
Mr. Xcoder

You might be able to shorten this using either @VQUQ or .DVQUQ For diagonals / deleting diagonals. But that would require a completely different approach. Not sure though... (BTW forgot to update link?)
Mr. Xcoder

@Mr.Xcoder Fixed link, I'll try to mess around with other strategies tomorrow.
Steven H.

I arrived at an alternative 21-byter using my VQUQ idea: >.A++hCQhQ.(VQUQsstCt. This seems highly redundant, though. You might be able to tweak it in order to save a few bytes.
Mr. Xcoder

2

Pip, 31 23 22 bytes

{0<_!=B>0MC#a==0=_MMa}

This is a function that takes a 2D nested list of numbers. Try it online!

Explanation

A whole lot of comparisons going on here. The first thing to know is that comparison operators in Pip can be chained together, like in Python: 5>4>3 is 5>4 and 4>3 (true), not (5>4)>3 (false). The second is that this doesn't apply to ==, the "exactly equals" operator. Another difference: regular comparisons have higher precedence than the mapping operators MC and MM and can be used in lambda expressions, while == has lower precedence and can't.

{                    }  Define a function with argument a:
 0<_!=B>0MC#a            Generate a matrix (as nested lists) that has 0 on the first row,
                          first column, and main diagonal, and 1 elsewhere (see below for
                          details)
               0=_MMa    Map the function 0=_ to the elements of the elements of a,
                          generating a matrix that is 0 where a is nonzero and vice versa
             ==          Test if the two matrices are equal, returning 0 or 1 accordingly

To generate the first matrix, we use MC, "map-coords." This operator takes a number, generates a square coordinate grid of that size, and maps a function to each (x,y) coordinate pair, returning a list of lists of the results. For example, {a+b} MC 3 would give the result [[0; 1; 2]; [1; 2; 3]; [2; 3; 4]].

Here, the size of the grid is #a, the size of our original argument. The function is 0<_!=B>0, which is a shorter way of writing {0 < a != b > 0}:

{        }  Function; a and b are the arguments (in our case, row and column)
 0<a        Return 1 (truthy) if a is greater than 0
    !=b     and a is not equal to b
       >0   and b is greater than 0

This returns 0 for the first row/column and the main diagonal, and 1 elsewhere.


2

Husk, 12 11 bytes

S≡ȯ´Ṫ§^*=ŀL

Try it online!

Explanation

S≡ȯ´Ṫ§^*=ŀL  Input is a k×k array A.
          L  The length, k.
         ŀ   The range [0,1..k-1].
  ȯ´Ṫ        Outer product with itself by this function:
              Arguments are two numbers x and y.
        =     Equality of x and y
     §^       to the power of
       *      x times y.
S≡           Does the result have the same shape and distribution of truthy values as A?

The idea is that Husk defines 0 to the power of 0 as 1, so the outer product has 1s on the first row and column. Also, 1 to the power of any number is 1, so the outer product has 1s on the diagonal. Other entries are 0 to the power of some positive number, which is 0. This gives a binary arrowhead matrix, which we compare to the input with .


2

APL+WIN, 36 33 bytes

(↑⍴m)=+/(+⌿m)=+/m←×m×n∘.×n←⍳↑⍴m←⎕

Prompts for screen input of an APL 2d matrix.


2

Clojure, 128 95 92 85 bytes

#(every? neg?(for[R[(range(count %))]i R j R]((if((set[i(- i j)j])0)- dec)((% i)j))))

It is always exciting to see two consecutive opening brackets.

Original version:

#(and(apply =(map assoc(for[i(rest %)](subvec i 1))(range)(repeat 0)))(every? pos?(concat(map nth %(range))(% 0)(map first %))))

The first part works by associng diagonal elements of the sub-matrix to zero, and checking that all rows are equal :) I used a similar trick at Jacobian method.

Latter part concatenates the diagonal + first row and column and checks that they are positive.


2

Javascript (ES6), 58 bytes

My solution for Javascript:

m=>m.some((r,i)=>m[0][i]*r[0]*r[i]==0|r.filter(c=>i*c)[2])

Not as clever as Herman's answer, but I just felt like I should post it here too.


3
Welcome to PPCG!
Steadybox

2

Clojure, 212 206 188 bytes

-6 bytes by removing some missed spaces, and shortcutting range. I might have to let this sit so I can think of a better way.

-18 bytes thanks to @NikoNyrh, and creating shortcuts for map.

(fn[m](let[r range a map z zero?](and(every? #(not(z %))(concat(m 0)(rest(a #(% 0)m))(a get m(r))))(every? z(apply concat(into(a #(take(dec %)%2)(r)(a rest m))(a take-last(r)(reverse(rest m)))))))))

Awful, just awful. I don't know why I can't wrap my head around a reasonable solution.

Takes a nested vector as input.

(defn arrowhead? [matrix]
  (let [; Get the 0th cell of the 0th row, then the 1st cell of the 1st row...
        main-diagonal (map get matrix (range))

        ; Get the 0th cell of each row
        first-col (rest (map #(% 0) matrix))
        arrowhead (concat (matrix 0) first-col main-diagonal)

        ;
        right-rest (map take-last (range) (reverse (rest matrix)))
        left-rest (map #(take (dec %) %2) (range) (map rest matrix))
        rest-matrix (apply concat (into left-rest right-rest))]

    ; And check them
    (and (every? pos? %) arrowhead
         (every? zero? rest-matrix))))

I tried rewriting this from scratch using a different method, and it ended up longer. Instead of manually carving out the "rest" sections of the matrix, I instead decided to try generating all the coordinates in the matrix, generating the coordinates of the arrowhead, then use clojure.set/difference to get the non-arrowhead cells. Unfortunately, the call to that built-in is costly:

223 bytes

(fn[m](let[l(range(count m))g #(get-in m(reverse %))e every? a(for[y l x l][x y])k #(map % l)r(concat(k #(do[% %]))(k #(do[0%]))(k #(do[% 0])))](and(e #(zero?(g %))(clojure.set/difference(set a)(set r)))(e #(pos?(g %)))r)))

(defn arrowhead? [matrix]
  (let [length-range (range (count matrix))
        get-cell #(get-in matrix (reverse %))
        all-coords (for [y length-range
                         x length-range]
                     [x y])

        k #(map % length-range)

        diag (k #(do[% %]))
        top-side (k #(do [0 %]))
        left-side (k #(do [% 0]))
        arrowhead (concat diag top-side left-side)

                   ; 22 bytes! Ouch
        rest-cells (clojure.set/difference (set all-coords) (set arrowhead))]

    (and (every? #(zero? (get-cell %)) rest-cells)
         (every? #(pos? (get-cell %)) arrowhead))))

There is quite lot of room for improvement, for example #(drop 1 %) is same as rest and #(not(zero? %)) is same as pos? (as we have non-negative numbers). You might want to have a look at my 128-byte answer, which has similar approacha s this one. After implementing that I realized that it is a lot shorted to deal with index-based access in a for-loop.
NikoNyrh

@NikoNyrh Ya, I wasn't in a very good groove that day. I don't know how I forgot about rest. I should probably just scrap this attempt and try again.
Carcigenicate

2

Stax, 11 bytesCP437

ä¢⌠┐xⁿtH↔BU

Try it online!

Unpacked version with 13 bytes:

B|AsF:10i^\=*

Finally tied Husk and beaten by Jelly by just one byte ...

Explanation

B                Push tail (all except 1st row) of the input array, then push the head (1st row)
 |A              All elements in the head are truthy
                 This will be used as an accumulator
   sF            For each element in the tail, execute the rest of the program
     :1          All truthy indices
       0i^\      Expected truthy indices (0 and the current row number)
           =     The truthy indices are as expected
            *    Perform logical "and" with the accumulator
                 Implicit output of the final accumulator


1

C, 117 bytes

i,j,r;f(A,n)int*A;{for(i=r=0;i<n;++i)for(j=-1;++j<n;(!i||!j||i==j)&&!A[i*n+j]&&++r)i*j&&i-j&&A[i*n+j]&&++r;return!r;}

Try it online!


1

PowerShell, 186 bytes

$a=$($args);if($a[0]-contains0){0;exit};0..($a.Length-1)|%{if($a[$_][0]-eq0-or$a[$_][$_]-eq0){0;exit};$r=$a[$_];$d=$_;if($_-ne0){1..($r.Length-1)|%{if($r[$_]-ne0-and$_-ne$d){0;exit}}}};1

Try it online!


2
Some golfs -- use param($a) to take input, the -contains can be swapped for an -in and all of the -eq0 can be swapped for !. Finally, you can loop from 1 up to $a.length and get rid of the if($_-ne0) in the loop body.
AdmBorkBork

1

Perl 5, 136 + 2 (-ap) = 138 bytes

push@a,[@F]}{push@b,"@{$a[0]}"=~/\b0\b/;map{//;map$a[$'][$_]=!$a[$'][$_],0,$';shift@{$a[$']};push@b,@{$a[$']}}1..$#a;say!("@b"=~y/ 0//c)

Try it online!




1

K (oK), 27 30 bytes

Solution:

x~a*x|a:a|+(a:1,(#1_x)#0)|=#x:

Try it online!

Explanation:

I must be doing something dumb as the APL solutions are less than half the byte count...

24 bytes spent creating the arrowhead. or together the following three matrices:

/ assume 4x4 matrix
=#x
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1

+(a:1,(#1_x)#0)
1 0 0 0
1 0 0 0
1 0 0 0
1 0 0 0

a
1 1 1 1
0 0 0 0
0 0 0 0
0 0 0 0

Full breakdown:

x~a*x|a:a|+(a:1,(#1_x)#0)|=#x: / the solution
                            x: / save input as x
                           #   / count length
                          =    / identity matrix
                         |     / or with
           (            )      / do this together
                      #0       / take from 0
                ( 1_x)         / drop first of x
                 #             / count
              1,               / prepend 1
            a:                 / save as a
          +                    / flip rows/cols
         |                     / or with
        a                      / a
      a:                       / save as a
     |                         / or with
    x                          / x
  a*                           / multiply by arrowhead
x~                             / matches input?
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.