Problem:
Score : 300 points

Problem Statement

To make it difficult to withdraw money, a certain bank allows its customers to withdraw only one of the following amounts in one operation:

1 yen (the currency of Japan)

6 yen, 6^2(=36) yen, 6^3(=216) yen, ...

9 yen, 9^2(=81) yen, 9^3(=729) yen, ...

At least how many operations are required to withdraw exactly N yen in total?

It is not allowed to re-deposit the money you withdrew.

Constraints

1 \leq N \leq 100000

N is an integer.

Input

Input is given from Standard Input in the following format:

N

Output

If at least x operations are required to withdraw exactly N yen in total, print x.

Sample Input 1

127

Sample Output 1

4

By withdrawing 1 yen, 9 yen, 36(=6^2) yen and 81(=9^2) yen, we can withdraw 127 yen in four operations.

Sample Input 2

3

Sample Output 2

3

By withdrawing 1 yen three times, we can withdraw 3 yen in three operations.

Sample Input 3

44852

Sample Output 3

16

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;

class Program {
    static void Main(string[] args) {
        int N;
        Input(out N);
        int[] min = new int[N / 3 + 1];
        min[0] = 0;
        for(int i = 1; i <= N / 3; i++) {
            min[i] = min[i - 1] + 3;
            for(int j = 1; j <= Log(i * 3, 6); j++) {
                int cost = min[i - (Pow(6, j) / 3)] + 1;
                if(cost < min[i]) {
                    min[i] = cost;
                    //Console.WriteLine($"{i * 3}:6^{j}:min,cost{min[i - (Pow(6, j) / 3)]}+1");
                }
            }
            for(int j = 1; j <= Log(i * 3, 9); j++) {
                int cost = min[i - (Pow(9, j) / 3)] + 1;
                if(cost < min[i]) {
                    min[i] = cost;
                    //Console.WriteLine($"{i * 3}:9^{j}:min,cost{min[i - (Pow(9, j) / 3)]}+1");
                }
                if(i == 59049 / 3) {
                    //Console.WriteLine($"59049:{cost}");
                }
            }
        }
        for(int i = 0; i <= N; i++) {
            //Console.WriteLine($"{i}:{min[i / 3] + i % 3}");
        }
        Console.WriteLine(min[N / 3] + N % 3);
    }
    static int Pow(int a, int b) {
        if(b == 0) {
            return 1;
        } else {
            if(b % 2 == 0) {
                return Pow(a * a, b / 2);
            } else {
                return a * Pow(a, b - 1);
            }
        }
    }
    static int Log(int a, int b) {
        for(int i = 0; true; i++) {
            if(a < Pow(b, i)) {
                return i - 1;
            }
        }
    }
    static T ChangeT<T>(string s) => (T)Convert.ChangeType(s, typeof(T));
    static void Input<A>(out A a) {
        var words = Console.ReadLine().Split(new[] { ' ' }, options: StringSplitOptions.RemoveEmptyEntries);
        a = ChangeT<A>(words[0]);
    }
    static void Input<A, B>(out A a, out B b) {
        var words = Console.ReadLine().Split(new[] { ' ' }, options: StringSplitOptions.RemoveEmptyEntries);
        a = ChangeT<A>(words[0]);
        b = ChangeT<B>(words[1]);
    }
    static void Input<A, B, C>(out A a, out B b, out C c) {
        var words = Console.ReadLine().Split(new[] { ' ' }, options: StringSplitOptions.RemoveEmptyEntries);
        a = ChangeT<A>(words[0]);
        b = ChangeT<B>(words[1]);
        c = ChangeT<C>(words[2]);
    }
    static void Input<A, B, C, D>(out A a, out B b, out C c, out D d) {
        var words = Console.ReadLine().Split(new[] { ' ' }, options: StringSplitOptions.RemoveEmptyEntries);
        a = ChangeT<A>(words[0]);
        b = ChangeT<B>(words[1]);
        c = ChangeT<C>(words[2]);
        d = ChangeT<D>(words[3]);
    }
    static void Input<A, B, C, D, E>(out A a, out B b, out C c, out D d, out E e) {
        var words = Console.ReadLine().Split(new[] { ' ' }, options: StringSplitOptions.RemoveEmptyEntries);
        a = ChangeT<A>(words[0]);
        b = ChangeT<B>(words[1]);
        c = ChangeT<C>(words[2]);
        d = ChangeT<D>(words[3]);
        e = ChangeT<E>(words[4]);
    }
    static void Input<A, B, C, D, E, F>(out A a, out B b, out C c, out D d, out E e, out F f) {
        var words = Console.ReadLine().Split(new[] { ' ' }, options: StringSplitOptions.RemoveEmptyEntries);
        a = ChangeT<A>(words[0]);
        b = ChangeT<B>(words[1]);
        c = ChangeT<C>(words[2]);
        d = ChangeT<D>(words[3]);
        e = ChangeT<E>(words[4]);
        f = ChangeT<F>(words[5]);
    }
    static void InputArray<T>(out T[] array) {
        array = Console.ReadLine().Split(new[] { ' ' }, options: StringSplitOptions.RemoveEmptyEntries).Select(s => ChangeT<T>(s)).ToArray();
    }
}