15
\$\begingroup\$

Consider the infinite table of the nonnegative integers with width 12:

 0  1  2  3  4  5  6  7  8  9 10 11
12 13 14 15 16 17 18 19 20 21 22 23
24 25 26 27 28 29 30 31 32 33 34 35
36 37 38 39 40 41 42 43 44 45 46 47
48 49 50 51 52 53 54 55 56 57 58 59
60 61 62 63 64 65 66 67 68 69 70 71...

This can be divided into rectangular chunks 3 wide and 4 tall:

+----------+----------+----------+----------+
|  0  1  2 |  3  4  5 |  6  7  8 |  9 10 11 |
| 12 13 14 | 15 16 17 | 18 19 20 | 21 22 23 |
| 24 25 26 | 27 28 29 | 30 31 32 | 33 34 35 |
| 36 37 38 | 39 40 41 | 42 43 44 | 45 46 47 |
+----------+----------+----------+----------+
| 48 49 50 | 51 52 53 | 54 55 56 | 57 58 59 |
| 60 61 62 | 63 64 65 | 66 67 68 | 69 70 71 |
| 72 73 74 | 75 76 77 | 78 79 80 | 81 82 83 |
| 84 85 86 | 87 88 89 | 90 91 92 | 93 94 95 |
+----------+----------+----------+----------+
|   ....   |   ....   |   ....   |   ....   |

Take the sum of each number in each chunk:

 228  264  300  336  
 804  840  876  912
1380 1416 1452 1488...

If you flatten this table, you get an infinite sequence:

228 264 300 336 804 840 876 912 1380 1416 1452 ...

This type of sequence can be found for any positive X, Y, and W where W is the width of the table, X is the width of each chunk, Y is the height of each chunk, and X evenly divides W. In this example, X is 3, Y is 4, and W is 12.

Given X, Y, and W (in any order), output the infinite sequence of the form described above. Alternatively, rather than taking W, you may take W ÷ X, or in other words the number of X-wide chunks in each row. You can assume you will never receive invalid input.

The sequence can be represented by any of the default rules:

  • Given n, output the nth term of the sequence.
  • Given n, output the first n terms of the sequence.
  • Output the sequence indefinitely.

This is , so the solution with the shortest code in each language wins.

Here are the first few terms of some sample cases:

X Y W  -> seq

3 4 12 -> 228 264 300 336 804 840 876 912 1380 1416 1452
5 4 20 -> 640 740 840 940 2240 2340 2440 2540 3840 3940 4040
1 1 6  -> 0 1 2 3 4 5 6 7 8 9 10
4 2 24 -> 108 140 172 204 236 268 492 524 556 588 620
4 5 24 -> 990 1070 1150 1230 1310 1390 3390 3470 3550 3630 3710
3 5 9  -> 285 330 375 960 1005 1050 1635 1680 1725 2310 2355
3 4 9  -> 174 210 246 606 642 678 1038 1074 1110 1470 1506
\$\endgroup\$
3
  • 2
    \$\begingroup\$ Suggested testcase: x,y,w all odd. My solution initially failed on these \$\endgroup\$
    – emanresu A
    Commented Aug 12 at 19:56
  • \$\begingroup\$ @emanresuA Added 3,5,9. \$\endgroup\$ Commented Aug 12 at 22:08
  • \$\begingroup\$ Also, suggested: 3,4,9 (174 210 246 606 642 678 1038 1074 1110 1470) \$\endgroup\$
    – emanresu A
    Commented Aug 13 at 8:58

15 Answers 15

11
\$\begingroup\$

JavaScript (Node.js), 48 47 46 43 42 48 46 45 44 bytes

(n,x,y,w)=>x*y*(n*x*y+(--y*w+x-1)/2-n*x%w*y)

Try it online! -3ish thanks to Arnauld, -1 thanks to xnor, hopefully now actually works. There might be a shorter version taking w/x instead.

Simple numeric formula. They say a picture speaks a thousand words:

enter image description here

\$\endgroup\$
10
  • \$\begingroup\$ @Arnauld No worries, thanks for all the golfs :). Do you see any way too for that into the 43 I just found? \$\endgroup\$
    – emanresu A
    Commented Aug 12 at 22:20
  • \$\begingroup\$ 42 bytes, I think. But please double-check. \$\endgroup\$
    – Arnauld
    Commented Aug 12 at 22:29
  • \$\begingroup\$ @Arnauld Turns out my original version was broken, assuming y=w/x, and only worked because that's actually the case in the testcase. Working on a fix. \$\endgroup\$
    – emanresu A
    Commented Aug 12 at 23:23
  • \$\begingroup\$ Isn't it shorter to write n*x twice rather than updating n*=x? \$\endgroup\$
    – xnor
    Commented Aug 13 at 0:25
  • 2
    \$\begingroup\$ @Arnauld Nice! Now all we need is one more golf and this can have a "crossed out 44 is still 44" :p \$\endgroup\$
    – emanresu A
    Commented Aug 13 at 7:22
7
\$\begingroup\$

05AB1E, 14 13 bytes

∞<IôIô€øO˜IôO

-1 byte thanks to @emanresuA.

Inputs in the order \$W,Y,X\$. Outputs the infinite sequence.

Try it online.

Explanation:

∞              # Push an infinite positive list: [1,2,3,...]
 <             # Decrease each by 1 to a non-negative infinite list: [0,1,2,...]
  Iô           # Split it into groups of the first input W
    Iô         # Split those into groups of the second input Y
      €        # Map over each inner matrix:
       ø       #  Zip/transpose; swapping rows/columns
        O      # Sum each inner-most list
         ˜     # Flatten the infinite list of lists
          Iô   # Split it into groups of the third input X
            O  # Sum each inner list again
               # (after which the infinite list is lazily output implicitly)
\$\endgroup\$
2
  • \$\begingroup\$ You should be able to avoid mapping ô entirely - see my vyxal \$\endgroup\$
    – emanresu A
    Commented Aug 13 at 9:23
  • \$\begingroup\$ @emanresuA Thanks, that saves a byte. :) \$\endgroup\$ Commented Aug 13 at 9:32
7
\$\begingroup\$

Vyxal, 8 bytes

Þ:ẇẇṠfẇṠ

Try it Online! Outputs an infinite list given w,y,x.

Þ:       # 0...infinity
  ẇ      # Cut into chunks of length w
   ẇṠ    # Sum groups of length y
     fẇṠ # Flatten, and sum groups of length x
\$\endgroup\$
1
  • \$\begingroup\$ That's roughly what I had but actually working :p \$\endgroup\$
    – lyxal
    Commented Aug 12 at 23:17
6
\$\begingroup\$

K (ngn/k), 24 bytes

{+/y/(!x)+x*(0,_y%x 1)\}

Try it online!

Input [y x;w]. Returns a function that computes the \$n\$th term of the sequence.

I think the dumb approach is shorter.

\$\endgroup\$
4
\$\begingroup\$

Charcoal, 38 33 bytes

NθNηNζNεI÷××θη⊖×θ⊕⁻⊗×εη×⁻⊗﹪εζζ⊖η²

Try it online! Link is to verbose version of code. Takes X, Y, W/X, n as inputs. Explanation: Looks like I've found the same closed formula. Really, verbose mode says it all, except of course the variables have to be called q, h, z, and e instead, just in case you want to save 8 bytes by requiring input in JSON format. Edit: Saved 5 bytes by porting @xnor's golf to @Lucenaposition's answer.

\$\endgroup\$
3
  • \$\begingroup\$ Even in Charcoal, using an array approach similar to my vyxal answer is probably shorter (likely using range(n * x * y) instead of [0, ∞)) \$\endgroup\$
    – emanresu A
    Commented Aug 13 at 1:49
  • \$\begingroup\$ @emanresuA I have no idea what "sum groups of length y" even means, but it sounds like something Charcoal can't readily do. \$\endgroup\$
    – Neil
    Commented Aug 13 at 5:05
  • \$\begingroup\$ @emanresuA I tried an approach on my experimental Zip branch but even then it was 35 bytes; with current Charcoal it would be much longer. \$\endgroup\$
    – Neil
    Commented Aug 13 at 8:44
4
\$\begingroup\$

R, 52 51 bytes

Edit: -1 byte by taking g directly as a parameter

\(n,x,y,g)y*x*((y*g-g+1)*x/2+n%/%g*g*x*y+n%%g*x-.5)

Attempt This Online!

Started from:

xychunks=
function(n,l,w,h){
    startpos=n%%(l/w)*w+n%/%(l/w)*h*l
    increment=outer(1:w-1,(1:h-1)*l,`+`)
    sum(startpos+increment)
}

and gradually re-arranged from there.

The final golfed form seems quite similar to some answers in other languages, and I suspect that different initial approaches will converge to similar shortest re-arranged structures...


R + pryr, 44 bytes

f(y*x*((y*g-g+1)*x/2+n%/%g*g*x*y+n%%g*x-.5))

Try it at rdrr.io

Same as above, but the using the pryr package to 'guess' the function arguments from the code.

\$\endgroup\$
4
\$\begingroup\$

Python 2, 58 54 53 51 49 48 bytes

lambda x,y,w,n:x*y*~(x*~(n*y*2-(n%w*2-w)*~-y))/2

Try it online!

Here w means the number of x-wide chunks in a row.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ ~-y saves two bytes over (y-1) and you don't need to count the f= \$\endgroup\$
    – emanresu A
    Commented Aug 12 at 23:50
  • 1
    \$\begingroup\$ 49 bytes with some tactical ~'s \$\endgroup\$
    – xnor
    Commented Aug 13 at 6:58
  • \$\begingroup\$ (building off xnor's) The //2 doesn't seem to ever have to deal with an odd number, so it should be able to be a /2 with the caveat of returning a float. \$\endgroup\$
    – emanresu A
    Commented Aug 13 at 7:27
  • 1
    \$\begingroup\$ It's fine to eventually fail due to floating point imprecision as long as your solution would theoretically work with arbitrarily precise floats \$\endgroup\$
    – emanresu A
    Commented Aug 13 at 10:55
3
\$\begingroup\$

JavaScript (Node.js), 66 bytes

(x,y,w,n)=>(g=i=>i&&(i/w/x/y^n/w|i/x%w^n%w?0:i)+g(i-1))(x*w*~y*~n)

Try it online!

Input W ÷ X

Silly.

\$\endgroup\$
3
\$\begingroup\$

R, 85 82 bytes

-3 bytes thanks to pajonk

\(x,y,w,`[`=matrix,s=colSums)repeat show(s(s(((y*w*F):(y*w*(F=F+1)-1))[x])[y,,T]))

Just to see the source and the bytecount: Attempt This Online!

A user-friendly version: Test cases at TIO

A function that takes x,y and w as an input and outputs indefinetely the sequence of the sums.

Explanation (a naive approach):

Let's take \$X=3\$, \$Y=4\$, \$W=12\$ as an example. First, we obtain a matrix with the dimensions X × W*Y/X:

     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15] [,16]
[1,]    0    3    6    9   12   15   18   21   24    27    30    33    36    39    42    45
[2,]    1    4    7   10   13   16   19   22   25    28    31    34    37    40    43    46
[3,]    2    5    8   11   14   17   20   23   26    29    32    35    38    41    44    47

Calculate the column-sums:

   3  12  21  30  39  48  57  66  75  84  93 102 111 120 129 138

Rearrange them into the matrix Y × W/X:

     [,1] [,2] [,3] [,4]
[1,]    3   12   21   30
[2,]   39   48   57   66
[3,]   75   84   93  102
[4,]  111  120  129  138

Calculate the column-sums:

228 264 300 336

Proceed with the next part of the sequence Y*W to 2*Y*W-1 etc.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ -3 bytes. \$\endgroup\$
    – pajonk
    Commented Aug 14 at 11:29
2
\$\begingroup\$

APL+WIN, 52 bytes

Prompts for a vector of n,x,y and w/x. Outputs first n terms. Index origin = 0

(n x y w)←⎕⋄n↑,+⌿[1] +/¨(n,y,w)⍴(+\0=x|i)⊂i←⍳n×x×y×w

Try it online! Thanks to Dyalog Classic

\$\endgroup\$
2
\$\begingroup\$

JavaScript, 50 bytes

(n,x,y,w)=>x*y*(y*w*(x*n/w|0)+(w*~-y+x-1)/2+x*n%w)

Attempt This Online!

This uses a very similar method to emanresu A's solution, though I found it independently.

Explanation: We can view the problem as dealing with arithmetic series.

Here's the first chunk from the example in the question:

+----------+
|  0  1  2 |
| 12 13 14 |
| 24 25 26 |
| 36 37 38 |
+----------+

Take the vertical sums of each column:

0+12+24+36 = 72
1+13+25+37 = 76
2+14+26+38 = 80

This is an arithmetic sequence with first term 72 and common difference of 4. The 4 comes from the value of y, and the 72 comes from an arithmetic series of y terms with first term zero and common difference w.

Except, the first term of that inner arithmetic series isn't always zero. Look at the first chunk of the second column:

+----------+
| 48 49 50 |
| 60 61 62 |
| 72 73 74 |
| 84 85 86 |
+----------+

Here, the first term isn't 0 - it's 48. We get this 48 by multiplying y, w, and the column number of the cell. In JS, this is written as y*w*(x*n/w|0) (where |0 floors a number).

Now we can get the sum of any cell in the first column, but we still need to account for the difference between rows.

The sums of the first row are 228, 264, 300, and 336. The difference between each sum is 36, which is \$ x^2y \$. We multiply that by the row number, giving x*n%w*x*y. Here, x*n%w gives us the row number multiplied by x.

Okay, that's all we need to write this all out in JS. Remember that the formula for an arithmetic series is \$ \frac{n}{2}(2a+(n-1)d) \$, where n is the number of terms, a is the first term, and d is the common difference.

x/2*(2*y/2*(2*w*y*(x*n/w|0)+(y-1)*w)+(x-1)*y)+x*n%w*x*y

Now reduce this expression to its final golfed form:

x/2*(2*y/2*(2*w*y*(x*n/w|0)+(y-1)*w)+(x-1)*y)+x*n%w*x*y
x/2*(y*(2*w*y*(x*n/w|0)+(y-1)*w)+(x-1)*y)+x*n%w*x*y // 2*y/2 = y
x/2*(y*(2*w*y*(x*n/w|0)+~-y*w)+~-x*y)+x*n%w*x*y     // (y-1) = ~-y
x*(y*(2*w*y*(x*n/w|0)+~-y*w)+~-x*y)/2+x*n%w*x*y     // rearrange
x*y*(2*w*y*(x*n/w|0)+~-y*w+~-x)/2+x*n%w*x*y         // factor out y
x*y*((2*w*y*(x*n/w|0)+~-y*w+~-x)/2+x*n%w)           // factor out x*y
x*y*(w*y*(x*n/w|0)+(~-y*w+~-x)/2+x*n%w)             // factor out 2
\$\endgroup\$
4
  • \$\begingroup\$ This is almost exactly the same equation as in the emanresu's image. \$\endgroup\$
    – att
    Commented Aug 14 at 14:21
  • \$\begingroup\$ @att Okay yeah now that I take a closer look at it they are very similar, though I did find this independently. I still don't really understand hers though because the diagram is hard for me to follow. \$\endgroup\$ Commented Aug 14 at 14:37
  • \$\begingroup\$ This isn't quite correct - fails on 3,4,9 due to floor division rounding when it shouldn't. I ran into the exact same issue trying to golf mine :p \$\endgroup\$
    – emanresu A
    Commented Aug 16 at 11:22
  • \$\begingroup\$ @emanresuA Good catch, thanks. I didn't consider that using BigInts to make the floor division by w shorter would break the division by 2. The fix is 3 bytes, which I am editing in now \$\endgroup\$ Commented Aug 20 at 1:36
1
\$\begingroup\$

Wolfram Language (Mathematica), 68 60 bytes

Saved 8 bytes thanks to @noodle person

Try it online!

f[w_,x_,y_,n_]:=x*y(y*w⌊n*x/w⌋+Mod[n*x,w]+(y*w-w+x-1)/2)
\$\endgroup\$
1
  • \$\begingroup\$ The division by 2 should not be floor division, and you can save a few characters with implicit multiplication, so 60 bytes: f[w_,x_,y_,n_]:=x*y(y*w⌊n*x/w⌋+Mod[n*x,w]+(y*w-w+x-1)/2) \$\endgroup\$ Commented Aug 20 at 15:16
1
\$\begingroup\$

Ruby, 46 47 bytes

->w,x,y,n{(n*x/w*w*y*2+n*x%w*2+y*w+~w+x)*x*y/2}

Try it online!

Short explanation: first get the first and last number of a chunk, then sum and multiply by x"y/2

Thanks @emanresu A for +1 byte. Actually, for fixing an oversimplification which led to a wrong result in some cases.

\$\endgroup\$
0
1
\$\begingroup\$

Clojure, 87 bytes

#(for[P[partition]p(P %2(P(quot %3 %1)(P %1(range))))r(apply map concat p)](apply + r))

TIO. Yay, Clojure is quite good with partitioning and "transposing" lists. This doesn't take any mathematical short-cuts, as you can see. apply map concat was a bit tricky to get right. This anonymous function evaluates into an infinite sequence of sums.

\$\endgroup\$
1
\$\begingroup\$

Python, 131 bytes

import numpy
lambda a,b,c,n:numpy.arange(b*c*n).reshape((-1,b,c)).transpose((0,2,1)).reshape((-1,a,b)).sum(axis=(1,2)).flatten()[n]

TIO. Unlike the other Python answer, this re-constructs the entire grid and uses Numpy's ndarray manipulation to squeeze out the correct numbers. You get the complete summed grid if you remove .sum(axis=(1,2)).flatten()[n]. It was very helpful when debuggin :)

Interesting how this is longer than my Clojure solution, while here I'm using specially-built Numpy operations and Clojure uses general-purose partition.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.