2014年7月19日土曜日

SECCON 2014 オンライン予選 writeup - プログラミング300 あみだ

手動で2時間くらいかけて150問解いたところで挫折、 プログラムで解こうとコーディングを始めて1時間半で終了。 最初から組めや>自分

手順は以下の通り。

*が開始座標
*の[上下右左]が[||--]ならそれが進行方向、1つ進む
while 現在位置が[||--]
    現在位置の進行方向横が[-|]なら[|-]になるまで横にスライド
    1つ進行方向に進む
現在位置の文字出力


import java.io.*;
import java.util.*;

public class T {
 public static final int NO_DIRECTION = 0;
 public static final int TO_DOWN = 1;
 public static final int TO_UP = 2;
 public static final int TO_RIGHT = 3;
 public static final int TO_LEFT = 4;

 public static void main(String args[]) {
  InputStream is = null;
  OutputStream os = null;
  try {
   Process p = Runtime.getRuntime().exec("./amida");
   is = p.getInputStream();
   os = p.getOutputStream();
  } catch (Exception ex) {
   ex.printStackTrace();
  }
  try {
   new T().go(is, os);
  } catch (Exception ex) {
   ex.printStackTrace();
  }
 }

 public void go(InputStream is, OutputStream os) throws Exception {
  int no = 1;
  while (true) {
   int c;
   int width = 0;
   int height = 0;
   while ((c = is.read()) != '\n') {
    if (c == -1)
     System.exit(1);
    System.out.print((char)c);
   }
   System.out.println();

   StringBuffer sb = new StringBuffer();
   String line = null;
   ArrayList list = new ArrayList();
   while ((c = is.read()) != '?') {
    if (c == -1)
     System.exit(1);
    // System.out.println("2:" + c);
    if (c == '\n') {
     line = sb.toString();
     if (line.length() > 0) {
      width = line.length();
      list.add(line);
      sb = new StringBuffer();
     }
    } else {
     sb.append((char)c);
    }
   }

   is.read();

   height = list.size();
   char amida[][] = new char[height][width];
   int startX = 0;
   int startY = 0;

   for (int i = 0; i < list.size(); i++) {
    line = list.get(i);
    System.out.println(line);

    for (int j = 0; j < line.length(); j++) {
     amida[i][j] = line.charAt(j);
     if (amida[i][j] == '*') {
      startY = i;
      startX = j;
     }
    }
   }
   //System.out.println(startY + ":" + startX);

   int direction = NO_DIRECTION;
   int y = startY;
   int x = startX;
   if (startY == 0 && amida[1][startX] == '|') {
    direction = TO_DOWN;
    y++;
   } else if (startY == height - 1 &&
    amida[height - 2][startX] == '|') {
    direction = TO_UP;
    y--;
   } else if (startX == 0 && amida[startY][1] == '-') {
    direction = TO_RIGHT;
    x++;
   } else {
    direction = TO_LEFT;
    x--;
   }

   //System.out.println("direction:" + direction);
   //System.out.println(y + ":" + x);

   while (amida[y][x] == '|' || amida[y][x] == '-') {
    // System.out.println(y + ":" + x + ":" + amida[y][x]);
    if (direction == TO_DOWN || direction == TO_UP) {
     if (x > 0 && amida[y][x - 1] == '-') {
      x--;
      while (amida[y][x] != '|')
       x--;
      if (direction == TO_DOWN)
       y++;
      else
       y--;
     } else if (x < width - 1 && amida[y][x + 1] == '-') {
      x++;
      while (amida[y][x] != '|')
       x++;
      if (direction == TO_DOWN)
       y++;
      else
       y--;
     } else {
      if (direction == TO_DOWN)
       y++;
      else if (direction == TO_UP)
       y--;
     }
    } else if (direction == TO_RIGHT || direction == TO_LEFT) {
     if (y > 0 && amida[y - 1][x] == '|') {
      y--;
      while (amida[y][x] != '-')
       y--;
      if (direction == TO_RIGHT)
       x++;
      else
       x--;
     } else if (y < height - 1 && amida[y + 1][x] == '|') {
      y++;
      while (amida[y][x] != '-')
       y++;
      if (direction == TO_RIGHT)
       x++;
      else
       x--;
     } else {
      if (direction == TO_RIGHT)
       x++;
      else
       x--;
     }
    }
   }

   os.write(amida[y][x]);
   System.out.println("Ans=" + amida[y][x]);
   os.write('\n');
   os.flush();
   no++;
  }
 }
}

No.79だけバグってる模様。これだけハードコードで7。 (バグってたのは自分の頭、2014/07/22訂正) 1,000問解いてやっとキーが出てきた。

No.1000
            *  
| | |-| | | | |
|-| | |-| | |-|
| | | | | | | |
| |-| |-| | | |
|-| | | |-| |-|
| |-| | | | | |
|-| | |-| |-| |
| | |-| |-| |-|
| |-| |-| | | |
|-| | | | | |-|
| |-| |-| |-| |
| | |-| | | |-|
| | | | |-| | |
|-| |-| | |-| |
| |-| | | | | |
| | |-| | |-| |
|-| | | |-| | |
| | | |-| |-| |
| | |-| |-| |-|
1 2 3 4 5 6 7 8
Ans=3
FLAG{c4693af1761200417d5645bd084e28f0f2b426bf}