16
\$\begingroup\$

Goal

In light of the World Series being around the corner, I need a program that can read the box scores and tell me what inning it is. This is complicated slightly because baseball uses an odd method to record the score. They don't write down the at-bat team's score for the inning until they've scored a run (and are still going) or have finished their at-bat. Thus a 0 on the scoreboard always means a finished at-bat. For example:

Example A:
Inning| 1| 2| 3| 4| 5| 6| 7| 8| 9|
  Them| 0| 0| 0| 0| 0| 2|  |  |  |
    Us| 0| 0| 2| 0| 0| 0|  |  |  |

Example B:
Inning| 1| 2| 3| 4| 5| 6| 7| 8| 9|
  Them| 0| 0| 0| 0| 0| 2|  |  |  |
    Us| 0| 0| 2| 0| 0| 1|  |  |  |

Example C:
Inning| 1| 2| 3| 4| 5| 6| 7| 8| 9|
  Them| 0| 0| 0| 0| 0| 2|  |  |  |
    Us| 0| 0| 2| 0| 0|  |  |  |  |

#Them is the Away Team, Us is the Home Team (who are the guys you root for)
  • Example A: We know we're at the top of the 7th because Us has a recorded 0 in the Bottom of the 6th and the Top of the 7th is blank.
  • Example B: It can either be the Bottom of the 6th or the Top of the 7th.
  • Example C: It can either be the Top or Bottom of the 6th.

Your task is to return which inning(s) it could be.

Input

Two lists of non-negative integers. Lists will be assumed jagged with the Away team's list being either the same size or one element larger in comparison to the Home team's. You can take the scores in either order but state in your answer if you do not use the default. I.e., Away Team then Home team (the default), or Home team then Away team (reversed). They can also be padded with dummy data if you want, state in your answer if you do so.

Output

A string or something equivalent which identifies the inning number and whether it's the top or bottom. E.g. 7B 8T, B7 T8, ['7B','8T'] are all fine. If there are two answers, you must output both. The format is pretty flexible though.

Rules

  • Input will always be valid
  • Games can go into indefinite extra innings. Your program should be able to support up to 255 innings.
  • Standard Loopholes are forbidden
  • This is so shortest code wins

Test Cases

#Input:
[[], 
 []] 
#Output: 1T

#Input:
[[0], 
 []] 
#Output: 1B

#Input:
[[0,0,0,1], 
 [0,0,0,0]] 
#Output: 5T

#Input:
[[0,0,0,1], 
 [0,0,0,1]] 
#Output: 4B, 5T

#Input:
[[0,0,0,1,0,0,1,0,0,1],
 [0,0,0,0,1,0,0,1,0,1]] 
#Output: 10B, 11T

#Input:
[[0,0,0,1], 
 [0,0,0]] 
#Output: 4T, 4B

#Input:
[[0,0,0,0], 
 [0,0,0]] 
#Output: 4B
\$\endgroup\$
4
  • \$\begingroup\$ Can we take the two lists in reverse order? i.e. bottom then top? \$\endgroup\$
    – Jo King
    Oct 23, 2018 at 3:24
  • \$\begingroup\$ @JoKing Sure, as long as it's noted and the answer still matches up correctly. \$\endgroup\$
    – Veskah
    Oct 23, 2018 at 3:30
  • \$\begingroup\$ Is positive/negative integer return value acceptable output? \$\endgroup\$
    – user77406
    Oct 23, 2018 at 8:49
  • \$\begingroup\$ @Rogem That's pushing it a bit but reading your write-up, that's fine. I did say output is quite flexible. \$\endgroup\$
    – Veskah
    Oct 23, 2018 at 18:24

8 Answers 8

4
\$\begingroup\$

C (gcc), 50 bytes

Takes input as a pointer to an interleaved list (i.e. {them#1, us#1, them#2,...}).

Returns one option via modification, and the other via return value.

Negative values indicate bottom of the inning, positive values indicate top of the inning. Zeroes are "empty". The absolute value of the output is the number of the inning. So, -4,5 indicates the possibilities being top of the fifth and bottom of the fourth, and 1,0 indicates the only possibility being the top of the first.

The return value of the macro can be used to determine whether there's one or two possible innings; the return value is 0 if there's no other inning. Otherwise, it is the number of the inning.

Zero bytes of source code. Use the following as a preprocessor flag:

-Df(o,n,l)=({o=n%2?~n/2:n/2+1;l[n-1]?-o-~n%2:0;})

Try it online!

Degolf

-Df(o,n,l)=({
// Define a function-like macro f(o,n,l)
// o is the output variable, n is the size of the list, 
// l is a pointer to the first element of the list.
o=n%2?~n/2:n/2+1;
// If there's an odd number of elements, first possible inning is -(n+1)/2. 
// Else, it is (n/2)+1.
l[n-1]?-o-~n%2:0})
// If the score from the last inning is non-zero, the other possible inning
// needs to be determined; flip the sign of first output value then deduct 
// 1 from it if the number of elements is even.
\$\endgroup\$
3
  • \$\begingroup\$ Also, this could be golfed an additional 4 bytes if I can assume the list to be in reverse order (last to first), or the pointer to point to the last element in the array. Didn't go for that, as it felt like too much of a cheat. \$\endgroup\$
    – user77406
    Oct 23, 2018 at 14:23
  • \$\begingroup\$ I'd love to hear from @veskah if taking input as you did is ok, because it seems quite different (and useful) from the original spec. \$\endgroup\$
    – BLT
    Oct 23, 2018 at 19:26
  • 2
    \$\begingroup\$ @BLT By convention, interleaving is how lists of lists are done in C; multiple dereferencing is very taxing on resources. Other option would be to have one list after the other, but then it would be very impractical to append new elements to. \$\endgroup\$
    – user77406
    Oct 23, 2018 at 19:40
3
\$\begingroup\$

Perl 6, 52 48 45 bytes

-3 bytes thanks to some restructuring from nwellnhof!

->\a,\b{(+a,a==b if (b,a)[a>b].tail;b+1,a>b)}

Try it online!

Anonymous code block that takes input as two lists, top then bottom. Output is a list of tuples, where the first element is the inning number and the second element is True or False, corresponding to Bottom or Top.

Explanation:

       {                                    }  # Anonymous code block
->\a,\b   # That takes input lists a and b
        (                                  )   # Return a list of
                                    b+1,a>b    # A list of 
                                               #  The length of the second list plus 1
                                               #  And top/bottom
         +a,a==b     # And the length of the first list
                     # And the other of top/bottom
                 if  # Only if:
                    (b,a)[a>b]      # The current of top/bottom's
                              .tail # Last element exists and is not 0
\$\endgroup\$
0
3
\$\begingroup\$

R, 103 96 bytes

function(a,b,l=sum(a|1),k=sum(b|1))I(l,I(l-k,I(a[l],c(l,-l),-l),I(b[l],c(-l,l+1),l+1)),1)
I=`if`

Try it online!

@digEmAll saved 7 bytes!

Takes two lists vectors as input, and outputs one or two integers representing the possible innings. Positive integers are the top of the inning, and negative integers are the bottom of the inning.

In R, positive integers are truthy, so I can use the difference in lengths as the first argument to if().

\$\endgroup\$
3
  • \$\begingroup\$ You'd probably have better luck with [[ as an if replacement since you use [ in your code. \$\endgroup\$
    – Giuseppe
    Oct 24, 2018 at 1:45
  • \$\begingroup\$ @Giuseppe I tried it with < and ^. I think [ was the one used in the example I remember. \$\endgroup\$
    – BLT
    Oct 24, 2018 at 18:44
  • \$\begingroup\$ You can also give another name to 'if' (and remove {} and move f= outside) : 96 bytes \$\endgroup\$
    – digEmAll
    Oct 25, 2018 at 6:29
2
\$\begingroup\$

JavaScript (Node.js), 75 bytes

f=(a,c=1,p=0,z=0)=>1/(t=a[p][c-1])?f(a,c+p,1-p,t):[c,p]+(z?[,c+p-1,1-p]:'')

Try it online!

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

Jelly, 11 bytes

ZẎṖṠṪ$СẈd2

Try it online!

First element: 0-based index of column.
Second element: 0 for top, 1 for bottom.

Output is a list of one or two pairs as specified above (prettified to show it better). The output innings are in reverse order.

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

Python 2, 135 129 126 125 123 119 bytes

a,b=input()
c=len(a)
e,f=`c+1`+"T",`c`+"B"
print((f+e,e)[b[-1]<1],(`c`+"T"+f,f)[a[-1]<1])[len(b)<c]if b else"1"+"TB"[c]

Try it online!

-1 with thanks to @ovs

-4 thanks again to @ovs

\$\endgroup\$
6
  • \$\begingroup\$ if d else"11BT"[c<1::2] for -3 \$\endgroup\$
    – ovs
    Oct 23, 2018 at 14:18
  • \$\begingroup\$ if d I can see (shouldn't have missed that!) but else"11BT"[c<1::2] doesn't come out any shorter for me unless I am missing something. \$\endgroup\$
    – ElPedro
    Oct 23, 2018 at 14:28
  • \$\begingroup\$ No worries @ovs as I found another way inspired by your if d anyway. \$\endgroup\$
    – ElPedro
    Oct 23, 2018 at 15:02
  • \$\begingroup\$ Instead of if d you can do if b, then you do not need to store len(b) in variable. \$\endgroup\$
    – ovs
    Oct 23, 2018 at 15:40
  • \$\begingroup\$ @ovs I looked at that but also need d for [d<c]. Can't see a way round that. Any ideas? \$\endgroup\$
    – ElPedro
    Oct 23, 2018 at 17:36
1
\$\begingroup\$

Python 2, 65 bytes

a,b=input()
exec"a,b=[0]+b,a;print[len(b)][a[-1]<len(a+b)%2:];"*2

Try it online!

Prints two lines, first the bottom inning possibility then the top one, as a singleton list. If either one is not possible, that list is empty.

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

Clean, 84 75 bytes

import StdEnv
$ =length
?v|last[0:v]>0= $v=0
@a b| $b< $a=(?a,$a)=($a+1,?b)

Try it online!

Defines the function @ :: [Int] [Int] -> (Int, Int) and some helpers.
Gives output in the form (Top, Bottom) where a zero signifies a null possibility.

\$\endgroup\$

Your Answer

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

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