Guest User

Untitled

a guest
Nov 19th, 2017
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.40 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Numerics;
  5. using System.Threading;
  6. using System.Threading.Tasks;
  7.  
  8. namespace ConsoleApplication8 {
  9. class Program {
  10. static uint[][] _lchecks; // bitmasks for sets of 6 progressive checks involving more than one u32 segment
  11. static readonly uint[] U32Strings = new uint[437502481]; // all valid 32 bit strings that don't trigger an invalid bit within the next 6 and have high order bit 0
  12.  
  13. static void Main(string[] args) {
  14. var checks = GenerateChecks().ToArray();
  15. Array.Sort(checks);
  16. int i;
  17. var sChecks = GetShortChecks(checks, out i);
  18. var iChecks = GetIntChecks(checks, ref i);
  19. _lchecks = GetMultipleQuadChecks(checks, i);
  20.  
  21. var local = U32Strings;
  22. int c = 0;
  23. foreach (var u in Valid32BitStrings(sChecks, iChecks)) {
  24. local[c] = u;
  25. if (c % 1000000 == 0) Console.WriteLine(c);
  26. c++;
  27. }
  28.  
  29. Console.WriteLine(c);
  30. // Dive(0x60d11de1);
  31. var opts = new ParallelOptions {MaxDegreeOfParallelism = 6};
  32. Parallel.ForEach(local, opts, Dive);
  33. }
  34.  
  35. private static int total = 0;
  36. [ThreadStatic]
  37. private static long N = 0;
  38. private static void Dive(uint prefix) {
  39. var max = Dive(new List<uint> {prefix}, 1, 0);
  40. Interlocked.Increment(ref total);
  41. Console.WriteLine("{0} : {1:x8} : {2}", total, prefix, max);
  42. }
  43.  
  44. private static int Dive(List<uint> canvas, int count, int lcheckLower) {
  45. N++;
  46. // int b = 0;
  47. int max = count;
  48. int lcheckUpper;
  49. uint checkIfAny0;
  50. uint checkIfAny1;
  51. uint[] checkIfAll0;
  52. uint[] checkIfAll1;
  53. if (!ProduceBitmaskChecks(canvas, count, lcheckLower, out lcheckUpper, out checkIfAny0, out checkIfAll0, out checkIfAny1, out checkIfAll1)) return max;
  54. var u32 = U32Strings;
  55. if (checkIfAny0 <= int.MaxValue) {
  56. foreach (var subsequence in u32) {
  57. if ((subsequence & checkIfAny1) != 0) continue;
  58. var inverted = ~subsequence;
  59. if ((inverted & checkIfAny0) != 0) continue;
  60. foreach (var mask in checkIfAll1) {
  61. if ((subsequence & mask) == mask) {
  62. goto next;
  63. }
  64. }
  65. foreach (var mask in checkIfAll0) {
  66. if ((inverted & mask) == mask) {
  67. goto next;
  68. }
  69. }
  70.  
  71. canvas.Add(subsequence);
  72. // b++;
  73. max = Math.Max(max, Dive(canvas, count + 1, lcheckUpper));
  74. canvas.RemoveAt(count);
  75. next:
  76. continue;
  77. }
  78. }
  79. if (checkIfAny1 <= int.MaxValue) {
  80. foreach (var inverted in u32) {
  81. var subsequence = ~inverted;
  82. if ((subsequence & checkIfAny1) != 0) continue;
  83. if ((inverted & checkIfAny0) != 0) continue;
  84. foreach (var mask in checkIfAll1) {
  85. if ((subsequence & mask) == mask) {
  86. goto next;
  87. }
  88. }
  89. foreach (var mask in checkIfAll0) {
  90. if ((inverted & mask) == mask) {
  91. goto next;
  92. }
  93. }
  94.  
  95. canvas.Add(subsequence);
  96. // b++;
  97. max = Math.Max(max, Dive(canvas, count + 1, lcheckUpper));
  98. canvas.RemoveAt(count);
  99. next:
  100. continue;
  101. }
  102. }
  103. // if (b == 0) {
  104. // var value = string.Join("", canvas.Select(x => $"{x:x8}"));
  105. // using (var x = File.OpenWrite(value + ".txt")) {
  106. // using (var writer = new StreamWriter(x))
  107. // {
  108. // writer.WriteLine("any 0: {0:X8}", checkIfAny0);
  109. // writer.WriteLine("all 0:");
  110. // foreach (var mask in checkIfAll0)
  111. // {
  112. // writer.WriteLine("{0:x8}", mask);
  113. // }
  114. // writer.WriteLine("any 1: {0:X8}", checkIfAny1);
  115. // writer.WriteLine("all 1:");
  116. // foreach (var mask in checkIfAll1)
  117. // {
  118. // writer.WriteLine("{0:x8}", mask);
  119. // }
  120. // }
  121. // }
  122. // }
  123. return max;
  124. }
  125.  
  126. private static bool ProduceBitmaskChecks(List<uint> canvas, int count, int lcheckLower, out int lcheckUpper, out uint checkIfAny0, out uint[] acheckIfAll0, out uint checkIfAny1, out uint[] acheckIfAll1) {
  127. var lchecks = _lchecks;
  128. lcheckUpper = 0;
  129. List<uint> checkIfAll0 = new List<uint>();
  130. checkIfAny0 = 0;
  131. List<uint> checkIfAll1 = new List<uint>();
  132. checkIfAny1 = 0;
  133. acheckIfAll0 = null;
  134. acheckIfAll1 = null;
  135. for (int i = lcheckLower; i < lchecks.Length; i++) {
  136. var bitmask = lchecks[i];
  137. if (bitmask.Length > count + 1) {
  138. // done computing necessary checks at this depth
  139. lcheckUpper = i;
  140. break;
  141. }
  142. var check0 = true;
  143. var check1 = true;
  144. for (int j = 0; j < canvas.Count && (check0 || check1); j++) {
  145. var subsequence = canvas[j];
  146. var mask = bitmask[j];
  147. check0 = check0 && (~subsequence & mask) == mask;
  148. check1 = check1 && (subsequence & mask) == mask;
  149. }
  150. var finalmask = bitmask[count];
  151. var singlebit = (finalmask & (finalmask - 1)) == 0;
  152. if (check0) {
  153. if (singlebit) {
  154. checkIfAny0 = checkIfAny0 | finalmask;
  155. } else {
  156. checkIfAll0.Add(finalmask);
  157. }
  158. }
  159. if (check1) {
  160. if (singlebit) {
  161. checkIfAny1 = checkIfAny1 | finalmask;
  162. } else {
  163. checkIfAll1.Add(finalmask);
  164. }
  165. }
  166. }
  167. if (lcheckUpper == 0) {
  168. //todo: call out to another function to handle bit strings that are within 32 bits of maximum length
  169. //last 32 bits handled special
  170. var value = string.Join("", canvas.Select(x => $"{x:x8}"));
  171. Console.WriteLine(value);
  172. return false;
  173. }
  174. if (count > 5) {
  175. // this is completely arbitrary
  176. var value = string.Join("", canvas.Select(x => $"{x:x8}"));
  177. UpdateLongest(value);
  178. }
  179. // if any single must not be 1 and must not be 0 at the same time, no need to do any of this
  180. if ((checkIfAny0 & checkIfAny1) != 0) {
  181. return false;
  182. }
  183. // remove covering checks, ex:
  184. // *.1.1.1.1
  185. // *.1.1
  186. // you cannot match the first without also matching the second, so no need for the first check
  187. acheckIfAll0 = ReduceChecks(checkIfAll0, checkIfAny0);
  188. acheckIfAll1 = ReduceChecks(checkIfAll1, checkIfAny1);
  189.  
  190.  
  191. foreach (var mask in checkIfAll1) {
  192. // given mask
  193. // *.1.1
  194. // if all are 1, test will fail
  195. // if any are 0 test will pass
  196. // thus if all mask bits are in the any0 mask, that test will fail
  197. if ((checkIfAny0 & mask) == mask) goto fls;
  198. }
  199. foreach (var mask in checkIfAll0) {
  200. if ((checkIfAny1 & mask) == mask) goto fls;
  201. }
  202. return true;
  203. fls:
  204. return false;
  205. }
  206.  
  207. private static uint[] ReduceChecks(List<uint> list, uint singles) {
  208. var remove = new bool[list.Count];
  209. var any = false;
  210. for (int i = 0; i < list.Count; i++) {
  211. var c = list[i];
  212. if ((c & singles) != 0) {
  213. //if a single bit covers this mask it will also cover any mask that this mask covers
  214. remove[i] = true;
  215. any = true;
  216. //so no need to do the inner loop
  217. continue;
  218. }
  219. for (int j = i + 1; j < list.Count; j++) {
  220. var d = list[j];
  221. var u = c & d;
  222. if (u == c) {
  223. // if all bits in c are also in d then d is unnecessary
  224. remove[j] = true;
  225. any = true;
  226. } else if (u == d) {
  227. // and the reverse
  228. remove[i] = true;
  229. any = true;
  230. }
  231. }
  232. }
  233.  
  234. if (any) {
  235. var temp = new List<uint>(list.Count);
  236. for (int i = 0; i < list.Count; i++) {
  237. if (!remove[i]) {
  238. temp.Add(list[i]);
  239. }
  240. }
  241. return temp.ToArray();
  242. }
  243. return list.ToArray();
  244. }
  245.  
  246. static readonly object l = new object();
  247. private static string longest = "";
  248.  
  249. private static void UpdateLongest(string value) {
  250. Console.WriteLine(N);
  251. if (value.Length > longest.Length) {
  252. lock (l) {
  253. if (value.Length > longest.Length) {
  254. longest = value;
  255. Console.WriteLine(longest.Length + " : " + longest);
  256. }
  257. }
  258. }
  259. }
  260.  
  261. private static IEnumerable<uint> Valid32BitStrings(ushort[] sChecks, uint[] iChecks) {
  262. var u16Strings = Valid16BitStrings(sChecks);
  263. var hu16Strings = u16Strings.Select(b => (uint) b << 16).TakeWhile(b => b <= int.MaxValue).ToArray();
  264. uint[] testForce32 = new uint[] {
  265. 0x2082083F, // if a string masked by this ...
  266. 0x218A4A30,
  267. 0x10C52518,
  268. 0x0862928C,
  269. 0x04314946,
  270. 0x0218A4A3,
  271. 0x81031519,
  272. 0x81230C4A,
  273. 0x40918625,
  274. 0x8512450C,
  275. 0x42892286,
  276. 0x21449143
  277. };
  278. uint[] checkForce32 = new uint[] {
  279. 0x0000001F, // ... equals this, the next bit in the progression identified here
  280. 0x01084210, // cannot be either 0 or 1
  281. 0x00842108,
  282. 0x00421084,
  283. 0x00210842,
  284. 0x00108421,
  285. 0x81020408,
  286. 0x81020408,
  287. 0x40810204,
  288. 0x81020408,
  289. 0x40810204,
  290. 0x20408102
  291. };
  292. foreach (var high in hu16Strings) {
  293. foreach (var low in u16Strings) {
  294. var b = high + low;
  295. var nb = ~b;
  296. bool g = true;
  297. foreach (var check in iChecks) {
  298. if ((b & check) == check) {
  299. g = false;
  300. break;
  301. }
  302. if ((nb & check) == check) {
  303. g = false;
  304. break;
  305. }
  306. }
  307. if (g) {
  308. for (int i = 0; i < testForce32.Length; i++) {
  309. if ((b & testForce32[i]) == checkForce32[i])
  310. {
  311. g = false;
  312. break;
  313. }
  314. if ((nb & testForce32[i]) == checkForce32[i])
  315. {
  316. g = false;
  317. break;
  318. }
  319. }
  320. }
  321. if (g) {
  322. // these sequences prevent one of the next 6 bits from being either 0 or 1
  323. yield return b;
  324. }
  325. }
  326. }
  327. }
  328.  
  329. private static ushort[] Valid16BitStrings(ushort[] sChecks) {
  330. List<ushort> good = new List<ushort>();
  331. for (ushort b = 0; b < ushort.MaxValue; b++) {
  332. bool g = true;
  333. var nb = ~b;
  334. foreach (var check1 in sChecks) {
  335. if ((b & check1) == check1) {
  336. g = false;
  337. break;
  338. }
  339. if ((nb & check1) == check1) {
  340. g = false;
  341. break;
  342. }
  343. }
  344. if (g) {
  345. good.Add(b);
  346. if (good.Count % 10 == 0) Console.WriteLine("{0}, {1:x}", good.Count, b);
  347. }
  348. }
  349. Console.WriteLine(good.Count);
  350. return good.ToArray();
  351. }
  352.  
  353. private static uint[][] GetMultipleQuadChecks(BigInteger[] checks, int i) {
  354. // checks larger than uint.MaxValue are initially stored in BigInteger values and we need them in uint[] arrays
  355. // BigInteger provides a method that returns the underlying bytes but they are in the wrong order if we
  356. // simply reinterpreted the array... given a big endian BigInteger stored like this:
  357. // hgfedcba87654321
  358. // we need this (little endian):
  359. // 12345678abcdefgh
  360. // ToByteArray returns this:
  361. // 87654321hgfedcba
  362. // (each byte is big endian, byte array is little endian)
  363. List<uint[]> lchecks = new List<uint[]>();
  364. for (; i < checks.Length; i++) {
  365. var bytes = checks[i].ToByteArray();
  366. if (bytes.Length < 5) {
  367. throw new Exception("program failure; int check discovered where longer check expected");
  368. }
  369.  
  370. var s = new List<uint>();
  371. for (int j = 0; j < bytes.Length; j += 4) {
  372. uint u1 = j + 3 < bytes.Length ? ReverseBits(bytes[j + 3]) : 0;
  373. uint u2 = j + 2 < bytes.Length ? ReverseBits(bytes[j + 2]) << 8 : 0;
  374. uint u3 = j + 1 < bytes.Length ? ReverseBits(bytes[j + 1]) << 16 : 0;
  375. uint u4 = ReverseBits(bytes[j]) << 24;
  376. s.Add(u1 + u2 + u3 + u4);
  377. }
  378. if (s[s.Count - 1] == 0) {
  379. // remove the extra sign byte that occurs if bytes[bytes.Length-1]>128 && bytes.Length % 4 = 1
  380. s.RemoveAt(s.Count - 1);
  381. }
  382.  
  383. // any bitmask that fits inside a single uint is unnecessary because such a result wouldn't be returned from Valid32BitStrings
  384. if (s.Where(s1 => s1 != 0).Take(2).Count() == 1) continue;
  385. lchecks.Add(s.ToArray());
  386. }
  387. var multipleQuadChecks = lchecks.ToArray();
  388. return multipleQuadChecks;
  389. }
  390.  
  391. static uint ReverseBits(byte a) {
  392. return (uint) (((a & 0x1) << 7) | ((a & 0x2) << 5) |
  393. ((a & 0x4) << 3) | ((a & 0x8) << 1) |
  394. ((a & 0x10) >> 1) | ((a & 0x20) >> 3) |
  395. ((a & 0x40) >> 5) | ((a & 0x80) >> 7));
  396. }
  397.  
  398. private static uint[] GetIntChecks(BigInteger[] checks, ref int i) {
  399. List<uint> iChecks = new List<uint>();
  400. while (checks[i] < uint.MaxValue) {
  401. var item = (uint) checks[i];
  402. if ((item & ushort.MaxValue) != 0) {
  403. //we only care about the ones with low bits set (if no low bits are set, the high bits were checked already)
  404. iChecks.Add(item);
  405. }
  406. i++;
  407. }
  408. return iChecks.ToArray();
  409. }
  410.  
  411. private static ushort[] GetShortChecks(BigInteger[] checks, out int i) {
  412. i = 0;
  413. List<ushort> sChecks = new List<ushort>();
  414. while (checks[i] < ushort.MaxValue) {
  415. sChecks.Add((ushort) checks[i]);
  416. i++;
  417. }
  418. return sChecks.ToArray();
  419. }
  420.  
  421. static IEnumerable<BigInteger> GenerateChecks() {
  422. BigInteger max = BigInteger.Pow(2, 1134);
  423. //n ^ 5 + n ^ 4 + n ^ 3 + n ^ 2 + n + 1
  424. BigInteger n = 2;
  425. do {
  426. var n2 = n * n;
  427. var n3 = n2 * n;
  428. var n4 = n3 * n;
  429. var n5 = n4 * n;
  430. if (n5 > max) yield break;
  431. var check = n5 + n4 + n3 + n2 + n + 1;
  432. while (check < max) {
  433. yield return check;
  434. check <<= 1;
  435. }
  436. n <<= 1;
  437. } while (true);
  438. }
  439. }
  440. }
Add Comment
Please, Sign In to add comment