Sally wants more apples!

Last time , Sally moved through her garden eating an apple in every square.

But this time Sally feels more enthusiastic. This time she's going to do the same but now, she can also move diagonally. Find the number of ways in which Sally can eat all 25 apples

Details and Assumptions

  • She has a 5 × 5 5 \times 5 garden with total of 25 apples.

  • She can move forward, backward, up, down or diagonally as long as there is an apple in the cell she is moving to.

  • She is standing in the center of the garden, i.e. 3 rd 3^{\text{rd}} row and 3 rd 3^{\text{rd}} column.

  • If the garden was of size 3 × 3 3 \times 3 , then she can eat all the apples in exactly 32 ways.

Warning

  • The best C++ code (so far) takes nearly 100 seconds on a Quad Core 2.67 2.67 GHz processor. So, it's okay if your code is running for long.

Inspiration .


The answer is 25373376.

This section requires Javascript.
You are seeing this because something didn't load right. We suggest you, (a) try refreshing the page, (b) enabling javascript if it is disabled on your browser and, finally, (c) loading the non-javascript version of this page . We're sorry about the hassle.

4 solutions

Here is the modification of the depth first search using a stack as opposed to plain recursion.

Later Edit: Turns out recursion actually works better. See below.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include <iostream>
#include <stdio.h>
#include <stack>
#include <time.h>

const int size = 5;
const int total_steps = size*size;

struct State{
    bool grid[size][size] = {{false}};
    int nSteps = 0;
    int x = (size-1)/2, y = (size-1)/2;
};

int main() {
    clock_t tStart = clock();

    int nPaths = 0;
    std::stack<State> stack;

    stack.push(State());

    while (!stack.empty())
    {
        State st = stack.top(); stack.pop();

        if (st.nSteps == total_steps-1)
        {
            nPaths++;
            continue;
        }

        st.grid[st.x][st.y]=true;

        if (st.x - 1 >= 0 && st.grid[st.x-1][st.y] == false){
            State temp = st;
            temp.nSteps++;
            temp.x--;
            stack.push(temp);
        }
        if (st.x + 1 < size && st.grid[st.x+1][st.y] == false){
            State temp = st;
            temp.nSteps++;
            temp.x++;
            stack.push(temp);
        }       
        if (st.y - 1 >= 0 && st.grid[st.x][st.y-1] == false){
            State temp = st;
            temp.nSteps++;
            temp.y--;
            stack.push(temp);
        }
        if (st.y + 1 < size && st.grid[st.x][st.y+1] == false){
            State temp = st;
            temp.nSteps++;
            temp.y++;
            stack.push(temp);
        }
        if ((st.y + 1 < size && st.x + 1 < size) && st.grid[st.x+1][st.y+1] == false){
            State temp = st;
            temp.nSteps++;
            temp.x++;
            temp.y++;
            stack.push(temp);
        }
        if ((st.y + 1 < size && st.x - 1 >= 0) && st.grid[st.x-1][st.y+1] == false){
            State temp = st;
            temp.nSteps++;
            temp.x--;
            temp.y++;
            stack.push(temp);
        }
        if ((st.y - 1 >= 0 && st.x + 1 < size) && st.grid[st.x+1][st.y-1] == false){
            State temp = st;
            temp.nSteps++;
            temp.x++;
            temp.y--;
            stack.push(temp);
        }
        if ((st.y - 1 >= 0 && st.x - 1 >= 0) && st.grid[st.x-1][st.y-1] == false){
            State temp = st;
            temp.nSteps++;
            temp.x--;
            temp.y--;
            stack.push(temp);
        }
    }

    std::cout << nPaths << std::endl;

    printf("Time taken: %.2fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);   

    return 0;
}

Output:

1
2
25373376
Time taken: 588.09s


It turns out that recursion is faster. This code is forked from Abdelhamid Saadi's solution to this problem .

If it were not for performance, I would say that this code has many practices that I do not like. Especially, the use of global variables.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <cstdio>
#include <time.h>

int grid[5][5];
int k,r;

void find(int x,int y){

  grid[x][y]=1;
  k++;

  if(k==25){
    r++;
  }

  if(x-1>=0 && grid[x-1][y]==0){
    find(x-1,y);
  }

  if(x+1<5 && grid[x+1][y]==0){
    find(x+1,y);
  }

  if(y-1>=0 && grid[x][y-1]==0){
    find(x,y-1);
  }

  if(y+1<5 && grid[x][y+1]==0){
    find(x,y+1);
  }

  if ((y-1>=0 && x-1>=0) && grid[x-1][y-1] == 0){
    find(x-1,y-1);
  }

  if ((y-1>=0 && x+1<5) && grid[x+1][y-1]==0){
    find(x+1,y-1);
  }

  if ((y+1<5 && x+1<5) && grid[x+1][y+1]==0){
    find(x+1,y+1);
  }

  if ((y+1<5 && x-1>=0) && grid[x-1][y+1]==0){
    find(x-1,y+1);
  }

  grid[x][y]=0;
  k--;

}


int main(){

  clock_t tStart = clock();

  find(2,2);
  printf("%d\n",r);

  printf("Time taken: %.2fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);

  return 0;

}

Output:

1
2
25373376
Time taken: 107.23s

@Arulx Z , Check this out?

Agnishom Chattopadhyay - 5 years, 9 months ago

Log in to reply

Nice job! The stack solution is really nice. Also, your recursion solution is almost 20 times faster than mine!

Arulx Z - 5 years, 9 months ago

Log in to reply

Mainly because Java runs on a virtual machine whereas C++ is compiled code.

I guess the same algorithm would be faster in assembly and like 20 times slower in Python

Agnishom Chattopadhyay - 5 years, 8 months ago

I am not expert in C++, this is a rewrite of your code with no global variables.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <iostream>
#include <time.h>
using namespace std;

class Garden
{
    int grid[5][5];
    int k;

    public :
        Garden(){
            k = 0;
            r = 0;
            for(int i=0; i<5; i++)
                for(int j=0; j<5; j++)
                    grid[i][j]=1;
        }
        long r;
        void find(int x,int y){
            grid[x][y]=0;
            k++;

            if(k==25)   r++;

            if(x-1>=0 && grid[x-1][y]==1)        find(x-1,y);    

            if(x+1<5 && grid[x+1][y]==1) find(x+1,y);

            if(y-1>=0 && grid[x][y-1]==1)    find(x,y-1);

            if(y+1<5 && grid[x][y+1]==1) find(x,y+1);

            if ((y-1>=0 && x-1>=0) && grid[x-1][y-1] ==1) find(x-1,y-1);

            if ((y-1>=0 && x+1<5) && grid[x+1][y-1]==1)   find(x+1,y-1);

            if ((y+1<5 && x+1<5) && grid[x+1][y+1]==1)    find(x+1,y+1);

            if ((y+1<5 && x-1>=0) && grid[x-1][y+1]==1)   find(x-1,y+1);

            grid[x][y]=1;
            k--;
    }
};

int main(){

    clock_t tStart = clock();
    Garden garden;
    garden.find(2,2);
    cout << "Number of ways: " << garden.r <<"\n"; 
        cout << "Time taken: ", (double)(clock() - tStart)/CLOCKS_PER_SEC)<<"s\n";  
    return 0;
}

Abdelhamid Saadi - 5 years, 8 months ago

Log in to reply

I am trying to brush up my C++ skills too.

How fast is your code?

Agnishom Chattopadhyay - 5 years, 8 months ago

Log in to reply

about 120 seconds.

Abdelhamid Saadi - 5 years, 8 months ago
Abdelhamid Saadi
Sep 16, 2015

Here is my solution in python 3.4

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
garden = {}
voisins = {}
ariane = []
nbpaths = 0
taille = 0
def initgarden(n):
    for i in range(1, n+1):
        for j in range(1, n+1):
            garden[(i,j)] = True
    for i in range(1, n+1):
        for j in range(1, n+1):
            voisins[(i,j)] = [x for x in
                              [(i+1,j), (i-1,j), (i,j+1), (i,j-1),
                               (i+1,j+1), (i+1,j-1), (i-1,j+1), (i-1,j-1)
                               ] if x in garden]

def godeep(x, n):
    global nbpaths, taille
    if n == taille*taille :
        nbpaths += 1
    garden[x] = False
    ariane.append(x)
    for y in voisins[x]:
        if garden[y]:
            godeep(y, n + 1)
    x = ariane.pop()
    garden[x] = True

def solve(n):
    "Sally wants more apples!"
    global taille
    initgarden(n)
    taille = n
    godeep((n//2 + 1 , n//2 + 1), 1)
    return nbpaths

print(solve(5))

Nice solution! By the way, what is the execution time? When I ran my solution, it took very long to compute the answer. (I have Python 2.7 installed so I can't test your code directly on my system without messing it up).

Arulx Z - 5 years, 9 months ago

Log in to reply

In my machine,it takes 70 minutes.

A modified version could divide the execution time by 4 to 8.

Abdelhamid Saadi - 5 years, 9 months ago

Log in to reply

I am giving a try to nested loops as deep recursion probably makes the code slower.

Arulx Z - 5 years, 9 months ago

Log in to reply

@Arulx Z What time does it take for the fastest java version? My version takes a lot, like 175 seconds or so.

Sergio Tomás - 5 years, 8 months ago

Log in to reply

@Sergio Tomás Can you post your code? 175 secs is actually a very good time. My version takes almost 30-35 mins to execute.

Arulx Z - 5 years, 8 months ago

Log in to reply

@Arulx Z Sure, here it is: * OLD SOLUTION REMOVED, IMPROVED BELOW*

Sergio Tomás - 5 years, 8 months ago

Log in to reply

@Sergio Tomás It takes 90 secs to run on my machine (which is a really good speed). However, for some weird reasons, I am getting the answer as 25372384 instead of 25373376. I haven't analyzed your code yet so pardon me if I made any mistake in interpretation of the answer.

Arulx Z - 5 years, 8 months ago

Log in to reply

@Arulx Z You are totally right, something has broken with some last-minute change :) I will try to find the small bug polluting the result :)

Sergio Tomás - 5 years, 8 months ago

Log in to reply

@Sergio Tomás There seems to be an issue in the cache logic for big combinations. If you change the CACHE SUB NODE MAX SIZE constant to a smaller value, like 9 it gives you the proper 25373376 taking more time of course. It's something :)

Sergio Tomás - 5 years, 8 months ago

@Arulx Z I have made some modifications based on some things I have seen on other answers, to try to optimize the java solution. It runs on 160 seconds on my machine, so it should be pretty fast in your machine, if the previous one was running so fast.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 
 * @author Sergio Tomas (@Disruption)
 *
 */
public class SallyBetter {
    private static final int ROWS = 5;
    private static final int COLUMNS = 5;
    private static final int CACHE_SUB_NODE_MAX_SIZE = 6;

    //  0  1  2  3  4
    //  5  6  7  8  9
    // 10 11 12 13 14
    // 15 16 17 18 19
    // 20 21 22 23 24


    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        List<Integer> availablePositions = new ArrayList<Integer>();
        Map<Integer, List<Integer>> nextAvailablePositions = new HashMap<>();
        Map<Integer, Map<List<Integer>, Integer>> cache = new HashMap<>();
        for (int i = 0; i < 25; i++) {
            // Available positions will be 0 to 24
            availablePositions.add(i);
            // Every node will know where it can go, so we avoid doing that calculations again and again and again..
            nextAvailablePositions.put(i, calculateNextPositions(i));
        }
        // We start from the center, position 12, so it's never available
        availablePositions.remove(12);

        // Branch starting from next node 17
        availablePositions.remove((Integer) 17);

        // Subbranch node 18, axial symmetry, so result must be multiplied by 2
        availablePositions.remove((Integer) 18);
        int result = 2*calculatePossiblePaths(18, availablePositions, nextAvailablePositions, cache);
        availablePositions.add((Integer) 18);

        // Subbranch node 13, axial symmetry, so result must be multiplied by 2
        availablePositions.remove((Integer) 13);
        result += 2*calculatePossiblePaths(13, availablePositions, nextAvailablePositions, cache);
        availablePositions.add((Integer) 13);

        // Subbranch node 23, axial symmetry, so result must be multiplied by 2
        availablePositions.remove((Integer) 23);
        result += 2*calculatePossiblePaths(23, availablePositions, nextAvailablePositions, cache);
        availablePositions.add((Integer) 23);

        // Subbranch node 22, no symmetry
        availablePositions.remove((Integer) 22);
        result += calculatePossiblePaths(22, availablePositions, nextAvailablePositions, cache);
        availablePositions.add((Integer) 22);

        // Base node switched from 17 to 18
        availablePositions.add((Integer) 17);

        // Process branch from node 18
        availablePositions.remove((Integer) 18);

        // Subbranch node 17, axial symmetry, so result must be multiplied by 2
        availablePositions.remove((Integer) 17);
        result += 2*calculatePossiblePaths(17, availablePositions, nextAvailablePositions, cache);
        availablePositions.add((Integer) 17);

        // Subbranch node 14, axial symmetry, so result must be multiplied by 2
        availablePositions.remove((Integer) 14);
        result += 2*calculatePossiblePaths(14, availablePositions, nextAvailablePositions, cache);
        availablePositions.add((Integer) 14);

        // Subbranch node 19, axial symmetry, so result must be multiplied by 2
        availablePositions.remove((Integer) 19);
        result += 2*calculatePossiblePaths(19, availablePositions, nextAvailablePositions, cache);
        availablePositions.add((Integer) 19);

        // Subbranch node 24, no symmetry
        availablePositions.remove((Integer) 24);
        result += calculatePossiblePaths(24, availablePositions, nextAvailablePositions, cache);

        System.out.println(4 * result);
        long time = System.currentTimeMillis() - startTime;
        System.out.println(time + " ms. " + (time / 1000) + " s.");

    }

    public static int calculatePossiblePaths(int currentPosition, List<Integer> availablePositions, Map<Integer, List<Integer>> nextAvailablePositions, Map<Integer, Map<List<Integer>, Integer>> cache) {
        // Base case, when we have an empty positions list, we found a combination
        if (availablePositions.size() == 0) {
            return 1;
        }

        int result = 0;
        List<Integer> candidates = nextAvailablePositions.get(currentPosition);

        for (Integer candidate : candidates) {
            if (availablePositions.contains(candidate)) {
                availablePositions.remove(candidate);
                Map<List<Integer>, Integer> subPaths = null;
                // Check if we have this subpath cached. If it is, add it's subresult and continue with the next candidate
                if (availablePositions.size() <= CACHE_SUB_NODE_MAX_SIZE && availablePositions.size() > 0) {
                    subPaths = cache.get(candidate);
                    Integer subResult = subPaths != null ? subPaths.get(availablePositions) : null;
                    if (subResult != null) {
                        result += subResult;
                        availablePositions.add(candidate);
                        continue;
                    }
                }
                int subresult = calculatePossiblePaths(candidate, availablePositions, nextAvailablePositions, cache);
                // If we are below or on the cache limit, cache this result so we don't recalculate this subtree anymore
                if (availablePositions.size() <= CACHE_SUB_NODE_MAX_SIZE) {
                    List<Integer> subNodes = new ArrayList<>();
                    subNodes.addAll(availablePositions);
                    if (subPaths != null) {
                        subPaths.put(availablePositions, subresult);
                    } else {
                        subPaths = new HashMap<>();
                        subPaths.put(availablePositions, subresult);
                        cache.put(candidate, subPaths);
                    }
                }
                result += subresult;
                availablePositions.add(candidate);
            }
        }

        return result;
    }

    // Calculates what positions can be reached from position i
    private static List<Integer> calculateNextPositions(int i) {
        int currentRow = i / COLUMNS;
        int currentColumn = i % COLUMNS;
        List<Integer> neighbours = new ArrayList<>();
        for (int col = -1 ; col < 2; col++) {
            for (int row = -1 ; row < 2; row++) {
                if (row != 0 || col != 0) {
                    int newRow = currentRow + row;
                    int newColumn = currentColumn + col;
                    if (newRow >= 0 && newRow < ROWS && newColumn >= 0 && newColumn < COLUMNS) {
                        neighbours.add(newRow * COLUMNS + newColumn);
                    }
                }
            }
        }
        return neighbours;
    }

}

Result: 25373376 160133 ms. 160 s.

Sergio Tomás - 5 years, 8 months ago

Log in to reply

@Sergio Tomás Nice solution! Good Job! Why not post it as solution instead as a comment? I'm sure you'll get tons of upvotes.

Arulx Z - 5 years, 8 months ago

Log in to reply

@Arulx Z Oh, sure. Will do now :)

Sergio Tomás - 5 years, 8 months ago

Can you provide pseudo-code for the modified version?

Arulx Z - 5 years, 8 months ago

Log in to reply

@Arulx Z This a modified version in python 3.4:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
from time import time
garden = {}
voisins = {}
ariane = []
nbpaths = 0
taille = 0
def initgarden(n):
    for i in range(1, n+1):
        for j in range(1, n+1):
            garden[(i,j)] = True
    for i in range(1, n+1):
        for j in range(1, n+1):
            voisins[(i,j)] = [x for x in
                              [(i+1,j), (i-1,j), (i,j+1), (i,j-1),
                               (i+1,j+1), (i+1,j-1), (i-1,j+1), (i-1,j-1)
                               ] if x in garden]

def godeep(x, n):
    global nbpaths, taille
    if n == taille*taille :
        nbpaths += 1
        return
    garden[x] = False
    ariane.append(x)
    for y in voisins[x]:
        if garden[y]:
            godeep(y, n + 1)
    x = ariane.pop()
    garden[x] = True

def solvehelper(a, b):
    global nbpaths
    nbpaths = 0
    garden[(3,3)] = False
    garden[a] = False
    godeep(b, 3)
    return nbpaths

def solve():
    "Sally wants more apples!"
    global taille
    allpaths = 0
    initgarden(5)
    taille = 5
    allpaths += 2*solvehelper((3,4),(4,4))
    allpaths += 2*solvehelper((3,4),(4,3))
    allpaths += 2*solvehelper((3,4),(4,5))
    allpaths += solvehelper((3,4),(3,5))
    allpaths += 2*solvehelper((4,4),(3,4))
    allpaths += 2*solvehelper((4,4),(5,3))
    allpaths += 2*solvehelper((4,4),(5,4))
    allpaths += solvehelper((4,4),(5,5))
    allpaths *= 4
    return allpaths

start = time()
print(solve())
print("execution time: ",time() - start)

Output:

1
2
25373376
execution time:  403.128057718277

Abdelhamid Saadi - 5 years, 8 months ago

It takes around 95 secodnds on an online C++11 compiler.

If you can explain me how the solution works, may be we can improve on the time a bit.

Agnishom Chattopadhyay - 5 years, 9 months ago

Log in to reply

Ok. I have a slightly different solution in Java (I'll post it in 10 mins). We'll try improving it as even I'm unclear about how this solution works.

Arulx Z - 5 years, 9 months ago

Log in to reply

@Arulx Z You do not need to post your Java code. You already posted it on the other solution thread.

I would be obliged if you explained how it works instead?

Agnishom Chattopadhyay - 5 years, 9 months ago

Log in to reply

@Agnishom Chattopadhyay Wait, no. i got it. i will work on optimizing the code

Agnishom Chattopadhyay - 5 years, 9 months ago

Log in to reply

@Agnishom Chattopadhyay Ok. I have made already made a brief description so I'll post it anyways.

Arulx Z - 5 years, 9 months ago

@Agnishom Chattopadhyay Ok.

Here is the working -

I have created an 5 × 5 5 \times 5 two dimensional array. The array is filled with 0's. 0's represent apple. 1's represent that apple has been eaten. Here's the numbering system -

1
2
3
4
5
[1,  2,  3,  4,  5 ],
[6,  7,  8,  9,  10],
[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20],
[21, 22, 23, 24, 25]

For sake of explanation, let's call this naming method nc .

The array numbering is indexed at [0, 0] at top left (ie, 1 = [0, 0] , 8 = [1, 2] ).


The method ntc converts coordinates of form nc to Cartesian , so that I can feed nc to array.


The method neighbours takes a nc as the argument and then looks for the neighbours of nc . This works from the fact that, if subtract 4 from nc , we get the top-right neighbour. Similarly, here are the other results -

1
2
3
4
5
6
7
8
9
Adding -5: top neighbour
Adding -6: top-left neighbour

Adding 1: Right neighbour
Adding -1: Left neighbour

Adding 4: Bottom left neighbour
Adding 5: Bottom neighbour
Adding 6: Bottom right neighbour

Additionally the method only checks for neighbours with 0 in it (ie, the cell which contain apple). Also, it checks if the neighbour fits in the 5 × 5 5 \times 5 grid. For example, if pass the argument as 49, it will have no right neighbour as 49 + 1 > 49 49 + 1 > 49 . Also, 49 doesn't have bottom, bottom-right and bottom-left neighbour.

The neighbours which satisfy all the checks are added to a list and returned.


The method recursion solve the problem. Here's the working -

First I start in the center cell, ie 13. Then I look for neighbours of 13. I get a list containing the neighbours of 13. Then I look for the neighbours of neighbours of 13 and then so on. If a path has 25 steps, then it is a valid path for Sally. This way, I iterate over all the possible paths.


There is a slight change in my code from the previous thread. I have added some lines in the neighbours method.

Here's the new code -

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import java.util.ArrayList;
import java.util.List;

class bril {
    private static int count = 0;
    private static int matrix[][] = new int[5][5];

    public static void main (String args[]){
        for (int i = 0; i < 5; i++)
            for (int j = 0; j < 5; j++)
                matrix[i][j] = 0;
        matrix[2][2] = 1;
        recursion(matrix, 13, 0);
        System.out.println(count);
    }

    private static void recursion(int mx[][], int cell, int step){
        if (step < 24){
            for(int x : neighbours(cell)){
                int coords[] = ntc(x);
                matrix[coords[1]][coords[0]] = 1;
                recursion(matrix, x, step + 1);
                matrix[coords[1]][coords[0]] = 0;
            }
        } else
            count++;
    }

    private static List<Integer> neighbours(int n){
        List<Integer> list = new ArrayList<>();

        for(int i : new int[]{4, 5, 6}) //top 3 //change LATER
            if (n - i >= 1 && (Math.floor((n - 1) / 5) == (Math.floor((n - i - 1) / 5) + 1))){
                int coords[] = ntc(n - i);
                if(matrix[coords[1]][coords[0]] == 0)
                    list.add(n - i);
            }

        for(int i : new int[]{-1, 1}){  //middle 2 //change
            if (n + i >= 1 && n + i <= 25 && Math.floor((n - 1) / 5) == Math.floor((n + i - 1) / 5)){
                int coords[] = ntc(n + i);
                if(matrix[coords[1]][coords[0]] == 0)
                    list.add(n + i);
            }
        }

        for(int i : new int[]{4, 5, 6}) // bottom 3 //change
            if (n + i <= 25 && Math.floor((n - 1) / 5) == Math.floor((n + i - 1) / 5) - 1){
                int coords[] = ntc(n + i);
                if(matrix[coords[1]][coords[0]] == 0)
                    list.add(n + i);
            }
        return list;
    }

    private static int[] ntc(int n){
        int y = (int) Math.floor((n - 1) / 5);
        return new int[]{(int) (n - 5 * y - 1), (int) y}; //x, y. x, y = [0, 0] at top left
    }
}


Sorry for late reply. I'm in school so I can only work during free lectures.

Arulx Z - 5 years, 9 months ago

Can you explain how the solution actually works?

Agnishom Chattopadhyay - 5 years, 9 months ago
Milan Milanic
May 4, 2016

My one works correctly and time 30.0009 s. I also used recursive functions. Almost forgot, great problem! I gave it a like.

Thanks! Can you post your solution?

Arulx Z - 5 years, 1 month ago

Log in to reply

This would be my code for such solution.

#include <iostream>

using namespace std;


const int A = 5, A_2 = A * A;
bool Field[A + 2][A + 2];

void initialization()
{
    int i, j;
    for(i = 0; i <= A + 1; ++i)
    {
        for(j = 0; j <= A + 1; ++j)
        {
            if(i && j && i <= A && j <= A)  Field[i][j] = true;
            else    Field[i][j] = false;
        }
    }
}


long long int solution = 0;
void Ike(int i, int j, int KO)
{
    if(!Field[i][j])    return;

    ++KO;

    Field[i][j] = false;
    if(KO == A_2)
    {
        ++solution;
        Field[i][j] = true;
        return;
    }

    else
    {
        Ike(i + 1, j, KO);
        Ike(i - 1, j, KO);
        Ike(i, j + 1, KO);
        Ike(i, j - 1, KO);

        Ike(i + 1, j + 1, KO);
        Ike(i + 1, j - 1, KO);
        Ike(i - 1, j + 1, KO);
        Ike(i - 1, j - 1, KO);
    }

    Field[i][j] = true;
}


int main()
{
    initialization();

    int c = (A + 1) / 2;
    Field[c][c] = false;

    Ike(c, c + 1, 1);
    Ike(c + 1, c + 1, 1);

    solution *= 4;

    cout << solution;
    return 0;
}

Milan Milanic - 5 years, 1 month ago
Jorge Fernández
Dec 22, 2015
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <cstdio>
#define MAX 5
int V[MAX][MAX];
int timer = 0,res=0;
void search(int i , int j){
    V[i][j] = 1;
    timer++;
    if(timer == MAX*MAX){
        res++;
        V[i][j] = 0;
        timer--;
        return;
    }
    for(int k = i-1 ; k <= i+1; k++){
        for(int l = j-1; l <= j+1; l++){
            if(k>=0 && l>=0 && k<MAX && l<MAX){
                if(V[k][l]==0)
                search(k,l);
            }
        } 
    }
    timer--;
    V[i][j]=0;
}
int main(){
    search(MAX/2,MAX/2);
    printf("%d\n",res);
}

What is the time taken?

Arulx Z - 5 years, 5 months ago

0 pending reports

×

Problem Loading...

Note Loading...

Set Loading...