понедельник, 17 ноября 2014 г.

Задача с lightsoft.ru Перестройка предложения

Дело было вечером, делать было... Искал работу QA Automation и набрёл случайно на сайт
 lightsoft.ru. А там задачка, вот вечер был потрачен на решение задачи

Пожалуйста, разработайте функцию\класс для "перемешивания" предложения.
Символ | является разделителем слов-вариантов. Например:
"{Пожалуйста|Просто} сделайте так, чтобы это {удивительное|крутое|простое} тестовое предложение {изменялось {быстро|мгновенно} случайным образом|менялось каждый раз}."
На выходе должно получаться:
"Пожалуйста сделайте так, чтобы это крутое тестовое предложение изменялось каждый раз." или "Просто сделайте так, чтобы это удивительное тестовое предложение изменялось мгновенно случайным образом".
Вот решил поделиться моим решением на C#:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace lightsoft
{
    class Program
    {
       
        static Dictionary<int, ArrayList> dictions = new Dictionary<int, ArrayList>();
        static int pos = 0;

        /// <summary>
        /// Возвращаем блок из строки
        /// </summary>
        /// <param name="str"></param>
        /// <returns>block</returns>
        private static string RetBlock(string str) {
            int startIndex = -1, finishIndex = -1;
            int counterStart = 0, counterFinish = 0;

            for (int i = 0; i < str.Length; i++)
            {
                if (str.Substring(i, 1) == "{")
                {
                    if (startIndex == -1) startIndex = i;
                    counterStart++;
                }

                if (str.Substring(i, 1) == "}")
                {
                    finishIndex = i;
                    counterFinish++;
                }
               
                if (startIndex < finishIndex && counterStart == counterFinish)
                {
                    return str.Substring(startIndex + 1, finishIndex - startIndex - 1);
                }

            }

            if (counterStart != counterFinish || startIndex > finishIndex)
            {
                throw new Exception("Error parse string:" + str);
            }

            return string.Empty;
        }

        /// <summary>
        /// Парсим строку на блоки и добавляем блоки в словарь
        /// </summary>
        /// <param name="str"></param>
        /// <returns>template</returns>
        private static string Parse(string str) {
          
            bool flagAdd = true;
            while(flagAdd){
                flagAdd = false;
                string block = RetBlock(str);
                if (block == string.Empty) return str;

                string str1 = Parse(block);             // используем рекурсию для всех внутренних блоков
                str = str.Replace(block, str1);
                block = str1;

                ArrayList words = new ArrayList();      // масив для варианов подстановки
                foreach(string blk in block.Split('|'))
                {
                    words.Add(blk);
                    flagAdd = true;
                }
                string posstr = "%" + Convert.ToString(pos) + "%";
                str = str.Replace("{" + block + "}", posstr);
                dictions.Add(pos, words);               // добавляем массив в словарь
                pos++;
            }

            return str;
        }


        private static Random rnd = new Random();

        /// <summary>
        /// Возвращаем случайный набор из массива
        /// </summary>
        /// <param name="idBlock"></param>
        /// <returns>random words</returns>
        private static string GetRndWords(int idBlock) {
            ArrayList words = new ArrayList();
            dictions.TryGetValue(idBlock, out words);
            int idWord = rnd.Next(0, words.Count);
            return (string)words[idWord];       
        }

        /// <summary>
        /// Генерируем строку
        /// </summary>
        /// <param name="template"></param>
        /// <returns>new sentence</returns>
        private static string GenSentence(string template)
        {
            bool flag = true;
            string pattern = @"%[0-9]*%";
            Regex rgx = new Regex(pattern);           
            while(flag)
            {
                flag = false;
                foreach (Match match in rgx.Matches(template))
                {
                    int idBlock = Convert.ToInt32(match.Value.Replace("%",string.Empty));
                    template = template.Replace(match.Value, GetRndWords(idBlock));
                    flag = true;
                }
            }

            return template;
        }

        static void Main(string[] args)
        {
            string template = Parse(args[0]);
            for (int i = 0; i < 30; i++)
            {
                System.Console.WriteLine(GenSentence(template));
            }
            System.Console.ReadKey();
        }


    }
}


 Результат работы:
Просто сделайте так, чтобы это простое тестовое предложение менялось каждый раз.
Просто сделайте так, чтобы это удивительное тестовое предложение изменялось быстро случайным образом.
Просто сделайте так, чтобы это удивительное тестовое предложение менялось каждый раз.
Просто сделайте так, чтобы это крутое тестовое предложение менялось каждый раз.
Пожалуйста сделайте так, чтобы это простое тестовое предложение изменялось быстро случайным образом.
Пожалуйста сделайте так, чтобы это простое тестовое предложение изменялось быстро случайным образом.
Пожалуйста сделайте так, чтобы это простое тестовое предложение менялось каждый раз.
Пожалуйста сделайте так, чтобы это простое тестовое предложение изменялось быстро случайным образом.
Просто сделайте так, чтобы это удивительное тестовое предложение менялось каждый раз.
Пожалуйста сделайте так, чтобы это удивительное тестовое предложение изменялось быстро случайным образом.
Просто сделайте так, чтобы это удивительное тестовое предложение менялось каждый раз.
Пожалуйста сделайте так, чтобы это удивительное тестовое предложение менялось каждый раз.
Пожалуйста сделайте так, чтобы это крутое тестовое предложение изменялось быстро случайным образом.
Пожалуйста сделайте так, чтобы это крутое тестовое предложение изменялось мгновенно случайным образом.
Просто сделайте так, чтобы это удивительное тестовое предложение изменялось мгновенно случайным образом.
Пожалуйста сделайте так, чтобы это удивительное тестовое предложение изменялось мгновенно случайным образом.
Пожалуйста сделайте так, чтобы это крутое тестовое предложение изменялось быстро случайным образом.
Просто сделайте так, чтобы это простое тестовое предложение изменялось мгновенно случайным образом.
Пожалуйста сделайте так, чтобы это удивительное тестовое предложение изменялось мгновенно случайным образом.
Пожалуйста сделайте так, чтобы это удивительное тестовое предложение менялось каждый раз.
Пожалуйста сделайте так, чтобы это простое тестовое предложение изменялось мгновенно случайным образом.
Просто сделайте так, чтобы это крутое тестовое предложение изменялось быстро случайным образом.
Пожалуйста сделайте так, чтобы это простое тестовое предложение изменялось быстро случайным образом.
Просто сделайте так, чтобы это простое тестовое предложение изменялось быстро случайным образом.
Пожалуйста сделайте так, чтобы это крутое тестовое предложение менялось каждый раз.
Просто сделайте так, чтобы это удивительное тестовое предложение изменялось мгновенно случайным образом.
Просто сделайте так, чтобы это удивительное тестовое предложение изменялось быстро случайным образом.
Просто сделайте так, чтобы это простое тестовое предложение менялось каждый раз.
Пожалуйста сделайте так, чтобы это простое тестовое предложение изменялось мгновенно случайным образом.
Пожалуйста сделайте так, чтобы это простое тестовое предложение менялось каждый раз.

Комментариев нет:

Отправить комментарий