Codingame『Boggle』

Super Big Boggle by Winning Moves [並行輸入品]


実際に商品として存在する

 何気に初めて見た。


思い違いしてた

 例えばABCDEという単語を調べる場合、
BACD
    E
という並びでもいいのかと考えてた。


 実際には上の場合はfalseになって、行ったり来たりしない
ABCD
    E
の場合だけtrueになる。
後、地味に'T'rue 'F'alseだとダメで't'rue 'f'alseにしないといけなかったり。


再帰……

 何か久しぶりに再帰使った気がする……。
他の人のコード見るともっとスマートに再帰使ってて「えぇ…(感嘆)」状態になる。


コード
using System;
using System.Linq;
using System.IO;
using System.Text;
using System.Collections;
using System.Collections.Generic;

/**
 * Auto-generated code below aims at helping you parse
 * the standard input according to the problem statement.
 **/
class Solution
{
    static void Main(string[] args)
    {
        Boggle b = new Boggle();

        b.CheckWords();
        b.DrawResults();
    }
}

class Boggle
{
    private int size = 4;
    private char[,] grid;
    private bool[,] flagGrid;
    private string[] word;
    private bool[] results;

    /// <summary>
    /// コンストラクタ
    /// </summary>
    public Boggle()
    {
        this.InitGrid();
        this.ReadCheckWords();
    }

    /// <summary>
    /// 単語のチェック
    /// </summary>
    public void CheckWords()
    {
        for (int i = 0; i < this.word.Length; i++)
        {
            this.results[i] = this.IsWordOnGrid(i);
        }
    }

    /// <summary>
    /// 単語がグリッド上に存在するか
    /// </summary>
    private bool IsWordOnGrid(int i)
    {
        for (int y = 0; y < this.size; y++)
        {
            for (int x = 0; x < this.size; x++)
            {
                this.FlagInitialize();

                if (this.SearchChar(x, y, new string(this.word[i].ToCharArray())) == "")
                {
                    return true;
                }
            }
        }

        return false;
    }

    /// <summary>
    /// 文字の検索
    /// </summary>
    private string SearchChar(int x, int y, string w)
    {
        //単語の最後まで調べられている
        if (w == "") return w;

        //グリッド外
        if (x < 0 | x >= this.size) return w;
        if (y < 0 | y >= this.size) return w;

        //既に調べ済み
        if (this.flagGrid[x, y] == true) return w;

        //単語内に文字があるかどうか
        int find = w.IndexOf(this.grid[x, y]);

        //あった場合は削除
        if ( find > -1 & find == 0)
        {
            this.flagGrid[x, y] = true;
            w = w.Remove(find, 1);
        }
        else return w;

        //8方向検索
        w = this.SearchChar(x - 1, y - 1, w);
        w = this.SearchChar(x - 1, y, w);
        w = this.SearchChar(x - 1, y + 1, w);
        w = this.SearchChar(x, y - 1, w);
        w = this.SearchChar(x, y + 1, w);
        w = this.SearchChar(x + 1, y - 1, w);
        w = this.SearchChar(x + 1, y, w);
        w = this.SearchChar(x + 1, y + 1, w);

        return w;

    }

    /// <summary>
    /// 探索済みフラグを初期化する
    /// </summary>
    private void FlagInitialize()
    {
        for (int y = 0; y < this.size; y++)
        {
            for (int x = 0; x < this.size; x++)
            {
                this.flagGrid[x, y] = false;
            }
        }
    }

    /// <summary>
    /// 結果の描画
    /// </summary>
    public void DrawResults()
    {
        Console.Error.WriteLine("*** Results ***");

        for (int i = 0; i < this.results.Length; i++)
        {
            Console.WriteLine(this.results[i].ToString().ToLower());
        }
    }

    /// <summary>
    /// グリッドの初期化
    /// </summary>
    private void InitGrid()
    {
        this.grid = new char[this.size, this.size];
        this.flagGrid = new bool[this.size, this.size];

        string line;

        for (int l = 0; l < this.size; l++)
        {
            line = Console.ReadLine();
            for (int x = 0; x < this.size; x++)
            {
                this.grid[x, l] = line[x];
            }
        }

    }

    /// <summary>
    /// 調べる単語の読み込み
    /// </summary>
    private void ReadCheckWords()
    {
        int n = int.Parse(Console.ReadLine());

        this.word = new string[n];
        this.results = new bool[n];

        for (int i = 0; i < n; i++)
        {
            word[i] = Console.ReadLine();
        }
    }
}