Last active
April 18, 2021 17:35
-
-
Save shibayan/e48aa420129e583a31f6bef4c6774452 to your computer and use it in GitHub Desktop.
cskawari
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Text.RegularExpressions; | |
namespace ConsoleApp15 | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var dic = new KawariDictionary | |
{ | |
{ "day", "Sunday", "Monday", "Tuesday", "Wednesday", "Thirsday", "Friday", "Saturday" }, | |
{ "number", "1", "2", "3", "4", "5", "6" }, | |
{ "sentence", "${number}: Today is ${day}.", "No. ${number}: 今日の曜日は${day}", "${number}, ${number}, ${number}。逆順で言うと${2}, ${1}, ${0}。" } | |
}; | |
for (int i = 0; i < 10; i++) | |
{ | |
Console.WriteLine($"sentence: {dic.Call("sentence")}"); | |
} | |
} | |
} | |
public class KawariDictionary : Dictionary<string, List<string>> | |
{ | |
private readonly Random _random = new Random(); | |
private readonly Regex _entryCallRegex = new Regex(@"\$\{([^${}]+)\}", RegexOptions.Compiled); | |
public void Add(string entry, params string[] words) | |
{ | |
if (!TryGetValue(entry, out var entryList)) | |
{ | |
entryList = new List<string>(); | |
Add(entry, entryList); | |
} | |
entryList.AddRange(words); | |
} | |
public string Call(string entry) | |
{ | |
var history = new List<string>(); | |
var answer = RawEntryCall(entry, history); | |
while (true) | |
{ | |
var result = _entryCallRegex.Match(answer); | |
if (!result.Success) | |
{ | |
break; | |
} | |
var entryString = RawEntryCall(result.Groups[1].Value, history); | |
answer = answer[..result.Index] + entryString + answer[(result.Index + result.Length)..]; | |
if (!int.TryParse(result.Groups[1].Value, out _)) | |
{ | |
history.Add(entryString); | |
} | |
} | |
return answer; | |
} | |
private string RawEntryCall(string entry, IReadOnlyList<string> history) | |
{ | |
if (int.TryParse(entry, out var index)) | |
{ | |
return index < 0 || index >= history.Count ? "" : history[index]; | |
} | |
if (!TryGetValue(entry, out var entryList)) | |
{ | |
return ""; | |
} | |
var wordIndex = _random.Next(entryList.Count); | |
return entryList[wordIndex]; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment