Project

General

Profile

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

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

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 org.distorted.objectlib.R;
13
import org.distorted.objectlib.helpers.OperatingSystemInterface;
14

    
15
///////////////////////////////////////////////////////////////////////////////////////////////////
16

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

    
23
///////////////////////////////////////////////////////////////////////////////////////////////////
24

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

    
30
///////////////////////////////////////////////////////////////////////////////////////////////////
31

    
32
  public TBDino4(OperatingSystemInterface os)
33
    {
34
    super(os, new int[] {R.raw.din4_3_pruning2,R.raw.din4_3_pruning3}, new int[] {R.raw.din4_3_pruning7});
35
    }
36

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

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

    
48
///////////////////////////////////////////////////////////////////////////////////////////////////
49
// ditto
50

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

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

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

    
70
///////////////////////////////////////////////////////////////////////////////////////////////////
71

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

    
77
///////////////////////////////////////////////////////////////////////////////////////////////////
78

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

    
84
///////////////////////////////////////////////////////////////////////////////////////////////////
85

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

    
91
///////////////////////////////////////////////////////////////////////////////////////////////////
92

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

    
98
///////////////////////////////////////////////////////////////////////////////////////////////////
99

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

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

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

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

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

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

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

    
130
///////////////////////////////////////////////////////////////////////////////////////////////////
131

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

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

    
141
///////////////////////////////////////////////////////////////////////////////////////////////////
142

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

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

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

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

    
168
    int index2 = index1+1;
169

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

    
181
///////////////////////////////////////////////////////////////////////////////////////////////////
182

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

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

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

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

    
200
    return part;
201
    }
202

    
203
///////////////////////////////////////////////////////////////////////////////////////////////////
204

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

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

    
215
///////////////////////////////////////////////////////////////////////////////////////////////////
216

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

    
225
    return TBDino.getQuatsFromPerm(perm);
226
    }
227

    
228
///////////////////////////////////////////////////////////////////////////////////////////////////
229

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

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

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

    
244
    int newVal=0;
245

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

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

    
255
        newVal++;
256
        }
257
      }
258

    
259
    return part;
260
    }
261

    
262
///////////////////////////////////////////////////////////////////////////////////////////////////
263

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

    
270
///////////////////////////////////////////////////////////////////////////////////////////////////
271

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

    
(7-7/19)