I came across this challenge from codewars. I wish to know how to solve this problem. The problem description is given below.
Its elements are in range[1..n^2]. The matrix is filled by rings, from the outwards the innermost. Each ring is filled with numbers in the following way:
- The first number is written in the top left corner;
- The second number is written in the top right corner;
- The third number is written in the bottom right corner;
- The fourth number is written in the bottom left corner;
- Each next number is written next to the number written 4 steps before it, until the ring is filled.
The matrix is constructed when all numbers are written.```
Given the size of the hole, return the number written at (a, b) - you may use any consistent indexing, but please specify if (a, b) is anything other than 0-indexed and row-major.
Example
For n = 4, a = 1, b = 1, the output should be 13.
The hole looks like this:
[ [ 1, 5, 9, 2 ]
[ 12, 13, 14, 6 ]
[ 8, 16, 15, 10 ]
[ 4, 11, 7, 3 ]
]
The element at (1, 1) is 13
Test cases
(a, b) is 0-indexed and row-major here.
n a b result
1 0 0 1
2 0 0 1
3 0 0 1
4 0 0 1
2 0 1 2
3 0 1 5
3 1 1 9
4 1 1 13
4 2 1 16
5 2 3 22
-
1\$\begingroup\$ Welcome to the site. As it stands your question is lacking a crucial component that we require of all questions, an "objective winning criterion". That is, an objective way to score answers. The most common one is code-golf. \$\endgroup\$Wheat Wizard– Wheat Wizard ♦2019年03月09日 14:17:50 +00:00Commented Mar 9, 2019 at 14:17
-
\$\begingroup\$ @SriotchilismO'Zaic, Hi When I heard about Programming Puzzles and Code gulf, I thought it's about asking a programming challenge and getting a solution to it. Am sorry, am new to this site. I don't know 'Objective winning criterion' \$\endgroup\$James K J– James K J2019年03月09日 14:59:37 +00:00Commented Mar 9, 2019 at 14:59
-
\$\begingroup\$ If you want an easy winning criterion, the majority of the questions on this site are tagged as code-golf, meaning that the winning criterion is the least bytes. \$\endgroup\$senox13– senox132019年03月09日 15:48:22 +00:00Commented Mar 9, 2019 at 15:48
-
6\$\begingroup\$ Does codewars allow their challenges to be posted on other sites? \$\endgroup\$Jo King– Jo King2019年03月10日 00:38:39 +00:00Commented Mar 10, 2019 at 0:38
-
4\$\begingroup\$ If you're going to accept an answer at all, then at least accept the one that is actually winning by the winning criterion \$\endgroup\$Jo King– Jo King2019年03月14日 08:48:18 +00:00Commented Mar 14, 2019 at 8:48
6 Answers 6
Python 2, (削除) 120 (削除ここまで) (削除) 119 (削除ここまで) 90 bytes
def f(n,a,b):n-=1;A,B,C=min((a,b,1),(n-b,a,2),(n-a,n-b,3),(b,n-a,4));return(n-A)*4*A+4*B+C
Python 3, 87 bytes
def f(n,a,b):A,B=min((a,b+1/4),(n+~b,a+.5),(n+~a,n-b-1/4),(b,n-a));return(n+~A)*4*A+B*4
Returns a float
-3 bytes, thanks to Arnauld
Explanation:
This takes advantage of the fact that there is some symmetry to the matrix.
The matrix can be split into four quarters, which are equal when rotated (+ an offset of 1-3).
The first part A,B,C=... finds out which quarter the current coordinates are in, by finding the smallest coordinates, relative to each quarter:
(green: (a,b), yellow: (n-b,a), red: (n-a,n-b), blue: (b,n-a))
The coordinate pair is then converted to a value:
(0,0) = 1, (0,1) = 5, and so on; each coordinate is 4 larger than the previous.
sum((n-(i*2))*4for i in range(A)) skips the rows above, +(B-A)*4 moves along the row, and +C adds the offset.
sum((n-(i*2))*4for i in range(A))+(B-A)*4+C is shortened to (n-A)*4*A+4*B+C
-
\$\begingroup\$ it's interesting, the question seems to imply the input is always an even number, but your algorithm works for odd as well? \$\endgroup\$don bright– don bright2019年03月14日 02:53:57 +00:00Commented Mar 14, 2019 at 2:53
-
1\$\begingroup\$ @donbright The testcases have both even and odd numbers? \$\endgroup\$TFeld– TFeld2019年03月14日 07:33:31 +00:00Commented Mar 14, 2019 at 7:33
-
\$\begingroup\$ lol oops! my bad \$\endgroup\$don bright– don bright2019年03月14日 23:25:19 +00:00Commented Mar 14, 2019 at 23:25
05AB1E (legacy), (削除) 36 (削除ここまで) (削除) 31 (削除ここまで) (削除) 28 (削除ここまで) 25 bytes
<αìRDÀsā)ø{н`Š4*ŠD1<α4**O
Port of @TFeld's Python answer, so make sure to upvote him!
-3 bytes thanks to @Emigna.
Inputs are \$n\$ and \$[a,b]\$.
Uses the legacy version instead of the new 05AB1E version, because there seems to be a bug with the sorting ({) of multidimensional lists.
Try it online or verify all test cases.
Explanation:
< # Decrease the (implicit) input `n` by 1
α # Take the absolute difference with the (implicit) input-list
# (we now have `[n-1-a, n-1-b]`)
ì # Prepend the input (we now have `[n-1-a, n-1-b, a, b]`)
R # Reverse the list (we now have `[b, a, n-1-b, n-1-a]`)
DÀ # Duplicate this list, and rotate it once towards the left
s # Swap these two lists
ā # Push a list in the range [1, length_list] without popping the list: [1,2,3,4]
) # Wrap all three lists into a list (we now have
# `[[a, n-1-b, n-1-a, b], [b, a, n-1-b, n-1-a], [1, 2, 3, 4]]`)
ø # Zip/transpose; swapping rows/columns (we now have
# `[[a, b, 1], [n-1-b, a, 2], [n-1-a, n-1-b, 3], [b, n-1-a, 4]]`)
{н # Get the minimum by sorting the lists and getting the first inner list
# (since the minimum builtins in 05AB1E flatten multidimensional lists
# and give a single integer)
` # Push all three values to the stack: `A`, `B`, and `C`
Š # Triple-swap once, so the order is now `C`, `A`, `B`
4* # Multiply `B` by 4
Š # Triple-swap again to `B*4`, `C`, `A`
D # Duplicate `A`
1<α # Take the absolute difference with `n-1` (so basically `n-1-A`)
4* # Multiply that by 4
* # Multiply it with the duplicated `A`
O # Sum all values on the stack (`B*4 + C + (n-1-A)*4*A`)
# (and output the result implicitly)
-
1\$\begingroup\$
<αRIRìcan be<αìRand4Lcan beā. \$\endgroup\$Emigna– Emigna2019年03月14日 07:31:48 +00:00Commented Mar 14, 2019 at 7:31 -
\$\begingroup\$ @Emigna I'm an idiot.. I tried some things with append, prepend, and rotates, and eventually ended up with what I had. Two reverses and a prepend.. Why not just prepend first and then reverse.. dohh.. Thanks! Oh, also thanks for
ā. I always forget about that builtin for some reason.. \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2019年03月14日 07:47:46 +00:00Commented Mar 14, 2019 at 7:47
Jelly, 28 bytes
3_×ばつ4
’0;_ⱮpƝẎAμżJṂFμæ.Ç
Based on @TFeld’s python answer so be sure to upvote that one too.
JavaScript (ES6), 86 bytes
(w,y,x)=>[x+(Y=w+~y)*y,y+(w+=~x)*x,w+Y*y,Y+w*x][k=x<y?x>Y?2:3:x<Y?0:x>y?1:Y-y&&2]*4-~k
Jelly, 20 bytes
ZUẎTḢṬ_Ʋṁ
+þ`ṠÇƬSœị@
A dyadic Link accepting n on the left and [a,b] (1-indexed) on the right.
How?
ZUẎTḢṬ_Ʋṁ - Link 1, next matrix (rotated): current matrix
Z - transpose }
U - reverse each row } -> rotate clockwise 1/4
Ẏ - tighten into a flat list of values
Ʋ - last four links as a monad:
T - truthy indices -- e.g. [0,0,1,0,1,1,0] -> [3,5,6]
Ḣ - head (empty list yields 0) -> 3
Ṭ - un-truth (0 yields an empty list) -> [0,0,1]
_ - subtract (vectorises) -> [0,0,0,0,1,1,0]
ṁ - mould to shape of the current matrix again
+þ`ṠÇƬSœị@ - Main Link: integer, n; list of integers [a,b]
` - using left (n) as both arguments:
þ - table of (implicit range of integer arguments)
+ - addition
Ṡ - sign -- now we have an n by n matrix of ones
Ƭ - collect up (a list of matrices) while results are different with:
Ç - last Link (1) as a monad
¬ - logical NOT (replace the 1s with 0s and vice-versa)
S - sum (vectorises)
@ - with swapped arguments:
œị - multidimensional index into
Rust - 340 bytes
fn f(n:usize,x:usize,y:usize)->usize{let (mut r,d)=(0,(n-1)&1);for l in ((1+d)..=n).step_by(2) {let (mut i,m,mx,mut z)=(0,l/2,n/2,0);loop {z=4*i+n*n-l*l;let u=[mx+m-i-d,mx-m,mx+m-d,mx-m+i];if (x,y)==(u[0],u[1]){r=z+4}if (x,y)==(u[2],u[0]){r=z+3}if (x,y)==(u[3],u[2]){r=z+2}if (x,y)==(u[1],u[3]){r=z+1}i+=1;if i>=l-1{break};}}r}
still got some work to do, but it basically draws the whole spiral, centered on a point in the middle, and saves the value at requested point x,y.