## DEV Community is a community of 752,525 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

# Daily Challenge #153 - Horse Race Gamble

### Setup

Your friend likes to go to the horse races and gamble on which horses will finish first, second, and third place. Unfortunately, he doesn't know how many horses will be entering until he gets to the track.

Write a function that will take any number of horses as its only argument. This function must return the total number of different combinations of winners for the gold, silver, and bronze medals.

For example, if there are 15 horses, there are 2730 possible unique combinations of winners. If the number of horses is 3 or less, return the input value. If the number of horses is not an integer, return `undefined`.

### Examples

horses(15), 2730, true)
horses(2.5), undefined, false)

### Tests

horses(12)
horses(2)
horses(11)
horses(a)

Good luck!

This challenge comes from tu6619 on CodeWars. Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge idea for a future post? Email yo+challenge@dev.to with your suggestions!

## Discussion (14) Nick Holmes

The code (F#)

``````let WinnerCombinations n =
if (n <= 3) then None
else Some (n * (n-1) * (n-2))
``````

As F# is a strongly typed language, no need to check n is an integer - it is. Idiomatically, "undefined" in F# is handled with the Option monad, so we return either None or Some result.

The actual calculation is trivial; n * (n-1) * (n-2) Michael Kohl

“ If the number of horses is 3 or less, return the input value.”

You don’t need an `Option`, the case that should return `undefined` wouldn’t compile in F#. Nick Holmes

Yes, I said that in my post.

However, I misread the challenge, and thought that "undefined" should be returned when n <= 3, although it should actually return the input. Brett Martin • Edited on

Shortest answer I could think of:

``````const horses = n => {
if(Number.isInteger(n)) return n < 3 ? n : n * (n-1) * (n-2)
};
``````

And in Standard ML, since it has type checking I can skip the int check:

``````fun horses(n: int) : int = if n < 3 then n else n * (n - 1) * (n - 2)
`````` Nicholas Saccente

Here's my submission while I'm learning Nim.

``````proc fac(n: int): int =
if n <= 1: return 1
result = n * fac(n - 1)

proc nPr(n: int, r: int): int =
result = fac(n) div fac(n-r)

proc `%`(n: int, r: int): int =
result = nPr(n, r)

proc horses(n: int): int =
if n <= 3: return n
result = n % 3

when isMainModule:
echo horses(15)    #=> 2730
echo horses(12)    #=> 1320
echo horses(2)     #=> 2
echo horses(11)    #=> 990
# echo horses(a)   #=> compiler error

`````` Kermit Alexander II • Edited on

The word "combinations" being used here provides us with a good jumping-off point to figure out the solution - combinatorics! We can calculate the `n` choose `k`/binomial coefficient for the horses, where `n` is the total number of horses, and `k` is equal to 3, since we're looking for 3 horses (gold, silver, and bronze winners). From there, we need to take into account that ordering - which horse won which position - matters to us; mathematical combinations are sets in which order doesn't normally matter. We'll need permutations for that part.

So, knowing that the number of permutations for a set of `n` elements is equal to `n!`, we can multiply the result of our `n` choose `k` by 6 (which is just a shorthand for multiplying by `3!`, as `3! = 6`). Putting that all together with a little bit of error checking, we have the following short Python solution:

``````#!/usr/bin/env python3
import math

def nchoosek(n, k):
n_fac = math.factorial(n)
denominator = math.factorial(k) * math.factorial(n - k)
return n_fac / denominator

def horses(num_horses):
try:
# check for non-integer but still numerical input
if int(num_horses) != num_horses:
return None
except ValueError:
# check for non-numerical input
return None
if num_horses <= 3:
return num_horses
return int(nchoosek(num_horses, 3) * 6)

if __name__ == "__main__":
print(horses(15))
print(horses(4))
print(horses(1))
print(horses("whoops"))
print(horses(4.5))
``````

edit: forgot to add code to check for floating-point numbers as input, whoops Roberto B.
``````function horse(n: any): number|void {
if (n === parseInt(n, 10)) {
if (n > 3) {
return n * (n - 1) * (n - 2)
} else {
return n
}

} else {
return undefined
}
}

console.log(horse(15))
console.log(horse(12))
console.log(horse(2))
console.log(horse(11))
console.log(horse("a"))
`````` Cent | Shannon Myers • Edited on

Good old factorials. I had fun with this one. Feel free to give advice if I can make my code better!

JS

CodePen

Edit: forgot to convert the input to a number making all of the numbers that go through the function a string

``````
// grabs the input, the number of horses, from the input tag
const calculate = (horses = Number(document.querySelector("#horses").value)) => {

//puts the answer into an empty div
horses !== parseInt(horses) ? undefined :
horses < 4 ? horses :
factorial(horses)/factorial(horses - 3);
}

const factorial = (n) => {
return n ? n * factorial(n - 1) : 1;
}

`````` Rafael Acioly

Python solution 🐍

``````from intertools import permutations

WINNERS_QUANTITY = 3

def winner_combination(horses_amount: int) -> int:
if horses_amount <= WINNERS_QUANTITY:
return horses_amount

possibilities = list(permutations(
range(horses_amount), WINNERS_QUANTITY
))
return len(possibilities)

`````` SavagePixie • Edited on

My JavaScript solution:

``````const winCombos = n => !Number.isInteger(n)
? undefined
: n < 4
? n
: n * (n - 1) * (n - 2)
`````` Rashmin Dandekar

Ruby

``````def horses(num)
if !(num % 1 == 0) || !(num.is_a? Numeric)
return "undefined"
elsif num < 3
return num
else
return num*(num-1)*(num-2)
end
end

puts horses(12)
puts horses(2)
puts horses(11)
puts horses(2.5)
puts horses("a")

`````` Idan Arye

If the number of horses is 3 or less, return the input value.

Shouldn't that be "less than 3"? Shouldn't `horses(3)` return 6?