22
\$\begingroup\$

Challenge:

Given an NxN matrix where \$N\geq2\$ and one of eight distinct 'folding options', output a 2D array/list with the subtracted values.

The eight folding options are: left-to-right; right-to-left; top-to-bottom; bottom-to-top; topleft-to-bottomright; topright-to-bottomleft; bottomleft-to-topright; bottomright-to-topleft.

Step by step examples:

Input matrix:

[[ 1, 3, 5, 7],
 [ 0, 8, 6, 4],
 [ 1, 1, 1, 1], (a'th row in the explanation below)
 [ 1,25, 0,75]]

With folding option top-to-bottom we output the following as result:

[[ 1,-7,-5,-3],
 [ 0,22,-5,68]]

Why? We fold from the top to the bottom. Since the matrix dimensions are even, we don't have a middle layer to preserve as is. The \$a\$'th row [1, 1, 1, 1] will be subtracted by the \$(a-1)\$'th row (would have been \$(a-2)\$'th row for odd dimension matrices); so [1-0, 1-8, 1-6, 1-4] becomes [1, -7, -5, -3]. The \$(a+1)\$'th row [1, 25, 0, 75] will then be subtracted by the \$(a-2)\$'th row (would have been \$(a-3)\$'th row for odd dimension matrices); so [1-1, 25-3, 0-5, 75-7] becomes [0, 22, -5, 68].

With folding option bottomright-to-topleft instead (with the same input-matrix above) we output the following as result:

[[-74, 2, 1, 7],
 [ 0, 7, 6],
 [-24, 1],
 [ 1]]

With the following folding subtractions:

[[1-75, 3-1, 5-4, 7],
 [ 0-0, 8-1, 6],
 [1-25, 1],
 [ 1]]

Challenge rules:

  • You can use any eight distinct letters [A-Za-z] or distinct numbers in the range \$[-99,99]\$ for the folding options. Numbers \$[1..8]\$ or \$[0..7]\$ are probably the most common options, but if you want to use different numbers within the range for some smart calculations, feel free to do so. Please state which folding options you've used in your answer.
  • The input-matrix will always be a square NxN matrix, so you don't have to handle any rectangular NxM matrices. \$N\$ will also always be at least 2, since an empty or 1x1 matrix cannot be folded.
  • The input of the matrix will always contain non-negative numbers in the range \$[0, 999]\$ (the numbers in the output will therefore be in the range \$[-999, 999]\$).
  • With the (anti-)diagonal folding or odd-dimension vertical/horizontal folding, the middle 'layer' will remain unchanged.
  • I/O is flexible. Can be a 2D array/list of integers; can be returned or printed as a space-and-newline delimited string; you can modify the input-matrix and replace the numbers that should be gone with null or a number outside of the [-999, 999] range to indicate they're gone; etc. etc.

General rules:

  • This is , so shortest answer in bytes wins.
    Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
  • Standard rules apply for your answer with default I/O rules, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call.
  • Default Loopholes are forbidden.
  • If possible, please add a link with a test for your code (i.e. TIO).
  • Also, adding an explanation for your answer is highly recommended.

Test cases:

Input-matrix 1:

Input-matrix (for the following eight test cases):
[[ 1, 3, 5, 7],
 [ 0, 8, 6, 4],
 [ 1, 1, 1, 1],
 [ 1,25, 0,75]]
Input-folding option: left-to-right
Output: [[2,6],[-2,4],[0,0],[-25,74]]
Input-folding option: right-to-left
Output: [[-6,-2],[-4,2],[0,0],[-74,25]]
Input-folding option: top-to-bottom
Output: [[1,-7,-5,-3],[0,22,-5,68]]
Input-folding option: bottom-to-top
Output: [[0,-22,5,-68],[-1,7,5,3]]
Input-folding option: topleft-to-bottomright
Output: [[7],[6,-1],[1,-7,-2],[1,24,0,74]]
Input-folding option: topright-to-bottomleft
Output: [[1],[-3,8],[-4,-5,1],[-6,21,-1,75]]
Input-folding option: bottomleft-to-topright
Output: [[1,3,4,6],[8,5,-21],[1,1],[75]]
Input-folding option: bottomright-to-topleft
Output: [[-74,2,1,7],[0,7,6],[-24,1],[1]]

Input-matrix 2:

Input-matrix (for the following eight test cases):
[[17, 4, 3],
 [ 8, 1,11],
 [11, 9, 7]]
Input-folding option: left-to-right
Output: [[4,-14],[1,3],[9,-4]]
Input-folding option: right-to-left
Output: [[14,4],[-3,1],[4,9]]
Input-folding option: top-to-bottom
Output: [[8,1,11],[-6,5,4]]
Input-folding option: bottom-to-top
Output: [[6,-5,-4],[8,1,11]]
Input-folding option: topleft-to-bottomright
Output: [[3],[1,7],[11,1,-10]]
Input-folding option: topright-to-bottomleft
Output: [[17],[4,1],[8,-2,7]]
Input-folding option: bottomleft-to-topright
Output: [[17,-4,-8],[1,2],[7]]
Input-folding option: bottomright-to-topleft
Output: [[10,-7,3],[-1,1],[11]]
asked Jun 17, 2019 at 11:24
\$\endgroup\$
7
  • \$\begingroup\$ Does the order of the folding options matter? \$\endgroup\$ Commented Jun 17, 2019 at 14:12
  • \$\begingroup\$ Also, can we just output the 8xNxN matrix of all possible folds? \$\endgroup\$ Commented Jun 17, 2019 at 14:19
  • \$\begingroup\$ Shouldn't this test sample Input-folding option: bottom-to-top Output: [[-1,7,5,3],[0,-22,5,-68]] be flipped? \$\endgroup\$ Commented Jun 17, 2019 at 14:33
  • \$\begingroup\$ also for matrix 2, 17-11 is 6, not 4? \$\endgroup\$ Commented Jun 17, 2019 at 14:52
  • \$\begingroup\$ @ExpiredData As specified in the rules, you can use any letter A-Za-z or any integer in the range [-999,999], so order doesn't matter. And sorry, but you must output the correct fold based on the input, so outputting all eight isn't allowed. \$\endgroup\$ Commented Jun 17, 2019 at 16:41

6 Answers 6

5
\$\begingroup\$

Octave, (削除) 256 (削除ここまで) (削除) 248 (削除ここまで) (削除) 244 (削除ここまで) 248 bytes

m=d=x=@(a,b=1)rot90(a,b)
y=@(a,b=2)flip(a,b)
z=@(a,b=1)tril(a+1e3,-1)+a-x(y(tril(a)))+b*diag(diag(a))
f=@(a,b){m=((a-y(a))(:,1:(d=size(a,2)/2))),-y(m),m=y(x((a=x(a))-y(a)))(d+1:end,:),y(m,1),-y(z(a,-1)),x(z(x(a,2)),2),z(a=x(a,3)),x(z(x(a,2)),2)}{b}

Try it online!

-2 bytes (and a bity of tidying up) thanks to Luis Mendo

+2 bytes due to the correction for T-B

1-Indexed operations for values of b from 1-8:

R-L
L-R
B-T
T-B
BR-TL
TR-BL
BL-TR
TL-BR

This gave me a headache, I'll golf it properly later

answered Jun 17, 2019 at 14:59
\$\endgroup\$
1
  • \$\begingroup\$ Suggest rows(a) instead of size(a,2) \$\endgroup\$ Commented Oct 15, 2019 at 21:49
5
\$\begingroup\$

Jelly, (削除) 39 (削除ここまで) 34 bytes

There is possibly further golfing possible by combining some of the two "functions".
...yep: -5 thanks to NickKennedy!

ṃ"Z"Ṛ"U" "ŒDṙL ZZṚ"ŒḄFḲj"ŒH_Ṛ}\/"v

Try it online!

A dyadic link accepting an integer (the instruction) and a list of lists of numbers (the matrix).

Uses the option to take the instruction as an integer in \$[-99,99]\$ to our advantage, and hence has the following seemingly bizarre mapping:

 Instruction | integer
------------------------+---------
 left-to-right | 4
 right-to-left | 14
 top-to-bottom | 9
 bottom-to-top | 39
topleft-to-bottomright | 65
topright-to-bottomleft | 15
bottomleft-to-topright | 10
bottomright-to-topleft | 0

How?

The link creates Jelly code which is then evaluated using M as an input...

ṃ"Z"Ṛ"U" "ŒDṙL ZZṚ"ŒḄFḲj"ŒH_Ṛ}\/"v - Link: integer, I; matrix, M
 "Z"Ṛ"U" "ŒDṙL ZZṚ" - list of lists of characters = ["Z", "Ṛ", "U", " ", "ŒDṙL ZZṚ"]
ṃ - base decompress (I) using those lists as the digits
 - ...i.e. convert to base 5 and then convert the digits:
 - [1,2,3,4,0] -> ["Z", "Ṛ", "U", " ", "ŒDṙL ZZṚ"]
 ŒḄ - bounce
 - ...e.g. [a, b, c] -> [a, b, c, b, a]
 F - flatten to a list of characters
 Ḳ - split at spaces
 j - join with:
 "ŒH_Ṛ}\/" - list of characters = "ŒH_Ṛ}\/"
 v - evaluate as Jelly code with an input of M

Each of the eight options are then:

left-to-right (4): ŒH_Ṛ}\/
right-to-left (14): ṚŒH_Ṛ}\/Ṛ
top-to-bottom (9): ZŒH_Ṛ}\/Z
bottom-to-top (39): ZṚŒH_Ṛ}\/ṚZ
topleft-to-bottomright (65): ṚUŒDṙLŒH_Ṛ}\/ZZṚUṚ
topright-to-bottomleft (15): UŒDṙLŒH_Ṛ}\/ZZṚU
bottomleft-to-topright (10): ṚŒDṙLŒH_Ṛ}\/ZZṚṚ
bottomright-to-topleft (0): ŒDṙLŒH_Ṛ}\/ZZṚ

These each (except 0 and 4) apply a transform to M using some of Z (transpose), (reverse), and U (reverse each); then one of two functions (see below), then the inverse of the setup transformation (if there was one) implemented with the reverse of the code.

The two inner functions are:

ŒH_Ṛ}\/ - Function A: Fold bottom-to-top: matrix, M
ŒH - split M into two equal lists of rows (first half bigger by 1 if need be)
 / - reduce by:
 \ - last two links as a dyad:
 } - using the right argument (i.e. second half):
 Ṛ - reverse
 _ - subtract
ŒDṙLŒH_Ṛ}\/ZZṚ - Function B: Fold topright-to-bottomleft: matrix, M
ŒD - diagonals of M
 ṙ - rotate left by:
 L - length of M (puts them in order from bottom left most)
 ŒH_Ṛ}\/ - same action as calling Function A on the diagonals
 Z - transpose
 Z - transpose
 Ṛ - reverse
answered Jun 18, 2019 at 20:03
\$\endgroup\$
5
  • 1
    \$\begingroup\$ Ah nice, I was wondering if anyone would make use of the somewhat flexible input-options! Cool to see how you've used the values for a convenient base-conversion to Jelly code to evaluate to the desired folding. :) \$\endgroup\$ Commented Jun 18, 2019 at 20:34
  • \$\begingroup\$ Using some of the code from my answer, and reusing code common to both, here’s a 34-byter: tio.run/##y0rNyan8///… \$\endgroup\$ Commented Jun 18, 2019 at 20:54
  • \$\begingroup\$ If we were allowed 16 bit integers it could be even shorter \$\endgroup\$ Commented Jun 18, 2019 at 20:56
  • \$\begingroup\$ Non-competing 23 byte answer using 16-bit integers as the parameter for selecting which fold: tio.run/##y0rNyan8///… \$\endgroup\$ Commented Jun 18, 2019 at 21:04
  • \$\begingroup\$ @NickKennedy - thanks. I like the split and join! I'll have to come back later to change the description fully. \$\endgroup\$ Commented Jun 20, 2019 at 8:12
3
\$\begingroup\$

JavaScript (ES6), (削除) 149 ... 133 (削除ここまで) 128 bytes

Takes input as (matrix)(d) with \0ドル\le d\le7\$. Removed values are replaced with NaN.

Folding directions: \0ドル =\;\rightarrow\$, \1ドル =\;\downarrow\$, \2ドル =\;\small\searrow\$, \3ドル =\;\small\swarrow\$, \4ドル =\;\leftarrow\$, \5ドル =\;\uparrow\$, \6ドル =\;\small\nwarrow\$, \7ドル =\;\small\nearrow\$

m=>d=>m.map((r,y)=>r.map((v,x)=>v-=(w=m.length+~y)-(p=[x+x-y,y,x,q=w+y-x][d&3])&&[r[q],m[w][x],m[q][w],m[x][y]][d>3^p>w?d&3:m]))

Try it online!

Commented

m => d => // m[] = matrix; d = direction
 m.map((r, y) => // for each row r[] at position y in m[]:
 r.map((v, x) => // for each value v at position x in r[]:
 v -= // subtract from v:
 ( // define w as:
 w = m.length + ~y // the width of input matrix - y - 1
 ) - ( // and compare it with
 p = [ // p defined as:
 x + x - y, // 2 * x - y for vertical folding
 y, // y for horizontal folding
 x, // x for diagonal folding
 q = w + y - x // q = w + y - x for anti-diagonal folding
 ][d & 3] // using d MOD 4
 ) && // if p is equal to w, leave v unchanged
 [ // otherwise, subtract:
 r[q], // r[q] for vertical folding
 m[w][x], // m[w][x] for horizontal folding
 m[q][w], // m[q][w] for diagonal folding
 m[x][y] // m[x][y] for anti-diagonal folding
 ][ // provided that we're located in the target area:
 d > 3 ^ // test p < w if d > 3 
 p > w ? d & 3 // or p > w if d <= 3
 : m // and yield either d MOD 4 or m[]
 ] // (when using m[], we subtract 'undefined' from v,
 // which sets it to NaN instead)
 ) // end of inner map()
 ) // end of outer map()
answered Jun 18, 2019 at 8:04
\$\endgroup\$
3
\$\begingroup\$

Jelly, (削除) 71 (削除ここまで) 34 bytes

ḃ2ŒḄ,UZṚŒDṙLƊŒH_Ṛ}\/$ZZṚƊṚZ8ƭ$ị@\ƒ

Try it online!

Test Suite

A full program. Right argument is the matrix. Left argument is the type of fold:

44 = L-R
40 = R-L
36 = T-B
32 = B-T
50 = TL-BR
34 = TR-BR
54 = BL-TR
38 = BR-TL

Rewritten to use 5-bit bijective binary as input. Note the program given above won’t work repeatedly for multiple folds.

answered Jun 17, 2019 at 21:21
\$\endgroup\$
1
\$\begingroup\$

Octave, (削除) 482 bytes (削除ここまで), 459 Bytes

The inputs for deciding folding directions are:
1)left to right
2)bottom to top
3)right to left
4)top to bottom
5)tr to bl
6)br to tl
7)bl to tr
8)tl to br
Each call only generates the specified fold, rather than all of them (which would probably would take less bytes). Biggest problem is that for this case I can't figure out how to put folds 1-4 and 5-8 in the same loop. But at least octave has nice looking matrices.

 function[m]=f(n,o)
 k=length(n);m=NaN(k);if(o<5)
 if(mod(o,2)>0)n=n'end
 q=[0,0,k+1,k+1](o)
 for x=1:ceil(k/2)if(x*2>k)m(x,:)=n(x,:)else
 for a=1:k
 m(abs(q-x),a)=n(abs(q-x),a)-n(abs(q-(k+1-x)),a)end
 end
 end
 if(mod(o,2)>0)m=flipud(m')end
 else
 if(mod(o,2)>0)n=flip(n)end
 q=[0,0,k+1,k+1](o-4)
 for x=1:k
 for a=1:k+1-x
 if(a==k+1-x)m(x,a)=n(x,a)else
 m(abs(q-x),abs(q-a))=n(abs(q-x),abs(q-a))-n(abs(q-(k+1-a)),abs(q-(k+1-x)))end
 end
 end
 end
 if(mod(o,2)>0)m=flip(m)end
 end

Try it online!

Output suppression costs bytes, so ignore everything that isn't the return statement(ans = ).

answered Jun 17, 2019 at 15:04
\$\endgroup\$
5
  • \$\begingroup\$ How many bytes did you lose to writing "end"? \$\endgroup\$ Commented Jun 17, 2019 at 15:06
  • \$\begingroup\$ do you not have to write end? \$\endgroup\$ Commented Jun 17, 2019 at 15:07
  • \$\begingroup\$ You do unless you restructure it so it's not a bunch of if/else and for statements \$\endgroup\$ Commented Jun 17, 2019 at 15:08
  • \$\begingroup\$ wow tbh looking at your code there's tons of stuff I didn't even know you could do in matlab. \$\endgroup\$ Commented Jun 17, 2019 at 15:10
  • \$\begingroup\$ I don't know much about octave tbh it can probably save 50-100 bytes pretty easily \$\endgroup\$ Commented Jun 17, 2019 at 15:11
1
\$\begingroup\$

Charcoal, (削除) 78 (削除ここまで) 77 bytes

F4«UMηE⮌η§μλ¿=ιθUMηEκ⎇‹⊕⊗νLη−μ§⮌κν⎇›⊕⊗νLηωμ¿=ι%θ4UMηEκ⎇‹λν−μ§§ηνλ⎇›λνωμ»Eη⪫ι,

Try it online! Link is to verbose version of code. Uses the following folding options:

0 top-to-bottom
1 left-to-right
2 bottom-to-top
3 right-to-left
4 bottomright-to-topleft
5 topright-to-bottomleft
6 topleft-to-bottomright
7 bottomleft-to-topright

Folded values are replaced by empty strings. Explanation:

F4«≔UMηE⮌η§μλ

Rotate the array four times.

¿=ιθUMηEκ⎇‹⊕⊗νLη−μ§⮌κν⎇›⊕⊗νLηωμ

Fold the array horizontally when appropriate.

¿=ι%θ4UMηEκ⎇‹λν−μ§§ηνλ⎇›λνωμ

Fold the array diagonally when appropriate.

»Eη⪫ι,

Output the array once it is rotated back to its original orientation.

answered Jun 17, 2019 at 23:07
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.