Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.10.31;
Скачать: [xml.tar.bz2];

Вниз

Ход конём   Найти похожие ветки 

 
Ezhik   (2004-10-12 01:31) [0]

Уважаемые мастера, я в отчаянии. Пишу широкоизвестную прогу "Ход конём"(есть поле 10*10, и надо начиная с любой клетки порйти все 100 ходов побывав в каждой из них единажды). Алгоритм я понимаю и все казалось бы прозрачно (рекурсия), но что-то не то.:( Уже 2-а дня сижу за отладкой, надпись на клавише ф7 уже стерлась :). Через ф7, я наблюдаю, что все идеально, вродеб-то. Умоляю, посмотрите что в этом алгоритме не так... Спасибо за внимание

var
 Hodu: array of array of byte; //сюда пишем сделаные ходы
 Masiv: array[1..10,1..10] of Boolean; //Помечаем ечейку занетой
 VariantListXXX: array of byte; //
 VariantListYYY: array of byte; //списки возможных ходов
 Variantu: array[1..100,1..2] of byte; //пишем число вариантов ходов и под каким вариантом мы зашли в даный момент
 x,y,FreeCount,move_num: integer;

x:=0;
y:=0;

procedure Recors();
var
i,a,b: byte;
begin
 CheckHodCount(x,y); //проверяем число возможных ходов
 if FreeCount <> 0 then
 begin
   SetLength(Hodu,move_num+1,2);

   Masiv[x,y]:= True;
   Hodu[move_num,0]:= x;
   Hodu[move_num,1]:= y;
                                       
   Variantu[move_num+1,1]:= FreeCount;
   Inc(move_num);

   if move_num >= 100 then begin ShowMessage("100!!!"); draw; exit end;

   X:= VariantListXXX[Variantu[move_num,2]]; //первый раз мы берём из списка возможных ходов первый, при неудаче - 2-й, и т.д.
   Y:= VariantListYYY[Variantu[move_num,2]];

//    Form1.Caption:= Inttostr(move_num);
   Recors;
 end
 else
 begin
//  ShowMessage("000");
   repeat
     a:= Variantu[move_num,1];
     b:= Variantu[move_num,2];
     Masiv[(Hodu[move_num-1,0]),(Hodu[move_num-1,1])]:= False;
     if a <= b+1 then
     begin                      
       Variantu[move_num,1]:=0;
       Variantu[move_num,2]:=0;
     end;
     inc(move_num,-1);
   until a > b+1;

   x:= Hodu[move_num,0];
   y:= Hodu[move_num,1];
   Variantu[move_num+1,2]:= Variantu[move_num+1,2] + 1;
   Recors
 end;
end;

CheckHodCount(x,y); - это порцедура мне возврашает число вариантов ходовю


 
Defunct ©   (2004-10-12 02:01) [1]

можно уточнить: ходить можно только буквой Г?


 
Defunct ©   (2004-10-12 04:08) [2]

Если ходить можно только бугвой Г, то задача не имеет решения, невозможно покрыть даже 90 клеточек не говоря уж о всех 100:

unit Unitxx;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, Grids;

type
 TForm3 = class(TForm)
   SG: TStringGrid;
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
   function Move(Location:TPoint; Direction: Word;  History:Integer):Integer;
 end;

var
 Form3: TForm3;

implementation

{$R *.dfm}

const d_ur = $FE01;  // вверх на 2, вправо на 1
     d_ul = $FEFF;  // вверх на 2, влево на 1
     d_dr = $0201;  // вниз на 2,  вправо на 1
     d_dl = $02FF;  // вниз на 2,  влево на 1
     d_ru = $FF02;  // вверх на 1, вправо на 2
     d_lu = $FFFE;  // вверх на 1, влево на 2
     d_rd = $0102;  // вниз на 1,  вправо на 2
     d_ld = $01FE;  // вниз на 1,  влево на 2

     AllDirections : Array[1..8] of word =
     (d_ur, d_ul, d_dr, d_dl, d_ru, d_lu, d_rd, d_ld);

function InBound(var Location: TPoint; Direction: Word):Boolean;
Var XD, YD: Integer;
Begin
 XD := Byte(Direction And $FF);
 If XD> 127 Then XD := XD or $FFFFFF00;
 YD := Byte(Direction Shr 8);
 If YD> 127 Then YD := YD or $FFFFFF00;

 Location.X := Location.X + XD;
 Location.Y := Location.Y + YD;

 Result := (Location.X>=0) And (Location.Y>=0) And
           (Location.X<=9) And (Location.Y<=9);
End;

function TForm3.Move(Location:TPoint; Direction: Word;  History:Integer):Integer;
Var NH : Integer;
   I  : Integer;
Begin
 Result := History;
 If History>90 Then ShowMessage("Found");
{ выполнение движения }
 If InBound(Location, Direction) Then
 Begin
   Inc(History);
   If SG.Cells[Location.X, Location.Y] <> "P" Then
   Begin
     SG.Cells[Location.X, Location.Y] := "P";

     For I:=1 To 8 Do
     Begin
       NH := Move(Location, AllDirections[i], History);
       If NH > Result Then Result := NH;
     End;

     SG.Cells[Location.X, Location.Y] := "c";
     Button1.Caption := IntToStr( Result );
     Application.ProcessMessages;
   End

 End;

End;

procedure TForm3.Button1Click(Sender: TObject);
Var P:TPoint;
   S: Integer;
begin
 P.X := 5;
 P.Y := 5;
 S := 0;
 Move(P, d_rd, S);
end;

end.


Советую уточнить условие.


 
Defunct ©   (2004-10-12 04:30) [3]

[2]
хотя вру 94 клеточки покрыло, но ждать пришлось очень долго.
Возможно покроет и 100.. правда 8^100 вариантов, кто вам дал такое задание?


 
wnew ©   (2004-10-12 04:48) [4]

Стандартная задача по программированию. Смотри по этой ссылке http://www.gymnasium-odenthal.de/download/iflk_abi03_material/_pdfs/Klausur_LK_12_1_N.pdf четвёртую страницу в PDF-файле. Или скачай этот исходник http://www.salvator.net/salmat/info/springer.zip


 
wnew ©   (2004-10-12 04:53) [5]

Есть две таких задачи: по условию первой - конь должен стартовать из угла и побывать в каждой клетке один раз, а по условию второй - конь должен стартовать из угла, побывать в каждой клетке один раз и вернуться на клетку с которой стартовал.


 
wnew ©   (2004-10-12 04:55) [6]

Здесь решение для первой задачи на Си:
#include <iostream.h>
//#include <stdlib.h>

int xsize=0,ysize=0,*feld=0;

int springer(int x, int y, int pos)
{
if(feld[y*xsize+x]) return(0);

feld[y*xsize+x]=pos;
if(pos!=((xsize-4)*(ysize-4)))
 if(!springer(x+1,y-2,pos+1))
  if(!springer(x+2,y-1,pos+1))
   if(!springer(x+2,y+1,pos+1))
    if(!springer(x+1,y+2,pos+1))
     if(!springer(x-1,y+2,pos+1))
      if(!springer(x-2,y+1,pos+1))
       if(!springer(x-2,y-1,pos+1))
        if(!springer(x-1,y-2,pos+1))
         {
          feld[y*xsize+x]=0;
          return(0);
         }
return(1);
}

void main(void)
{
int x,y,z,xstart,ystart;

cout << "Breite des Feldes :";
cin >> xsize;
cout << "Hцhe des Feldes   :";
cin >> ysize;

xsize+=4;
ysize+=4;
if(feld=new(int[xsize*ysize]))
 {
   for(x=0;x<xsize;x++)
   for(y=0;y<ysize;y++)
    feld[y*xsize+x]=0;

  for(x=0;x<xsize;x++)
   {
    feld[x]=-1;
    feld[xsize+x]=-1;
    feld[((ysize-1)*xsize)+x]=-1;
    feld[((ysize-2)*xsize)+x]=-1;

   }

  for(y=0;y<ysize;y++)
   {
    feld[xsize*y]=-1;
    feld[xsize*y+1]=-1;
    feld[xsize*y+x-1]=-1;
    feld[xsize*y+x-2]=-1;

   }

  do
   {
    cout << "X-Position des Springers ( 1-" << xsize-4 << ") :";
    cin >>xstart;
   } while((xstart<1)||(xstart>(xsize-4)));

  do
   {
    cout << "Y-Position des Springers ( 1-" << ysize-4 << ") :";
    cin >> ystart;
   } while((ystart<1)||(ystart>(ysize-4)));

  cout << "\nBerechne Loesung fuer Feldgroesse (" << xsize-4 << "," << ysize-4 << ") ";
  cout << "und Startposition (" << xstart << "," << ystart << "...\n\n";

  if(!springer(xstart+1,ystart+1,1))
   cout << "Es gibt keine Lцsung!!\n\n";
  else
   {
    for(z=1;z<=(ysize-4)*(xsize-4);z++)
     for(y=2;y<ysize-2;y++)
       for(x=2;x<xsize-2;x++)
       if(feld[y*xsize+x]==z)
        cout << "(" << x-1 << "," << y-1 << ")\n";
   }

  delete(feld);
 }

}


 
wnew ©   (2004-10-12 04:56) [7]

А здесь решение для второй, тоже на Си:
#include <iostream.h>
//#include <stdlib.h>

int xsize=0,ysize=0,*feld=0;

int springer(int x, int y)
{
static int pos=1;

if((feld[y*xsize+x]==1)&&(pos==((xsize-4)*(ysize-4)+1)))
 return(1);

if(feld[y*xsize+x]) return(0);

feld[y*xsize+x]=pos;
pos++;
if(!springer(x+1,y-2))
 if(!springer(x+2,y-1))
  if(!springer(x+2,y+1))
   if(!springer(x+1,y+2))
    if(!springer(x-1,y+2))
     if(!springer(x-2,y+1))
      if(!springer(x-2,y-1))
       if(!springer(x-1,y-2))
        {
         feld[y*xsize+x]=0;
         pos--;
         return(0);
        }
return(1);
}

void main(void)
{
int x,y,z,xstart,ystart;

cout << "Breite des Feldes :";
cin >> xsize;
cout << "Hцhe des Feldes   :";
cin >> ysize;

xsize+=4;
ysize+=4;
if(feld=new(int[xsize*ysize]))
 {
   for(x=0;x<xsize;x++)
   for(y=0;y<ysize;y++)
    feld[y*xsize+x]=0;

  for(x=0;x<xsize;x++)
   {
    feld[x]=-1;
    feld[xsize+x]=-1;
    feld[((ysize-1)*xsize)+x]=-1;
    feld[((ysize-2)*xsize)+x]=-1;

   }

  for(y=0;y<ysize;y++)
   {
    feld[xsize*y]=-1;
    feld[xsize*y+1]=-1;
    feld[xsize*y+x-1]=-1;
    feld[xsize*y+x-2]=-1;

   }

  do
   {
    cout << "X-Position des Springers ( 1-" << xsize-4 << ") :";
    cin >>xstart;
   } while((xstart<1)||(xstart>(xsize-4)));

  do
   {
    cout << "Y-Position des Springers ( 1-" << ysize-4 << ") :";
    cin >> ystart;
   } while((ystart<1)||(ystart>(ysize-4)));

  cout << "\nBerechne Loesung fuer Feldgroesse (" << xsize-4 << "," << ysize-4 << ") ";
  cout << "und Startposition (" << xstart << "," << ystart << "...\n\n";

  if(!springer(xstart+1,ystart+1))
   cout << "Es gibt keine Lцsung!!\n\n";
  else
   {
    for(z=1;z<=(ysize-4)*(xsize-4);z++)
     for(y=2;y<ysize-2;y++)
       for(x=2;x<xsize-2;x++)
       if(feld[y*xsize+x]==z)
        cout << "(" << x-1 << "," << y-1 << ")\n";
   }

  delete(feld);
 }

}


 
Defunct ©   (2004-10-12 05:16) [8]

[5]
Не каждое поле можно обскакать, например, поля 2x2, 3x3, 4x4 обойти нельзя, неисключено что и 10x10 тоже.

[4]
Задача интересна для вас, поэтому и решать ее вам. Все что мог я и так уже сделал (на этом чисто академический интерес с моей стороны заканчивается, соответственно больше мне предложить нечего, по ссылкам лазить - увы нет желания). Простой рекурсивный обход [2] требует времени.


 
wnew ©   (2004-10-12 05:19) [9]

Defunct ©   (12.10.04 5:16) [8]
Да нет, это не мне она интересна, вопрос же не я задавал:) Я эту задачу решал 10 лет назад, когда на курсах по C++ учился :)


 
Defunct ©   (2004-10-12 05:27) [10]

wnew ©   (12.10.04 05:19) [9]

сорри, засиделся я уже не различаю ники, пора идти спать..

> Я эту задачу решал 10 лет назад, когда на курсах по C++ учился

для шахматного поля задача решается, а для 10x10 не знаю, [2] показывает - что нет.


 
wnew ©   (2004-10-12 05:59) [11]

Да, а я и не догадывался ввести поле больше, чем 8X8, сейчас попробовал - комп. уже пять минут перебирает по решению [6]. Хотя с полем 8X8 справляется мгновенно:) Пошёл курить:)


 
lehich ©   (2004-10-12 09:09) [12]

2Defunct как это для 10х10 не решается? еще 15 лет назад сидя на уроках от нечего делать рисовали такие поля и заполняли их целиком


 
Defunct ©   (2004-10-12 17:22) [13]

lehich ©   (12.10.04 09:09) [12]

приведите ваше решение.
лет 10-15 назад не было машин способных "на уроке решить такую задачу (пересмотреть 2^103 вариантов)".


 
Defunct ©   (2004-10-12 17:36) [14]

Defunct ©   (12.10.04 17:22) [13]

> (пересмотреть 2^103 вариантов)

ошибся 2^300 вариантов.


 
lehich ©   (2004-10-12 17:39) [15]

2Defunct вручную решали! вручную! может пари на что-нибудь что я в течении 3-4 дней вручную решу задачу (на бумажке) по ходу конем на поле 10х10 клеток? и оно будет ВСЁ заполнено? и пришлю отсканированный рисунок


 
Defunct ©   (2004-10-12 17:43) [16]

lehich ©   (12.10.04 17:39) [15]

вы что издеваетесь? или совсем не представляете сложности задачи?


 
Sha ©   (2004-10-12 18:29) [17]

Defunct ©   (12.10.04 17:43) [16]

Задача несложная.
Для малых досок - перебор, для больших - по частям.


 
Defunct ©   (2004-10-12 21:01) [18]

Sha ©   (12.10.04 18:29) [17]

Задача не решается.
Поле 5x5 покрыть нельзя, соотв нельзя покрыть 4x5x5


 
Sha ©   (2004-10-12 21:07) [19]

Defunct ©   (12.10.04 21:01) [18]

Надо уметь разрезать :)
У меня есть решение для досок сколь угодно большого размера.
В свое время писал для DelphiChallenge. Был такой сайт. Умер.


 
Defunct ©   (2004-10-12 21:11) [20]

> Sha

вопрос ведь не в размере доски, а в кратности.
8x8, 12x12, 16x16 и т.п. покрываются.

Как бы мы ни резали 10x10, получаются поля которые невозможно покрыть.


 
Ezhik   (2004-10-12 21:41) [21]

Точно утверждать не буду, но я видел эту игру уже написаную, тока там надо самому заполнять эти поля. Так вот там было поле именно 10*10. И в таблице рекордов были люди заполнившие все поле. Значит же можно какнибуть такое поле заполнить.


 
Sha ©   (2004-10-12 22:20) [22]

> Defunct ©   (12.10.04 21:11) [20]

> вопрос ведь не в размере доски, а в кратности.
> 8x8, 12x12, 16x16 и т.п. покрываются.
> Как бы мы ни резали 10x10, получаются поля которые невозможно покрыть.

Выбираются несколько фиксированных типоразмеров досок (не обязательно квадрадных, даже большинство не квадратных).
Затем для них отыскиваются решения кольцевого обхода.
Затем доказывается, что прямоугольные доски произвольного размера, большего m*n, можно разрезать на доски фиксированных типоразмеров с сохранением решения. Затем для ВСЕХ досок меньшего размера, для которых решение есть, отыскивается решение при помоши известных или оригинальных алгоритмов.
Все.


 
Defunct ©   (2004-10-12 22:37) [23]

> Sha

Просто скажи, 10x10 имеет решение или нет?
У меня получается, что нет. Может быть я заблуждаюсь.


 
Sha ©   (2004-10-12 22:39) [24]

Defunct ©   (12.10.04 22:37) [23]

Имеет


 
DDA ©   (2004-10-12 22:50) [25]


> Defunct ©   (12.10.04 22:37) [23]

на поле 10x10 решение есть,также как и на 9x9 8x8 7x7 6x6 5x5 6x5 7x5
всё это у меня на листочке который составил в шкеле га уроках

Нужен отсканеный рисунок? с этими полями


 
Sha ©   (2004-10-12 22:59) [26]

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


 
Sha ©   (2004-10-12 23:04) [27]

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


Это выход из программы перебора. Она позволяет отыскивать решения для досок размером примерно до 500*500 и даже чуть выше.

Кроме того, доску 10*10 можно склеить из двух 5*10.


 
DDA ©   (2004-10-12 23:14) [28]

ну вот всё и решилось


 
Defunct ©   (2004-10-12 23:28) [29]

> Sha, DDA

Thnx,

procedure TForm3.Button1Click(Sender: TObject);
Var P:TPoint;
  S: Integer;
begin
P.X := 2;
P.Y := 0;
S := 0;
Move(P, d_ld, S);
end;

С наглядным примером [26, 27] - перебор [2] нашел решение. Но у автора была оговорка:

> и надо начиная с любой клетки пройти все 100 ходов побывав в каждой из них единажды

IMHO одно отсюда можно точно вынести, высказывание неверно:
> Алгоритм я понимаю и все казалось бы прозрачно (рекурсия)

Простой рекурсией тут не обойтись.


 
Ezhik   (2004-10-12 23:42) [30]

>>Sha ©   (12.10.04 23:04) [27]
>>Это выход из программы перебора. Она позволяет отыскивать решения для досок размером примерно до 500*500 и даже чуть выше.

Я очень поршу, можна исходничек этой поги, я поанализирую все, что я нетак делаю.


 
Sha ©   (2004-10-13 01:17) [31]

Ezhik   (12.10.04 23:42) [30]

Прога исследовательская, там 90% кода тебе не потребуется.
В твоем случае поможет поиск в сети по слову Варнсдорф


 
wnew ©   (2004-10-13 01:44) [32]

Defunct ©   (12.10.04 21:01) [18]

> Поле 5x5 покрыть нельзя

Начиная с 4X5 все решаются. И код приведёный мной в [6] прекрасно это делает. Разумеется, начиная с 8X9 песня затягивается. Но 8X8 находит за пару секунд.


 
Defunct ©   (2004-10-13 02:21) [33]

> Sha

просьба обновить анкету ;>

> wnew ©   (13.10.04 01:44) [32]

да, уже вижу. только в 5x5 не находит краевых решений (когда точкой старта выбирается угол).


 
Defunct ©   (2004-10-13 02:37) [34]

Народ раз уж зашел вопрос о переборе, может кто подскажет, решается ли такое:


???  ?  ?
\|/  | /
[2] [3]-??
| /   /
[1]-[4]-[6]
  \   \
   [5]-?
    | \
    ?  ?

есть точки (на рисунке это 1-6 и ?) всего точек 17 каждая точка может быть связана с четырмя любыми другими точками. Можно ли так связать все эти точки, чтобы из любой точки в любую другую максимальный путь был не больше 2.


 
Ezhik   (2004-10-13 02:53) [35]

Уважаемые мастера, задачу я решил, но действительно только для поля 8*8, в этом же коде делаю поле 10*10 и все - бесконечная рекурсия, или может ответ и возможен, но нада долго ждать(я ждал около 5 мин, в то время как 8*8 нашло за 1 сек...).
Для поля 8*8 все легче чемк казалось:

procedure Recors;
var
i,nx,ny: integer;
begin
 Xodu[Nom,0]:= x;
 Xodu[Nom,1]:= y;
 pole[x,y]:= 1;
 inc(Nom);
 for i:= 0 to 7 do
 begin
   if Nom >= 100 then begin if flag = 0 then draw; exit; end;
   nx:= x + NextX[i];
   ny:= y + NextY[i];

   if (nx < 0) or (nx > 9) or (ny < 0) or (ny > 9) then continue;
   if pole[nx,ny] = 1 then continue;
   x:= nx;
   y:= ny;
   Recors;
 end;
 pole[Xodu[Nom-1,0],Xodu[Nom-1,1]]:= 0;
 x:= Xodu[nom-2,0];
 y:= Xodu[nom-2,1];
 Inc(Nom,-1);
end;


Так что всем огромное спасибо за расмотрение вопорса


 
lehich ©   (2004-10-13 09:23) [36]

2Defunct пари? чтож вы боитесь? вы же уверены в сложности задачи и ее нерешаемости!!!


 
Sha ©   (2004-10-13 09:29) [37]

> Defunct ©   (13.10.04 02:21) [33]
> просьба обновить анкету ;>

Обновил

> только в 5x5 не находит краевых решений (когда точкой старта выбирается угол).

Вот тебе решение 5*5 с началом(концом) в центре и концом(началом) в углу

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


 
Sha ©   (2004-10-13 09:35) [38]

> Ezhik   (13.10.04 02:53) [35]
> делаю поле 10*10 и все - бесконечная рекурсия,

Правило Варнсдорфа нашел?

> lehich ©   (13.10.04 09:23) [36]
> 2Defunct пари? чтож вы боитесь? вы же уверены в сложности задачи и ее нерешаемости!!!

Давай пари со мной для доски 1000*1000 - кто быстрее?


 
lehich ©   (2004-10-13 11:00) [39]

2Sha употею, яж не про компьютерный алгоритм говорю а про то что на бумаге это сделаю, тем более что в моем решении 10х10 сотая цифра почти в самом центре оказывается, следовательно 1000*1000 не разбить по десяткам...


 
Sha ©   (2004-10-13 11:25) [40]

> lehich ©   (13.10.04 11:00) [39]
> в моем решении 10х10 сотая цифра почти в самом центре
> оказывается, следовательно 1000*1000 не разбить по десяткам...

Как правило, для разбиения достаточно иметь замкнутый маршрут.
Если у тебя такой, то дело в шляпе.



Страницы: 1 2 вся ветка

Форум: "Основная";
Текущий архив: 2004.10.31;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.57 MB
Время: 0.035 c
14-1097569206
Григорьев Антон
2004-10-12 12:20
2004.10.31
Есть шанс заработать $200 - нужны связи в МГУ


3-1096970244
funtik123
2004-10-05 13:57
2004.10.31
Количсетво записей


3-1096696321
kaginava
2004-10-02 09:52
2004.10.31
Ошибка при выполнени запроса на вставку записей


4-1096116790
Nils
2004-09-25 16:53
2004.10.31
Нужен пример работы с TMemIni?


6-1093178110
Alena
2004-08-22 16:35
2004.10.31
Сокеты, Принятые файлы некорректны относительно исходных ?!





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский