17
\$\begingroup\$

The American football championship, Super Bowl 50, is happening today at 11:30pm UTC (and you can watch it live online). This challenge was made to celebrate it.


In an American football game, two teams compete to get the most points and there are six ways to score these points. We'll give each an abbreviation:

Write a program or function that takes in a single line string containing only these six abbreviations, in both uppercase and lowercase.

This string represents all the scoring events in a game (or portion of a game) of football, with the uppercase terms belonging to one team and the lowercase belonging to the other.

Your job is to report the final scores of the game and indicate who won with output of the form

[score 1] [to] [score 2]

where:

  • [score 1] is always the larger of the two scores (if not equal), regardless of if uppercase or lowercase won.
  • [score 2] is the smaller of the two scores (if not equal).
  • [to] is TO if the uppercase team won, to if the lowercase team won, and To if it's a tie.

Example: All the scoring events in Super Bowl XLIX could be summarized by the string

TDXPtdxpTDXPtdxpfgtdxpTDXPTDXP

where uppercase is the New England Patriots and lowercase is the Seattle Seahawks. The Patriots scored 28 and the Hawks 24, so the output would be:

28 TO 24

Notes

  • Your program/function must support any arbitrary input, including the empty string.
  • XP and XD will only occur right after TD. xp and xd will only occur right after td.
  • You may not assume the input string starts or ends in a certain case.
  • A single trailing newline is optionally allowed in both the input and output

Scoring

The shortest code in bytes wins. Answers that are posted before the kickoff (too late now!) of Super Bowl 50 may predict the winning team (either Panthers or Broncos), and if they are correct, get a -10% byte bonus!

(I will check revision history to ensure predictions have not changed and really were made before kickoff.)

Test Cases

[empty string] -> 0 To 0
TDXPtdxpTDXPtdxpfgtdxpTDXPTDXP -> 28 TO 24
FG -> 3 TO 0
fg -> 3 to 0
TD -> 6 TO 0
td -> 6 to 0
TDXP -> 7 TO 0
tdxp -> 7 to 0
TDXD -> 8 TO 0
tdxd -> 8 to 0
S -> 2 TO 0
s -> 2 to 0
FCK -> 3 TO 0
fck -> 3 to 0
TDTDXDSssFCKfgfckFGtd -> 22 TO 16
fcksFCKS -> 5 To 5
tdtdtdtdxp -> 25 to 0
SSSSSSSTD -> 20 TO 0
fgSfckFGfgtdxptdxdTDs -> 26 to 11
FGTDXPtdxdtdsStdxpfgTDfckTDXDFCK -> 29 To 29

\$\endgroup\$
  • 26
    \$\begingroup\$ I believe it's stylized as "Superb Owl", not "Superbowl" \$\endgroup\$ – Downgoat Feb 7 '16 at 20:48
  • \$\begingroup\$ Does the bonus still apply if you edit your post after the Super Bowl has finished? \$\endgroup\$ – Doorknob Feb 7 '16 at 20:50
  • 1
    \$\begingroup\$ @Doorknob How about this: If you make the prediction before kickoff and don't change it with any edits, you can edit your code as much as you want. (But your prediction must be in your answer, not in some comment. so you need working code to start.) \$\endgroup\$ – Calvin's Hobbies Feb 7 '16 at 20:52
  • 2
    \$\begingroup\$ Can I just make a prediction and not answer? :P \$\endgroup\$ – Rɪᴋᴇʀ Feb 7 '16 at 21:11
  • 2
    \$\begingroup\$ I'm not a big fan of the scoring bonus. It's unfair to those who first saw this challenge after the superb owl, it's biased towards those that pay attention to the NFL, and it's totally unrelated to programming ability. \$\endgroup\$ – DJMcMayhem Feb 8 '16 at 14:35
3
\$\begingroup\$

Pyth, 49 46 43 42 bytes (37.8 bytes with bonus)

jr" to "xh._-FJmsmhx"PSFT"kXd\D\S,rz2z2_SJ

Thanks to @Maltysen for helping me save 4 bytes!

Try it in the Pyth Compiler.

I like covering all bases, so I'll bet on the Broncos.

How it works

jr" to "xh._-FJmsmhx"PSFT"kXd\D\S,rz2z2_SJ Input: z

                                  rz2      Swap the case of z.
                                 ,   z     Pair the result with z.
               m                           Map; for each d in the pair:
                           Xd\D\S            Replace each D with an S.
                 m                           Map; for each character k:
                   x"PSFT"k                    Compute k's first index on "PSFT".
                  h                            Increment the index.
                s                            Compute the sum of the incr. indices.
                                               "FG"  -> [3, 0]     -> 3
                                               "TD"  -> [4, 2]     -> 6
                                               "XP"  -> [0, 1]     -> 1
                                               "XD"  -> [0, 2]     -> 2
                                               "S"   -> [2]        -> 2
                                               "FCK" -> [3, 0, 0]  -> 3
                                               (lowercase letters) -> 0
              J                            Save the resulting list of scores in J.
            -F                             Reduce J by subtraction.
          ._                               Compute the sign of the difference.
         h                                 Add 1.
        x                             2    XOR the result with 2.
 r" to "                                   Pick‡ a function and apply it to " to ".
                                       _SJ Sort and reverse the list of scores.
j                                          Join, separating by the modified string.

r is a family of functions that operate on strings.

  • If the first score in J (corresponding to swapped case z, i.e., the original lowercase letters) is lower than the second score, the sign function will return -1, (-1 + 1) ^ 2 == 2 and r" to "2 is swapcase, so it returns " TO ".

  • If the first score is higher than the second score, the sign function will return 1, (1 + 1) ^ 2 == 0 and r" to "0 is lowercase, so it returns " to ".

  • If the scores are equal, the sign function will return 0, (0 + 1) ^ 2 == 3 and r" to "3 is title, so it returns " To ".

\$\endgroup\$
  • \$\begingroup\$ I didn't try it, but you can probably save by making the various tos through different values to r \$\endgroup\$ – Maltysen Feb 7 '16 at 23:26
  • \$\begingroup\$ @Maltysen That worked nicely. Thanks! \$\endgroup\$ – Dennis Feb 7 '16 at 23:53
4
\$\begingroup\$

MATL, 51*0.9 = 45.9 54 57 58 63 bytes

Thanks to Dennis for removing 3 bytes!

'%i To %i'j0h!3'PDFTS'tkXc=s4:Hh*sSPYD3MdXK?kK0<?Xk

An empty input string is represented in the online compiler as a single newline character.

EDIT (June 8, 2016): The link below includes a modification as per release 18.1.0 of the language (move he first 3 right before Xc)

Try it online!

I bet on the Broncos.

Explanation

The scores are detected using a single letter, either upper or lowercase (uppercase is shown in the following):

  • P for XP (1 point)
  • D for XD (2 points)
  • F for FG (3 points) and for FCK (3 points)
  • T for TD (6 points)
  • S for S (2 points)

Each of these five letters corresponds uniquely to a score event except that

  • F is reused for FG and FCK, which have the same score. Thanks to @Dennis for this!
  • D will detect both TD and XD. So T will be assigned 4 points instead of 6 to compensate.

The ordering PDFTS, saves a few bytes when defining the number array that specifies the points: [1,2,3,4,2].

Each event is detected by the presence of one of the above letters in uppercase or lowercase. The comparison is done in three dimensions: input string length (N) × number of teams (2) × number of detected score events (5). Extensive use is made of broadcasting, which is the automatic expansion of an array along a singleton dimension to match the size of a larger array.

'%i To %i'  % string with format specifiers for two integers
j0h         % input string. Attach 0 so it's never empty. Gives string of length N>0
!           % transpose into char array of size N×1
3           % number literal
'PDFTS'     % characters to detect the five combined types of score
tk          % duplicate and convert to lowercase
Xc          % concatenate along the third dimension to produce a 1×5×2 array
=           % test for equality with broadcast. Gives N×5×2 array
s           % sum along 1st dim. Gives 1×5×2 array
4:Hh        % array [1,2,3,4,2] to compute the total score. Size 1×5(×1) 
*           % multiply with broadcast. Gives 1×5×2 array
s           % sum along 2nd dim. Gives 1×1×2 array with the two scores
SP          % sort in reverse order along 3rd dim
YD          % sprintf. Gives output string with "To"
3M          % push array with the two scores again
dXK         % difference along 3rd dim. Gives a number. Copy to clipboard K
?           % is it non-zero? If so we need to make either lowercase or uppercase
  k         %   make (tentatively) lowercase
  K0<       %   did the uppercase team win?
  ?         %   if so...
    Xk      %     make uppercase
            % implicitly end the two if's and display string
\$\endgroup\$
  • \$\begingroup\$ No win prediction? \$\endgroup\$ – Calvin's Hobbies Feb 7 '16 at 22:13
  • 2
    \$\begingroup\$ @Calvin'sHobbies I was consulting the Wikipedia... my knowledge of American football is close to nil :-) \$\endgroup\$ – Luis Mendo Feb 7 '16 at 22:16
  • 2
    \$\begingroup\$ Reusing the F in FG and FCK should save three bytes. \$\endgroup\$ – Dennis Feb 8 '16 at 2:12
3
\$\begingroup\$

CJam, 57 55 54 53 50 49 bytes

q_32f^]{"PSFTD"f#:)5Yer1b}%_$(@:-g"ToTOto"2/=\]S*

Try it online!

I have no idea what a Bronco is, so I'll bet on the Panthers.

How it works

q                              Read all input from STDIN.
 _                             Push a copy.
  32f^                         XOR all characters with 32. This swaps case.
      ]                        Wrap both strings in an array.
       {                 }%    Map; push the string S, then:
        "PSFTD"                    Push that string (T).
               f#                  Compute the index of each character of S in T.
                 :)                Increment each index.
                   5Yer            Replace 5's with 2's.
                       1b          Add the resulting integers.
                                       "FG"  -> [3 0]      -> 3
                                       "TD"  -> [4 2]      -> 6
                                       "XP"  -> [0 1]      -> 1
                                       "XD"  -> [0 2]      -> 2
                                       "S"   -> [2]        -> 2
                                       "FCK" -> [3 0 0]    -> 3
                                       (lowercase letters) -> 0

                               We've now computed the scores of the first (input)
                               and second (swapped case) team.

_$                             Push a copy of the array of scores and sort it.
  (                            Shift out the first (lower) score.
   @                           Rotate the array of scores on top.
    :-                         Reduce it by subtraction.
      g                        Compute the sign (1, 0 or -1) of the difference.
       "ToTOto"2/              Push ["To" "TO" "to"].
                 =             Select the string that corresponds to the sign.
                  \            Swap it with the lower score.
                   ]           Wrap the entire stack in an array.
                    S*         Join the resulting array, separating by spaces.
\$\endgroup\$
  • 3
    \$\begingroup\$ There ya go \$\endgroup\$ – Digital Trauma Feb 7 '16 at 21:35
  • 1
    \$\begingroup\$ :-g never seen that emoticon before \$\endgroup\$ – ETHproductions Feb 7 '16 at 21:45
  • \$\begingroup\$ @ETHproductions snail-mouth? \$\endgroup\$ – Not that Charles Feb 8 '16 at 4:26
  • \$\begingroup\$ @ETHproductions It's someone whose glasses have fallen down over their mouth. \$\endgroup\$ – CJ Dennis Feb 8 '16 at 12:37
  • \$\begingroup\$ This is a Bronco. \$\endgroup\$ – DJMcMayhem Feb 8 '16 at 14:41
3
\$\begingroup\$

JavaScript (ES6), 128 130 bytes

Edit 2 bytes saved applying @Neil's tip

s=>(l=u=0,s.replace(/fck|s|../gi,x=>(z=+' 231  362'[parseInt(x,36)%10],x>'a'?l+=z:u+=z)),l>u?l+' to '+u:u+(u>l?' TO ':' To ')+l

TEST

f=s=>(
  l=u=0,
  s.replace(/fck|s|../gi,x=>(
    z=+' 231  362'[parseInt(x,36)%10],
    x>'a'?l+=z:u+=z
  )),
  l>u?l+' to '+u:u+(u>l?' TO ':' To ')+l
)

//TEST
console.log=x=>O.textContent+=x+'\n'

;[
["","0 To 0"],
["TDXPtdxpTDXPtdxpfgtdxpTDXPTDXP", "28 TO 24"],
["FG", "3 TO 0"],
["fg", "3 to 0"],
["TD", "6 TO 0"],
["td", "6 to 0"],
["TDXP", "7 TO 0"],
["tdxp", "7 to 0"],
["TDXD", "8 TO 0"],
["tdxd", "8 to 0"],
["S", "2 TO 0"],
["s", "2 to 0"],
["FCK", "3 TO 0"],
["fck", "3 to 0"],
["TDTDXDSssFCKfgfckFGtd", "22 TO 16"],
["fcksFCKS", "5 To 5"],
["tdtdtdtdxp", "25 to 0"],
["SSSSSSSTD", "20 TO 0"],
["fgSfckFGfgtdxptdxdTDs", "26 to 11"],
["FGTDXPtdxdtdsStdxpfgTDfckTDXDFCK", "29 To 29"]
].forEach(t=>{
  var i=t[0],x=t[1],r=f(i)
  console.log(i+' -> '+r+(r==x?' OK':' FAIL expected '+x))
})
<pre id=O></pre>

\$\endgroup\$
  • 1
    \$\begingroup\$ Wow, that trick with parseInt is really clever! Using @Neil's tip of l>u?l+" to "+u:u+(u>l?" TO ":" To ")+l for the output would save 2 bytes as well. \$\endgroup\$ – user81655 Feb 8 '16 at 11:47
  • \$\begingroup\$ @user81655 well I consider parseInt each time I need to operate on some small group of letters in case insensitive way ... 99% of times it's useless. Thanks for pointing out Neil's tip \$\endgroup\$ – edc65 Feb 8 '16 at 11:53
2
\$\begingroup\$

JavaScript (ES6), 165 156 151 149 bytes

s=>(a=b=0,s.match(/S|FCK|../gi)||[]).map(m=>(u=m.toUpperCase(),p=u>"XO"?1:u=="TD"?6:u>"R"?2:3,u<m?a+=p:b+=p))&&a>b?a+" to "+b:b+(b>a?" TO ":" To ")+a

9 bytes saved thanks to @dev-null, 5 thanks to @Not that Charles and 2 thanks to @Neil!

Explanation

var solution =

s=>(
    a=b=0,                // scores for teams A and B
    s.match(/S|FCK|../gi) // get an array of each abbreviation
      ||[]                // if it returns null, default to an empty array
  ).map(m=>(              // for each abbreviation m
    u=m.toUpperCase(),    // u = abbreviation in upper-case
    p=                    // p = number of points for the abbreviation
      u>"XO"?1            // case "XP"
      :u=="TD"?6          // case "TD"
      :u>"R"?2            // case "XD" or "S"
      :3,                 // case "FG" or "FCK"
    u<m?a+=p:b+=p         // add the points to the appropriate team
  ))
  
  // Output the scores
  &&a>b?a+" to "+b
  :b+(b>a?" TO ":" To ")+a
<input type="text" id="input" value="FGTDXPtdxdtdsStdxpfgTDfckTDXDFCK" />
<button onclick="result.textContent=solution(input.value)">Go</button>
<pre id="result"></pre>

\$\endgroup\$
  • \$\begingroup\$ Cant you use /s|fck|../gi and map(..),a>b instead of map(..)&&a>b \$\endgroup\$ – andlrc Feb 8 '16 at 2:02
  • \$\begingroup\$ I think you'd save some if you did ...:u=="T"?6:u>"R"?2:3... \$\endgroup\$ – Not that Charles Feb 8 '16 at 4:19
  • \$\begingroup\$ @NotthatCharles True. Thanks for the tip! \$\endgroup\$ – user81655 Feb 8 '16 at 4:25
  • \$\begingroup\$ I think you might save 2 bytes using b+(b>a?" TO ":" To ")+a \$\endgroup\$ – Neil Feb 8 '16 at 9:56
2
\$\begingroup\$

Perl, 144 140 + 2 = 142 bytes

%a=qw(fg 3 td 6 xp 1 xd 2 s 2 fck 3);@a=(0,0);$^=lc,$a[$^eq$_]+=$a{$^}for/fck|s|../gi;$,=$".(To,TO,to)[$a[1]-$a[0]<=>0].$";say sort{$b-$a}@a

Requires the -n flag and -E:

$ echo "
TDXPtdxpTDXPtdxpfgtdxpTDXPTDXP
FG
fg
SSSSSSSTD
FGTDXPtdxdtdsStdxpfgTDfckTDXDFCK" | \
perl -nE'%a=qw(fg 3 td 6 xp 1 xd 2 s 2 fck 3);@a=(0,0);$^=lc,$a[$^eq$_]+=$a{$^}for/fck|s|../gi;$,=$".(To,TO,to)[$a[1]-$a[0]<=>0].$";say sort{$b-$a}@a'
0 To 0
28 TO 24 
3 TO 0
3 to 0
20 TO 0
29 To 29

Edit: Forgot to support to, To and TO.

\$\endgroup\$
  • \$\begingroup\$ Nice. But %a=qw(fg 3 td 6 xp 1 xd 2 s 2 fck 3) is briefer as %a=(fg,3,td,6,xp,1,xd,2,s,2,fck,3). And " " (in your definition of $,) is briefer as $". But I haven't tested either of those. \$\endgroup\$ – msh210 Feb 8 '16 at 6:16
  • \$\begingroup\$ @msh210, I can use $" and I can remove qw on the to To TO array, thanks! \$\endgroup\$ – andlrc Feb 8 '16 at 10:33
1
\$\begingroup\$

Lua, 231 200 Bytes

It was a lot of fun, even if I don't really know the rules of american football (We have Rugby here :)). I had to test a lot of things to make it as short as possible, I don't think there's a lot of things to improve, maybe there isn't.

Edit: I'm a total retard. The first solution I've worked on revolved around using array expansion, then I changed it and the array containing the scores for both the lowercase and the uppercase team wasn't useful anymore. Removing it and using plain variable makes a beautiful -31 bytes.

a={F=3,D=2,T=4,P=1,S=2}l,u=0,0 io.read():gsub(".",function(c)x=a[c:upper()]if a[c]then u=u+a[c]elseif x then l=l+x end end)w=l>u and" to "or l<u and" TO "or" To "print(math.max(l,u)..w..math.min(l,u))

Ungolfed and explanations

a={F=3,D=2,T=4,P=1,S=2}        -- define the table a with our scoring values
l,u=0,0                        -- scores for the upper and lowercase teams
io.read():gsub(".",function(c) -- iterate over each character in the input
  x=a[c:upper()]               -- x contains the score for a lowercase character
  if a[c]                      -- if a contains c (would evaluate to nil otherwise)
  then
    u=u+a[c]                   -- increment the score of the uppercase team
  elseif x                     -- if x isn't nil
  then                         -- same as "a contains c:upper()"
    l=l+x                      -- increment the score of the lowercase team
  end
end)                           -- exit the anonyme function
w=l>u and" to "               -- nested ternary, lower > upper, we will use "to"
    or l<u and" TO "       -- lower < uppercase, use "TO"
    or" To "                   -- else (draw), use "To"
print(math.max(l,u)        -- output the concatenated string using 
      ..b.w..math.min(l,u))-- min/max to put the winner in the first position
\$\endgroup\$
0
\$\begingroup\$

Python, 167 bytes

The superb owl is long past, but since there isn't a Python solution yet:

def f(s):g=lambda s:0if s==""else{68:1,70:3,83:2,84:5,88:1}.get(ord(s[0]),0)+g(s[1:]);a=g(s);b=g(s.upper())-a;return"%i %s %i"%((a,("To","TO")[a>b],b),(b,"to",a))[a<b]

Works in Python 2 or 3.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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