рдЬрд╛рд╡рд╛ рдореЗрдВ Google AI рдЪреИрд▓реЗрдВрдЬ рдкрд░ рд╢реБрд░реВ рдХрд░реЗрдВ

рдореБрдЭреЗ рдЖрднрд╛рд╕реА рджреБрдирд┐рдпрд╛ рдореЗрдВ рд╡рд╕реНрддреБрдУрдВ рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреА рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреЗ рд╡рд┐рд╖рдп рдореЗрдВ рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ рджрд┐рд▓рдЪрд╕реНрдкреА рд╣реИред рд▓реЗрдХрд┐рди рдЗрд╕ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдЬреНрдЮрд╛рди рд╡рд╛рдВрдЫрд┐рдд рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдХреБрдЫ рдЫреЛрдбрд╝ рджреЗрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдирд┐рд╡реЗрд╢ рдХреЗ рд▓рд┐рдП рдПрдХ рдЫреЛрдЯреА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреА рддрд▓рд╛рд╢ рд╢реБрд░реВ рдХреАред рдирддреАрдЬрддрди, рдореИрдВрдиреЗ рдкрд╛рдпрд╛, рдореИрдВ рдШреЛрд╖рдгрд╛ рдХреЗ рд▓рд┐рдП Google рдФрд░ ideas4ru рдХрд╛ рдЖрднрд╛рд░реА рд╣реВрдВред

рднрд╛рд╖рд╛ рдФрд░ рд╕реНрдЯрд╛рд░реНрдЯрд░ рдкреИрдХ


рдкрд░рд┐рдпреЛрдЬрдирд╛ рдЖрдпреЛрдЬрдХреЛрдВ рдиреЗ рдмреЙрдЯ рдХреЗ рд╡рд┐рдХрд╛рд╕ рдХреЗ рд▓рд┐рдП рдПрдХ рджрд░реНрдЬрди рд╕реЗ рдЕрдзрд┐рдХ рднрд╛рд╖рд╛рдУрдВ рдХреА рдкреЗрд╢рдХрд╢ рдХреА, рдореИрдВрдиреЗ рдЬрд╛рд╡рд╛ рдХреЛ рдЪреБрдирд╛ред рдореИрдВ рдпрд╣ рдирд╣реАрдВ рдХрд╣ рд╕рдХрддрд╛ рдХрд┐ рдореИрдВ рдЬрд╛рд╡рд╛ рдХреЛ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдЬрд╛рдирддрд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рд╣реБрдЖ (C ++ рдХреНрд░рд┐рдпрд╛ рд╣реИ, PHP рд╢рд╛рдВрдд рдирд╣реАрдВ рд╣реИ, C # рдмрд╣реБрдд рдирд░рдо рд╣реИ, V8 рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдмрд╣реБрдд рд▓рдВрдмрд╛ рд╣реИ, Lua рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреА рддрд░рд╣ рдирд╣реАрдВ рд╣реИ, рдкрд╛рд╕реНрдХрд▓ рдмрд╣реБрдд рд╕реНрдХреВрд▓ рдХреА рддрд░рд╣ рд╣реИ, рдкрд╛рдпрдерди - рдереЛрдбрд╝рд╛ рдбрд░рд╛рд╡рдирд╛)ред рдЖрдк рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рд╡реЗрдмрд╕рд╛рдЗрдЯ рд╕реЗ рдпрд╛ рдЗрд╕ рд╕реАрдзреЗ рд▓рд┐рдВрдХ рд╕реЗ рдЬрд╛рд╡рд╛ рдХреЗ рд▓рд┐рдП рд╕реНрдЯрд╛рд░реНрдЯрд░ рдкреИрдХ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдореИрдВрдиреЗ рдХреИрд╕реЗ рд╢реБрд░реБрдЖрдд рдХреА


рд╢рд╛рдпрдж рдореИрдВ рдПрдХ рдмреНрд░реЗрдХ рд╣реВрдВ рдпрд╛ рдореИрдВ рдЬрд╛рд╡рд╛ рдХреЛ рдирд╣реАрдВ рдЬрд╛рдирддрд╛, рд▓реЗрдХрд┐рди рд╢реБрд░реБрдЖрдд рдореЗрдВ рдореБрдЭреЗ рд╕рдордЭ рдирд╣реАрдВ рдЖрдпрд╛ рдХрд┐ рдХреЛрдб рдореБрдЦреНрдп рд╡рд░реНрдЧ рдореЗрдВ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ:
public void doTurn() { Ants ants = getAnts(); for (Tile myAnt : ants.getMyAnts()) { for (Aim direction : Aim.values()) { if (ants.getIlk(myAnt, direction).isPassable()) { ants.issueOrder(myAnt, direction); break; } } } } 

рд╕реНрдЯрд╛рд░реНрдЯрд░ рдкреИрдХ рдХреЗ рдкреВрд░реЗ рдХреЛрдб рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдореЗрдВ рдореБрдЭреЗ рд▓рдЧрднрдЧ рдПрдХ рдШрдВрдЯреЗ рдХрд╛ рд╕рдордп рд▓рдЧрд╛ (рдореИрдВ рд╕рднреА рдХреЛ рдРрд╕рд╛ рд╣реА рдХрд░рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВ, рдФрд░ рдЬрд▓реНрджреА рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдкрд░ рд▓реЗрдЦ рдирд╣реАрдВ рдкрдврд╝рддрд╛ рд╣реВрдВ)ред рдирддреАрдЬрддрди, рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рдкрд╣рд▓рд╛ рдЪрдХреНрд░ рдЕрдиреБрдХреВрд▓ рдЪреАрдВрдЯрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдХреЛрд╢рд┐рдХрд╛рдУрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЪрд▓рддрд╛ рд╣реИ, рдФрд░ рджреВрд╕рд░рд╛ рдЪреАрдВрдЯреА рдХреЛ рдЪрд╛рд░ рджрд┐рд╢рд╛рдУрдВ (рдПрдЖрдИрдПрдо рдХреЗ рдЕрдиреБрдХреНрд░рдорд┐рдХ рдЧрдгрди) рдореЗрдВ рд╕реЗ рдПрдХ рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддрд╛ рд╣реИред

рдкрд╣рд▓реЗ рдЪрд░рдг рдореЗрдВ, рдореИрдВ рдПрдХ рдмрд╣реБрдд рдЕрдЪреНрдЫреЗ рдирд┐рдпрдо рдХреЗ рд╕рд╛рде рдЖрдпрд╛ - рдЬрдм рдЖрдк рджреЛ рдЪреАрдВрдЯрд┐рдпреЛрдВ рдХреЛ рдПрдХ рд╣реА рд╕реЗрд▓ рдореЗрдВ рд▓реЗ рдЬрд╛рддреЗ рд╣реИрдВ, рддреЛ рд╡реЗ рджреЛрдиреЛрдВ рдорд░ рдЬрд╛рддреЗ рд╣реИрдВред рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЪреАрдВрдЯрд┐рдпреЛрдВ рдХреЗ рд╡рд░реНрдЧ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрд╢реЛрдзрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред

рдореИрдВрдиреЗ рдХрдмреНрдЬреЗ рд╡рд╛рд▓реА рдХреЛрд╢рд┐рдХрд╛рдУрдВ рдХреА рдПрдХ рд╕реВрдЪреА рдЬреЛрдбрд╝реА:
 public class Ants { private final Set<Tile> employed = new HashSet<Tile>(); //... 

рдЕрдиреБрдХреВрд▓ рдЪреАрдВрдЯрд┐рдпреЛрдВ рдХреЗ рдкрджреЛрдВ рдХреА рд╕рдлрд╛рдИ рдХрд░рддреЗ рд╕рдордп, рдореИрдВрдиреЗ рдХрдмреНрдЬреЗ рд╡рд╛рд▓реЗ рд╕реНрдерд╛рдиреЛрдВ рдХреА рд╕рдлрд╛рдИ рдХреЛ рдЬреЛрдбрд╝рд╛:
 public void clearMyAnts() { employed.clear(); //... 

рдФрд░ рдЕрдВрдд рдореЗрдВ, рдореИрдВ рд▓рдЧрднрдЧ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рдорд╕реНрдпрд╛ рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрддрд╛ рд╣реВрдВред
 public boolean issueOrder(Tile myAnt, Aim direction) { Order order = new Order(myAnt, direction); Tile newPosition = getTile(myAnt, direction); if(getIlk(myAnt, direction).isPassable() && !employed.contains(newPosition)) { orders.add(order); //     ,     employed.add(newPosition); System.out.println(order); System.out.flush(); return true; } return false; } 

рдореБрдЦреНрдп рд╡рд░реНрдЧ рдореЗрдВ рдХреЛрдб рдереЛрдбрд╝рд╛ рдХрдо рд╣реЛ рдЬрд╛рдПрдЧрд╛:
 public void doTurn() { Ants ants = getAnts(); for (Tile myAnt : ants.getMyAnts()) { for (Aim direction : Aim.values()) { if (ants.issueOrder(myAnt, direction)) break; } } } 

рдереЛрдбрд╝рд╛ рд╡реНрдпрдХреНрддрд┐рддреНрд╡


рд╣рдо рдереЛрдбрд╝рд╛ рд╕рдкрдирд╛ рджреЗрдЦрддреЗ рд╣реИрдВ рдФрд░ рдХрд▓реНрдкрдирд╛ рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рднрд╡рд┐рд╖реНрдп рдореЗрдВ, рд╣рдорд╛рд░рд╛ рдкреНрд░рддреНрдпреЗрдХ рдЪреАрдВрдЯреА рдПрдХ рд╡реНрдпрдХреНрддрд┐ рдФрд░ рдХреБрдЫ рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рдорд╛рд▓рд┐рдХ рд╣реЛрдЧрд╛ред рдЗрд╕ рддрд░рд╣ рдХреЗ рд╡рд┐рдЪрд╛рд░реЛрдВ рдХреА рдирд┐рд░рдВрддрд░рддрд╛ рдЪреАрдВрдЯреА рд╡рд░реНрдЧ рд╣реЛрдЧреА:
 public class Ant { protected Ants ants; protected Tile tile; protected int waitStep = 0; public Ant(Ants ants, Tile tile) { this.tile = tile; this.ants = ants; } public Tile getTile() { return tile; } //      (   !) public boolean issueOrder(Aim direction) { if(ants.issueOrder(tile, direction)) { tile = ants.getTile(tile, direction); return true; } else return false; } //    ,      public boolean waiting() { return waitStep-- > 0; } //  public void think() { for(Aim direction : Aim.values()) { if(ants.issueOrder(direction)) break; } } } 

рдЕрдЧрд▓рд╛, рдЖрдкрдХреЛ рдЗрд╕ рд╡рд░реНрдЧ рдХреЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рдлреА рдХреБрдЫ рдорд╛рдореВрд▓реА рдмрджрд▓рд╛рд╡ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрд╣ рдмрд╣реБрдд рдЙрдмрд╛рдК рдФрд░ рдиреАрд░рд╕ рд╣реИ, рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА ... рдЪрд▓реЛ MyBot рд╡рд┐рдзрд┐ рд╕реЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ:
  public void doTurn() { getAnts().think(); //     } 

рдЪреАрдВрдЯрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рд▓рд╛рдкрддрд╛ рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝реЗрдВ рдФрд░ myAnts рд╕реВрдЪреА рдХреА рд╕рд╛рдордЧреНрд░реА рдкреНрд░рдХрд╛рд░ рдмрджрд▓реЗрдВ:
  private final Set<Ant> myAnts = new HashSet<Ant>(); //... public void think() { for(Ant ant : myAnts) { if(ant.waiting()) // ,    continue; ant.think(); //    } } 

рдЕрдм рдЖрдкрдХреЛ рдЪреАрдВрдЯреА рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдФрд░ рд╣рдЯрд╛рдиреЗ рдХреА рд╕рд╛рд╡рдзрд╛рдиреАрдкреВрд░реНрд╡рдХ рдирд┐рдЧрд░рд╛рдиреА рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЬрд┐рди рд▓реЛрдЧреЛрдВ рдХреЛ рдХреЛрдб рдХрд╛ рдкрддрд╛ рдЪрд▓рд╛, рдЙрдиреНрд╣реЛрдВрдиреЗ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рдЪреАрдВрдЯрд┐рдпреЛрдВ рдХреА рдХрдХреНрд╖рд╛ рдореЗрдВ рдЕрджреНрдпрддрди рдкрджреНрдзрддрд┐ рдХреЛ рджреЗрдЦрд╛, рдЬрд┐рд╕рдореЗрдВ рдЖрдк рдПрдХ рджреЛрд╕реНрддрд╛рдирд╛ рдЪреАрдВрдЯреА рдФрд░ рдореМрдд рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреЛ рдЯреНрд░реИрдХ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рд▓реЗрдХрд┐рди рдореГрддреНрдпреБ рд╕рднреА рдЪреАрдВрдЯрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЖрдо рд╣реИ)ред рдЗрд╕ рдЖрдо рдореМрдд рдХреЛ рдХрдИ рддрд░реАрдХреЛрдВ рд╕реЗ рдареАрдХ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ... рдореИрдВрдиреЗ рджреЛ рддрд░рд╣ рдХреА рдореМрдд рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред

рдЪрд▓рд┐рдП рдПрд▓реНрдХ рдПрдиреНрдпреВрдорд░реЗрд╢рди рдХреНрд▓рд╛рд╕ рдореЗрдВ рдмрджрд▓рд╛рд╡ рдХрд░рддреЗ рд╣реИрдВ:
 public enum Ilk { MY_DEAD, ENEMY_DEAD, //  DEAD, //... public boolean isUnoccupied() { return this == LAND || this == MY_DEAD || this == ENEMY_DEAD; } } 

рдмреАрдУрдЯреА рдХрдХреНрд╖рд╛ рдореЗрдВ рд╣рдЯрд╛рдиреЗ рдХреА рд╡рд┐рдзрд┐ рдХреЛ рд╕рдорд╛рдпреЛрдЬрд┐рдд рдХрд░реЗрдВ:
  public void removeAnt(int row, int col, int owner) { ants.update(owner > 0 ? Ilk.ENEMY_DEAD : Ilk.MY_DEAD, new Tile(row, col)); } 

рдЕрдм рдЪреАрдВрдЯрд┐рдпреЛрдВ рдХреЗ "рдЕрд╡рд▓реЛрдХрди" рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдм рдХреБрдЫ рддреИрдпрд╛рд░ рд╣реИ, рдПрдЯреАрдПрд╕ рд╡рд░реНрдЧ рдореЗрдВ рдЕрдкрдбреЗрдЯ рд╡рд┐рдзрд┐ рдХреЛ рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ:
  public void update(Ilk ilk, Tile tile) { map[tile.getRow()][tile.getCol()] = ilk; switch (ilk) { case FOOD: foodTiles.add(tile); break; case MY_ANT: myAnts.add(new Ant(this, tile)); break; case ENEMY_ANT: enemyAnts.add(tile); break; case MY_DEAD: myAnts.remove(new Ant(this, tile)); } } 

рдлреВрдб рдПрдВрдб рдмреБрд▓рд╢рд┐рдЯ - рдЕ рд▓рд┐рдЯрд┐рд▓ рдмреНрд░реЗрди


рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╕рднреА рдЪрд░рдгреЛрдВ рдХреЛ рдЪрд┐рддреНрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдорддрд▓рдм рдирд╣реАрдВ рд╣реИ, рдмрд╕ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдХреЛрдб рджреЗрдВред рдЪреАрдВрдЯреА рд╡рд░реНрдЧ рдХреЛрдб рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХрд░рдХреЗ рдЪреАрдВрдЯреА рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдмрджрд▓реЗрдВ:
 public class Ant { //... public void think() { if(!doFood()) //   , doRandom(); //   } protected boolean doRandom() { while(!issueOrder(Aim.getRandom())); //     return true; } protected boolean doFood() { return moveToObject(ants.getFoodTiles()); } //        protected boolean moveToObject(Set<Tile> objects) { Tile object = findObject(objects); if(object != null) { issueOrder(ants.getDirections(object, tile).get(0)); return true; } return false; } //       protected Tile findObject(Set<Tile> objects) { Tile find = null; int distance = 0; int minDistance = ants.MAX_MAP_SIZE; for(Tile aspt : objects) { distance = ants.getDistance(aspt, tile); if(minDistance > distance) { find = aspt; minDistance = distance; } } return find; } } 

рдЗрд╕ рдХреЛрдб рдХреЛ рд▓рд┐рдЦрддреЗ рд╕рдордп, рдореИрдВрдиреЗ Aim рдЧрдгрди рд╡рд░реНрдЧ рдореЗрдВ рдПрдХ рд╕реНрдерд┐рд░ рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝реА рдЬреЛ рдПрдХ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рджрд┐рд╢рд╛ рджреЗрддрд╛ рд╣реИ:
 public enum Aim { private static final Random random = new Random(); //... public static Aim getRandom() { return values()[random.nextInt(values().length)]; } } 

рдЧрд╝рд▓рддреА


рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рдХреЛрдб рдореЗрдВ рдХрд╣реАрдВ рдЧрдбрд╝рдмрдбрд╝ рдХрд░ рджреА рд╣реЛ, рд▓реЗрдХрд┐рди рдпрд╣ Ants рд╡рд░реНрдЧ рдХреА getDirections рд╡рд┐рдзрд┐ рдореЗрдВ рдПрдХ рддреНрд░реБрдЯрд┐ рд╣реИред
  public List<Aim> getDirections(Tile t1, Tile t2) { List<Aim> directions = new ArrayList<Aim>(); if (t1.getRow() < t2.getRow()) { if (t2.getRow() - t1.getRow() >= rows / 2) { directions.add(Aim.SOUTH); // Aim.NORTH } else { directions.add(Aim.NORTH); // Aim.SOUTH } } else if (t1.getRow() > t2.getRow()) { if (t1.getRow() - t2.getRow() >= rows / 2) { directions.add(Aim.NORTH); //   ... } else { directions.add(Aim.SOUTH); //...    (  ) } } if (t1.getCol() < t2.getCol()) { if (t2.getCol() - t1.getCol() >= cols / 2) { directions.add(Aim.EAST); //   ... } else { directions.add(Aim.WEST); //...    (  ) } } else if (t1.getCol() > t2.getCol()) { if (t1.getCol() - t2.getCol() >= cols / 2) { directions.add(Aim.WEST); //   ... } else { directions.add(Aim.EAST); //...    (  ) } } return directions; } 

рд▓рдВрдмреЗ рд╕рдордп рддрдХ рдореИрдВ рд╕рдордЭ рдирд╣реАрдВ рдкрд╛рдпрд╛ рдХрд┐ рдХреНрдпрд╛ рдЧрд▓рдд рдерд╛ ... рдЪреАрдВрдЯреА рдХрд┐рд╕реА рднреА рддрд░рд╣ рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рднреЛрдЬрди рдХреА рддрд▓рд╛рд╢ рдХрд░ рд░рд╣реА рдереА ... рдпрд╣ рдорд╛рдорд▓рд╛ рдирд┐рдХрд▓рд╛ред

рдирд┐рд╖реНрдХрд░реНрд╖


рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдЗрд╕ рддрд░рд╣ рдХреЗ рдЦреЗрд▓ рдХреЗ рд▓рд┐рдП рдЖрддреНрдо-рд╢рд┐рдХреНрд╖рд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рд╢рд╛рдпрдж рд░рдгрдиреАрддрд┐рдпреЛрдВ рдХрд╛ рдПрдХ рд╕реЗрдЯ рд╣реЛрдирд╛ рдмреЗрд╣рддрд░ рд╣реЛрдЧрд╛ + рдПрдХ рдЫреЛрдЯрд╛ рд╕рдорд╛рдпреЛрдЬрди (рд╕рдореВрд╣ рдЖрдХрд╛рд░, рд╡рд░реНрддрдорд╛рди рд░рдгрдиреАрддрд┐ ... рдореИрдВ рдЕрднреА рдЕрдиреНрдп рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рдЦреБрд▓рд╛рд╕рд╛ рдирд╣реАрдВ рдХрд░реВрдВрдЧрд╛)ред рдореБрдЭреЗ рдЕрднреА рддрдХ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЗрд╕ рддрд░рд╣ рдХреА рдЪреАрдВрдЯрд┐рдпрд╛рдВ рдХрд┐рддрдиреА рдкреНрд░рднрд╛рд╡реА рд╣реЛрдВрдЧреА, рд▓реЗрдХрд┐рди рдореИрдВ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рджреВрд╕рд░реЗ рд▓реЗрдЦ рдореЗрдВ рд▓рд┐рдЦрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛ред

рдкреБрдирд╢реНрдЪ рд╕реНрд╡-рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдПрдХ рдмрдВрдж рдкреНрд░рдгрд╛рд▓реА рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдирдП рдХрд╛рд░рдХ рджрд┐рдЦрд╛рдИ рдирд╣реАрдВ рджреЗрддреЗ рд╣реИрдВред рдЗрд╕ рдмреАрдЪ, рдЖрддреНрдо-рд╕реАрдЦрдиреЗ рд╡рд╛рд▓рд╛ рджреБрд╢реНрдорди рд╕реАрдЦ рд░рд╣рд╛ рд╣реИ, рдЖрдк рджреБрд╢реНрдорди рдкрд╣рд╛рдбрд╝рд┐рдпреЛрдВ рдкрд░ рдХрдмреНрдЬрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ :)

Source: https://habr.com/ru/post/In130722/


All Articles