-2

Was recently trying to solve this coding challenge from a company and I was stumped.

Let T(n) denote the number of different ways that a value of n cents, where n >= 4 and n is even, can be made by using 4-cent and 6-cent coins. For example, if n = 12 then we can use 3 4-cent coins or 2 6-cent coins, so T(12) = 2. Write a recursive algorithm in Python to find T(n) for n >= 4 and n is even.

I nailed down the base cases to be T(n < 4 or n not even) = 0, T(4) = 1 distinct way (1 4-cent coin) and T(6) = 1 distinct way (1 6-cent coin). But I'm not entirely sure how to proceed with a value greater than 6 and is even. Actually, if n > 4 and is even I did think of using modulo (%), so

if(n % 4 == 0): increment count
if(n % 6 == 0): increment count

I guess, I'm stuck on the recursive part because the two if-statements I've computed would count as only a single a way whereas there can be multiple ways to compute N.

aDabOfRanch
  • 137
  • 9
  • When asking about homework (1) **Be aware of your school policy**: asking here for help may constitute cheating. (2) Specify that the question is homework. (3) **Make a good faith attempt** to solve the problem yourself first (include your code in your question). (4) **Ask about a specific problem** with your existing implementation; see [Minimal, complete, verifiable example](https://stackoverflow.com/help/minimal-reproducible-example). Also, [here](https://meta.stackoverflow.com/questions/334822/how-do-i-ask-and-answer-homework-questions) is guidance on asking homework questions. – Prune Oct 14 '19 at 18:33
  • 2
    ["Can Someone Help Me?" is not a valid SO question](https://meta.stackoverflow.com/questions/284236/why-is-can-someone-help-me-not-an-actual-question). This usually suggests that what you need is time with a local tutor or walk through a tutorial, rather than Stack Overflow. Best of all, each tutorial will teach you a collection of related techniques, rather than merely solving the immediate problem. – Prune Oct 14 '19 at 18:34

4 Answers4

1

Not recursive, but should help you get started.

To determine unique solutions, you are basically asking for partitions of N such that N1 + N2 = N and N1 % 4 == 0 and N2 % 6 == 0. An iterative solution would go something like this:

count = 0
for j in range(0, N + 1, 4):
    if (N - j) % 6 == 0:
        count += 1

Turning this loop into a recursion is trivial:

def count(N):
    def count4(N, n4):
        if n4 > N:
            return 0
        return int((N - n4) % 6 == 0) + count4(N, n4 + 4)
    if N < 4 or N % 2:
        return 0
    return count4(N, 0)
Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
0

Assuming that ways means "exact order in which coins are laid out", here is a recursive solution.

def T_recurse (n):
    if 0 == n:
        return 1
    elif n < 3:
        return 0
    else:
        return T_recurse(n - 4) + T_recurse(n - 6)

print(T_recurse(100))

And a faster solution

def T_iter(n):
    if n < 0:
        return 0
    else:
        answers = [1, 0, 0, 0, 1, 0]
        while len(answers) <= n:
            answers.append(answers[-4] + answers[-6])
        return answers[n]

print(T_iter(100))

(There is also an analytical solution involving the roots of the polynomial x^6 - x^2 - 1, but that is slower to calculate in practice.)

Assuming that ways means "this many of one, that many of the other", then here is a recursive solution:

def S_recurse (n, coins):
    if 0 == n:
        return 1
    elif n < 0:
        return 0
    elif len(coins) == 0:
        return 0
    else:
        return S_recurse(n - coins[0], coins) + S_recurse(n, coins[1:])

S_recurse(12, [4, 6])

The recursive slowdown is not as bad though still exponential. However but iterative gives you quadratic:

def S_iter (n, coins):
    last_row = [0 for i in range(n + 1)]
    last_row[0] = 1
    for coin in coins:
        this_row = []
        for i in range(n+1):
            if i < coin:
               this_row.append(last_row[i])
            else:
               this_row.append(last_row[i] + this_row[i - coin])
        last_row = this_row
    return last_row[n]
btilly
  • 43,296
  • 3
  • 59
  • 88
  • It gives 2 for n=10, though there is only one solution (4 + 6) – Thierry Lathuille Oct 14 '19 at 18:47
  • @ThierryLathuille As the description says, it is counting exact order. So `(4, 6)` is counted differently from `(6, 4)`. I added a solution for the second as well. I don't know the actual intended problem, but in combinatorics I'd expect "ways" to mean with order mattering. – btilly Oct 14 '19 at 18:51
  • @btilly No we just want the count, the total number of ways the value N can be constructed. But it was cool to see how you would keep track of the way N can be made. – aDabOfRanch Oct 14 '19 at 19:53
  • @aDabOfRanch Then the last two solutions should do what you want. – btilly Oct 14 '19 at 21:00
0

You can use an optional parameter to keep track of the current sum of 6-cent coins for a given recursive call, and return 1 when the given number is divisible by 4 after deducting the sum of 6's:

def count46(n, sum6=0):
    return sum6 <= n and (((n - sum6) % 4) == 0) + count46(n, sum6 + 6)

so that:

for i in range(4, 24, 2):
    print(i, count_4_6(i))

outputs:

4 1
6 1
8 1
10 1
12 2
14 1
16 2
18 2
20 2
22 2
blhsing
  • 91,368
  • 6
  • 71
  • 106
-1

Not the most optimized but it returns an array of all distinct solutions

def coins(n, sum=0, current=[], answers=[]):
  if sum > n:
    return

  if sum == n:
    answers.append(current)
    return

  a4 = list(current)
  a4.append(4)

  coins(n, sum+4, a4, answers)

  lastIndex = len(current) - 1

  if len(current) == 0 or current[lastIndex] == 6:
    a6 = list(current)
    a6.append(6)
    coins(n, sum+6, a6, answers)


  return answers

Try it online!

Asleepace
  • 3,466
  • 2
  • 23
  • 36
  • The question asks for counts. – blhsing Oct 14 '19 at 19:24
  • @blhsing it's trivial to just return the length – Asleepace Oct 14 '19 at 20:05
  • It would also return an incorrect answer on a second call. – blhsing Oct 14 '19 at 20:06
  • @blhsing looks fine to me: https://tio.run/##bY9LDoIwEIb3nGKWNqIBbLowqXvPQFg0UCIJDk1bop4eW6S84q79X/lGfeyjw8swVLKGsmvQHDAG0z95EkPZay3R8ryIQaB5SW3cm1wjgKb2IbgB@h@AlrbXGC0O58GammehlMTqMI2SXU1Q4NA2xq4DgoYWJT60BjxSB0VnsNFvhbF3rOTbb0mcp@AE6cS2kR1kAp0Oh@Zzv/AWm/jZHzIvBzb2EzZwzIGxLVwUzh0ZFkfpBt322E4TQrZCthMySsgwfAE – Asleepace Oct 14 '19 at 20:09
  • How does 12 have 3 combinations, and how does 24 have 6 combinations? – blhsing Oct 14 '19 at 20:10
  • Interesting subsequent calls seems to stack, calling the function without default parameters works: https://tio.run/##dZBNDoIwEEb3nGKWEqsBbLowqXvPQFg0UCIJDk1bop4eW6T8GN218@abvBn1srcOT8NQyRrKrkGzQwKmv/OEQNlrLdHyvCAg0DykNu4dnyOApvZNcAH0PwAtba8xWgjnAU3Jo1BKYrWbhsZfMUGBQ9sYu24QNKRo7JvWgnvqpOgsNvJWGHvFSj79LInzKDhAOrltyk4ygU6HRfM5X3jEJn/2w8yXgxv7FDZyzImxrVwU1h0dFqJ0g272mE4TkhB3bnfleAuyPyCjCxiGNw – Asleepace Oct 14 '19 at 20:13
  • You can fix it with the solutions from one of the most frequently asked Python questions on SO: https://stackoverflow.com/questions/1132941/least-astonishment-and-the-mutable-default-argument – blhsing Oct 14 '19 at 20:15