一般化されたマトリックストレース


23

インスピレーション。

与えられた(とにかく):

  • 2つの引数(または2つの要素のリストで構成される単一の引数)ブラックボックス関数、(入力と出力は1、2、3、…)f: ℤ+ × ℤ+ → ℤ+
  • 少なくとも2行2列の厳密に正の整数行列

行列の関数traceを返します

関数トレースとは何ですか?

通常のマトリックストレースは、マトリックスの主な対角線(左上から右下)の合計です。

[[1,2,3],[4,5,6],[7,8,9]][1,5,9]1+5+915

しかし、加算する代わりfに、対角線に沿って適用したい:

[[1,2,3],[4,5,6],[7,8,9]][1,5,9]f(f(1,5),9)f(1,f(5,9))

左から右または右から左のどちらを使用するかを明記してください。

指定された行列とすべての中間値は、言語の整数ドメイン内の厳密に正の整数になります。行列は非正方形の場合があります。

f(x,y) = xy[[1,2,3],[4,5,6],[7,8,9]]1×5×945

f(x,y) = xy[[1,2,3],[4,5,6],[7,8,9]]→ →1591

f(x,y) = x-y[[4,5,6],[1,2,3]]4-22

f(x,y) = (x+y)⁄2[[2,3,4],[5,6,7],[8,9,10]]5または7

f(x,y) = x+2y[[1,2,3],[4,5,6],[7,8,9]]47または29

f(x,y) = max(x,y)[[1,2,3],[4,5,6],[7,8,9]]max(1,5,9)9

f(x,y) = 2x[[1,2,3],[4,5,6],[7,8,9]]2または4

f(x,y) = lcm(x,y)[[2,2,2],[2,2,3],[2,3,3],[4,4,4]]lcm(2,2,3)6

リファレンス実装。


対角線とは何[[2,2,2],[2,2,3],[2,3,3],[4,4,4]]ですか?
完全に人間

3
@totallyhuman:[2,2,3]
エミグナ

1
くそ、私は「一般化マトリックストランス」などのタイトルを読み、ページがロードされたときに痛んでがっかりした
タール

回答:


9

R40 30バイト

function(m,F)Reduce(F,diag(m))

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

テストケースを確認します。

対角線を下にたどるので、この場合は左から右へ。算術演算子のために、あなたは使うことができ"+"、オペレータの周りやバッククォート(+,*,-,%/%,^,%%

非常に簡単:ReduceとRの等価ではあるfoldし、行列の対角がそれらの要素である、すなわち、及びUMNインデックスが同じです。a_iji==jrowcol diag非正方行列に対して適切な動作をします。


8

Haskell、39バイト

以前無効だった解決策の修正を支援してくれた@Laikoniに感謝します!

f!m=foldl1 f[h|h:_<-zipWith drop[0..]m]

左側のアソシエイツ、オンライン試してみてください!(置き換えるfoldl1ことにより、foldr1右結合のため)


どうfoldl1 f$zipWith(!!)m[0..]
誇りに思ってhaskeller

@proudhaskeller:それは他の人がすでに試したことですが、非正方行列では失敗します
。–

5

Mathematica、16バイト

マーティン・エンダーのおかげで-1バイト。

#~Tr~Fold[g]@*0&

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

代替ソリューション、17バイト

Fold[g]@*Diagonal

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


17バイト(ブラックボックス機能は、与えられた名前で仮定することができる)
氏Xcoder

この@*{}構文はあまり意味がありません(おそらく@*List)が、とにかく動作するという事実はかなりクールです。実際には、それはあなたが交換することができることを意味{}して0バイトに保存します。
マーティンエンダー

@MartinEnder私は実際にList最初に持っていましたが、私はそれを試した{}だけで、それが機能することを非常に驚きました。理にかなっていますが、どのように機能し0ますか?O0
totallyhuman

1
@totallyhumanと同じ方法{}。現在{}、関数として(または実際にはMathematicaの用語を使用する「ヘッド」として)使用しています。fそこにジェネリックを使用した場合は、得られますf[1,2,3](それが対角線の場合)。しかし、{}あなたが得る{}[1,2,3]。それは完全に無意味な表現ですが、ヘッド自体が任意の表現である可能性があり、Mathematicaがそれらをどう処理するのか分からない場合は、そのまま残します。Mathematicaのリスト操作関数のほとんどは実際には任意のヘッドを持つ式で動作しますが、の場合にFoldはヘッドは無視されます。[tbc]
マーティンエンダー

そのため0、代わりにheadとして使用できます。これは、0[1,2,3]どちらがまだ無意味であっても、すべて同じように機能します。
マーティンエンダー

4

オクターブ61 57 53バイト

function m=g(f,m)for i=diag(m)'(2:end)m=f(m(1),i);end

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

g関数ハンドルfと行列を取る関数を定義しますm。最初の反復で、m(1)左上のマトリックス要素を返します。その後、単にを返しますm



@Giuseppeそれが最初の61バイトバージョンでやったことです。もちろん、57バイトと61バイトのバージョンの長所を組み合わせる必要がありました。確かに53バイトの答えが得られます。もう一度見てくれてありがとう!
-Sanchises


3

Haskell47 45 42バイト

f%((h:t):r)|[]<-t*>r=h|x<-tail<$>r=f h$f%x

オンラインでお試しください!(%)入力としてリストのリストとして関数とマトリックスを取る関数を定義します。

関数は右から左に折り畳まれます:

f % [[1,2,3], -> f 1 ( f % [[5,6],   -> f 1 ( f 5 ( f % [[9]] ) ) -> f 1 ( f 5 ( f 9 ) ) )
     [4,5,6],               [8,9]] )
     [7,8,9]]

f % ((h:t):r)              -- (h:t) is the first row and r the remaining rows
 | [] <- t *> r = h         -- a shorter way of checking wether t==[] or r==[]
 | x<-tail<$>r = f h $ f%x -- apply f to h and the result of recursively calling (%) on
                           -- the remaining matrix with the first column removed

編集:BMOのおかげで-2バイト、Zgarbのおかげで-3バイト!


1
$条件を使用および簡略化することにより、43バイト*>
ズガルブ

@Zgarb使用するのは良いアイデア*>です!
ライコニ

3

APL(Dyalog Unicode)、7バイト(AdámのSBCS

⎕/1 1⍉⎕

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

-3これをAdámによる完全なプログラムに変換する提案のおかげです

右から左へ。


ここでAdámのSBCSを使用する必要はありません。DyalogClassicを使用できます。
ザカリー

@Zacharý事は、私がDyalog Unicodeで答えているということです。Classicは時間とともに非推奨になっています。
エリックアウトゴルファー

コードページthoughmコードページがに住んわけではありません
ザカリー

@Zacharýまあ、むしろ一貫性を保ちましょう。:P
エリック・ザ・アウトゴルファー




2

JavaScript(ES6)、58 56バイト

g=(f,a,r=a[i=0][0],e=a[++i]&&a[i][i])=>e?g(f,a,f(r,e)):r

左から右に折ります。編集:配列が厳密に正であるという事実を使用して2バイトを保存しました。代替ソリューション、56バイト:

(f,a,g=r=>(e=a[++i]&&a[i][i])?g(f(r,e)):r)=>g(a[i=0][0])

必要なようには見えませんが、1/いくつかのものを移動することでさらに2バイトを節約できますf=>a=>(h=r=>(e=a[++i]&&a[i][i])?h(f(r,e)):r)(a[i=0][0])TIO
シャギー

@Shaggyああ、それは厳密にポジティブだ、私はそれを見なかった。
ニール

どうやら、ブラックボックス関数が事前定義された変数に割り当てられていると仮定できるため、それを利用したい場合は2バイト節約できます。
シャギー

@Shaggy実際にはf,、最初のバージョンから4バイト(2x )節約できると思いますか?
ニール

あなたが正しい; 申し訳ありませんが、再度f,電話をかけるときにカウントを忘れていましgた。
シャギー

2

JavaScript、46バイト

f=>a=>a.reduce((p,l,i)=>l[i]?f(p[0]|p,l[i]):p)

@Shaggyのおかげで、ビット単位を使用するか、1バイトを節約してください。それは魔法です。


行列の列が列よりも多い場合、これは機能しないようです。
シャギー

@シャギーとても悲しい、47バイト今
...-tsh

ええ、それも私が元々持っていたものです。ちょうど私の解決策に修正編集しようとしていましたが、あなたはそれが:(私は、ビット単位を使用することによって、しかし、あなたは1バイトを取り戻すことができると思いORしかし、あまりにも私を倒す。
シャギー

@Shaggy so magic
tsh

言及するのを忘れました:明らかに、ブラックボックス関数は事前定義された変数に割り当てられているので、それを利用したい場合は3バイト節約できます。
シャギー

2

Java 8、88 81 70バイト

m->{int r=m[0][0],i=1;try{for(;;)r=f(r,m[i][i++]);}finally{return r;}}

折りたため[[1,2,3],[4,5,6],[7,8,9]]f(f(1,5),9)

-7間接的に感謝バイト@KamilDrakariを、彼はで行ったのと同様のトリックを使って、彼のC#の答え:代わりの行/列に基づいてループの最大の境界を持つ、単にのtry-catch ArrayIndexOutOfBoundsException
-11バイトはに置き換えcatch(Exception e)られfinallyます。

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

古い88バイトの答え:

m->{int r=m[0][0],i=1;for(;i<Math.min(m.length,m[0].length);)r=f(r,m[i][i++]);return r;}

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

説明:

m->{                   // Method with integer-matrix parameter and integer return-type
  int r=m[0][0],       //  Start the result at the integer of position 0,0 (0-indexed)
      i=1;             //  Start the index at 1 (0-indexed)
  try{for(;;)          //  Loop indefinitely
    r=f(r,m[i][i++]);} //   Call f with the result + next diagonal cell as arguments
                       //   (and increase `i` by 1 with `i++` afterwards)
  finally{             //  If an ArrayIndexOutOfBoundsException occurred we're done,
   return r;}}         //   in which case we return the result-integer

ブラックボックス入力形式:

名前付き関数int f(int x,int y)が存在すると仮定しますこれ、このメタ回答に従って許可されます

上記のラムダと同様にTest、デフォルト関数を含む抽象クラスがありますf(x,y)

abstract class Test{
  int f(int x,int y){
    return x+y;
  }

  public java.util.function.Function<int[][],Integer>c=
    m->{int r=m[0][0],i=1;for(;i<Math.min(m.length,m[0].length);)r=f(r,m[i][i++]);return r;}
  ;
}

テストケースでは、この関数を上書きしますf。たとえば、最初のテストケースは次のように呼び出されます。

System.out.println(new Test(){
  @Override
  int f(int x,int y){
    return x*y;
  }
}.c.apply(new int[][]{
  new int[]{1,2,3},
  new int[]{4,5,6},
  new int[]{7,8,9}
}));

2

アタッシュ、14バイト

Fold#/Diagonal

オンラインでお試しください!に設定しf、として呼び出しますf[function, array]

説明

これは、2つの関数の分岐です:Fold/Diagonal。これは、引数fおよびのa場合、次と同等です。

Fold[f, (/Diagonal)[f, a]]

/、関数に単項で適用されると、最後の引数に適用される関数を返します。したがって、これは次と同等です。

Fold[f, Diagonal[a]]

これは、関数fをの主対角線上で折り畳みaます。



@Adám; Dはい、そうです!
コナーオブライエン

2

AWK、77バイト

func z(F,M,r){for(e=1;e<M[1]&&e<M[2];)r=@F(r==""?M[1,1]:r,M[++e,e])
return r}

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

AWK関数型プログラミングができるかどうか興味がありました。これは重要だと思います。

「マトリックス」は、追加のフィールドM[1]=#rowsとを含む標準の連想配列として定義されますM[2]=#columns。関数名は、@F(...)構文を介して評価される文字列として渡されます。評価は左から右に実行されます。このrパラメーターは、既存のr変数の上書きを防ぎ、各呼び出しで再初期化する必要を回避するためのプレースホルダーです。通常AWK、このようなプレースホルダーを指定するために余分なスペースが追加されますが、これはコードゴルフであるため、すべてのバイトがカウントされます。:)

TIOリンクは、すべてのテストケースを実装します。


2

05AB1E15 10バイト

右から左に折りたたむKevin Cruijssen
によって提案された新しいビルトインを使用して5バイトを保存

Å\`[.g#I.V

説明

古いバージョンと同じようにÅ\機能しますが、メインの対角線を押すための新しいビルトインです。

オンラインでお試しください! またはテストスイートとして

古いバージョン

¬g£vyNè}[.g#I.V

オンラインでお試しください! またはテストスイートとして

説明

¬                 # get the head of the input (first row)
 g                # get its length (number of columns)
  £               # take that many rows from input
   v              # for each row_index, row (N,y) do:
    y             # push the row
     Nè           # get the nth element of the row
       }          # end loop
        [.g#      # loop until one value remain on the stack
            I.V   # run the input function

1
¬g£vyNè}[Å\`[5バイトを節約できるようになりました。
ケビンクルーッセン

1

、7バイト

投稿を修正してくれてありがとう@Zgarb!

Ḟ₁§z!Tŀ

左側のアソシエイツ、オンラインでお試しください!(右結合バージョンの場合は、単にに置き換えてくださいF

説明

残念ながら、行列の対角線を取得する簡単な方法はないため、ほとんどのバイトはそのためのものです。

Ḟ₁§z!Tŀ  -- function ₁ is the function and matrix A implicit, example: 
  §      -- fork A
     T   -- | transpose A: [[1,4,7],[2,5,8],[3,6,9]]
      ŀ  -- | enumerate A: [1,2,3]
   z!    -- and zipWith index: [1,5,9]
Ḟ₁       -- right fold function

Huh、対角線用ではなく、対角線用に
組み込まれています‽–アダム

2
@Adámこれは、無限行列の対角線は計算できますが、対角線は計算できないからだと思います。
マーティンエンダー

1

SNOBOL4(CSNOBOL4)、86バイト

T	I =1
	T =M<1,1>
I	I =I + 1
	T =EVAL(F '(T,M<I,I>)')	:S(I)F(RETURN)
	DEFINE('T(M,F)')

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

関数の名前である文字列とを受け取る関数T(for TRACE)を定義します。左から右に折ります。ARRAYF

間接参照($)の使用は、関数では機能しません。したがってEVAL、文字列を使用して名前に渡すことが、SNOBOLでブラックボックス関数を取得する唯一の方法のようです。

また、配列を定義するのは非常に苦痛です。ただし、無効な配列参照が原因であるためFAILURE、これは非正方形配列で機能します。Iどちらかの次元で範囲外の場合F(RETURN)、関数は 強制的に戻ります。

編集:

おそらく、に基づいて、このメタ後、私はブラックボックス機能をと仮定することができるF名前で定義されるF75バイト(削除の使用にこれを落とすことになる、EVAL,F機能定義で)。ただし、関数への参照を渡すのに近いため、このバージョンの方が好きです。



1

tinylisp、79バイト

(load library
(d D(q((M)(i(h M)(c(h(h M))(D(map t(t M))))(
(q((F M)(foldl F(D M

最後の行は、関数と行列を取り、行列のトレースを返す名前のないラムダ関数です。トレースは左結合(つまりf(f(1,5),9))です。オンラインでお試しください!

非ゴルフ

対角線を計算するヘルパー関数を定義します。次にgeneralized-trace、ライブラリ関数の単なる小さなラッパーfoldlです。

(load library)

(def diagonal
 (lambda (matrix)
  (if (head matrix)
   (cons
    (head (head matrix))
    (diagonal (map tail (tail matrix))))
   nil)))

(def generalized-trace
 (lambda (func matrix)
  (foldl func (diagonal matrix))))

対角線を再帰的に計算するとき、(head matrix)真実かどうかをチェックします。行列が行外の場合、それは空のリスト(nil)になりhead、nilはnil--falseyになります。または、マトリックスの列が不足している場合、その最初の行(先頭)は空のリスト(nil)になります(falsey)。そうでない場合、空でない最初の行がありますが、これは真実です。

したがって、最初の行が存在しないか空の場合、nilを返します。それ以外の場合、空でない最初の行がある場合、最初の行の(head (head matrix))最初の要素を取得しcons、再帰呼び出しの結果に(追加)します。再帰呼び出しの引数は-- (map tail (tail matrix))つまり、最初の行を除くすべての行を取得し、各行の最初の要素を除くすべての行を取得します。



1

C#(Visual C#コンパイラ)72 69 60バイト

m=>{try{for(int i=1;;m[0][0]=f(m[0][0],m[i][i++]));}catch{}}

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

try/catch 対角線に沿って進み、範囲外になったら終了することで、対角線に正しく到達できます

Kevin Cruijssenが指摘したように、特定の名前ブラックボックス関数が存在すると想定できるため、3バイトが節約されました。

引数変更することで戻ることで9バイト節約されました。

したがって、目的の関数をnameという名前fで保存することにより、関数が呼び出されtrace(matrix)、結果がに保存されmatrix[0][0]ます。

また、冗長性が本当に好きな場合は、

C#(Visual C#コンパイラ)97 + 13 = 110 78 69バイト

(int[][]m)=>{try{for(int i=1;;m[0][0]=f(m[0][0],m[i][i++]));}catch{}}

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

事前定義関数を使用することで32バイトが節約されました。関数をパラメーターとして使用しないことで、Systemインポートと長いFuncジェネリック型を削除できるためです


try-catchを使用した素敵なトリック。私は7バイトの私のJava 8の答え(私が使用することを持っているにもかかわらずにゴルフすることができましたcatch(Exception e)代わりにcatch。:)編集:ああ、交換することができたcatch(Exception e)とのfinallyより多くのバイトを保存します。再度、感謝します。私から+1。
ケビンクルーイッセン

@KevinCruijssenまた、私の最新の改善から利益を得ることができるかもしれません(Javaが引数の変更に適しているかどうかは確かに覚えていませんが)
カミルDrakari

知らせてくれてありがとうございます。それはJavaで可能ですが、それは私が変更する必要があります意味finallyにはcatch(Exception e)、私は最終的にはもう内部で戻っていないよので、。したがって、m->{try{for(int i=1;;m[0][0]=f(m[0][0],m[i][i++]));}catch(Exception e){}}(73バイト)は、現在の回答m->{int r=m[0][0],i=1;try{for(;;)r=f(r,m[i][i++]);}finally{return r;}}(70バイト)と比較して残念ながら長いですが、実際には回答のバイトを節約するのに良い方法です!:)残念ですが、あなたの答えに1回しか+1できません。
ケビンクルーイッセン

1

JavaScript、61 57 56 52 50 44 42バイト

左から右に縮小します。関数が変数fに割り当てられていると仮定します。このメタ投稿に従って、Xcoder&totallyhuman氏が私の注意を喚起しました。入力が事前定義された変数に割り当てられているとは仮定しないという既存のコンセンサスと直接矛盾するため、同意できませんが、ここでは数バイト節約します。

a=>a.map((y,z)=>x=(n=y[z])?z?f(x,n):n:x)|x

テストケース

g=
a=>a.map((y,z)=>x=(n=y[z])?z?f(x,n):n:x)|x
o.innerHTML=[[`f(x,y) = xy`,[[1,2,3],[4,5,6],[7,8,9]],(x,y)=>x*y,45],[`f(x,y) = x<sup>y</sup>`,[[1,2,3],[4,5,6],[7,8,9]],(x,y)=>x**y,1],[`f(x,y) = x-y`,[[4,5,6],[1,2,3]],(x,y)=>x-y,2],[`f(x,y) = <sup>(x+y)</sup>⁄<sub>2</sub>`,[[2,3,4],[5,6,7],[8,9,10]],(x,y)=>(x+y)/2,7],[`f(x,y) = x+2y`,[[1,2,3],[4,5,6],[7,8,9]],(x,y)=>x+2*y,29],[`f(x,y) = max(x,y)`,[[1,2,3],[4,5,6],[7,8,9]],(x,y)=>Math.max(x,y),9],[`f(x,y) = 2x`,[[1,2,3],[4,5,6],[7,8,9]],(x,y)=>2*x,4],[`f(x,y) = lcm(x,y)`,[[2,2,2],[2,2,3],[2,3,3],[4,4,4]],(x,y)=>-~[...Array(x*y).keys()].find(z=>!(++z%x|z%y)),6]].map(([a,b,c,d],e)=>`Test #${++e}:  ${a}\nMatrix:   ${JSON.stringify(b)}\nFunction: ${f=c}\nResult:   ${g(b)}\nExpected: ${d}`).join`\n\n`
<pre id=o></pre>


1

APL NARS、20バイト、10文字

{⍺⍺/1 1⍉⍵}

テスト:

  f←{⍺⍺/1 1⍉⍵}
  ⎕←q←3 3⍴⍳10    
1 2 3
4 5 6
7 8 9
  ×f q
45
  *f q
1
  {⍺+2×⍵}f q
47
  ⌈f q
9
  {2×⍺+0×⍵}f q
2
  -f ⊃(4 5 6)(1 2 3)
2
  {(⍺+⍵)÷2}f ⊃(2 3 4)(5 6 7)(8 9 10)
5
  ∧f ⊃(2 2 2)(2 2 3)(2 3 3)(4 4 4)
6

よくやった。あなたは自分でこれにたどり着くと思いますが、それはたまたまErik the Outgolferの元のソリューションと同じです。
アダム

0

ゼリー、5バイト

左から右へ。

ŒDḢç/

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

免責事項:これがブラックボックス機能の受け入れ可能な入力方法であるかどうかはわかりません。これは、関数が上記のリンクに実装されているため、「名前付き」(つまり、呼び出し可能)çであると想定していますが、そうでない場合はに割り当てる方法がありませんç。誰かがゼリー+ブラックボックス機能の経験があれば、私は考えを感謝します。チャットでしばらく時間を過ごした後、使用は実際に有効である可能性があると考えましç


0

Clojure、30バイト

#(reduce %2(map nth %(range)))

「左から」を減らします。


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