diff options
author | Alexandre Rames <alexandre.rames@linaro.org> | 2015-11-11 10:07:52 +0000 |
---|---|---|
committer | Alexandre Rames <alexandre.rames@linaro.org> | 2015-11-11 10:07:52 +0000 |
commit | acf3101157760443e3979261f6d6a3ff018db8ab (patch) | |
tree | d8df26036cfb5bf3efcc7ac4417f7affa64ab51b /benchmarks | |
parent | 8b67f8c2fb8bbb733be06b6cba4a2b3098b30781 (diff) | |
download | art-testing-acf3101157760443e3979261f6d6a3ff018db8ab.tar.gz |
Introduce a new benchmark for sorting algorithms.
Change-Id: Iebecde825a010a5812e9f4877cc0d9fee9d9ac2c
Diffstat (limited to 'benchmarks')
-rw-r--r-- | benchmarks/algorithm/Sort.java | 492 |
1 files changed, 492 insertions, 0 deletions
diff --git a/benchmarks/algorithm/Sort.java b/benchmarks/algorithm/Sort.java new file mode 100644 index 0000000..3c40e4f --- /dev/null +++ b/benchmarks/algorithm/Sort.java @@ -0,0 +1,492 @@ +/* + * Copyright 2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/* + * Description: Implementation of various sort algorithms. + * + * Main Focus: array accesses, array copies, branching. + * + * TODO: Add more sorting algorithms. + */ + +package benchmarks.algorithm; + +import java.lang.System; +import java.util.ArrayList; +import java.util.Arrays; + +public class Sort { + public ArrayList<int[]> systemSortArraysToVerify = new ArrayList<int[]>(); + public ArrayList<int[]> bubbleSortArraysToVerify = new ArrayList<int[]>(); + public ArrayList<int[]> insertionSortArraysToVerify = new ArrayList<int[]>(); + public ArrayList<int[]> mergeSortArraysToVerify = new ArrayList<int[]>(); + + void initArray(int array[]) { + int copyBase; + int copySize; + for (copyBase = 0; copyBase < array.length; copyBase += copySize) { + copySize = Math.min(referenceInputArray.length, array.length - copyBase); + System.arraycopy(referenceInputArray, 0, array, copyBase, copySize); + } + } + + boolean arraysEqual(int array_1[], int array_2[]) { + int length = Math.min(array_1.length, array_2.length); + for (int i = 0; i < length; i++) { + if (array_1[i] != array_2[i]) { + System.out.println("ERROR: Arrays differ at index " + i + ": " + + array_1[i] + " != " + array_2[i]); + return false; + } + } + if (array_1.length != array_2.length) { + System.out.println("ERROR: Arrays have different lengths: " + + array_1.length + " != " + array_2.length); + return false; + } + return true; + } + + boolean isArraySorted(int array[]) { + for (int i = 0; i < array.length - 1; ++i) { + if (array[i] > array[i + 1]) { + System.out.println("ERROR: The array is not sorted at index " + i + ": " + + array[i] + " > " + array[i + 1]); + return false; + } + } + return true; + } + + /* Bubble sort */ + + void bubbleSort(int array[]) { + for (int i = 0; i < array.length; ++i) { + for (int j = 0; j < array.length - i - 1; ++j) { + if (array[j] > array[j + 1]) { + int temp = array[j]; + array[j] = array[j + 1]; + array[j + 1] = temp; + } + } + } + } + + public void benchBubbleSort(int arraySize, int iterations) { + int array[] = new int[arraySize]; + bubbleSortArraysToVerify.add(array); + for (int iter = 0; iter < iterations; ++iter) { + initArray(array); + bubbleSort(array); + } + } + + public boolean verifyBubbleSort() { + for (int array[] : bubbleSortArraysToVerify) { + int ref[] = new int[array.length]; + initArray(ref); + Arrays.sort(ref); + if (!isArraySorted(array) || !arraysEqual(ref, array)) { + return false; + } + } + bubbleSortArraysToVerify.clear(); + return true; + } + + + /* Insertion sort */ + + void insertionSort(int array[]) { + for (int k = 1; k < array.length; ++k) { + int i; + int key = array[k]; + for (i = k; i > 0 && array[i - 1] > key; --i) { + array[i] = array[i - 1]; + } + array[i] = key; + } + } + + public void benchInsertionSort(int arraySize, int iterations) { + int array[] = new int[arraySize]; + insertionSortArraysToVerify.add(array); + for (int iter = 0; iter < iterations; ++iter) { + initArray(array); + insertionSort(array); + } + } + + public boolean verifyInsertionSort() { + for (int array[] : insertionSortArraysToVerify) { + int ref[] = new int[array.length]; + initArray(ref); + Arrays.sort(ref); + if (!isArraySorted(array) || !arraysEqual(ref, array)) { + return false; + } + } + insertionSortArraysToVerify.clear(); + return true; + } + + + /* Merge sort */ + + void mergeSort(int array[], int scratch[]) { + mergeSort(array, 0, array.length, scratch); + } + + void mergeSort(int array[], int index, int size, int scratch[]) { + if (size <= 1) { + return; + } + + int index_1 = index; + int size_1 = size / 2; + int index_2 = index + size_1; + int size_2 = size - size_1; + mergeSort(array, index_1, size_1, scratch); + mergeSort(array, index_2, size_2, scratch); + mergeArrays(array, index_1, size_1, index_2, size_2, scratch); + } + + void mergeArrays(int array[], + int index_1, int size_1, + int index_2, int size_2, + int scratch[]) { + int end_1 = index_1 + size_1; + int end_2 = index_2 + size_2; + int i1 = index_1; + int i2 = index_2; + int j = 0; + + while (i1 != end_1 && i2 != end_2) { + if (array[i1] < array[i2]) { + scratch[j] = array[i1]; + ++i1; + } else { + scratch[j] = array[i2]; + ++i2; + } + ++j; + } + + if (i1 != end_1) { + System.arraycopy(array, i1, scratch, j, end_1 - i1); + } + + if (i2 != end_2) { + System.arraycopy(array, i2, scratch, j, end_2 - i2); + } + + System.arraycopy(scratch, 0, array, index_1, size_1 + size_2); + } + + public void benchMergeSort(int arraySize, int iterations) { + int array[] = new int[arraySize]; + int scratch[] = new int[arraySize]; + mergeSortArraysToVerify.add(array); + for (int iter = 0; iter < iterations; ++iter) { + initArray(array); + mergeSort(array, scratch); + } + } + + public boolean verifyMergeSort() { + for (int array[] : mergeSortArraysToVerify) { + int ref[] = new int[array.length]; + initArray(ref); + Arrays.sort(ref); + if (!isArraySorted(array) || !arraysEqual(ref, array)) { + return false; + } + } + mergeSortArraysToVerify.clear(); + return true; + } + + + /* System sort */ + + void systemSort(int array[]) { + // This is wrapped in a helper to match the implementation for other sort + // algorithms. + Arrays.sort(array); + } + + void benchSystemSort(int arraySize, int iterations) { + int array[] = new int[arraySize]; + systemSortArraysToVerify.add(array); + for (int iter = 0; iter < iterations; ++iter) { + initArray(array); + systemSort(array); + } + } + + public boolean verifySystemSort() { + for (int array[] : systemSortArraysToVerify) { + int ref[] = new int[array.length]; + System.arraycopy(array, 0, ref, 0, array.length); + Arrays.sort(ref); + if (!isArraySorted(array) || !arraysEqual(ref, array)) { + return false; + } + } + systemSortArraysToVerify.clear(); + return true; + } + + + // CHECKSTYLE.OFF: LeftCurly + // CHECKSTYLE.OFF: RightCurly + // CHECKSTYLE.OFF: EmptyLineSeparator + public void timeBubbleSort____16(int iterations) { benchBubbleSort( 16, iterations); } + public void timeBubbleSort___128(int iterations) { benchBubbleSort( 128, iterations); } + public void timeBubbleSort__2048(int iterations) { benchBubbleSort( 2048, iterations); } + public void timeInsertionSort____16(int iterations) { benchInsertionSort( 16, iterations); } + public void timeInsertionSort___128(int iterations) { benchInsertionSort( 128, iterations); } + public void timeInsertionSort__2048(int iterations) { benchInsertionSort( 2048, iterations); } + public void timeMergeSort____16(int iterations) { benchMergeSort( 16, iterations); } + public void timeMergeSort___128(int iterations) { benchMergeSort( 128, iterations); } + public void timeMergeSort__2048(int iterations) { benchMergeSort( 2048, iterations); } + public void timeSystemSort____16(int iterations) { benchSystemSort( 16, iterations); } + public void timeSystemSort___128(int iterations) { benchSystemSort( 128, iterations); } + public void timeSystemSort__2048(int iterations) { benchSystemSort( 2048, iterations); } + // CHECKSTYLE.ON: EmptyLineSeparator + // CHECKSTYLE.ON: RightCurly + // CHECKSTYLE.ON: LeftCurly + + + public static void main(String args[]) { + int rc = 0; + long b; // before + long a; // after + Sort o = new Sort(); // object + + // The number of iterations run were calibrated so that each benchmark runs in about one second. + + // CHECKSTYLE.OFF: LineLength + // CHECKSTYLE.OFF: OneStatementPerLine + b = System.currentTimeMillis(); o.timeBubbleSort____16(15000); a = System.currentTimeMillis(); + System.out.println("benchmarks/algo/Sort.BubbleSort____16: " + (a - b)); + b = System.currentTimeMillis(); o.timeBubbleSort___128(250); a = System.currentTimeMillis(); + System.out.println("benchmarks/algo/Sort.BubbleSort___128: " + (a - b)); + b = System.currentTimeMillis(); o.timeBubbleSort__2048(1); a = System.currentTimeMillis(); + System.out.println("benchmarks/algo/Sort.BubbleSort__2048: " + (a - b)); + if (!o.verifyBubbleSort()) { + rc++; + } + + b = System.currentTimeMillis(); o.timeInsertionSort____16(35000); a = System.currentTimeMillis(); + System.out.println("benchmarks/algo/Sort.InsertionSort____16: " + (a - b)); + b = System.currentTimeMillis(); o.timeInsertionSort___128(750); a = System.currentTimeMillis(); + System.out.println("benchmarks/algo/Sort.InsertionSort___128: " + (a - b)); + b = System.currentTimeMillis(); o.timeInsertionSort__2048(3); a = System.currentTimeMillis(); + System.out.println("benchmarks/algo/Sort.InsertionSort__2048: " + (a - b)); + if (!o.verifyInsertionSort()) { + rc++; + } + + b = System.currentTimeMillis(); o.timeMergeSort____16(10000); a = System.currentTimeMillis(); + System.out.println("benchmarks/algo/Sort.MergeSort____16: " + (a - b)); + b = System.currentTimeMillis(); o.timeMergeSort___128(1000); a = System.currentTimeMillis(); + System.out.println("benchmarks/algo/Sort.MergeSort___128: " + (a - b)); + b = System.currentTimeMillis(); o.timeMergeSort__2048(50); a = System.currentTimeMillis(); + System.out.println("benchmarks/algo/Sort.MergeSort__2048: " + (a - b)); + if (!o.verifyMergeSort()) { + rc++; + } + + b = System.currentTimeMillis(); o.timeSystemSort____16(35000); a = System.currentTimeMillis(); + System.out.println("benchmarks/algo/Sort.SystemSort____16: " + (a - b)); + b = System.currentTimeMillis(); o.timeSystemSort___128(2500); a = System.currentTimeMillis(); + System.out.println("benchmarks/algo/Sort.SystemSort___128: " + (a - b)); + b = System.currentTimeMillis(); o.timeSystemSort__2048(125); a = System.currentTimeMillis(); + System.out.println("benchmarks/algo/Sort.SystemSort__2048: " + (a - b)); + if (!o.verifySystemSort()) { + rc++; + } + // CHECKSTYLE.ON: OneStatementPerLine + // CHECKSTYLE.ON: LineLength + + System.exit(rc); + } + + // Array of 2048 integers between 0 and 4096. + public int referenceInputArray[] = { + 2334, 3368, 316, 762, 3183, 3200, 1037, 814, 238, 1882, 3382, 3682, 4034, + 2655, 119, 1820, 1287, 896, 1871, 939, 1478, 3882, 327, 3368, 1764, 3712, + 2363, 2823, 878, 3094, 1961, 3351, 1518, 2658, 2627, 3537, 4096, 1917, 1403, + 183, 61, 1753, 2223, 3080, 2952, 1514, 1291, 1588, 4037, 960, 721, 3470, + 574, 3277, 3068, 3190, 3257, 481, 2698, 2817, 1863, 3671, 2677, 3969, 1403, + 3408, 3829, 2487, 136, 3810, 2247, 1402, 2680, 2255, 1532, 723, 1274, 655, + 2389, 1820, 59, 10, 3981, 3605, 2735, 3959, 1914, 808, 3485, 507, 1345, 545, + 1673, 1056, 4074, 1257, 1165, 1625, 3505, 1686, 3927, 3842, 3216, 276, 1930, + 1578, 2915, 2400, 3401, 1150, 987, 3350, 2338, 2333, 1489, 3395, 2157, 3475, + 2861, 4067, 2135, 2893, 1518, 3298, 1954, 3512, 2219, 576, 3776, 19, 3784, + 3922, 1769, 1000, 2440, 3949, 1725, 55, 2194, 3764, 1178, 615, 1722, 152, + 476, 2947, 2700, 2076, 1985, 1631, 1823, 1300, 62, 1389, 1821, 3313, 1350, + 15, 3015, 3639, 2281, 4039, 2284, 3560, 4044, 764, 163, 3989, 152, 1347, + 3069, 3801, 3256, 301, 71, 1419, 1781, 2832, 2671, 1977, 450, 472, 1834, + 2478, 2735, 1940, 996, 1954, 269, 408, 246, 1995, 2937, 273, 766, 3012, + 1215, 2538, 2222, 480, 157, 60, 3107, 33, 2551, 246, 482, 4000, 700, 90, + 540, 3359, 1436, 344, 3751, 2657, 3406, 2072, 2245, 2896, 127, 2157, 249, + 2185, 813, 336, 2757, 1456, 1, 2565, 3178, 2235, 2069, 759, 1932, 570, 1386, + 2236, 3192, 3138, 2720, 3819, 1111, 3340, 360, 2998, 3344, 2350, 781, 3474, + 1870, 2608, 2456, 3740, 1845, 2802, 1109, 2042, 1671, 1794, 3774, 3073, + 2339, 3191, 374, 668, 1243, 3421, 1541, 3376, 2986, 2209, 167, 1652, 1908, + 3567, 233, 2703, 3753, 3548, 3642, 3703, 3792, 16, 3612, 867, 2130, 1271, + 318, 440, 1097, 350, 2211, 163, 1226, 3265, 3882, 3513, 3651, 316, 523, + 1757, 1691, 718, 3637, 3634, 2677, 3938, 1781, 2890, 683, 2605, 1631, 2673, + 2347, 274, 1726, 1084, 539, 1368, 1448, 225, 3042, 345, 310, 698, 2257, + 3208, 2427, 330, 4091, 463, 2033, 107, 331, 1968, 1339, 3495, 2764, 3114, + 1095, 2693, 3699, 963, 2466, 1517, 1088, 672, 1658, 1345, 2455, 2454, 223, + 469, 3347, 2699, 1937, 2029, 2467, 1735, 2244, 3866, 1214, 1907, 2717, 47, + 2301, 2051, 1156, 2391, 3241, 2644, 912, 2535, 1911, 1350, 854, 2909, 2001, + 4063, 983, 2565, 3495, 1875, 1187, 4025, 1613, 3390, 1376, 3970, 2297, 1511, + 305, 3331, 2630, 1867, 2989, 1718, 2037, 3504, 3628, 1133, 2705, 864, 3325, + 1106, 2662, 2093, 2283, 753, 494, 3, 2892, 2687, 2244, 4044, 2087, 3200, + 1712, 1879, 1197, 2820, 1473, 2045, 3757, 16, 421, 435, 2504, 1236, 1415, + 3889, 1336, 1754, 2679, 2196, 3680, 3431, 385, 744, 3835, 1959, 3117, 2690, + 2990, 3598, 2355, 1242, 2711, 2032, 2145, 3509, 2963, 567, 1549, 772, 1554, + 249, 184, 228, 1631, 361, 1605, 2984, 2287, 571, 2158, 3658, 1401, 383, + 2495, 777, 869, 3625, 952, 3691, 1831, 1350, 1856, 3872, 1960, 2243, 2234, + 2970, 3468, 1180, 3416, 1551, 4088, 4043, 2043, 3889, 539, 1200, 2145, 2346, + 1641, 1303, 2022, 1924, 1342, 3348, 723, 1766, 1170, 2377, 2732, 2995, 1649, + 3766, 1760, 2390, 1193, 451, 2134, 2568, 486, 987, 548, 3733, 2687, 2357, + 4060, 556, 586, 3663, 1410, 1502, 1637, 2670, 874, 2465, 3958, 3091, 1433, + 471, 1251, 2567, 3695, 1768, 2569, 2546, 585, 1767, 1098, 962, 1900, 1943, + 3367, 3878, 3247, 2893, 3627, 3429, 3668, 3800, 369, 4004, 3444, 2820, 1642, + 2090, 1880, 3611, 1964, 1689, 1369, 679, 2033, 2832, 596, 2040, 3932, 856, + 994, 2678, 2486, 737, 1402, 3979, 3183, 2082, 1323, 3093, 1853, 1704, 3546, + 2967, 659, 2559, 400, 668, 3881, 1090, 3153, 1287, 1183, 2884, 2753, 1757, + 2133, 2618, 1581, 2308, 2742, 3596, 3592, 3789, 2704, 2035, 1098, 494, 1896, + 1581, 2384, 2679, 101, 401, 3097, 69, 3251, 1574, 3695, 1287, 3663, 2378, + 1706, 2136, 2847, 2361, 1416, 1556, 2448, 2072, 3539, 1726, 75, 1927, 3933, + 583, 2838, 1993, 2715, 1825, 2538, 3867, 3039, 3757, 1726, 2808, 141, 1378, + 3750, 849, 1592, 342, 288, 97, 1647, 3110, 540, 1231, 3832, 2012, 3065, 393, + 1695, 626, 2258, 2285, 3782, 1227, 3432, 2595, 1980, 225, 403, 912, 1871, + 3255, 3456, 964, 1053, 1006, 1263, 792, 1377, 1573, 176, 2474, 34, 1257, + 409, 717, 1901, 1119, 873, 3322, 2880, 3092, 2199, 797, 1574, 2379, 2541, + 1689, 427, 2586, 2384, 945, 179, 1001, 2777, 2855, 1207, 3187, 210, 2436, + 1862, 3120, 491, 1030, 1890, 3212, 3658, 2933, 2914, 681, 3592, 93, 2709, + 3270, 112, 3239, 2541, 28, 2323, 3735, 39, 364, 86, 1055, 947, 3367, 3778, + 636, 1269, 3045, 116, 296, 3843, 3650, 338, 3408, 145, 1020, 3632, 435, + 4056, 554, 1456, 3931, 3549, 1028, 2169, 2176, 2798, 344, 3291, 3183, 2904, + 2959, 1293, 3176, 557, 1705, 3583, 3297, 2395, 2157, 976, 399, 803, 228, + 3382, 4035, 3951, 3188, 3822, 1158, 3386, 1849, 3777, 1398, 3793, 2749, + 1691, 247, 278, 493, 3061, 3826, 153, 879, 1070, 2355, 1502, 3198, 999, + 2047, 1762, 1753, 2470, 1331, 2190, 1708, 997, 2280, 1863, 1931, 2690, 4074, + 3585, 2030, 3792, 958, 1425, 1707, 506, 2363, 1847, 2721, 3630, 362, 626, + 1012, 784, 2069, 3268, 3060, 2717, 489, 1421, 1287, 3552, 540, 1486, 1306, + 1736, 3397, 2930, 1499, 3337, 57, 2044, 718, 3081, 2252, 3348, 2806, 2335, + 3172, 2126, 3998, 1304, 2460, 2553, 3548, 3457, 1967, 1844, 2973, 2288, 118, + 810, 2469, 1371, 1522, 279, 1963, 1659, 57, 1260, 2275, 3243, 389, 3952, + 465, 1557, 3294, 2064, 382, 1182, 484, 1698, 1170, 572, 4029, 1395, 3521, + 1009, 3313, 4062, 2595, 2559, 2172, 72, 3685, 3803, 1498, 224, 3731, 2441, + 3514, 2479, 1831, 96, 2615, 878, 2216, 352, 1741, 503, 1701, 327, 2966, 916, + 3139, 2295, 3377, 1137, 1714, 3449, 722, 2728, 3608, 1427, 1876, 971, 3573, + 1661, 1008, 2130, 2689, 821, 2946, 1070, 1511, 2574, 3153, 3913, 1552, 3496, + 2448, 1220, 457, 2640, 118, 3010, 3361, 3749, 2266, 3770, 1788, 524, 1802, + 3054, 2271, 3887, 3728, 1749, 2525, 1498, 3421, 35, 3185, 1150, 1452, 3468, + 1289, 2541, 608, 2601, 269, 2097, 1466, 2073, 1542, 1544, 236, 1082, 2626, + 1117, 1462, 2959, 3254, 1435, 1584, 2672, 1452, 1384, 814, 3983, 2447, 859, + 2087, 3211, 2873, 1842, 2524, 4021, 2025, 1824, 342, 3795, 2637, 2490, 1376, + 1647, 3405, 1709, 2148, 861, 305, 3486, 3263, 690, 1410, 341, 1405, 2148, + 439, 3895, 3074, 425, 1108, 1518, 3874, 854, 797, 2417, 840, 3603, 1178, + 3640, 3018, 2911, 675, 578, 657, 2937, 2478, 2216, 1596, 2886, 1540, 1016, + 4, 1331, 2519, 1255, 1134, 2685, 2129, 3927, 3993, 1793, 3279, 817, 3844, + 1372, 3043, 472, 1522, 3667, 3724, 1115, 104, 1084, 1218, 3029, 3767, 2870, + 3170, 3925, 3452, 973, 3400, 928, 751, 2177, 2972, 62, 3708, 3216, 4081, + 2573, 232, 532, 3128, 1400, 1855, 2601, 3443, 1938, 490, 2985, 8, 1906, + 1517, 1040, 14, 817, 2736, 3031, 240, 546, 3833, 3585, 3193, 990, 1687, + 3489, 3669, 1278, 1746, 3673, 3694, 2077, 743, 3534, 880, 2814, 3330, 3714, + 4038, 3426, 2433, 3181, 2441, 2797, 3547, 274, 940, 1937, 2487, 1964, 1565, + 2240, 2976, 784, 1994, 15, 3599, 2234, 2374, 2175, 3704, 301, 95, 3955, + 2064, 896, 1528, 578, 220, 1574, 1072, 2192, 3048, 2556, 2502, 2240, 1915, + 3715, 3794, 3072, 3282, 2572, 3300, 2035, 3078, 2902, 3887, 1721, 3263, + 1009, 1915, 1247, 3648, 350, 3348, 1651, 1276, 3180, 2334, 2578, 3269, 1203, + 1088, 436, 1827, 3548, 2587, 3299, 3949, 2846, 1692, 3043, 2627, 1653, 4062, + 2388, 680, 3926, 166, 639, 1142, 2405, 1421, 3214, 2027, 1428, 2361, 3456, + 2250, 3648, 2972, 533, 3470, 2157, 1847, 1317, 1708, 3781, 785, 2228, 250, + 2563, 906, 1771, 1688, 1587, 3149, 1748, 2180, 3331, 3389, 2294, 423, 1041, + 190, 982, 1994, 755, 2149, 3773, 1922, 3293, 3233, 300, 3402, 846, 1316, + 2397, 2408, 2425, 2857, 3848, 1097, 3559, 3113, 52, 3200, 964, 815, 3382, + 1242, 4034, 2382, 2853, 743, 3592, 3375, 685, 688, 933, 3038, 3825, 446, + 2557, 3657, 2696, 3087, 1866, 4059, 1593, 1171, 164, 1016, 2375, 2373, 3580, + 3586, 208, 2648, 2261, 1487, 1720, 559, 1116, 1666, 3735, 3944, 3875, 422, + 3886, 1370, 3677, 3071, 1797, 2133, 2522, 804, 3164, 1138, 3442, 3937, 2909, + 1765, 3507, 1010, 3145, 1803, 2101, 3072, 2252, 2533, 1617, 3981, 3593, + 1446, 1508, 3070, 754, 3477, 2722, 2573, 2528, 110, 766, 1593, 3906, 1958, + 3712, 2160, 3184, 2577, 821, 3929, 888, 2165, 322, 2508, 516, 4033, 3297, + 3008, 3297, 2073, 757, 2210, 3969, 2033, 481, 3138, 3901, 3578, 1020, 2160, + 237, 3190, 1360, 3553, 3310, 3969, 851, 1804, 1243, 1712, 2506, 3500, 3469, + 720, 3664, 3137, 2173, 186, 2323, 2198, 2382, 3037, 2661, 3213, 664, 1068, + 3244, 2435, 211, 3897, 1976, 1595, 619, 1676, 13, 3431, 2809, 2512, 518, + 2794, 2701, 484, 916, 1572, 970, 786, 1077, 1854, 3864, 1771, 80, 587, 3045, + 2171, 1159, 4085, 511, 370, 3259, 9, 1977, 3555, 961, 3788, 3926, 450, 135, + 277, 515, 2208, 2922, 4063, 1879, 2394, 824, 1827, 824, 405, 1783, 483, + 1718, 1169, 3737, 3441, 2808, 3326, 3481, 3182, 626, 1129, 3495, 3466, 3935, + 83, 401, 3369, 336, 2954, 2355, 3485, 1562, 370, 413, 567, 2818, 3581, 859, + 209, 3382, 2722, 2060, 1476, 855, 601, 3819, 3928, 2099, 3158, 538, 485, + 837, 840, 3176, 3231, 1056, 1528, 3667, 3623, 2400, 790, 2658, 749, 3115, + 254, 1333, 2409, 1334, 2894, 3703, 1644, 1779, 3676, 847, 3745, 1362, 255, + 191, 3153, 2421, 1775, 2068, 2016, 1827, 3279, 852, 2295, 3979, 4038, 2588, + 2132, 606, 496, 3576, 508, 1915, 1261, 1592, 970, 3458, 3183, 3879, 1933, + 2426, 2477, 259, 1953, 2393, 4040, 1130, 2807, 2397, 326, 4044, 61, 2638, + 332, 3219, 2094, 1448, 1416, 2597, 2607, 2340, 3921, 3573, 3556, 3557, 3603, + 264, 1189, 2079, 995, 2188, 1437, 810, 3105, 1828, 498, 3495, 1253, 1165, + 82, 1455, 1916, 2976, 99, 3774, 1784, 1471, 2874, 2121, 3058, 1307, 71, + 1012, 3399, 582, 1713, 918, 1509, 3076, 3313, 1307, 3051, 3074, 2073, 1243, + 825, 3574, 829, 3028, 3849, 2561, 1365, 461, 50, 100, 2088, 607, 651, 1400, + 3572, 1565, 569, 270, 1392, 340, 3706, 2992, 450, 2113, 679, 1381, 3876, + 243, 4013, 366, 1733, 1010, 1445, 1042, 789, 1600, 2786, 1595, 796, 3670, + 987, 3824, 593, 3069, 4014, 2248, 866, 2830, 3896, 354, 2185, 2455, 2467, + 2320, 2107, 1534, 2670, 1978, 2632, 1679, 38, 2260, 1374, 2619, 2966, 1638, + 2447, 2289, 667, 361, 2647, 704, 2704, 3679, 2808, 1940, 1873, 1580, 1259, + 2237, 723, 2154, 2284, 1848, 3076, 2250, 2498, 3334, 361, 3172, 3369, 3468, + 539, 2594, 2385, 1715, 1254, 881, 3530, 2686, 3063, 2654, 145, 2218, 3711, + 3392, 2429, 1275, 3471, 314, 1024, 3971, 1371, 1355, 3974, 3318, 1819, 2714, + 1814, 2031, 555, 2791, 896, 380, 1662, 1377, 3602, 3447, 2729, 684, 2374, + 391, 2868, 2601, 1545, 2449, 1651, 198, 1140, 302, 3546, 2249, 115, 755, + 3324, 1374, 3705, 3587, 3735, 1642, 2067, 452, 3342, 3069, 1232, 698, 2784, + 540, 570, 2657, 511, 1497, 992, 959, 1301, 1707, 2992, 2306, 4019, 1358, + 809, 1967, 1468, 1531, 1919, 1330, 1197, 404, 1364, 1142, 3059, 3067, 1536, + 2546, 1358, 1653, 71, 3120, 2224, 2437, 2927, 2440, 2138, 1114, 824, 2324, + 1726, 3246, 1541, 2062, 3733, 2749, 3844, 1678, 3838, 1938, 2393, 2321, + 3419, 3709, 3162, 1033, 2216, 1799, 2512, 2171, 2826, 2962, 3531, 1548, 911, + 1386, 3111, 265, 3387, 4046, 3869, 899, 1453, 1559, 1177, 1665, 3498, 811, + 3273, 1545, 403, 1785, 263, 2975, 932, 3279, 2709, 1807, 1895, 3470, 3771, + 3649, 766, 265, 3105, 2402, 3065, 3489, 3392, 3325, 1219, 1362, 272, 449, + 89, 1814, 1424, 1929, 3234, 3643, 3773, 862, 3938, 2957, 3773, 415, 1770, + 2999, 3167, 3992, 3640, 405, 2616, 2046, 919, 1019, 324, 2104, 3851, 3795, + 1571, 2779, 2360, 1915, 2773, 1359, 2850, 1891, 480, 589, 2772, 2449, 977, + 2106, 2539, 1262, 1129, 2383, 3092, 4023, 50, 2228, 367, 3644, 1100, 2055, + 2203, 3067, 3062, 42, 313, 3685, 3606, 1462, 3324, 2052, 2355, 2586, 3762, + 2879, 3653, 38, 783, 1262, 1540, 3002, 1466, 1639, 3472, 1801, 3830, 3801, + 2620, 514, 1183, 2361, 3002, 2043, 2020, 3798, 1198, 3151, 942, 4016, 2957, + 4018, 2874, 4095, 1358, 2796, 2728, 3034, 2927, 1224, 1178, 24, 2396, 3422, + 124, 3164, 635, 170, 4083, 3085, 2528, 1685, 3959, 2319, 3832, 3223, 65, + 3899, 48, 3629, 2633, 3241, 2127, 2291, 2725, 1067, 3772, 2948, 2816, 3493, + 3732, 578, 3219, 4026, 635, 2807, 417, 2868, 929, 3072, 3312, 238, 1584, 92, + 807, 2235, 794, 1233, 3815, 4074, 1105, 141, 1315, 1517, 2346, 1132, 3899, + 3904, 3063, 3085, 1630, 1880, 743, 1825, 1793, 2441, 709, 2477, 3382, 348, + 2626 + }; +} + |