Головоломка Fiver

Тема в разделе "WASM.A&O", создана пользователем Stiver, 10 май 2007.

  1. Stiver

    Stiver Партизан дзена

    Публикаций:
    0
    Регистрация:
    18 дек 2004
    Сообщения:
    812
    Адрес:
    Germany
    На cracklab'e был задан достаточно интересный вопрос, который я переместил сюда, так как там ему ответов похоже не светит. Речь идет об игрушке Fiver) (по ссылке Java Applet) и нужно написать программку, находящую минимальное(относительно количества нажатых кнопок) решение для заданного размера поля. Находящую естественно как можно более эффективно.

    Можно рассмотреть отдельно нахождение произвольного решения и нахождение минимального решения, но такое ощущение, что решение может быть только одно (с точностью до симметрии конечно) По крайней мере для n<=10 это точно так.

    У меня пока получился топорный метод со скоростью O(2^n) для поля n x n. Не знаю, есть ли что-то более быстрое. По идее эта задача тоже относится к виду "расставь что-то на доске" (как Задача о восьми Ферзях и Путешествие Коня), а значит вполне может существовать линейный алгоритм.
     
  2. Stiver

    Stiver Партизан дзена

    Публикаций:
    0
    Регистрация:
    18 дек 2004
    Сообщения:
    812
    Адрес:
    Germany
    Вот решение перебором. Полезной работы всего пара строчек в main() , остальное в основном вывод на экран.

    Код (Text):
    1. #include <stdio.h>
    2.  
    3. int countbits(int v) {
    4.     int c = 0;
    5.     for(;v;c++) {
    6.         v  &= v-1;
    7.     }
    8.     return c;
    9. }
    10.  
    11. void printresult(int count, int a, int n) {
    12.     int i, j, aold = 0, temp;
    13.     int mask = (1<<n) - 1;
    14.  
    15.     printf("Solutions: %d\n\n", count);
    16.     if(count==0)return;
    17.  
    18.     for(j=n-1;j>=0;j--) {
    19.         temp = a;
    20.         for(i=0; i<n; i++)
    21.         {
    22.             if(temp & 1)
    23.             {
    24.                 printf("X");
    25.             } else {
    26.                 printf("O");
    27.             }
    28.             temp = temp>>1;
    29.         }
    30.         printf("\n");
    31.  
    32.         temp = a;
    33.         a = (~(a ^ (a<<1) ^ (a>>1) ^ aold)) & mask;
    34.         aold = temp;
    35.     }
    36. }
    37.  
    38. void main() {
    39.     int i,j,a,aold,temp,minsolution,n;
    40.     int mask, mincount, solcount = 0, count;
    41.  
    42.     printf("enter field dimension n: ");
    43.     scanf("%d",&n);
    44.  
    45.     mask = (1<<n) - 1;
    46.     mincount = n*n;
    47.  
    48.     for(i=mask;i>=0;i--) {
    49.         aold = 0;
    50.         a = i;
    51.        
    52.         count = 0;
    53.         for(j=n-1;j>=0;j--) {
    54.             count += countbits(a);
    55.             temp = a;
    56.             a = (~(a ^ (a<<1) ^ (a>>1) ^ aold)) & mask;
    57.             aold = temp;
    58.         }
    59.  
    60.         if(!a) {
    61.             if(count<mincount) {
    62.                 mincount = count;
    63.                 minsolution = i;
    64.                 solcount++;
    65.             }
    66.         }
    67.     }
    68.     printresult(solcount, minsolution, n);
    69.     getch();
    70. }
     
  3. AVE5

    AVE5 New Member

    Публикаций:
    0
    Регистрация:
    10 мар 2007
    Сообщения:
    17
    Stiver Нифига себе. Спасибо.
     
  4. halyavin

    halyavin New Member

    Публикаций:
    0
    Регистрация:
    13 май 2005
    Сообщения:
    252
    Адрес:
    Russia
    Нахождение всех образующих решений требует O(n^3) действий и легко выполняется на бумаге даже при n порядка 10. Выбор оптимального - O(2^m), где m - размерность пространства решений. Ботайте линейную алгебру.
     
  5. AVE5

    AVE5 New Member

    Публикаций:
    0
    Регистрация:
    10 мар 2007
    Сообщения:
    17
    Stiver Объясни алгоритм перебора на пальцах :rolleyes:
    Си не знаю, охота написать на паскале/делфи
     
  6. Lord_De_Seis

    Lord_De_Seis New Member

    Публикаций:
    0
    Регистрация:
    18 авг 2005
    Сообщения:
    55
    halyavin - прав..
    Перебор это как то по-детски.
    Задачу можно решить простым методом гауса.
     
  7. Stiver

    Stiver Партизан дзена

    Публикаций:
    0
    Регистрация:
    18 дек 2004
    Сообщения:
    812
    Адрес:
    Germany
    Действительно, задачу можно записать в виде системы линейных уравнений, об этом я не подумал. Получим матрицу размером n^2 x n^2, где нормальный Гаус даст скорость O(n^6). (хотя для Z_{2} должны быть и немного более быстрые методы) Выбирать из решений оптимальное видимо не придется, так как оно будет одно с точностью до симетрии. Интересно посчитать, начиная с какого n имеет смысл решать таким образом.
     
  8. AVE5

    AVE5 New Member

    Публикаций:
    0
    Регистрация:
    10 мар 2007
    Сообщения:
    17
    Ну допустим имею поле 3х3 как будет выглядеть матрица?
     
  9. halyavin

    halyavin New Member

    Публикаций:
    0
    Регистрация:
    13 май 2005
    Сообщения:
    252
    Адрес:
    Russia
    Гаусс здесь будет n x n - поскольку по первой строчке все определяется. Соотвественно для всех образующих в первой строчке смотрим невязки в последней и получаем матрицу n x n. Решая систему получаем все первые строчки и соотвественно все матрицы.
     
  10. Stiver

    Stiver Партизан дзена

    Публикаций:
    0
    Регистрация:
    18 дек 2004
    Сообщения:
    812
    Адрес:
    Germany
    halyavin
    Не уверен, что понимаю мысль.. Можно на примере пояснить, хотя бы 3х3?
     
  11. RElf

    RElf New Member

    Публикаций:
    0
    Регистрация:
    25 дек 2004
    Сообщения:
    159
    Вот еще похожая онлайн-головоломка: http://www.var.ru/bz/js/floor.html

    А еще в старой игрухе "Братья-Пилоты" была подобная, и в "Седьмом Госте" тоже.
    В RU.ALGORITHMS решение разбирали: http://groups.google.com/group/fido7.ru.algorithms/msg/290936fc164b79cf
     
  12. Stiver

    Stiver Партизан дзена

    Публикаций:
    0
    Регистрация:
    18 дек 2004
    Сообщения:
    812
    Адрес:
    Germany
    RElf
    Вот еще похожая онлайн-головоломка: http://www.var.ru/bz/js/floor.html

    Не похожая, а именно она и есть :)

    В RU.ALGORITHMS решение разбирали: http://groups.google.com/group/fido7.ru.algorithms/msg/290936fc164b79cf

    Не знаю, как там была сформулирована задача, но решение разбирается явно от немного другой головоломки. А именно: при нажатие клетки переключаются весь столбец и вся строка, тогда как в Fiver только по одной клетке на север, юг, запад и восток. Тот вариант по-моему менее интересен, так как для любого четного n будет A=A^{-1} и при начальном векторе (0,0,...,0) и конечном (1,1,....,1) решение будет всегда одно - тривиальное (1,1,....,1).

    А так похоже действительно остается только решать систему размерностью n^2. Если конечно halyavin не объяснит его идею.

    AVE5
    Ну допустим имею поле 3х3 как будет выглядеть матрица?

    До n равного как минимум 13-15 перебор будет быстрее.