Generalized matrix trace

23

2

Inspiration.

Given (by any means):

  • A two-argument (or single argument consisting of a two-element list) black box function, f: ℤ+ × ℤ+ → ℤ+ (input and output are 1, 2, 3,…)
  • A strictly positive integer matrix with at least two rows and two columns

return the matrix's function trace.

What is a function trace?

A normal matrix trace is the sum of the major diagonal (top-left to bottom-right) of a matrix:

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

But instead of summing, we want to apply f along the diagonal:

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

Please state whether you use left-to-right or right-to-left.

The given matrix and all intermediate values will be strictly positive integers within your language's integer domain. The matrix may be non-square.

Examples

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 or 7

f(x,y) = x+2y, [[1,2,3],[4,5,6],[7,8,9]]47 or 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 or 4

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

Reference implementation.

Adám

Posted 2018-01-24T12:12:43.803

Reputation: 37 779

What is the diagonal of [[2,2,2],[2,2,3],[2,3,3],[4,4,4]]? – totallyhuman – 2018-01-24T12:21:18.310

3@totallyhuman:[2,2,3] – Emigna – 2018-01-24T12:22:27.817

1Dammit, I read the title as "Generalized Matrix trance" and was sorely disappointed when the page loaded – tar – 2018-01-25T14:50:10.733

Answers

9

R, 40 30 bytes

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

Try it online!

Verify the test cases.

Traverses down the diagonal, so left-to-right in this case. For arithmetic operators, you can use "+" or backticks around the operators (+,*,-,%/%,^,%%)

Pretty straightforward: Reduce is R's equivalent to a fold, and the diagonal of a matrix is those elements a_ij where i==j, i.e., where the row and column indices are the same. diag has the appropriate behavior for non-square matrices.

Giuseppe

Posted 2018-01-24T12:12:43.803

Reputation: 21 077

8

Haskell, 39 bytes

Thanks @Laikoni for helping me fix the previously invalid solution!

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

Associates to the left, try it online! (replace foldl1 by foldr1 for right-associative)

ბიმო

Posted 2018-01-24T12:12:43.803

Reputation: 15 345

how about foldl1 f$zipWith(!!)m[0..]? – proud haskeller – 2018-01-25T17:52:54.920

@proudhaskeller: That's what others tried already, but that fails on non-square matrices.. – ბიმო – 2018-01-25T17:56:55.807

5

Mathematica, 16 bytes

-1 byte thanks to Martin Ender.

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

Try it online!

Alternate solution, 17 bytes

Fold[g]@*Diagonal

Try it online!

totallyhuman

Posted 2018-01-24T12:12:43.803

Reputation: 15 378

17 bytes (black-box functions can be assumed under a given name) – Mr. Xcoder – 2018-01-24T13:09:41.760

That @*{} syntax doesn't make a lot of sense (you probably meant @*List), but the fact that it works anyway is pretty cool. In fact, it means you can replace the {} with a 0 and save a byte. – Martin Ender – 2018-01-24T13:47:48.093

@MartinEnder I actually did have List first but I tried {} just for the heck of it and was extremely surprised that it worked. Makes sense but how does 0 work? o0 – totallyhuman – 2018-01-24T14:05:46.957

1@totallyhuman The same way as {}. You're currently using {} as a function (or actually as a "head" using Mathematica terminology). If you used a generic f there, you'd get f[1,2,3] (if that's the diagonal). But with {} you get {}[1,2,3]. That's a completely meaningless expression, but heads can be arbitrary expressions themselves, and if Mathematica doesn't know what to do with them, it just leaves them as they are. Most of Mathematica's list manipulation functions actually work with expressions with an arbitrary head and in the case of Fold, the head is just ignored. [tbc] – Martin Ender – 2018-01-24T14:07:51.180

So you can use 0 as the head instead, which gives 0[1,2,3] which is still meaningless, but works all the same. – Martin Ender – 2018-01-24T14:08:08.183

@MartinEnder Ah, so I had misunderstood how it worked in the first place. Thanks! – totallyhuman – 2018-01-24T14:10:58.590

It looks like you're not taking the function as input here. – Shaggy – 2018-01-24T18:03:23.527

@Shaggy First comment on this answer

– totallyhuman – 2018-01-24T18:19:00.677

Yeah, saw that after I commented. @Mr.Xcoder, I was going to ask if that's not in violation of our consensus that we cannot assume input to be assigned to a predefined variable but then I found this which directly contradicts that.

– Shaggy – 2018-01-24T18:34:32.270

4

Octave, 61 57 53 bytes

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

Try it online!

Defines a function g which takes a function handle f and matrix m. On the first iteration, m(1) returns the top-left matrix element; after that, it just returns m.

Sanchises

Posted 2018-01-24T12:12:43.803

Reputation: 8 530

53 bytes – Giuseppe – 2018-01-24T14:55:22.487

@Giuseppe That's what I did with my initial 61-byte version. Of course, I should've combined the strong points of my 57- and 61 byte version, which indeeds gives a 53 byte answer. Thanks for making me look at that again! – Sanchises – 2018-01-24T14:56:41.717

3

Haskell, 47 45 42 bytes

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

Try it online! Defines a function (%) which takes a function and a matrix as a list of lists as input.

The function is folds from right-to-left:

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

Edit: -2 bytes thanks to BMO and -3 bytes thanks to Zgarb!

Laikoni

Posted 2018-01-24T12:12:43.803

Reputation: 23 676

143 bytes by using $ and simplifying the conditional with *>. – Zgarb – 2018-01-24T13:25:06.207

@Zgarb Nice idea to use *>! – Laikoni – 2018-01-24T13:27:39.877

3

Clean, 56 bytes

t[[h:_]]f=h
t[[h]:_]f=h
t[[h:_]:r]f=f h(t[t\\[_:t]<-r]f)

Try it online! Folds from right-to-left.

[t\\[_:t]<-r] is the same as map tl r, but does not need import StdEnv.

Laikoni

Posted 2018-01-24T12:12:43.803

Reputation: 23 676

1Very elegant avoidance of StdEnv – Οurous – 2018-01-24T21:23:20.370

3

APL (Dyalog Unicode), 7 bytes (Adám's SBCS)

⎕/1 1⍉⎕

Try it online!

-3 thanks to a suggestion to convert this to a full program by Adám.

Right-to-left.

Erik the Outgolfer

Posted 2018-01-24T12:12:43.803

Reputation: 38 134

No need to use Adám's SBCS here: you could just use Dyalog Classic's. – Zacharý – 2018-05-25T02:30:26.717

@Zacharý The thing is that I'm answering in Dyalog Unicode, Classic is getting deprecated over time. – Erik the Outgolfer – 2018-05-25T08:40:42.560

Not the codepage thoughm the codepage will live on – Zacharý – 2018-05-25T14:43:06.277

@Zacharý Well, let's rather be consistent. :P – Erik the Outgolfer – 2018-05-25T17:06:36.407

2

Haskell, 44 bytes

f#m=foldl1 f$zipWith(!!)m[0..length(m!!0)-1]

Try it online!

totallyhuman

Posted 2018-01-24T12:12:43.803

Reputation: 15 378

2

05AB1E, 15 10 bytes

Folds from right-to-left
Saved 5 bytes using a new built-in as suggested by Kevin Cruijssen

Å\`[.g#I.V

Explanation

Works the same as the old version, except that Å\ is a new built-in for pushing the main diagonal.

Try it online! or as a Test Suite

Old Version

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

Try it online! or as a Test suite

Explanation

¬                 # 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

Emigna

Posted 2018-01-24T12:12:43.803

Reputation: 50 798

1¬g£vyNè}[ can be Å\`[ now, saving 5 bytes. – Kevin Cruijssen – 2019-02-18T14:19:05.373

2

Husk, 7 bytes

Thanks @Zgarb for fixing my submission!

Ḟ₁§z!Tŀ

Associates to the left, Try it online! (for a right-associative version simply replace by F)

Explanation

Unfortunately there's no easy way to get the diagonal of a matrix, so most the bytes are for that:

Ḟ₁§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

ბიმო

Posted 2018-01-24T12:12:43.803

Reputation: 15 345

Huh, built-in for anti-diagonals, but not for diagonals‽ – Adám – 2018-01-24T12:27:21.397

2@Adám I assume that's because you can compute antidiagonals of infinite matrices but not diagonals. – Martin Ender – 2018-01-24T12:29:02.347

2

Python 2, 61 bytes

lambda f,m:reduce(f,[l[i]for i,l in enumerate(m)if len(l)>i])

Try it online!

This works left-to-right.

Rod

Posted 2018-01-24T12:12:43.803

Reputation: 17 588

@AsoneTuhid it can be any way, check the (x+y)⁄2 and x+2yexamples – Rod – 2018-01-24T14:41:36.700

Right, I misread, sorry – Asone Tuhid – 2018-01-24T17:20:47.250

2

JavaScript (ES6), 58 56 bytes

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

Folds left-to-right. Edit: Saved 2 bytes by using the fact that the array is strictly positive. Alternate solution, also 56 bytes:

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

Neil

Posted 2018-01-24T12:12:43.803

Reputation: 95 035

It doesn't look like you need the 1/ and you can save another 2 bytes by moving some stuff around: f=>a=>(h=r=>(e=a[++i]&&a[i][i])?h(f(r,e)):r)(a[i=0][0]). TIO

– Shaggy – 2018-01-24T15:38:56.440

@Shaggy Oh, it's strictly positive, I hadn't seen that. – Neil – 2018-01-24T17:36:40.690

Apparently we can assume that black-box functions are assigned to a predefined variable so you could save 2 bytes if you want to take advantage of that. – Shaggy – 2018-01-25T11:35:49.263

@Shaggy Actually I think it would save 4 bytes (2x f,) off the first version? – Neil – 2018-01-25T16:10:32.223

You're right; sorry, forgot to count the f, when calling g again. – Shaggy – 2018-01-25T16:26:35.527

2

Java 8, 88 81 70 69 bytes

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

Puts the result in the very first cell of the matrix instead of returning an integer (to save a byte).

Try it online.

Both folds [[1,2,3],[4,5,6],[7,8,9]] to f(f(1,5),9).

-7 bytes indirectly thanks to @KamilDrakari by using a similar trick as he did in his C# answer: instead of having a maximum boundary for the loop based on the rows/columns, simply try-catch the ArrayIndexOutOfBoundsException.
-11 bytes replacing catch(Exception e) with finally.
-1 byte thanks to @KamilDrakari again by putting the result in the very first cell.

Explanation:

m->{                   // Method with integer-matrix parameter and no return-type
  try{for(int i=1;     //  Start the index at 1 (0-based indexing)
          ;)           //   Loop indefinitely:
    m[0][0]=           //    Replace the value in the first cell with:
     f(m[0][0],        //     Call f with the current value of the first cell
       m[i][i++]));}   //     and the next diagonal cell as arguments
  finally{             //  If an ArrayIndexOutOfBoundsException occurred we're done,
    return;}}          //   in which case we'll terminate the method

Black box input format:

Assumes a named function int f(int x,int y) is present, which is allowed according to this meta answer.

I have an abstract class Test containing the default function f(x,y), as well as the lambda above:

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

  public java.util.function.Consumer<int[][]> c =
    m->{try{for(int i=1;;m[0][0]=f(m[0][0],m[i][i++]));}finally{return;}}
  ;
}

For the test cases, I overwrite this function f. For example, the first test case is called like this:

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

Kevin Cruijssen

Posted 2018-01-24T12:12:43.803

Reputation: 67 575

2

Standard ML (MLton), 59 bytes

fun t[h::_]f=h|t([h]::_)f=h|t((h::_)::r)f=f(h,t(map tl r)f)

Try it online! Folds from right-to-left.

Ungolfed:

fun trace [h::_]      f = h
  | trace ([h]::_)    f = h
  | trace ((h::_)::r) f = f (h, trace (map tl r) f)

Try it online!

Laikoni

Posted 2018-01-24T12:12:43.803

Reputation: 23 676

2

JavaScript, 46 bytes

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

Thanks to @Shaggy, use bitwise or save one byte. That's magic.

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

c=()=>o.value=g(eval(`(x,y)=>${f.value}`))(m.value.split(/\n/g).map(x=>x.trim().split(/\s+/).filter(v=>v.length).map(v=>+v)).filter(x=>x.length))
<p>a = <textarea id=m>1 2 3
4 5 6
7 8 9</textarea></p>
<p>f = (x, y) => <input id=f type=text value="x + y" /></p>
<p><button onclick=c()>Calc</button></p>
<p>Result = <output id=o></output></p>

tsh

Posted 2018-01-24T12:12:43.803

Reputation: 13 072

This doesn't seem to work if the matrix has more rows than columns. – Shaggy – 2018-01-25T10:45:55.050

@Shaggy so sad, 47 bytes now... – tsh – 2018-01-25T11:01:43.587

Yeah, that's what I had originally, too. Was just about to edit the fix into my solution but you beat me too it :( I think you can get one byte back, though, by using bitwise OR, though. – Shaggy – 2018-01-25T11:04:33.977

@Shaggy so magic – tsh – 2018-01-25T11:09:07.653

Forgot to mention: Apparently we can assume that black-box functions are assigned to a predefined variable so you could save 3 bytes if you wanted to take advantage of that. – Shaggy – 2018-01-25T15:33:51.820

2

Attache, 14 bytes

Fold#/Diagonal

Try it online! Set to f and call as f[function, array].

Explanation

This is a fork of two functions: Fold and /Diagonal. This, for arguments f and a, is equivalent to:

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

/, when applied monadically to a function, returns a function that is applied to its last argument. So, this is equivalent to:

Fold[f, Diagonal[a]]

This folds the function f over the main diagonal of a.

Conor O'Brien

Posted 2018-01-24T12:12:43.803

Reputation: 36 228

A home-brewed language which is readable‽ – Adám – 2018-01-25T15:16:48.200

@Adám ;D yes indeed! – Conor O'Brien – 2018-01-25T15:30:21.920

2

AWK, 77 bytes

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}

Try it online!

I was curious if AWK could do functional programming at all. I think this counts.

The "Matrix" is defined as a standard associative array, with extra fields M[1]=#rows and M[2]=#columns. The function name is passed in as a string which is evaluated via the @F(...) syntax. Evaluation is performed left to right. The r parameter is a placeholder to prevent overwriting an existing r variable and to avoid the need to reinitialize for each call. Typically extra space is added to designate such placeholders in AWK, but this is code golf, so every byte counts. :)

The TIO link implements all the test cases.

Robert Benson

Posted 2018-01-24T12:12:43.803

Reputation: 1 339

1

SNOBOL4 (CSNOBOL4), 86 bytes

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)')

Try it online!

Defines a function T (for TRACE) that takes an ARRAY and a string F that's the name of a function. Folds left-to-right.

Using indirect reference ($) doesn't work with functions. So using EVAL and passing a string to the name seems to be the only way to get a black-box function in SNOBOL.

Also, it's quite painful to define arrays; however, because invalid array references cause FAILURE, this works for non-square arrays -- if I is out-of-bounds in either dimension, the F(RETURN) forces the function to return.

Edit:

Possibly, based on this meta post, I may assume that the black-box function F is defined under the name F, which would drop this to 75 bytes (remove use of EVAL and ,F in the function definition). However, I prefer this version since it's closer to passing a reference to a function.

Giuseppe

Posted 2018-01-24T12:12:43.803

Reputation: 21 077

1

Pari/GP, 42 bytes

f->a->fold(f,[a[i,i]|i<-[1..min(#a,#a~)]])

Try it online!

alephalpha

Posted 2018-01-24T12:12:43.803

Reputation: 23 988

1

JavaScript, 61 57 56 52 50 44 42 bytes

Reduces left to right. Assumes the function is assigned to variable f, as per this meta post brought to my attention by Mr. Xcoder & totallyhuman. Can't say as I agree with it as it directly contradicts our existing consensus that we may not assume input is assigned to a pre-defined variable, but I'll take the few bytes saving for now.

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

Test Cases

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>

Shaggy

Posted 2018-01-24T12:12:43.803

Reputation: 24 623

1

C, 76 bytes

i,t;f(g,A,n,m)int*A,(*g)();{for(t=*A,i=m+1;--n*--m;t=g(t,*A))A+=i;return t;}

Left-to-right.

Try it online!

Steadybox

Posted 2018-01-24T12:12:43.803

Reputation: 15 798

1

C# (Visual C# Compiler), 72 69 60 bytes

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

Try it online!

try/catch allows the diagonal to be correctly reached by simply going along it and terminating when out of bounds.

3 bytes saved because, as pointed out by Kevin Cruijssen, black-box functions can be assumed to exist under a specific name.

9 bytes saved by returning via modifying an argument.

Thus, the function is called by storing the desired function under the name f, calling trace(matrix), and the result is stored in matrix[0][0].

Alternatively, if you really like verbosity,

C# (Visual C# Compiler), 97 + 13 = 110 78 69 bytes

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

Try it online!

32 bytes saved by using a predefined function, because not taking the function as a parameter allowed removing the System import and the long Func generic type.

Kamil Drakari

Posted 2018-01-24T12:12:43.803

Reputation: 3 461

Nice trick with the try-catch. I've been able to golf 7 bytes on my Java 8 answer (even though I have to use catch(Exception e) instead of catch. :) EDIT: Oh, been able to replace the catch(Exception e) with finally to save more bytes. Thanks again. +1 from me. – Kevin Cruijssen – 2018-01-25T11:59:02.430

@KevinCruijssen you may also be able to benefit from my newest improvement (though I don't remember for sure whether Java is amenable to modifying arguments) – Kamil Drakari – 2018-01-26T02:16:28.343

Thanks for letting me know. Although it is possible in Java, it means I'll have to change the finally into catch(Exception e), because I'm not returning inside the finally anymore. So m->{try{for(int i=1;;m[0][0]=f(m[0][0],m[i][i++]));}catch(Exception e){}} (73 bytes) is unfortunately longer for me in comparison to my current answer m->{int r=m[0][0],i=1;try{for(;;)r=f(r,m[i][i++]);}finally{return r;}} (70 bytes) But indeed a nice way to save bytes in your answer! :) Too bad I can only +1 your answer once. – Kevin Cruijssen – 2018-01-26T08:11:17.170

1

tinylisp, 79 bytes

(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

The last line is an unnamed lambda function that takes a function and matrix and returns the matrix trace. The trace is left-associative (i.e. f(f(1,5),9)). Try it online!

Ungolfed

We define a helper function to compute the diagonal; then generalized-trace is merely a small wrapper around the library function 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))))

When computing the diagonal recursively, we check whether (head matrix) is truthy. If the matrix is out of rows, it will be the empty list (nil), and head of nil is nil--falsey. Or, if the matrix is out of columns, its first row (head) will be the empty list (nil)--falsey. Otherwise, there will be a nonempty first row, which is truthy.

So, if the first row doesn't exist or is empty, we return nil. Otherwise, if there is a nonempty first row, we take (head (head matrix))--the first element of the first row--and cons (prepend) it to the result of the recursive call. The argument to the recursive call is (map tail (tail matrix))--that is, take all rows but the first, and take all but the first element of each row.

DLosc

Posted 2018-01-24T12:12:43.803

Reputation: 21 213

1

APL NARS, 20 bytes, 10 chars

{⍺⍺/1 1⍉⍵}

test:

  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

RosLuP

Posted 2018-01-24T12:12:43.803

Reputation: 3 036

Good job. While I think you arrive to this on you own, it happens to be identical to Erik the Outgolfer's original solution.

– Adám – 2018-01-31T09:20:36.253

0

Jelly, 5 bytes

Left-to-right.

ŒDḢç/

Try it online!

Disclaimer: I do not know if this an acceptable input method for black-box functions. This assumes that the function is implemented in the link above, and is thus "named" (that is, it's callable with) ç, but otherwise I have no way to assign it to ç. If anyone has more experience with Jelly + black box functions, I would appreciate thoughts. After spending some time in chat, we figured that using ç might indeed be valid.

Mr. Xcoder

Posted 2018-01-24T12:12:43.803

Reputation: 39 774

0

Ruby, 55 53 bytes

->f,m,n=m[i=0][0]{(k=m[i+=1]&.[]i)?(n=f[n,k];redo):n}

Try it online!

Asone Tuhid

Posted 2018-01-24T12:12:43.803

Reputation: 1 944

0

Clojure, 30 bytes

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

Reduces "from the left".

NikoNyrh

Posted 2018-01-24T12:12:43.803

Reputation: 2 361