Let's divide a lattice

8

Let's say we have a n × n lattice; we can then divide the lattice into two sections by drawing a line through the lattice. Everything to one side of the line is in one set and everything else in another.

How many ways can we divide the lattice in the manner?

For example lets take a 2 × 2 lattice:

. .
. .

We can make 2 partitions dividing the lattice in half like so:

× ×    × o
o o    × o

We can also partition off each of the corners:

× o    o ×    o o    o o
o o    o o    × o    o ×

Lastly we can put all of the points in one partition by missing the lattice entirely:

× ×
× ×

This makes for a total of 7 partitions. Note that the following partition is not valid because it cannot be made with a single straight line.

× o
o ×

Here is a 3 × 3 lattice

. . .
. . .
. . .

There are 4 purely horizontal or vertical partitions

× × ×    × × ×    × o o    × × o
× × ×    o o o    × o o    × × o
o o o    o o o    × o o    × × o

There are 4 corner partitions

× o o    o o ×    o o o    o o o    
o o o    o o o    o o o    o o o
o o o    o o o    o o ×    × o o

There are 4 larger corner partitions

× × o    o × ×    o o o    o o o
× o o    o o ×    o o ×    × o o
o o o    o o o    o × ×    × × o

There are 8 partitions of partial corners

× × o    o × ×    o o ×    o o o    o o o    o o o    o o o    × o o
o o o    o o o    o o ×    o o ×    o o o    o o o    × o o    × o o
o o o    o o o    o o o    o o ×    o × ×    × × o    × o o    o o o

There are 8 knights move partitions

× × o    o × ×    × × ×    o o o    o o ×    × o o    o o o    × × ×
× o o    o o ×    o o ×    o o ×    o o ×    × o o    × o o    × o o
× o o    o o ×    o o o    × × ×    o × ×    × × o    × × ×    o o o

And there is one whole partition

× × ×
× × ×
× × ×

That makes for 29 partitions in total.

Task

Given a number n as input, output the number of partitions that can be made in this fashion of an n × n lattice.

This is a question so answers will be scored in bytes, with less bytes being better.

Test Cases

Here are the first 34 courtesy of the OEIS:

1, 7, 29, 87, 201, 419, 749, 1283, 2041, 3107, 4493, 6395, 8745, 11823, 15557, 20075, 25457, 32087, 39725, 48935, 59457, 71555, 85253, 101251, 119041, 139351, 161933, 187255, 215137, 246691, 280917, 319347, 361329, 407303

OEIS A114043

Post Rock Garf Hunter

Posted 2017-07-20T17:07:11.963

Reputation: 55 382

Can you please add an example with a lattice larger than 2×2? – Erik the Outgolfer – 2017-07-20T18:06:58.520

@EriktheOutgolfer Added. – Post Rock Garf Hunter – 2017-07-20T18:16:08.230

Answers

2

JavaScript (ES6), 113 111 bytes

Saved 2 bytes thanks to guest44851

0-indexed.

n=>[...Array(n)].map((_,i,a)=>a.map((_,j)=>x+=(g=(a,b)=>b?g(b,a%b):a<2&&(n-i-1)*(n-j))(i+1,++j)),x=n*++n)|x+x+1

Based on the formula mentioned on OEIS:

Let V(m,n) = Sum_{i=1..m, j=1..n, gcd(i,j)=1} (m+1-i)(n+1-j)
a(n+1) = 2(n2 + n + V(n,n)) + 1

Demo

let f =

n=>[...Array(n)].map((_,i,a)=>a.map((_,j)=>x+=(g=(a,b)=>b?g(b,a%b):a<2&&(n-i-1)*(n-j))(i+1,++j)),x=n*++n)|x+x+1

for(n = 0; n < 50; n++) {
  console.log('f(' + n + ') = ' + f(n));
}

Arnauld

Posted 2017-07-20T17:07:11.963

Reputation: 111 334

You can replace a==1&& with a<2&&. – None – 2017-07-20T18:01:37.043

@guest44851 Yes, this one works. :-) Thanks! – Arnauld – 2017-07-20T18:05:31.900

You can also replace &&x+x+1 with |x+x+1. – None – 2017-07-20T18:06:09.343

1

Mathematica, 59 bytes

2Sum[(#-i)(#-j)Boole[i~GCD~j<2],{i,#-1},{j,#-1}]+2#^2-2#+1&

courtesy of the OEIS (just like the question)

-1 byte from @ovs

Try it online!

J42161217

Posted 2017-07-20T17:07:11.963

Reputation: 15 931

1This is almost verbatim copied from the OEIS page – nmjcman101 – 2017-07-20T17:31:50.573

3The question is courtesy of the OEIS and so is this answer. An original question would have an original answer – J42161217 – 2017-07-20T17:35:18.567

3I don't disagree with you, which is why I didn't downvote, I just prefer transparency. – nmjcman101 – 2017-07-20T17:39:24.020

4Me too! But I think that OEIS-questions is an easy trick to get easy reputation points. That's why I answer in the same way, to state this situation – J42161217 – 2017-07-20T17:43:08.630

You can replace ==1 with <2 TIO.

– ovs – 2017-07-20T18:41:35.410

1

Python 2, 116 bytes

lambda n:2*(~-n*n+sum((n-i)*(n-j)*g(i,j)for i in range(1,n)for j in range(1,n)))+1
g=lambda x,y:y and g(y,x%y)or x<2

Try it online!

ovs

Posted 2017-07-20T17:07:11.963

Reputation: 21 408

R=range? Would that save some bytes? – Zacharý – 2017-07-20T22:51:34.587

@Zacharý not with two ranges – ovs – 2017-07-21T04:47:31.223

1

Jelly, 14 bytes

ạþ`Fgþ`FỊS_²H‘

Try it online!

Explanation

ạþ`Fgþ`FỊS_²H‘  Input: integer n
ạþ`             Form the table of absolute differences on [1, 2, ..., n]
   F            Flatten
    gþ`         Form a GCD table on that
       F        Flatten
        Ị       Test if the absolute value of each is <= 1
         S      Sum (Count the number of true's)
          _     Subtract
           ²    Square of n
            H   Halve
             ‘  Increment

miles

Posted 2017-07-20T17:07:11.963

Reputation: 15 654

0

Python 2, 90 bytes

lambda n:4*n*n-6*n+3+4*sum((n-i)*(n-k/i)for i in range(n)for k in range(i*i)if k/i*k%i==1)

orlp

Posted 2017-07-20T17:07:11.963

Reputation: 37 067