Perfect Squares Without Borders

16

2

Given n=m^2, return a list of integers that do not border the m x m grid of integers from 1 to n.

Examples

n=1 (m=1)

Grid:

[1]

Return:

[]

n=4 (m=2)

Grid:

[1,2]
[3,4]

Return:

[]

n=9 (m=3)

Grid:

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

Return:

[5]

n=16 (m=4)

Grid:

[ 1, 2, 3, 4]
[ 5, 6, 7, 8]
[ 9,10,11,12]
[13,14,15,16]

Return:

[6,7,10,11]

For higher values of m, this answer does a great visualization.


Rules:

  • You may take in either m or n (where n = m*m).
    • If taking in n you are allowed to have undefined behavior where there exists no m for n (E.G. 15).
    • n > 0, m > 0: Both must be integer values.
  • The output may be as a 1D/2D array, matrix or whitespace delimited
  • The output must be in order from least to greatest.
    • If outputting as a matrix this means it must be as it would be in the grid.
  • This is , lowest byte-count wins.

Magic Octopus Urn

Posted 2018-02-02T19:24:18.433

Reputation: 19 422

Complete fault on my end, I read it incorrectly. – DevelopingDeveloper – 2018-02-02T21:46:20.930

3@DevelopingDeveloper hey man, if I had a nickle for every time I did that I'd be able to buy a beer or two. – Magic Octopus Urn – 2018-02-02T21:51:01.563

If outputting as a 2D array, can a single empty array be included in the result? – Shaggy – 2018-02-03T09:41:23.970

Answers

6

C, 50 bytes

i;f(m){for(i=m;++i<m*m-m;)i%m>1&&printf("%d ",i);}

Try it online!

Steadybox

Posted 2018-02-02T19:24:18.433

Reputation: 15 798

6

Octave, 31 bytes

@(m)vec2mat(1:m*m,m--)(2:m,2:m)

Returns a matrix.

Try it online!

Steadybox

Posted 2018-02-02T19:24:18.433

Reputation: 15 798

2Nice! I've never come across the vec2mat function before. – Tom Carpenter – 2018-02-03T18:05:24.863

6

Octave, 26 bytes

@(m)find((t=[0:m-2 0])'*t)

The code defines an anonymous function that inputs m and outputs a (possibly empty) column vector.

Try it online!

Explanation

@(m)                          % Define anonymous function of m
          t=[0:m-2 0]         % Build row vector [0 1 2 ... m-2 0] and assign it
                              % to variable t
         (           )'       % Complex-conjugate transpose into a column vector
                       *t     % Matrix-multiply that column vector times the row
                              % vector t. This gives an m×m matrix with zeros in
                              % the border and nonzeros in the other entries.
    find(                )    % Linear indices of nonzero entries. The result is
                              % in increasing order

Luis Mendo

Posted 2018-02-02T19:24:18.433

Reputation: 87 464

5

Jelly, 8 bytes

’Ṗ×+€ṖḊ€

A monadic link taking m and returning a list of lists (the inner rows).

Try it online!

How?

’Ṗ×+€ṖḊ€ - Link m                    e.g. 5
’        - decrement                      4
 Ṗ       - pop (implicit range of input)  [1,2,3]
  ×      - multiply by m                  [5,10,15]
     Ṗ   - pop m                          [1,2,3,4]
   +€    - add €ach                       [[6,7,8,9],[11,12,13,14],[16,17,18,19]]
      Ḋ€ - dequeue €ach                   [[7,8,9],[12,13,14],[17,18,19]]

Jonathan Allan

Posted 2018-02-02T19:24:18.433

Reputation: 67 804

Didn't feel like doing the python one ;)? – Magic Octopus Urn – 2018-02-02T21:51:26.253

4

Haskell, 31 bytes

f m=[i|i<-[m..m*m-m],mod i m>1]

Try it online!

Math version:

f(m) = {i : i ∈ (m, m² - m), i mod m < 1}

:P

totallyhuman

Posted 2018-02-02T19:24:18.433

Reputation: 15 378

Wait, this isn't valid, f(5) should be 7,8,9,12,13,14,17,18,19 – Magic Octopus Urn – 2018-02-02T19:49:57.027

Wait, oops I'm a dumbass. – totallyhuman – 2018-02-02T19:54:44.183

4

R, 44 43 32 bytes

function(n)(x=n:(n^2-n))[x%%n>1]

Try it online!

Returns a vector.

Giuseppe

Posted 2018-02-02T19:24:18.433

Reputation: 21 077

Neat output format, is that by default how a matrix is output in R? – Magic Octopus Urn – 2018-02-02T19:51:20.007

1Yep, that's the print function for a matrix. – Giuseppe – 2018-02-02T19:51:54.207

1You can omit the second m in matrix(1:m^2,m,m,T): matrix(1:m^2,m,,T) – JAD – 2018-02-03T13:26:33.710

@JAD yes, of course. Thanks. – Giuseppe – 2018-02-05T16:26:00.530

Nice one, what do you think about using scan()? You might save 2 bytes. Try it online!

– Robert Hacken – 2018-02-10T12:40:46.387

4

Pure Bash, 49

The boring answer:

for((i=$1;i++<$1*$1-$1;));{ ((i%$1>1))&&echo $i;}

Try it online.


Or the interesting answer for 52:

(($1>2))&&eval echo \$[$1*{1..$[$1-2]}+{2..$[$1-1]}]

Try it online.

Digital Trauma

Posted 2018-02-02T19:24:18.433

Reputation: 64 644

3

Jelly, 8 bytes

sƽḊṖ$⁺€

Try it online!

Erik the Outgolfer

Posted 2018-02-02T19:24:18.433

Reputation: 38 134

Using m one could do ²s⁸ḊṖ$⁺€ too. (I have also posted another m alternative method.) – Jonathan Allan – 2018-02-02T21:14:40.643

@JonathanAllan Already discovered that, but no byte saving over there, you can't remove the :( – Erik the Outgolfer – 2018-02-02T21:18:55.607

3

Proton, 28 bytes

k=>filter(u=>1<u%k,k..k*~-k)

Try it online!

Takes m as input.

How?

Filters the integers in [k, k2-k) that, when divided by k, yield a remainder higher than 1. This ensures that both ends are trimmed, because the first one yields 0 and the last one yields 1. It is also guaranteed to return a higher value for any valid integer, because they are consecutive.

Mr. Xcoder

Posted 2018-02-02T19:24:18.433

Reputation: 39 774

3

Wolfram Language (Mathematica), 31 bytes

Table[# i+j+1,{i,#-2},{j,#-2}]&

Try it online!

Kelly Lowder

Posted 2018-02-02T19:24:18.433

Reputation: 3 225

2

05AB1E, 9 bytes

LItä¦¨ε¦¨

Try it online!

Mr. Xcoder

Posted 2018-02-02T19:24:18.433

Reputation: 39 774

LItä¦¨ε¦¨ is fine, the output can be a 2D array. – Magic Octopus Urn – 2018-02-02T20:19:15.400

Oh, I should have read the spec better. Thanks for the heads-up! – Mr. Xcoder – 2018-02-02T20:19:59.120

2

Bash + GNU utilities, 35

seq $1 $[$1*$1-$1]|sed 1~$1d\;2~$1d

Try it online.

Digital Trauma

Posted 2018-02-02T19:24:18.433

Reputation: 64 644

2

J, 23 19 bytes

-4 bytes thanks to FrownyFrog!

1 1}:@}.-@%:}:\1+i.

Try it online!

My original olution:

J, 23 bytes

[:|:@}:@}.^:2-@%:]\1+i.

Takes n as input, returns a matrix

How it works

1+i. - generates a list 1..n

-@%: - finds the square root of n and negates it (m)

]\ - makes a table (matrix) m x m from the list

^:2 - do the following twice:

|:@}:@}. - drop the first row, then drop the last row, then transpose

[: - cap the fork

Try it online!

Galen Ivanov

Posted 2018-02-02T19:24:18.433

Reputation: 13 815

1}:@}.-@%:}.@}:\1+i. – FrownyFrog – 2018-02-03T13:33:57.070

1No, 1 1}:@}.-@%:}:\1+i. – FrownyFrog – 2018-02-03T13:40:35.710

@FrownyFrog - Cool, thanks! I didn't know about the list left argument of }. – Galen Ivanov – 2018-02-03T17:26:34.667

2

Python 2, 44 bytes

lambda t:[k for k in range(t,~-t*t)if k%t>1]

Try it online!

I promise this is my last answer (to this challenge) today. Takes m as input.

Mr. Xcoder

Posted 2018-02-02T19:24:18.433

Reputation: 39 774

2

Julia 0.6, 36 bytes

m->reshape(1:m*m,(m,m))[2:m-1,2:m-1]

Try it online!

gggg

Posted 2018-02-02T19:24:18.433

Reputation: 1 715

2

Ruby, 32 bytes

->m{(m..m*m-m).reject{|e|e%m<2}}

Takes m, returns a one-dimensional array.

Try it online!

Reinstate Monica -- notmaynard

Posted 2018-02-02T19:24:18.433

Reputation: 1 053

2

MATL, 8 bytes

:G\1>&*f

Input is m. Output is the numbers in increasing order.

Try it online!

Explanation

Consider input 4 as an example.

:     % Implicit input: m. Push range [1 2 ... m-1 m]
      % STACK: [1 2 3 4]
G\    % Modulo m, element-wise
      % STACK: [1 2 3 0]
1>    % Greater than 1, element-wise.
      % STACK: [0 1 1 0]
&*    % Matrix of pair-wise products
      % STACK: [0 0 0 0;
                0 1 1 0;
                0 1 1 0;
                0 0 0 0]
f     % Column vector of linear indices of nonzeros. Implicit display
      % STACK: [ 6;
                 7;
                10;
                11]

Luis Mendo

Posted 2018-02-02T19:24:18.433

Reputation: 87 464

2

APL (Dyalog Classic), 14 bytes

1+⊢⊥¨∘⍳2⍴0⌈-∘2

Try it online!

ngn

Posted 2018-02-02T19:24:18.433

Reputation: 11 449

2

Japt, 14 bytes

²õ òU ÅkJ ®ÅkJ

Takes m as input

Explanation

 ²õ òU ÅkJ ®ÅkJ                                      
                // U = input                         | 3
U²              // U squared                         | 9
  õ             // Range [1...U²]                    | [1,2,3,4,5,6,7,8,9]
    òU          // Cut into slices of U              | [[1,2,3],[4,5,6],[7,8,9]]
       Å        // Remove the first item             | [[4,5,6],[7,8,9]]
        kJ      // Remove the last item              | [[4,5,6]]
           ®    // Map:                              |
            ÅkJ //   Remove the first and last items | 5     

Try it online!


The solution that takes n is also 14 bytes:

õ òU¬ ÅkJ ®ÅkJ

Try it online!

Oliver

Posted 2018-02-02T19:24:18.433

Reputation: 7 160

2

Batch, 85 bytes

@for /l %%i in (3,1,%1)do @for /l %%j in (3,1,%1)do @cmd/cset/a(%%i-2)*%1+%%j-1&echo(

I can't easily loop from 2 to m-1 so I loop from 3 to m and adjust in the calculation.

Neil

Posted 2018-02-02T19:24:18.433

Reputation: 95 035

2

Pari/GP, 26 bytes

n->[x|x<-[n..n^2-n],x%n>1]

Try it online!

alephalpha

Posted 2018-02-02T19:24:18.433

Reputation: 23 988

2

Japt, 12 bytes

I spent so long golfing the extraction of elements that I ran out of time to golf the array generation. I'm also only now noticing that we can take n as input instead so I may be able to save something there. To be revisited ...

òUnU²)òU m¤c

Try it


Explanation

                 :Implicit input of integer U=m     :e.g., 4
   U²            :U squared                         :16
 Un              :Minus U                           :12
ò                :Range [U,U**2-U]                  :[4,5,6,7,8,9,10,11,12]
      òU         :Partitions of length U            :[[4,5,6,7],[8,9,10,11],[12]]
         m       :Map
          ¤      :  Remove first 2 elements         :[[6,7],[10,11],[]]
           c     :Flatten                           :[6,7,10,11]

Shaggy

Posted 2018-02-02T19:24:18.433

Reputation: 24 623

2

Husk, 9 bytes

‼ȯTthS↑CN

Try it online!

Explanation

‼ȯTthS↑CN  Implicit input, say m=4.
       CN  Cut the natural numbers by m: [[1,2,3,4],[5,6,7,8],[9,10,11,12],..
     S↑    Take first m lists: [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]
‼ȯ         Do this twice:
    h       Remove last row,
   t        remove first row,
  T         transpose.
           Result is [[6,7],[10,11]]; print it implicitly.

Zgarb

Posted 2018-02-02T19:24:18.433

Reputation: 39 083

2

TI-BASIC, 44 43 bytes (tokenized)

DC 4D 3F CE 4D 6D 32 3F CF 3F DE 2A 08 09 3F D0 3F 4D 71 32 3F 23 4D 70 32 70 58 70 32 B1 58 83 72 11 2B 58 2B 30 2B 72 0D 71 31

Readable version:

:Input M
:If M≤2
:Then
:Disp "{}
:Else
:M-2
:seq(M+2+X+2int(X/Ans),X,0,Ans²-1

It was unfortunately necessary to print empty lists manually since TI-BASIC does not normally allow that. If m were given greater than two, the code could be reduced to just 29 bytes.

fakedad

Posted 2018-02-02T19:24:18.433

Reputation: 121

1

Pyth, 10 bytes

mtPdtPcQS*

Try it here!

Takes m as input.

Mr. Xcoder

Posted 2018-02-02T19:24:18.433

Reputation: 39 774

Alternative – Mr. Xcoder – 2018-02-02T20:31:17.960

1

Java 8, 241 183 170 162 160 132 122 bytes

j->{if(j<3)return new int[1];int e[]=new int[j*j-4*j+4],x=0,i=0;for(;++i<=j*j;)if(!(i<j|i>j*j-j|i%j<2))e[x++]=i;return e;}

Try it online!

Java makes it very tough(lots of bytes) when you have to create an array of somewhat "unknown" size.

  • -8 bytes thanks to Magic Octopus Urn
  • -28 bytes thanks to Mr. Xcoder
  • -10 bytes thanks to Kevin Cruijssen

DevelopingDeveloper

Posted 2018-02-02T19:24:18.433

Reputation: 1 415

1Also, yes, Java is rough for code-golf. But you're obviously good at it. Man, you need to check out this language called Groovy it's basically shorthand Java. – Magic Octopus Urn – 2018-02-02T22:00:18.530

2132 bytes by removing an extra condition from the if statement, and various tricks. – Mr. Xcoder – 2018-02-03T12:23:39.903

1122 bytes continuing @Mr.Xcoder's 132-byte version above by combining the int, changing the || to |, and removing the brackets of the single-line if-body. – Kevin Cruijssen – 2018-02-05T09:20:04.460

1101 bytes – ceilingcat – 2019-10-24T02:19:54.760

1

Red, 63 62 bytes

f: func[n][repeat i(n - 2 * n)[if(a: n + i)// n > 1[print a]]]

Try it online!

This is a Red port of totallyhuman's Haskell / Mr. Xcoder's Python 2 solution

Galen Ivanov

Posted 2018-02-02T19:24:18.433

Reputation: 13 815

1

Javascript (63 55 bytes)

m=>[...Array((m-2)*m)].map((x,i)=>i+m).filter(x=>x%m>1)

Explanation

m =>                    // function signature is m
    [...Array((m-2)*m)] // create an array of size m^2 - 2m,
                        // m^2 is the full array size, taking out 2m removes the top and bottom edges
                        // filled with undefined
    .map((x,i)=>i+m)    // fill with values m to n-m
                        // (skips the top and bottom edges of the square)
    .filter(x=>x%m>1)   // filter out x%m < 2, the left and right sides of the square

asgallant

Posted 2018-02-02T19:24:18.433

Reputation: 309

1You only use n once, so you can just use m*m directly. Also, the JavaScript (ES6) tips page has a tip for getting rid of fill. – Neil – 2018-02-03T02:36:16.537

You're right n=m*m is a holdover from a previous iteration when I had multiple references to n. And thanks for the tip on .fill, I figured there was a way to golf it, but I hadn't considered [...Array(x)]. – asgallant – 2018-02-05T16:25:53.550

1

Pyt, 13 bytes

ĐĐ⁻⁻ř*⇹⁻⁻ř⁺ɐ+

Port of Jonathan Allan's Jelly answer

Explanation:

                    Implicit input (takes m)
ĐĐ                  Triplicate the input (push it on the stack two more times)
  ⁻⁻                Decrement top of stack twice
    ř               Push [1,2,...,m-2]
     *              Multiplies by m
      ⇹             Swaps top two items on stack
       ⁻⁻           Decrement (m-2 is now on top)
         ř          Push [1,2,...,m-2]
          ⁺         Increment each element by 1
           ɐ+       Add [2,3,...,m-1] to each element of [m,2m,...,m(m-2)]
                    Implicit print

Try it online!

mudkip201

Posted 2018-02-02T19:24:18.433

Reputation: 833

1

Perl, 30 29 bytes

perl -E 'say$_+=@a+2for(@a=2..~-<>)x@a' <<< 4

Ton Hospel

Posted 2018-02-02T19:24:18.433

Reputation: 14 114

1

JavaScript, 47 bytes

  m=>{for(i=m;++i<m*m-m;)if(i%m>1)console.log(i)} // here's the 47-byte script

Also, 49 bytes:

  m=>{for(i=m;(i%m>1&&console.log(i))|++i<m*m-m;);} // here's the 49-byte script

JSGuy

Posted 2018-02-02T19:24:18.433

Reputation: 11

2Your solution presumes the input is assigned to a predefined variable, which we don't permit. – Shaggy – 2018-02-03T11:08:40.177

Not only that, but this solution isn't a function or a full program and relies on other variables and values. For this to be considered valid, either rewrite this as a function or a full program (asking for input with prompt()). Here's a sub-optimal 55 bytes long solution for you: (m,a=[])=>{for(i=m;++i<m*m-m;)if(i%m>1)a[i]=i;return a} – Ismael Miguel – 2018-02-03T11:46:54.970

Fixed in accordance with rules. – JSGuy – 2018-02-04T15:54:59.400

You can golf it further by switching to an arrow function: m=>{for(i=m;++i<m*m-m;)if(i%m>1)console.log(i)}, 47 bytes. – asgallant – 2018-02-05T17:17:05.927

alert is shorter than console.log. Welcome to PPCG, by the way. – Shaggy – 2018-02-06T08:54:03.810

1

Clean, 45 bytes

import StdEnv
$m=[i\\i<-[m..m*m-m]|i rem m>1]

Try it online!

This is just totallyhuman's Haskell answer but in Clean.

Οurous

Posted 2018-02-02T19:24:18.433

Reputation: 7 916

1

Python, 111 bytes

def f(s):
 r=[]
 for i in[i[1:-1]for i in[[(j*s)+i+1 for i in range(s)]for j in range(s)][1:-1]]:r+=i
 return r

sonrad10

Posted 2018-02-02T19:24:18.433

Reputation: 535

1

APL, 28 Bytes

Will run given value for m

1 1↓¯1 ¯1↓m m⍴⍳m*2

Try it...

Explanation

m*2 squares m

⍳m*2 gets list from 1 to m*2

m m⍴⍳m*2 wraps list to m by m matrix

¯1 ¯1↓m m⍴⍳m*2 drops -last row an column

1 1↓¯1 ¯1↓m m⍴⍳m*2 drops first row and column

Soda Adlmayer

Posted 2018-02-02T19:24:18.433

Reputation: 11

Welcome to the site! Could you provide some way to test the submission, such as a link to an online interpreter so that others can tell that it is a working solution? – caird coinheringaahing – 2018-02-07T14:05:13.960