7
\$\begingroup\$

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:

  1. The first number is written in the top left corner;
  2. The second number is written in the top right corner;
  3. The third number is written in the bottom right corner;
  4. The fourth number is written in the bottom left corner;
  5. 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
\$\endgroup\$
13
  • 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\$ Commented 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\$ Commented 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\$ Commented Mar 9, 2019 at 15:48
  • 6
    \$\begingroup\$ Does codewars allow their challenges to be posted on other sites? \$\endgroup\$ Commented 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\$ Commented Mar 14, 2019 at 8:48

6 Answers 6

10
\$\begingroup\$

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

Try it online!


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

Try it online!

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).

enter image description here

The first part A,B,C=... finds out which quarter the current coordinates are in, by finding the smallest coordinates, relative to each quarter:

enter image description here

(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

answered Mar 12, 2019 at 16:00
\$\endgroup\$
3
  • \$\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\$ Commented Mar 14, 2019 at 2:53
  • 1
    \$\begingroup\$ @donbright The testcases have both even and odd numbers? \$\endgroup\$ Commented Mar 14, 2019 at 7:33
  • \$\begingroup\$ lol oops! my bad \$\endgroup\$ Commented Mar 14, 2019 at 23:25
2
\$\begingroup\$

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)
answered Mar 13, 2019 at 14:32
\$\endgroup\$
2
  • 1
    \$\begingroup\$ <αRIRì can be <αìR and 4L can be ā. \$\endgroup\$ Commented 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\$ Commented Mar 14, 2019 at 7:47
1
\$\begingroup\$

Jelly, 28 bytes

3_×ばつ4
’0;_ⱮpƝẎAμżJṂFμæ.Ç

Try it online!

Based on @TFeld’s python answer so be sure to upvote that one too.

answered Mar 14, 2019 at 11:34
\$\endgroup\$
1
\$\begingroup\$

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

Try it online!

answered Mar 14, 2019 at 14:11
\$\endgroup\$
1
\$\begingroup\$

Jelly, 20 bytes

ZUẎTḢṬ_Ʋṁ
+þ`ṠÇƬSœị@

A dyadic Link accepting n on the left and [a,b] (1-indexed) on the right.

Try it online!

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
answered Mar 17, 2019 at 2:06
\$\endgroup\$
0
\$\begingroup\$

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.

ungolf spiral draw at play.rust-lang.org

answered Mar 15, 2019 at 4:29
\$\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.