Project

General

Profile

Download (6.34 KB) Statistics
| Branch: | Revision:

distorted-objectlib / src / main / java / org / distorted / objectlib / tablebases / TablebaseHelpers.java @ 6777e712

1 f9980f6a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2023 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8
///////////////////////////////////////////////////////////////////////////////////////////////////
9
10
package org.distorted.objectlib.tablebases;
11
12 74cc695a Leszek Koltunski
import java.util.Random;
13
14 f9980f6a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
15
16
public class TablebaseHelpers
17
{
18 74cc695a Leszek Koltunski
19 d6e2cf37 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
20
21 68b59ec3 Leszek Koltunski
  public static void displayTable(int[] table, String marker)
22 d6e2cf37 Leszek Koltunski
    {
23
    StringBuilder sb = new StringBuilder();
24
25
    for( int t : table )
26
      {
27
      sb.append(' ');
28
      sb.append(t);
29
      }
30
31
    android.util.Log.e("D", marker+" : "+sb);
32
    }
33
34 74cc695a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
35
36
  private static String print(int[][] move)
37
    {
38
    StringBuilder sb = new StringBuilder();
39
40
    if( move==null )
41
      {
42
      return ("move NULL!!");
43
      }
44
45
    for (int[] ints : move)
46
      {
47
      sb.append(' ');
48
      sb.append('(');
49
      sb.append(ints[0]);
50
      sb.append(' ');
51
      sb.append(ints[1]);
52
      sb.append(' ');
53
      sb.append(ints[2]);
54
      sb.append(')');
55
      }
56
57
    return sb.toString();
58
    }
59
60
///////////////////////////////////////////////////////////////////////////////////////////////////
61
62
  public static void test(TablebasesAbstract tb)
63
    {
64
    int size = tb.getSize();
65
66
    for(int i=0; i<size; i++)
67
      {
68
      boolean success = tb.test(i);
69
70
      if( (!success && i>0) || (success && i==0) )
71
        {
72
        android.util.Log.e("D", "--------> FAILED: "+i);
73
        break;
74
        }
75
76
      if( (i%1000)==0 )   android.util.Log.e("D", "trying "+i);
77
      }
78
    }
79
80
///////////////////////////////////////////////////////////////////////////////////////////////////
81
82 a80e95e4 Leszek Koltunski
  private final static int MAX_PERM=12;  // biggest N for which N! is still less than 2^32
83
  private final static int[] avail = new int[MAX_PERM];
84
  private final static int[] pos   = new int[MAX_PERM];
85
  private final static int[] fact  = new int[MAX_PERM];
86 74cc695a Leszek Koltunski
87 a80e95e4 Leszek Koltunski
  static
88
    {
89
    fact[0] = 1;
90
    for(int i=1; i<MAX_PERM; i++) fact[i] = fact[i-1]*i;
91 6777e712 leszek
    }
92 74cc695a Leszek Koltunski
93
///////////////////////////////////////////////////////////////////////////////////////////////////
94
95 a80e95e4 Leszek Koltunski
  public static void getPermutationFromNum(int[] buffer,int permSize, int permNum)
96 f9980f6a Leszek Koltunski
    {
97 a80e95e4 Leszek Koltunski
    avail[0] = pos[0] = 0;
98
    for(int i=1; i<permSize; i++) avail[i] = pos[i] = permSize-i;
99 f9980f6a Leszek Koltunski
100 a80e95e4 Leszek Koltunski
    for(int i=0; i<permSize-1; i++)
101 f9980f6a Leszek Koltunski
      {
102 a80e95e4 Leszek Koltunski
      int m = fact[permSize-1-i];
103
      int k = permNum/m;
104
      permNum %= m;
105
      buffer[i] = avail[k];
106
      int y = avail[permSize-1-i];
107
      pos[y] = k;
108
      avail[k] = y;
109 f9980f6a Leszek Koltunski
      }
110
111 a80e95e4 Leszek Koltunski
    buffer[permSize-1] = avail[0];
112 f9980f6a Leszek Koltunski
    }
113
114
///////////////////////////////////////////////////////////////////////////////////////////////////
115 a80e95e4 Leszek Koltunski
// Enumeration of permutations in linear time.
116
// 1) notice that 'avail' and 'pos' are always inverses: avail[m]=n iff pos[n]=m
117
// 2) notice that that implies that after the i-th execution of the loop, avail[0 ... n-1-i]
118
//    contains the n-i elements of the permutation we haven't scanned yet
119
//    ( that is because this is true initially, and during each loop, we remove avail[k] from
120
//      this list - but k = pos[buffer[i]] implies buffer[i] = avail[k] so we are really removing
121
//      buffer[i] - i.e. exactly the permutation element we have just scanned! )
122
// 3) each 'k' is a digit of the permutation in a strange ( n-1,n-2,...,2 ) notation where the most
123
//    significant digit can be one of the {0...,n-1}, the next most significant - one of the {0,...,n-2},
124
//    etc.
125
// 4) the ret = ret*(permSize-i) + k is a transform from this ( n-1,n-2,...,2 ) notation to an index.
126 d4212e97 Leszek Koltunski
//
127
// 'avail' is initially set to {0,n-1,n-2,...,2,1} because that implies that an 'empty' permutation
128
//  gets mapped to index=0.
129 a80e95e4 Leszek Koltunski
130
  public static int computePermutationNum(int[] buffer)
131 f9980f6a Leszek Koltunski
    {
132 a80e95e4 Leszek Koltunski
    int permSize = buffer.length;
133
    avail[0] = pos[0] = 0;
134
    for(int i=1; i<permSize; i++) avail[i] = pos[i] = permSize-i;
135 f9980f6a Leszek Koltunski
136
    int ret = 0;
137
138 a80e95e4 Leszek Koltunski
    for(int i=0; i<permSize-1; i++)
139 f9980f6a Leszek Koltunski
      {
140 a80e95e4 Leszek Koltunski
      int k = pos[buffer[i]];
141
      ret = ret*(permSize-i) + k;
142
      int y = avail[permSize-1-i];
143
      pos[y] = k;
144
      avail[k] = y;
145 f9980f6a Leszek Koltunski
      }
146
147
    return ret;
148
    }
149
150
///////////////////////////////////////////////////////////////////////////////////////////////////
151
152 a80e95e4 Leszek Koltunski
  public static int computeEvenPermutationNum(int[] buffer)
153 f9980f6a Leszek Koltunski
    {
154 a80e95e4 Leszek Koltunski
    int index = computePermutationNum(buffer);
155
    return index/2;
156
    }
157 f9980f6a Leszek Koltunski
158 a80e95e4 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
159 f9980f6a Leszek Koltunski
160 a80e95e4 Leszek Koltunski
  public static void getEvenPermutationFromNum(int[] buffer, int permNum)
161
    {
162
    getPermutationFromNum(buffer, buffer.length, 2*permNum);
163
    boolean even = permutationIsEven(buffer);
164
    if( !even ) getPermutationFromNum(buffer, buffer.length, 2*permNum+1 );
165 4d63b066 Leszek Koltunski
    }
166
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168
169 a80e95e4 Leszek Koltunski
  private static int swaps(int val, int[] buffer, int len)
170 4d63b066 Leszek Koltunski
    {
171
    int ret = 0;
172
173 a80e95e4 Leszek Koltunski
    for(int i=0; i<len; i++)
174 4d63b066 Leszek Koltunski
      {
175 a80e95e4 Leszek Koltunski
           if( buffer[i] >val ) ret++;
176
      else if( buffer[i]==val ) return ret;
177 4d63b066 Leszek Koltunski
      }
178
179 a80e95e4 Leszek Koltunski
    return -1;
180 4d63b066 Leszek Koltunski
    }
181 f9980f6a Leszek Koltunski
182 4d63b066 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
183
184 a80e95e4 Leszek Koltunski
  public static boolean permutationIsEven(int[] buffer)
185 4d63b066 Leszek Koltunski
    {
186 a80e95e4 Leszek Koltunski
    int len = buffer.length;
187
    int numOfSwaps = 0;
188
    for(int i=0; i<len-1; i++) numOfSwaps += swaps(i,buffer,len);
189
    return (numOfSwaps%2==0);
190 f9980f6a Leszek Koltunski
    }
191 8a489ebd Leszek Koltunski
192
///////////////////////////////////////////////////////////////////////////////////////////////////
193
194
  public static void invertPermutation(int[] perm, int[] output)
195
    {
196
    int len = perm.length;
197 43780264 Leszek Koltunski
    for(int i=0; i<len; i++) output[i] = -1;
198 8a489ebd Leszek Koltunski
    for(int i=0; i<len; i++) output[perm[i]] = i;
199
    }
200 f9980f6a Leszek Koltunski
}