Output diagonal positions of me squared

18

0

Given a number n, Output an ordered list of 1-based indices falling on either of the diagonals of an n*n square matrix.

Example:

For an input of 3:

The square shall be:

1 2 3
4 5 6
7 8 9

Now we select all the indices represented by \, / or X (# or non-diagonal positions are rejected)

\ # /
# X #
/ # \

The output shall be:

[1,3,5,7,9]

Test cases:

1=>[1]
2=>[1,2,3,4]
3=>[1,3,5,7,9]
4=>[1,4,6,7,10,11,13,16]
5=>[1,5,7,9,13,17,19,21,25]

There will be no accepted answer. I want to know the shortest code for each language.

sergiol

Posted 2017-08-24T09:15:17.233

Reputation: 3 055

1The question is asking for the (1-indexed) indices of the , / and X characters in the images. Not a bad question per se, but lacks explanation. – Arfie – 2017-08-24T09:24:01.623

If you are willing to provide a brief and clear explanation of what you want, We will probably reopen this, as it is not a bad challenge. As of now, it is just very unclear – Mr. Xcoder – 2017-08-24T09:36:58.197

I've voted to reopen, though you might also want to move the ascii images out of the examples area to avoid confusion. At first I wasn't sure if I had to produce those as well (but I understand the wanted output is only the list of indices) – Arfie – 2017-08-24T10:01:06.947

@Ruud: And how will do people understand what are the asked positions if they don't see the images? – sergiol – 2017-08-24T10:04:05.523

I'm not saying you shouldn't show them at all, just that you put them (or just two or three of them) with the explanation of the challenge, rather than the example inputs and outputs. – Arfie – 2017-08-24T10:05:10.523

7Does the order matter? – Mr. Xcoder – 2017-08-24T10:19:29.503

@sergiol Is 0-indexing allowed? My previous question stands ^ – Mr. Xcoder – 2017-08-24T10:58:39.620

@Mr.Xcoder: Does the order matter? Yes. Is 0-indexing allowed? No. Because it is how I specified the question in the examples. – sergiol – 2017-08-24T11:04:30.823

9FWIW I think having the order be irrelevant might make for more interesting golfs... – Jonathan Allan – 2017-08-24T11:17:11.577

Would a dash-separated string be a valid output? e.g. "1-3-5-7-9" – Arnauld – 2017-08-24T13:19:28.920

@Arnauld: yes . – sergiol – 2017-08-24T13:20:26.140

@ThePirateBay: If you don't publish the derived challenge, I will publish it myself! – sergiol – 2017-08-25T11:09:25.860

Answers

10

Octave, 28 bytes

@(n)find((I=eye(n))+flip(I))

Anonymous function that inputs a number and outputs a column vector of numbers.

Try it online!

Luis Mendo

Posted 2017-08-24T09:15:17.233

Reputation: 87 464

2So simple... :) – Stewie Griffin – 2017-08-24T16:24:17.950

7

JavaScript (ES6), 48 bytes

Outputs a dash-separated list of integers as a string.

f=(n,k=n*n)=>--k?f(n,k)+(k%~-n&&k%-~n?'':~k):'1'

Formatted and commented

f = (n, k = n * n) => // given n and starting with k = n²
  --k ?               // decrement k; if it does not equal zero:
    f(n, k) + (       //   return the result of a recursive call followed by:
      k % ~-n &&      //     if both k % (n - 1) and
      k % -~n ?       //             k % (n + 1) are non-zero:
        ''            //       an empty string
      :               //     else:
        ~k            //       -(k + 1) (instantly coerced to a string)
    )                 //   end of iteration
  :                   // else:
    '1'               //   return '1' and stop recursion

Test cases

f=(n,k=n*n)=>--k?f(n,k)+(k%~-n&&k%-~n?'':~k):'1'

;[1,2,3,4,5].forEach(n => console.log(n, '->', f(n)))

Arnauld

Posted 2017-08-24T09:15:17.233

Reputation: 111 334

Nice workaround, using the signs as separators. Could you use bitwsie & to save a byte? – Shaggy – 2017-08-24T13:47:59.417

@Shaggy No, that wouldn't work. For instance: 4%3 and 4%5 have no 1-bit in common, but both are non-zero. – Arnauld – 2017-08-24T13:58:43.673

Yup, just tested it with n=5 and spotted that it wouldn't work. – Shaggy – 2017-08-24T14:08:05.087

k%~-n&&k%-~n should work. nice trick with the separator! – Titus – 2017-08-24T17:12:25.580

@Titus Not that it really matters when it comes to golfing but ... yeah, that might be slightly more readable. :-) (updated) – Arnauld – 2017-08-24T20:00:05.750

7

R, 38 35 34 38 bytes

3 bytes saved when I remembered about the existence of the which function... , 1 byte saved thanks to @Rift

d=diag(n<-scan());which(d|d[n:1,])

+4 bytes for the argument ec=T when called as a full program by source()

Try it online!

Explanation:

n<-scan()            # take input
d=diag(n);           # create an identity matrix (ones on diagonal, zeros elsewhere)
d|d[n:1,]            # coerce d to logical and combine (OR) with a flipped version
which([d|d[n:1,]])   # Find indices for T values in the logical expression above

user2390246

Posted 2017-08-24T09:15:17.233

Reputation: 1 391

1-1 byte d=diag(n<-scan());which(d|d[n:1,]) – Rift – 2017-08-24T15:50:01.843

When running this as a full program (source) this doesn't print anything. You have to call cat. See this post on meta.

– JAD – 2017-08-25T12:06:03.647

@JarkoDubbeldam Fair enough! I had always worked on the basis that it gives valid output on TIO, never really considered the requirements of being a "full program". – user2390246 – 2017-08-25T12:30:30.680

Though I'm not planning on going back and editing all my old answers to fix this! – user2390246 – 2017-08-25T12:32:29.150

It is a bit vague, because of the console environment of R and code snippets being the main way of using it. Feel free to share insights on that meta thread I linked. It hasn't received all that much input. – JAD – 2017-08-25T12:41:34.263

37 bytes as a function – Giuseppe – 2017-09-25T15:55:17.323

6

Jelly, 8 bytes

⁼þ`+Ṛ$ẎT

Try it online!

Uses Luis Mendo's algorithm on his MATL answer.

Erik the Outgolfer

Posted 2017-08-24T09:15:17.233

Reputation: 38 134

Mhm, I am quite surprised you didn't use ŒD. – Mr. Xcoder – 2017-08-24T11:06:42.420

@Mr.Xcoder ŒD does something completely different from X of a specific size. – Erik the Outgolfer – 2017-08-24T11:14:17.377

5

Octave, 41 37 bytes

This works in MATLAB too by the way. No sneaky Octave specific functionality :)

@(x)unique([x:x-1:x^2-1;1:x+1:x*x+1])

Try it online!

Explanation:

Instead of creating a square matrix, and find the two diagonals, I figured I rather calculate the diagonals directly instead. This was 17 bytes shorter! =)

@(x)                                   % Anonymous function that takes 'x' as input
    unique(...                   ...)  % unique gives the unique elements, sorted
           [x:x-1:x^2-1                % The anti-diagonal (is that the correct word?)
                       ;               % New row
                        1:x+1:x*x+1])  % The regular diagonal

This is what it looks like, without unique:

ans =    
    6   11   16   21   26   31
    1    8   15   22   29   36

Yes, I should probably have flipped the order of the diagonals to make it more human-friendly.

Stewie Griffin

Posted 2017-08-24T09:15:17.233

Reputation: 43 471

5

MATL, 6 bytes

XytP+f

Try it online!

Explanation

Same approach as my Octave answer.

Consider input 3 as an example.

Xy   % Implicit input. Identity matrix of that size
     % STACK: [1 0 0;
               0 1 0;
               0 0 1]
t    % Duplicate
     % STACK: [1 0 0
               0 1 0
               0 0 1],
              [1 0 0
               0 1 0
               0 0 1]
P    % Flip vertically
     % STACK: [1 0 0
               0 1 0
               0 0 1],
              [0 0 1
               0 1 0
               1 0 0]
+    % Add
     % STACK: [1 0 1
               0 2 0
               1 0 1]
f    % Linear indices of nonzero entries. Implicit display  
     % STACK:[1; 3; 5; 7; 9]

Linear indexing is column-major, 1-based. For more information see length-12 snippet here.

Luis Mendo

Posted 2017-08-24T09:15:17.233

Reputation: 87 464

What is "transpose" supposed to mean? – Erik the Outgolfer – 2017-08-24T18:27:41.213

@EriktheOutgolfer Sorry, my bad. t is duplicate, not transpose. Also, I've added a worked out example – Luis Mendo – 2017-08-24T19:37:55.057

Amazing! It would take me two loops if I want to accomplish this. – mr5 – 2017-08-25T02:51:58.450

@LuisMendo I suspected so, because transposing an identity matrix makes no sense...hmm, I managed to save a byte with your algorithm. – Erik the Outgolfer – 2017-08-25T08:52:57.860

4

Python 2, 54 53 bytes

lambda n:[i+1for i in range(n*n)if i%-~n<1or i%~-n<1]

Try it online!

Arfie

Posted 2017-08-24T09:15:17.233

Reputation: 1 230

4

Mathematica, 42 bytes

Union@Flatten@Table[{i,#+1-i}+i#-#,{i,#}]&

Try it online!

@KellyLowder golfed it down to..

Mathematica, 37 bytes

##&@@@Table[{i-#,1-i}+i#,{i,#}]⋃{}&

and @alephalpha threw away the table!

Mathematica, 34 bytes

Union@@Range[{1,#},#^2,{#+1,#-1}]&

J42161217

Posted 2017-08-24T09:15:17.233

Reputation: 15 931

##&@@@Table[{i-#,1-i}+i#,{i,#}]⋃{}& is 5 bytes shorter – Kelly Lowder – 2017-08-24T14:54:45.013

Union@@Range[{1,#},#^2,{#+1,#-1}]& – alephalpha – 2017-08-25T11:55:37.757

4

Octave, 68 54 bytes

Thanks to @Stewie Griffin for saving 14 bytes!

@(x)unique([diag(m=reshape(1:x^2,x,x)),diag(flip(m))])

Try it online!

MATLAB, 68 bytes

x=input('');m=reshape([1:x*x],x,x);unique([diag(m) diag(flipud(m))])

Explanation:

@(x)                               % Anonymous function
m=reshape([1:x*x],x,x);            % Create a vector from 1 to x^2 and
                                   % reshape it into an x*x matrix.
diag(m)                            % Find the values on the diagonal.
diag(flip(m))                      % Flip the matrix upside down and
                                   % find the values on the diagonal.
unique([])                         % Place the values from both diagonals
                                   % into a vector and remove duplicates.

Steadybox

Posted 2017-08-24T09:15:17.233

Reputation: 15 798

@LuisMendo Thanks, Jimi's my favourite. – Steadybox – 2017-08-24T14:59:59.420

2

Proton, 41 bytes

n=>[i+1for i:0..n*n if!(i%-~n)or!(i%~-n)]

Try it online!

Mr. Xcoder

Posted 2017-08-24T09:15:17.233

Reputation: 39 774

2

MATL, 14 bytes

U:GeGXytPY|*Xz

Try it online!

Cinaski

Posted 2017-08-24T09:15:17.233

Reputation: 1 588

6 bytes – Luis Mendo – 2017-08-24T14:36:45.753

Wow! Please post it, I'll eventually delete mine – Cinaski – 2017-08-24T14:42:20.793

1I will post it if you are not going to incorporate it into your answer; but no need to delete yours – Luis Mendo – 2017-08-24T14:43:37.740

2

C (gcc), 65 58 bytes

-7 bytes thanks to Titus!

f(n,i){for(i=0;i<n*n;i++)i%-~n&&i%~-n||printf("%d ",i+1);}

Try it online!

scottinet

Posted 2017-08-24T09:15:17.233

Reputation: 981

1i%-~n&&i%~-n||printf("%d ",i+1) (-7 bytes) – Titus – 2017-08-24T16:54:50.253

2

Javascript, 73 63 bytes

old version

n=>[...Array(y=n*n).keys(),y].filter(x=>(--x/n|0)==x%n||(x/n|0)==n-x%n-1)

Saved 10 bytes thanks to @Shaggy

n=>[...Array(n*n)].map((_,y)=>y+1).filter(x=>!(--x%-~n&&x%~-n))

First time golfing! here's hoping I didn't mess up too badly.

let f=n=>[...Array(n*n)].map((_,y)=>y+1).filter(x=>!(--x%-~n&&x%~-n));
[1,2,3,4,5].forEach(n=>console.log(f(n)))

Marco Lepore

Posted 2017-08-24T09:15:17.233

Reputation: 21

Welcome to PPCG :) A similar solution to the one I was working on (only mine is 0-indexed). You might be able to save some bytes by using the following in your filter function: !(--x%(n+1)&&x%(n-1)) and by creating your array like so: [...Array(n*n+1).keys()] – Shaggy – 2017-08-24T14:02:34.827

@Shaggy Thank you! I'll try to improve the answer with your suggestion as soon as I get home from work! – Marco Lepore – 2017-08-24T14:07:34.460

You're welcome. By the way: "it's a bit shorter than creating a `[1...nn]range withArray(nn).fill().map((x,i)=>i+1)`" - [...Array(n*n)].map((_,y)=>y+1) is a shorter way of doing that, for future reference. – Shaggy – 2017-08-24T14:26:05.897

Did a bit more with it and ended up with this for 56 bytes: n=>[...Array(n*n+1).keys()].filter(x=>!(--x%-~n&&x%~-n)) – Shaggy – 2017-08-24T14:49:53.573

@Shaggy I tried your last version but it would output an extra zero for f(1) and f(2), it works with a [1...n*n] range though so I used the way you showed me in the previous comment. Or maybe I messed up someway? – Marco Lepore – 2017-08-27T13:41:10.580

2

C# (.NET Core), 97 83 bytes

f=>{var s="[";for(int i=0;i<n*n-1;)s+=i%-~n<1|i++%~-n<1?i+",":"";return s+n*n+"]";}

Try it online!

The change here is based on the shift between numbers to find. The two shifts starting at 0 are n-1 and n+1, so if n=5, the numbers for n-1 would be 0,4,8,12,16,20 and for n+1 would be 0,6,12,18,24. Combining these and giving 1-indexing (instead of 0-indexing) gives 1,5,7,9,13,17,19,21,25. The offset from n is achieved using bitwise negation (bitwise complement operation), where ~-n==n-1 and -~n==n+1.

Old Version

f=>{var s="[";for(int i=0;i<n*n-1;i++)s+=(i/n!=i%n&&n-1-i/n!=i%n?"":i+1+",");return s+$"{n*n}]";}

Try it online!

This approach uses the column and row indices for determining if the numbers are on the diagonals. i/n gives the row index, and i%n gives the column index.

Returning Only The Number Array

If constructing only the number array is deemed to count towards the byte cost, then the following could be done, based on Dennis.Verweij's suggestion (using System.Linq; adds an extra 18 bytes):

C# (.NET Core), 66+18=84 bytes

x=>Enumerable.Range(1,x*x).Where(v=>~-v%~-x<1|~-v%-~x<1).ToArray()

Try it online!

Ayb4btu

Posted 2017-08-24T09:15:17.233

Reputation: 541

you can reduce the code by getting rid of the extra &. The extra & is there only to break the comparison if the first input is false MSDN

– Dennis.Verweij – 2017-08-25T13:01:10.323

in fact you can have 92 bytes by using Linq Try it online!

– Dennis.Verweij – 2017-08-25T13:47:55.663

@Dennis.Verweij Neat, I wasn't sure how much I could shift to the header or footer in TIO. I'll have a play around with mine. – Ayb4btu – 2017-08-25T20:07:42.390

you have to remember to include 18 bytes for the reference to linq (using System.Linq;) which is unfortunate, but how it works :S – Dennis.Verweij – 2017-08-26T18:56:02.747

Ah, ok. But that isn't necessary for using System;? (I assume wrapping it in a namespace System.Linq isn't valid?) – Ayb4btu – 2017-08-26T21:14:19.693

1

Pyth, 20 18 bytes

(Here is the initial version.)

hMf|<%ThQ1<%TtQ1U*

Test Suite.

Pyth, 18 bytes

hMf>1*%ThQ%T|tQ1U*

Test Suite.

Mr. Xcoder

Posted 2017-08-24T09:15:17.233

Reputation: 39 774

1

Perl 5, 56 + 1 (-n) = 57 bytes

!(($_+1+$_/$,)%$,&&$_%($,+1))&&say++$_ for 0..($,=$_)**2

Try it online!

Xcali

Posted 2017-08-24T09:15:17.233

Reputation: 7 671

Shouldn't -n be +3? – sergiol – 2017-08-24T15:27:12.443

1No. The assumed command line is perl -e. The command line for this example would be perl -ne. That's a difference of +1. – Xcali – 2017-08-24T15:32:00.620

1

Java (OpenJDK 8), 71 bytes

n->{for(int i=0;i<n*n;i++)if(i%-~n<1||i%~-n<1)System.out.println(i+1);}

Try it online!

Port of scottinet's answer.

Olivier Grégoire

Posted 2017-08-24T09:15:17.233

Reputation: 10 647

1

Japt, 16 bytes

Can't seem to do better than this but I'm sure it's possible. Had to sacrifice 2 bytes for the unnecessary requirement that we use 1-indexing.

²õ f@´XvUÉ ªXvUÄ

Test it

Shaggy

Posted 2017-08-24T09:15:17.233

Reputation: 24 623

1

Octave, 32 bytes

@(n)find((m=abs(--n:-2:-n))==m')

Try it online!

rahnema1

Posted 2017-08-24T09:15:17.233

Reputation: 5 435

0

PHP, 56 54+1 bytes

+1 byte for -R flag

for(;$z**.5<$n=$argn;$z++)$z%-~$n&&$z%~-$n||print~+$z;

prints numbers prepended by dashes. Run as pipe with -nR or try it online.

requires PHP 5.6 or later for ** operator.
Add one byte for older PHP: Replace ;$z**.5<$n=$argn with $z=$argn;$z<$n*$n.

Titus

Posted 2017-08-24T09:15:17.233

Reputation: 13 814

0

Ruby, 45 bytes

->n{(n*n).times{|i|i%-~n>0&&i%~-n>0||p(i+1)}}

Works internally as zero indexed. checks if i modulo n+1 or n-1 is 0, if so prints i+1.

Level River St

Posted 2017-08-24T09:15:17.233

Reputation: 22 049