Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / tablebases / TBDino4.java @ a76bb8f6

1
///////////////////////////////////////////////////////////////////////////////////////////////////
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
import android.content.res.Resources;
13

    
14
import org.distorted.objectlib.R;
15

    
16
///////////////////////////////////////////////////////////////////////////////////////////////////
17

    
18
public class TBDino4 extends TBDino
19
{
20
  private static final int[][] SAME = {{0,3,7},{1,2,5},{4,8,9},{6,10,11}};
21
  private static final int SOLVED1 =  6237;  // partition 011021302233
22
  private static final int SOLVED2 = 10837;  // partition 001102133223
23

    
24
///////////////////////////////////////////////////////////////////////////////////////////////////
25

    
26
  public TBDino4()
27
    {
28
    super();
29
    }
30

    
31
///////////////////////////////////////////////////////////////////////////////////////////////////
32

    
33
  public TBDino4(Resources res)
34
    {
35
    super(res, new int[] {R.raw.din4_3_pruning2,R.raw.din4_3_pruning3}, new int[] {R.raw.din4_3_pruning7});
36
    }
37

    
38
///////////////////////////////////////////////////////////////////////////////////////////////////
39
// specifically for the tablebase
40
///////////////////////////////////////////////////////////////////////////////////////////////////
41
// two solved positions: original and mirrored (left face swapped with right)
42

    
43
  @Override
44
  int[] getSolvedIndices()
45
    {
46
    return new int[] {SOLVED1,SOLVED2};
47
    }
48

    
49
///////////////////////////////////////////////////////////////////////////////////////////////////
50
// ditto
51

    
52
  @Override
53
  boolean isSolved(int index)
54
    {
55
    return index==SOLVED1 || index==SOLVED2;
56
    }
57

    
58
///////////////////////////////////////////////////////////////////////////////////////////////////
59
// 15408 really (see https://www.jaapsch.net/puzzles/dinocube.htm)
60
// Here 15400 because we equal positions where colors are simply swapped (those are the same with
61
// respect to distance to the 2 solved positions) so there are (11 choose 2)*(8 choose 2)*(5 choose 2)
62
// = 55*28*10 = 15400 possibilities.
63
// We do not pack those tightly, some positions in the same orbit (by Burnside lemma) have 3 different
64
// indices.
65

    
66
  int getSize()
67
    {
68
    return 15400;
69
    }
70

    
71
///////////////////////////////////////////////////////////////////////////////////////////////////
72

    
73
  int getMinScramble()
74
    {
75
    return 5;
76
    }
77

    
78
///////////////////////////////////////////////////////////////////////////////////////////////////
79

    
80
  int[] getMidPruningLevels()
81
    {
82
    return new int[] {2,3};
83
    }
84

    
85
///////////////////////////////////////////////////////////////////////////////////////////////////
86

    
87
  int[] getHighPruningLevels()
88
    {
89
    return new int[] {7};
90
    }
91

    
92
///////////////////////////////////////////////////////////////////////////////////////////////////
93

    
94
  int getGodsNumber()
95
    {
96
    return 7;
97
    }
98

    
99
///////////////////////////////////////////////////////////////////////////////////////////////////
100

    
101
  private static int computeIndex(int[] partition, int section, int size)
102
    {
103
    int index0=0;
104

    
105
    for(;index0<12; index0++)
106
      if(partition[index0]==section ) break;
107

    
108
    int index1=index0+1;
109
    int D1 = 0;
110

    
111
    for(;index1<12; index1++)
112
      {
113
      int val = partition[index1];
114
      if(val >section ) D1++;
115
      if(val==section ) break;
116
      }
117

    
118
    int index2=index1+1;
119
    int D2 = 0;
120

    
121
    for(;index2<12; index2++)
122
      {
123
      int val = partition[index2];
124
      if(val >section ) D2++;
125
      if(val==section ) break;
126
      }
127

    
128
    return D1*size - (D1+1)*D1/2 + D2;
129
    }
130

    
131
///////////////////////////////////////////////////////////////////////////////////////////////////
132

    
133
  public static int indexFromPartition(int[] partition)
134
    {
135
    int index0 = computeIndex(partition,0,11);
136
    int index1 = computeIndex(partition,1,8);
137
    int index2 = computeIndex(partition,2,5);
138

    
139
    return index0 + 55*(index1 + 28*index2);
140
    }
141

    
142
///////////////////////////////////////////////////////////////////////////////////////////////////
143

    
144
  private static void fillPart(int[] part, int index, int section, int size)
145
    {
146
    int index0=0;
147

    
148
    for(; index0<10; index0++)
149
      if( part[index0]<0 )
150
        {
151
        part[index0] = section;
152
        break;
153
        }
154

    
155
    int index1 = index0+1;
156
    int diff = size-1;
157

    
158
    for(; index1<11; index1++)
159
      if( part[index1]<0 )
160
        {
161
        if( index<diff )
162
          {
163
          part[index1] = section;
164
          break;
165
          }
166
        else { index-=diff; diff--; }
167
        }
168

    
169
    int index2 = index1+1;
170

    
171
    for(; index2<12; index2++)
172
      {
173
      if( part[index2]<0 ) index--;
174
      if( index<0 )
175
        {
176
        part[index2] = section;
177
        break;
178
        }
179
      }
180
    }
181

    
182
///////////////////////////////////////////////////////////////////////////////////////////////////
183

    
184
  private static int[] partitionFromIndex(int index)
185
    {
186
    int index0 = (index%55);
187
    index /= 55;
188
    int index1 = (index%28);
189
    int index2 = (index/28);
190

    
191
    int[] part = new int[12];
192
    for(int i=0; i<12; i++) part[i] = -1;
193

    
194
    fillPart(part,index0,0,11);
195
    fillPart(part,index1,1,8);
196
    fillPart(part,index2,2,5);
197

    
198
    for(int i=0; i<12; i++)
199
      if( part[i]<0 ) part[i] = 3;
200

    
201
    return part;
202
    }
203

    
204
///////////////////////////////////////////////////////////////////////////////////////////////////
205

    
206
  private static void fillPerm(int[] perm, int[] part, int section)
207
    {
208
    int num=0;
209
    int[] same = SAME[section];
210

    
211
    for(int i=0; i<12; i++)
212
      if( part[i]==section )
213
        perm[same[num++]] = i;
214
    }
215

    
216
///////////////////////////////////////////////////////////////////////////////////////////////////
217

    
218
  private static int[] quatsFromPartition(int[] partition)
219
    {
220
    int[] perm = new int[12];
221
    fillPerm(perm,partition,0);
222
    fillPerm(perm,partition,1);
223
    fillPerm(perm,partition,2);
224
    fillPerm(perm,partition,3);
225

    
226
    return TBDino6.getQuatsFromPerm(perm);
227
    }
228

    
229
///////////////////////////////////////////////////////////////////////////////////////////////////
230

    
231
  private static int[] partitionFromQuats(int[] quats)
232
    {
233
    int[] perm = new int[12];
234
    System.arraycopy(quats, 0, perm, 0, 12);
235
    TBDino6.getPermFromQuats(perm);
236

    
237
    int[] part = new int[12];
238

    
239
    for(int i=0; i<4; i++)
240
      {
241
      int[] index = SAME[i];
242
      part[perm[index[0]]] = part[perm[index[1]]] = part[perm[index[2]]] = (-i-1);
243
      }
244

    
245
    int newVal=0;
246

    
247
    for(int i=0; i<12; i++)
248
      {
249
      int val = part[i];
250

    
251
      if( val<0 )
252
        {
253
        for(int j=i; j<12; j++)
254
          if( part[j]==val ) part[j] = newVal;
255

    
256
        newVal++;
257
        }
258
      }
259

    
260
    return part;
261
    }
262

    
263
///////////////////////////////////////////////////////////////////////////////////////////////////
264

    
265
  int[] getQuats(int index)
266
    {
267
    int[] partition = partitionFromIndex(index);
268
    return quatsFromPartition(partition);
269
    }
270

    
271
///////////////////////////////////////////////////////////////////////////////////////////////////
272

    
273
  int getIndex(int[] quats)
274
    {
275
    normalizeQuats(quats);
276
    int[] partition = partitionFromQuats(quats);
277
    return indexFromPartition(partition);
278
    }
279
}  
280

    
(6-6/17)