-1

Find and output the given number's shortest square sum.

Example: 12 = 2^2 + 2^2 + 2^2 (not 3^2 + 1^2 + 1^2 + 1^2)

Output: {2 2 2}

Stan
  • 149
  • 1
  • 2
  • 9
  • I think you should try to post your question here instead : http://math.stackexchange.com/ – Alex Jun 16 '15 at 16:21
  • 1
    Or even better, just try to solve your homework by yourself first, then post here if you're stuck. – biziclop Jun 16 '15 at 16:24
  • 1
    And I would absolutely not recommend math.stackexchange.com, this would be way off topic there. – biziclop Jun 16 '15 at 16:27
  • This would be better phrased as "Find the shortest list of numbers whose squares sum to the given number." – Teepeemm Aug 05 '15 at 00:44

3 Answers3

7

This is min-coin-change problem, where the coins are [1,4,9,...,(ceil(sqrt(n)))^2].

It can be solved using Dynamic Programming (DP) by following the recurrence formula:

D(i,0) = 0
D(i,x) = infinity    x<0
D(0,x) = infinity    x>0
D(i,x) = min { D(i,x-i^2) + 1, D(i-1,x) }

When building your matrix (assuming bottom-up DP), the element denoted in the matrix in D(ceil(sqrt(n)),n) is the minimal number of "coins" (squared numbers) needed to build your input number.

Getting the actual elements is done by tracking back your choices in the matrix after it is built, and at each point checking if you added a summand or not.
This is explained in more details for similar problems in this thread and this thread.

Community
  • 1
  • 1
amit
  • 175,853
  • 27
  • 231
  • 333
  • 1
    [Min-Coin Change](http://www.algorithmist.com/index.php/Min-Coin_Change) to be precise. ([Coin Change](http://www.algorithmist.com/index.php/Coin_Change) is typically about finding the number of different possibilities.) – aioobe Jun 16 '15 at 22:01
0

Here is a visual basic solution to the problem. An edit would need to be done to cache intermediate answers so that the algorithm would be significantly faster. Currently ... only a value of about 40 to 50 is quickly computed. This is fully working and tested. It only returns the shortest answer and one where the higher value are to the left of other values.

Private Function ShortestSquareSum(x As Integer) As Integer()()
    If x < 0 Then
        Throw New ArgumentException("Parameter cannot be negative.", "x")
    ElseIf x = 0 Then
        Return New Integer()() {New Integer() {}}
    Else
        Dim answers As New List(Of Integer())
        Dim shortest As Integer? = Nothing
        For y As Integer = Math.Floor(Math.Sqrt(x)) To 1 Step -1
            Dim remaining As Integer = x - y * y
            Dim tempAnswers As Integer()() = ShortestSquareSum(x - y * y)
            For Each answer As Integer() In tempAnswers
                Dim currentAnswer As New List(Of Integer)
                currentAnswer.Add(y)
                currentAnswer.AddRange(answer)
                If Not shortest.HasValue OrElse currentAnswer.Count < shortest Then
                    shortest = currentAnswer.Count
                    answers.Clear()
                    answers.Add(currentAnswer.ToArray())
                ElseIf currentAnswer.Count = shortest AndAlso (answer.Count = 0 OrElse y > answer(0)) Then
                    answers.Add(currentAnswer.ToArray())
                End If
            Next
        Next
        Return answers.ToArray()
    End If
End Function
Marc Johnston
  • 1,276
  • 1
  • 7
  • 16
0
public static void shortest_square(int n)
{
    int i=2;
    List<Integer> list= new ArrayList<Integer>();
    while(i<=n) || n!=0)
    {
     if(n%(i*i)==0)
     {
      n=n-(i*i);
      list.add(i);
     }
     else
     {
      i++;
     }

    }
    System.out.println(list);
}
Archit Garg
  • 1,012
  • 8
  • 16
  • 1
    In general, it's best if you comment what your code is doing. In this case, starting `i` at 2 means it will count up, which will result in longer chains than necessary. And `i=1` is sometimes necessary. And some `i*i` won't divide `n`. – Teepeemm Aug 05 '15 at 00:42
  • so the i*i which wont divide n wont give any o/p ... no shortest square sum exists for them. i=1 is not necessary here. – Archit Garg Aug 05 '15 at 01:10
  • 13=2*2+3*3 has a shortest square sum that is not divisible by any of the summands (in fact, I think most square sums will not be divisible by any of the summands). 10=1*1+3*3 can only be written as a square sum using 1. – Teepeemm Aug 05 '15 at 13:56