2D Array Middle Point

4

Given dimensions of a 2D array, except 1xn, that results in an odd number of elements, find the midpoint index.

Example: Input is 3x5, representing the 2D array

[0,0] [0,1] [0,2] [0,3] [0,4]

[1,0] [1,1] [1,2] [1,3] [1,4]

[2,0] [2,1] [2,2] [2,3] [2,4]

The midpoint index is [1,2]

Input

3

5

Output

1 , 2

Rules

  • Standard code-golf rules, fewest bytes wins
  • Either full program or function is permitted
  • When input is either 1xn or the corresponding array would have an even number of elements, output must be [0,0]
  • nx1 should be treated like any other array

Noir Antares

Posted 2018-07-04T08:38:22.857

Reputation: 469

6Most challenges on PPCG try to avoid special cases or error cases, instead guaranteeing that the input will be valid. It's your call to make, but I find that error handling is usually boilerplate that makes solutions longer without making them more interesting. – Esolanging Fruit – 2018-07-04T09:01:09.757

2

We have a Sandbox for Proposed Challenges.

– user202729 – 2018-07-04T09:07:15.737

@EsolangingFruit The challenge here is to handle the invalid inputs, otherwise it would trivially be ⁽ⁿ⁻²⁾⁄₂. – Adám – 2018-07-04T09:24:08.167

5@Adám A challenge where the entire point is to detect and handle invalid inputs doesn't seem like a very interesting challenge to me. – Esolanging Fruit – 2018-07-04T09:29:22.570

4@EsolangingFruit There's nothing inherently wrong with challenges that a specific user happens to find uninteresting. Personally, I think having to catch such specific cases makes for some interesting golfing material. – Adám – 2018-07-04T09:31:28.377

1

@NoirAntares I've edited your challenge to make it unambiguous. Feel free to edit or roll back If my rewording does not match your intentions.

– Adám – 2018-07-04T09:33:01.970

@JoKing Well, [⁽ⁿ⁻²⁾⁄₂,0], yeah. – Adám – 2018-07-04T09:50:21.517

3output must be [0,0] any reason behind that? How does that part add anything to computing the midpoint? Obviously, 1xn arrays or arrays with an even dimension don't have [0,0] as their midpoints. – JungHwan Min – 2018-07-04T13:57:04.100

Answers

4

APL (Dyalog Classic), 20 19 15 13 bytes

⌊÷∘2×2|×/×1≠⊃

Try it online!

ngn

Posted 2018-07-04T08:38:22.857

Reputation: 11 449

4

Japt, 11 bytes

My first (somewhat) serious Japt submission! Any help is appreciated, I think ~10 bytes or even less may be possible. Saved 4 bytes thanks to Shaggy!

£ÎÉ©Ueu)*Xz

Try it here!

How it works

Slightly outdated.

£eu *UÎ>1 *Xz – Full program.
£             – For each X of the input array.
          *Xz – Multiply floor(X/2) by the truth value of:
 eu           – Are both numbers odd? And...
    *UÎ>1     – Is the initial element greater than 1?
              – Implicit output to STDOUT.

Mr. Xcoder

Posted 2018-07-04T08:38:22.857

Reputation: 39 774

3

05AB1E, 9 8 bytes

Saved 1 byte thanks to Mr. Xcoder (remove D)

¬≠*ÉP*;ï

Try it online! or as a Test Suite

Explanation

­*       # multiply the input by its first value falsified
   ÉP*    # multiply the input by the product of the results values' oddness
      ;   # divide by 2
       ï  # convert to int

Emigna

Posted 2018-07-04T08:38:22.857

Reputation: 50 798

Nice! I had ¬≠sPÉ*s2÷* for 10 bytes. Taking some inspiration from you though, would ¬≠*PÉ*2÷ work for 8 bytes? Alternatively, ¬≠*PÉ*;ï, of course.

– Mr. Xcoder – 2018-07-04T11:34:42.597

@Mr.Xcoder: Of course. I don't need the D here :/ Thanks! – Emigna – 2018-07-04T11:45:47.697

3

Japt, 24 16 bytes

-8 bytes saved thanks to @Shaggy

Neu ©UÉ?Nmz :2ÆT

Try it online!

Luis felipe De jesus Munoz

Posted 2018-07-04T08:38:22.857

Reputation: 9 639

1

You can get this down to 16 bytes with a few tricks, mainly making use of the N variable.

– Shaggy – 2018-07-04T14:13:34.287

Feel free to ping me in chat if you've any questions.

– Shaggy – 2018-07-04T14:44:09.180

2

APL (Dyalog Unicode), 23 bytesSBCS

Anonymous prefix function. Takes rows,columns as right argument.

{0::0 0⋄÷∘÷@0⌽¨⍨.5×⍵-1}

Try it online!

{} "dfn"; is right argument (rightmost letter of Greek alphabet).

0:: if any error happens:

  0 0 return [0,0]

 now try:

  ⍵-1 right argument minus 1

  .5× multiply by a half

  ⌽¨⍨ rotate each by itself (this errors on non-integers)

  ÷∘÷@0 reciprocal of reciprocal at position 0 (this errors when the first coordinate is 0)

Adám

Posted 2018-07-04T08:38:22.857

Reputation: 37 779

2

JavaScript (ES6), 31 bytes

Saved 1 byte thanks to @Neil

Takes the dimensions in currying syntax (w)(h).

w=>h=>w&h&w>1?[h>>1,w>>1]:[0,0]

Try it online!


Original version, 32 bytes

Takes the dimensions in currying syntax (w)(h).

w=>h=>w*h&!!--w?[h>>1,w/2]:[0,0]

Try it online!

How?

We want to test whether both \$w\$ and \$h\$ are odd, which is true if and only if \$w\times h\$ is odd. We also want to make sure that \$w\$ is not equal to \$1\$, which means that \$w-1\$ is not equal to \$0\$. We can merge both tests into:

w * h & !!--w

If this test passes, we know that \$w\$ was odd and is now even (since it was decremented), so we can divide it by \$2\$ with a standard division. For \$h\$, we use a bitwise shift instead because it's still odd.

Arnauld

Posted 2018-07-04T08:38:22.857

Reputation: 111 334

1w=>h=>w&h&w>1?[h>>1,w>>1]:[0,0]? – Neil – 2018-07-04T13:51:41.563

@Neil This is a bit more straightforward indeed. Thanks! – Arnauld – 2018-07-04T13:59:22.610

2

Perl 6, 42 39 bytes

{(^$^a X ^$^b)[$b-1&&$a*$b%2&&$a*$b/2]}

Try it online!

Anonymous code block that returns a list of two integers.

Explanation:

{                                     }  # Anonymous code block
 (^$^a X ^$^b)   # Cross product of the two ranges, basically the flattened 2D array
              [                      ] # Get the element at
                            &&$a*$b/2    # Midpoint of the array
                     $a*$b%2             # If the numbers are odd
               $b-1&&                    # And the second element is not 1
                                        # Else the 0th element, which is 0,0

Jo King

Posted 2018-07-04T08:38:22.857

Reputation: 38 234

Seems to fail on 7×1: Try it online!

– Adám – 2018-07-04T09:51:24.103

I'm confused. Why is 1xn expected to fail, but nx1 is fine? – Jo King – 2018-07-04T10:13:01.303

2Because OP says so. – Adám – 2018-07-04T10:19:26.890

2

Haskell, 46 42 bytes

x%y|odd$x*y,x>1=(`div`2)<$>[x,y]|1<2=[0,0]

Try it online!

EDIT: -4 bytes thanks to a trick from Arnauld's answer.

Amphibological

Posted 2018-07-04T08:38:22.857

Reputation: 1 394

1

Julia 0.6, 28 27 bytes

x\y=x&y&1&(x>1)*[x÷2,y÷2]

Try it online!

(-1 byte thanks to Jo King.)

Explanation:

x\y - define an operator instead of a function, to save bytes
x&y&1 - check that both inputs are odd.
&(x>1) - and that the first input is not 1
* - the result of the above checks is 0 or 1, multiply that with:
[x÷2,y÷2] - ÷ is integer division, so here for odd numbers gives (n-1)/2 i.e. the middle index. So this forms a vector of the two middle indices (which might be made [0, 0] if any of the previous checks fail).

sundar - Reinstate Monica

Posted 2018-07-04T08:38:22.857

Reputation: 5 296

I don't know Julia, but could you assign to a one byte operator instead, like +?

– Jo King – 2018-07-04T13:09:18.767

2

Short answer: Yes thank you! Long answer: Your comment finally prompted me to check why those work on TIO but not on my system (I'd assumed it was just version differences). Turns out I can assign to those if I haven't used them yet in that session. Makes some confusing behaviour around this make sense now.

– sundar - Reinstate Monica – 2018-07-04T13:44:29.090

1

Jelly, 10 bytes

This confused me :p

:2×Ḃ_ỊḢ$PƲ

A monadic link accepting a list of the dimensions returning a list of the middle-indices or [0,0] in the special-cases.

Try it online!

How?

:2×Ḃ_ỊḢ$PƲ - Link: list of dimension lengths        e.g.  [19,12]  or  [19,13]  or  [1,19]  or  [19,1]
:2        - integer divide by two (gets middle indices)   [9,6]         [9,6]       [0,9]       [9,0]
        Ʋ - last four links as a monad:
   Ḃ      -   bit (n%2) (of the input)                    [1,0]         [1,1]       [1,1]       [1,1]
       $  -   last two links as a monad (of the input):
     Ị    -     insignificant? (abs(n)<=1)                [0,0]         [0,0]       [1,0]       [0,1]
      Ḣ   -     head                                      0             0           1           0
    _     -   subtract (vectorises)                       [1,0]         [1,1]       [0,0]       [1,1]
       P  -   product                                     0             1           0           1
  ×       - multiply (vectorises)                         [0,0]         [9,6]       [0,0]       [9,0]

Jonathan Allan

Posted 2018-07-04T08:38:22.857

Reputation: 67 804

1

Jelly, 11 bytes

Ugh. Waaaaaaaay too long!

:2×ḂẠ$×Ḣn1Ɗ

Try it online!

Alternative, 11 bytes

ḷ/>1×ḂẠ$×:2

Try it online!

Mr. Xcoder

Posted 2018-07-04T08:38:22.857

Reputation: 39 774

1

Lua, 77 bytes

x,y=...f=math.floor print((x%2==1 and y%2==1)and f(x/2)..","..f(y/2)or "0,0")

Try it online!

not the smallest language but submission for practicing :)

Lycea

Posted 2018-07-04T08:38:22.857

Reputation: 141

I don't know much Lua (although I wish I did!), but I believe you can replace the oddness check x%2==1 and y%2==1 with x%2+y%2>1 Try it online!

– sundar - Reinstate Monica – 2018-07-04T14:30:11.360

2Also, this doesn't return 0,0 when x is 1, which is one of the question's requirements – sundar - Reinstate Monica – 2018-07-04T14:32:34.733

You can extend the condition to check that too, here's my attempt: Try it online! (also changed x%2+y%2 to x*y%2 after seeing Arnauld's answer.)

– sundar - Reinstate Monica – 2018-07-04T14:45:19.570

It's been a while since I've done anything in Lua, but it has the // operator yes? So you don't need the floor function – Jo King – 2018-07-04T14:49:42.227

1

Rust, 42 bytes

|w,h|if w>1&&w*h%2>0{(w/2,h/2)}else{(0,0)}

Try it online!

Konrad Borowski

Posted 2018-07-04T08:38:22.857

Reputation: 11 185

1

R, 38 29 28 bytes

An extra byte removed thanks to @Guiseppe

(i=scan()-1)/2*!any(i%%2,!i)

Try it online!

Get the input, subtract 1 store in i and divide by 2 and multiply by not any evens or 0's in i

MickyT

Posted 2018-07-04T08:38:22.857

Reputation: 11 735

!i instead of i<2? – Giuseppe – 2018-07-04T22:15:49.377

@Giuseppe good call, thanks – MickyT – 2018-07-04T23:57:18.547

0

Python 2, 39 bytes

-2 bytes thanks to ovs

lambda a,b:[0,a/2,0,b/2][a>1==a*b%2::2]

Try it online!

Dead Possum

Posted 2018-07-04T08:38:22.857

Reputation: 3 256

39 bytes – ovs – 2018-07-04T11:12:25.520

0

Python 2, 43 41 bytes

lambda a,b:((0,0),(a/2,b/2))[a*b%2*(a>1)]

Try it online!

No rocket science here.

-2 with thanks to @MrXcoder and @Enigma

ElPedro

Posted 2018-07-04T08:38:22.857

Reputation: 5 301

1[a*b%2*(a!=1)] should work for 42 bytes. – Mr. Xcoder – 2018-07-04T13:01:04.690

2@Mr.Xcoder: or even a>1. – Emigna – 2018-07-04T13:13:03.090