Enderlook

Word Finder

Apr 16th, 2021
713
333 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. internal static class Program
  2. {
  3.     // https://devhub.io/repos/mgp25-RAE-API
  4.     // https://stackoverflow.com/questions/756055/listing-all-permutations-of-a-string-integer
  5.     // https://stackoverflow.com/questions/4632322/finding-all-possible-combinations-of-numbers-to-reach-a-given-sum
  6.  
  7.     private static void Main(string[] args)
  8.     {
  9.         Console.WriteLine("Initializing...");
  10.         ILookup<string, string> lookup = GetWords().ToLookup(e => string.Concat(e.OrderBy(e => e)));
  11.  
  12.         string[] syllables = new string[]
  13.         {
  14.             "a", "a", "a", "an", "ar", "bi", "bo", "ca", "ce", "ci", "cia", "cia", "co", "cu", "cuer",
  15.             "cús", "da", "da", "da", "dad", "de", "de", "de", "dip", "do", "do", "dres", "es", "es", "for",
  16.             "gan", "gen", "je", "ji", "jun", "lei", "lien", "lin", "lla", "lo", "ma", "me", "me", "mía", "mo",
  17.             "mor", "ná", "no", "o", "o", "pa", "pi", "pio", "plen", "re", "sa", "ses", "só", "su", "ta", "tan",
  18.             "te", "to", "tos", "u", "ver", "vi", "yu"
  19. ,           };
  20.  
  21.         int[] sizes = new int[] { 5, 6, 9, 9, 9, 9, 9, 9, 8, 8, 7, 8, 8, 9, 9, 9, 9, 9, 9, 5 };
  22.         sizes = sizes.Distinct().ToArray();
  23.  
  24.         using StreamWriter stream = new StreamWriter(@"C:\Users\rolyg\Desktop\tmp.txt");
  25.  
  26.         HashSet<string> words = new HashSet<string>();
  27.  
  28.         Console.WriteLine("Preload...");
  29.         string[][] combinations = sizes
  30.             .AsParallel()
  31.             .AsUnordered()
  32.             .SelectMany(e => GetCombinations(syllables, e))
  33.             .ToArray();
  34.  
  35.         Console.WriteLine("Starting basic...");
  36.         foreach (string word in combinations
  37.             .AsParallel()
  38.             .AsUnordered()
  39.             .SelectMany(e =>
  40.             {
  41.                 HashSet<string> permutations = GetPermutations(e);
  42.                 return lookup[string.Concat(e.OrderBy(c => c))].Where(w => permutations.Contains(w));
  43.             }))
  44.         {
  45.             stream.Write(word + "\n");
  46.             words.Add(word);
  47.             Console.WriteLine(word);
  48.         }
  49.         Console.WriteLine("Finish basic...");
  50.  
  51.         Console.WriteLine("Starting deep...");
  52.         foreach (string word in GetAnagrams(combinations)
  53.             .Where(e => !words.Contains(e)))
  54.         {
  55.             stream.Write(word + "\n");
  56.             Console.WriteLine(word);
  57.         }
  58.     }
  59.  
  60.     private static IEnumerable<string> GetWords()
  61.     {
  62.         using StreamReader reader = new StreamReader(@"C:\Users\rolyg\source\repos\WordsFinder\words.txt");
  63.         string line;
  64.         while ((line = reader.ReadLine()) != null)
  65.             yield return line;
  66.     }
  67.  
  68.     private static ParallelQuery<string> GetAnagrams(IEnumerable<string[]> syllablesGrouped)
  69.     {
  70.         HttpClient client = new HttpClient();
  71.  
  72.         client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
  73.         client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", "cDY4MkpnaFMzOmFHZlVkQ2lFNDM0");
  74.  
  75.         return syllablesGrouped
  76.             .AsParallel()
  77.             .AsUnordered()
  78.             .Distinct(new ArrayComparer())
  79.             .Select(e => (e, string.Concat(e)))
  80.             .Select(e =>
  81.             {
  82.                 string w2 = e.Item2[^1] + e.Item2[0..^1];
  83.                 return (e.e,
  84.                     // Get anagrams of the word
  85.                     client.GetAsync($@"https://dle.rae.es/data/anagram?w={e.Item2}&callback=json"),
  86.                     /* Since RAE doesn't return the word used to get the anagrams
  87.                      * we must give him another word to get it and check if it's a word. */
  88.                     client.GetAsync($@"https://dle.rae.es/data/anagram?w={w2}&callback=json"));
  89.             })
  90.             .Select(e =>
  91.             {
  92.                 e.Item2.Wait();
  93.                 e.Item3.Wait();
  94.                 return (e.e, e.Item2.Result, e.Item3.Result);
  95.             })
  96.             .Where(e => e.Item2.IsSuccessStatusCode || e.Item3.IsSuccessStatusCode)
  97.             .Select(e => (e.e, e.Item2.Content.ReadAsStreamAsync(), e.Item3.Content.ReadAsStreamAsync()))
  98.             .Select(e =>
  99.             {
  100.                 e.Item2.Wait();
  101.                 e.Item3.Wait();
  102.                 return (e.e, e.Item2.Result, e.Item3.Result);
  103.             })
  104.             .Select(e => (e.e, JsonSerializer.DeserializeAsync<Answer>(e.Item2), JsonSerializer.DeserializeAsync<Answer>(e.Item3)))
  105.             .Select(e =>
  106.             {
  107.                 e.Item2.AsTask().Wait();
  108.                 e.Item3.AsTask().Wait();
  109.                 return (e.e, e.Item2.Result.res, e.Item3.Result.res);
  110.             })
  111.             .Where(e => (e.Item2?.Count > 0) || (e.Item3?.Count > 0))
  112.             .SelectMany(e =>
  113.             {
  114.                 // Cached this outside and check again whole result must be sightly faster in rare cases but would require massive amount of memory
  115.                 HashSet<string> permutations = GetPermutations(e.e);
  116.                 return (e.Item2.Select(e => e.word) ?? Enumerable.Empty<string>())
  117.                     .Concat(e.Item3.Select(e => e.word) ?? Enumerable.Empty<string>())
  118.                     // 1) RAE may return duplicated answers. 2) We call twice RAE, so we WILL get duplicated answers
  119.                     .Distinct()
  120.                     // RAE ignores accents and syllables, so we must check that only our syllables are used.
  121.                     .Where(word => permutations.Contains(word));
  122.                 // RAE may return duplicated answers.
  123.             })
  124.             .Distinct();
  125.     }
  126.  
  127.     public class Response
  128.     {
  129.         public string header { get; set; }
  130.         public string id { get; set; }
  131.         public string word { get; set; }
  132.     }
  133.  
  134.     public class Answer
  135.     {
  136.         public int approx { get; set; }
  137.         public List<Response> res { get; set; }
  138.     }
  139.  
  140.     private static IEnumerable<string[]> GetCombinations(List<string> syllables, int target, List<string> partial)
  141.     {
  142.         int s = partial.Sum(e => e.Length);
  143.         if (s == target)
  144.         {
  145.             yield return partial.ToArray();
  146.             yield break;
  147.         }
  148.         if (s >= target)
  149.             yield break;
  150.         for (int i = 0; i < syllables.Count; i++)
  151.         {
  152.             string n = syllables[i];
  153.             List<string> remaining = new List<string>();
  154.             for (int j = i + 1; j < syllables.Count; j++)
  155.                 remaining.Add(syllables[j]);
  156.             List<string> partial_rec = new List<string>(partial)
  157.             {
  158.                 n
  159.             };
  160.             foreach (string[] element in GetCombinations(remaining, target, partial_rec))
  161.                 yield return element;
  162.         }
  163.     }
  164.  
  165.     private static IEnumerable<string[]> GetCombinations(string[] syllables, int target) => GetCombinations(syllables.ToList(), target, new List<string>());
  166.  
  167.     private class ArrayComparer : IEqualityComparer<string[]>
  168.     {
  169.         public bool Equals([AllowNull] string[] x, [AllowNull] string[] y)
  170.         {
  171.             if (x is null && y is null)
  172.                 return true;
  173.             if (x is null || y is null)
  174.                 return false;
  175.             if (x.Length != y.Length)
  176.                 return false;
  177.             return x.SequenceEqual(y);
  178.         }
  179.  
  180.         public int GetHashCode([DisallowNull] string[] obj) => string.Concat(obj).GetHashCode(); // String hash is by value
  181.     }
  182.  
  183.     private static void Swap(ref string a, ref string b)
  184.     {
  185.         if (a == b) return;
  186.  
  187.         string temp = a;
  188.         a = b;
  189.         b = temp;
  190.     }
  191.  
  192.     public static HashSet<string> GetPermutations(string[] list)
  193.     {
  194.         HashSet<string> results = new HashSet<string>();
  195.         int x = list.Length - 1;
  196.         GetPermutations(list, 0, x, results);
  197.         return results;
  198.     }
  199.  
  200.     private static void GetPermutations(string[] list, int k, int m, HashSet<string> results)
  201.     {
  202.         if (k == m)
  203.             results.Add(string.Concat(list));
  204.         else
  205.             for (int i = k; i <= m; i++)
  206.             {
  207.                 Swap(ref list[k], ref list[i]);
  208.                 GetPermutations(list, k + 1, m, results);
  209.                 Swap(ref list[k], ref list[i]);
  210.             }
  211.     }
  212. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×