# Score my golf round!

Since this SE community is about golfing, I thought a golf-related challenge would be appropriate.

## Explanation

Normally, the objective of golf is to finish a hole (and consequently, the entire round) with the least amount of strokes. This is a simple version of golf: Play until you hole the ball and sum up your score. Finally subtract it from the total par and the resulting number indicates your score: 0 if you played exactly par, positive if you played worse and negative if you played better.

But in 1898 a guy named Dr. Frank Barney Gorton Stableford devised a new system of playing which was designed to be more forgiving. This system awards a number of points to a player, based on a relative rating per hole, called the stroke index (SI) which is based on a player rating called handicap. This limits the amount of points a player can lose per hole. Additionally, the handiccp ensures fair competition between players despite skill difference.

This format isn't used in professional golf, but can be found almost anywhere in amateur golf.

## The scoring algorithm

For anyone unfamiliar with golf, the algorithm for scoring a hole based version is as follows.

1. Beginning with the hardest hole (rating 1) to the easiest one (rating 18), increase the stroke index of that hole by 1 and decrement the handicap. If you exhaust the handicap, stop. If you hit the easiest hole you wrap around to the hardest and continue. (Ex: stroke index for hcp 24 and [1..18]: [2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1]).

2. For every score on a hole, subtract it from the sum of par and stroke index and add 2 (formula: (par + stroke index) - achieved score + 2). These are the stableford points received for that hole. Note that you cannot receive less than 0 points.

3. Sum up all the points. The resulting total is the total number of stableford points.

Thus, reaching 36 points is equivalent to playing exactly one's handicap, and more points are better.

## Rules

Your task will be to calculate the total number of stableford points of an arbitrary golf round on an arbitrary golf course given a handicap.

You will be given a list of difficulty ratings, a list of pars, a list of scores and the handicap to use. You may order these arguments as you wish, but please state how you order them.

You may write a function ot program, input can be taken either as command line argument or function argument.

Output may either be printed to STDOUT or the return value of a function.

You may assume the following about the input:

• Every list will contain exactly 18 elements.
• The lists are orderd by hole: First element = info for first hole, etc.
• The handicap will be an integer between 0 and 54 inclusive.
• Pars will be between 3 and 7.
• The score is always a positive integer.
• The difficulty rating list will always be a permutation of [1..18].

This is code golf, so the shortest answer in bytes wins.

## Examples

Input: hcp: 0
difficulty: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]
pars: [3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,5,5,5]
score: [3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,5,5,5]
Output: 36

Input: hcp: 15
difficulty: [9,3,1,13,11,17,15,7,5,18,14,10,4,6,12,16,8,2]
pars: [4,4,4,3,5,4,3,4,4,4,3,4,4,4,5,3,5,4]
score: [5,5,4,5,4,4,4,4,5,7,3,5,5,6,4,6,5,5]
Output: 38

Input: hcp: 28
difficulty: [9,3,1,13,11,17,15,7,5,18,14,10,4,6,12,16,8,2]
pars: [4,4,4,3,5,4,3,4,4,4,3,4,4,4,5,3,5,4]
score: [5,5,5,6,3,7,3,6,5,8,4,6,7,8,4,7,6,5]
Outut: 37

Input: hcp: 54
difficulty: [9,3,1,13,11,17,15,7,5,18,14,10,4,6,12,16,8,2]
pars: [4,4,4,3,5,4,3,4,4,4,3,4,4,4,5,3,5,4]
score: [9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10,9,10]
Output: 3


Happy golfing!

# Pyth, 46 bytes

u+G.)S[0+-++@@Q2Hg%hQ18@@Q1H/hQ18@@Q3H2)Ul@Q1Z


A program that takes input as a list of the form [handicap, [difficulties], [pars], [scores]] and prints the overall score.

I am very new to Pyth, so this can probably be golfed further.

Try it online

How it works

u+G.)S[0+-++@@Q2Hg%hQ18@@Q1H/hQ18@@Q3H2)Ul@Q1Z  Program. Input: Q

+G.)S[0+-++@@Q2Hg%hQ18@@Q1H/hQ18@@Q3H2)        Function. Inputs: G, H
@@Q2H                               Q[2][H]
hQ                           Q[0]
18                         18
%                             Q[0]%18
@@Q1H                    Q[1][H]
g                              Q[0]%18>=Q[1][H]
+                                    Q[2][H]+Q[0]%18>=Q[1][H]
hQ                 Q[0]
18               18
/                   Q[0]//18
+                                     Q[2][H]+Q[0]%18>=Q[1][H]+Q[0]//18
@@Q3H          Q[3][H]
-                                      Q[2][H]+Q[0]%18>=Q[1][H]+Q[0]//18-Q[3][H]
2         2
+                                       Q[2][H]+Q[0]%18>=Q[1][H]+Q[0]//18-Q[3][H]+2
0                                        0
[                                )        List [0, above expression]
S                                          Sort ascending
.)                                           Pop last value, clamping negatives to 0
G                                             G
+                                              G + popped value

u                                       Ul@Q1Z
@Q1   Q[1]
l      Length
U       Unary range, yielding [0, len(Q[1])-1]
Z  0
u                                               Reduce the function over that, start at 0


## JavaScript (ES6), 72 bytes

(h,d,p,s)=>s.map((e,i)=>(e=p[i]+2-e+(h%18>=d[i])+h/18|0)<0?0:r+=e,r=0)|r


# Python 3, 71 bytes

lambda h,d,p,s:sum(max(0,j+(h%18>=i)+h//18-k+2)for i,j,k in zip(d,p,s))


An anonymous function that takes input via argument of a handicap h as an integer, and difficulties d, pars p and scores s as lists, and returns the overall score.

How it works

lambda h,d,p,s           Anonymous funtion with inputs handicap h, difficulties d, pars p
and scores s
for i,j,k in zip(d,p,s)  For each (difficulty, par, score) set (i, j, k):
(h%18>=i)+h//18          Calculate the stroke index...
j+...-k+2                ..calculate (par + stroke index) - score + 2...
max(0,...)               ...and clamp negative values to zero
:sum(...)                Return the sum of the above over all holes, which is the overall
score


Try it on Ideone

(h!d)p s=sum[max 0$j-k+2+hdiv18+1mindiv(hmod18)i|(i,j,k)<-zip3 d p s]  # Perl 5, 142 bytes ($h,@a)=map/\d+/g,<>;%d=map{$j++,$_}@a[0..17];$z+=($t=$a[18+$_]-$a[36+$_]+2+int$h/18+($k++<$h%18))>0?$t:0for sort{$d{$a}<=>$d{$b}}keys%d;say\$z