Initial commit to GitHub
The app has existed in play store since 2012, but I am now publishing the source to GitHub.
This commit is contained in:
parent
b52ce90f77
commit
189cc66c47
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module external.linked.project.id="DroidSudSolve" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" type="JAVA_MODULE" version="4">
|
||||||
|
<component name="FacetManager">
|
||||||
|
<facet type="java-gradle" name="Java-Gradle">
|
||||||
|
<configuration>
|
||||||
|
<option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
|
||||||
|
<option name="BUILDABLE" value="false" />
|
||||||
|
</configuration>
|
||||||
|
</facet>
|
||||||
|
</component>
|
||||||
|
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_6" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
|
@ -1 +1,7 @@
|
||||||
# droidsudsolve
|
Sudoku solver for Android (open source)
|
||||||
|
|
||||||
|
This sudoku solver is written by Ashik (ashik@ashikslab.in)
|
||||||
|
using the libexact software library for solving exact cover problems.
|
||||||
|
|
||||||
|
libexact was developed by Petteri Kaski and Olli Pottonen
|
||||||
|
at the Helsinki University of technology.
|
||||||
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4">
|
||||||
|
<component name="FacetManager">
|
||||||
|
<facet type="android-gradle" name="Android-Gradle">
|
||||||
|
<configuration>
|
||||||
|
<option name="GRADLE_PROJECT_PATH" value=":app" />
|
||||||
|
</configuration>
|
||||||
|
</facet>
|
||||||
|
<facet type="android" name="Android">
|
||||||
|
<configuration>
|
||||||
|
<option name="SELECTED_BUILD_VARIANT" value="debug" />
|
||||||
|
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
|
||||||
|
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
|
||||||
|
<afterSyncTasks>
|
||||||
|
<task>generateDebugSources</task>
|
||||||
|
</afterSyncTasks>
|
||||||
|
<option name="ALLOW_USER_CONFIGURATION" value="false" />
|
||||||
|
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
|
||||||
|
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
|
||||||
|
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
|
||||||
|
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
|
||||||
|
</configuration>
|
||||||
|
</facet>
|
||||||
|
<facet type="native-android-gradle" name="Native-Android-Gradle">
|
||||||
|
<configuration>
|
||||||
|
<option name="SELECTED_BUILD_VARIANT" value="debug" />
|
||||||
|
</configuration>
|
||||||
|
</facet>
|
||||||
|
</component>
|
||||||
|
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_6" inherit-compiler-output="false">
|
||||||
|
<output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
|
||||||
|
<output-test url="file://$MODULE_DIR$/build/intermediates/classes/test/debug" />
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$USER_HOME$/Dropbox/workspace/DroidSudSolve/jni">
|
||||||
|
<sourceFolder url="file://$USER_HOME$/Dropbox/workspace/DroidSudSolve/jni" isTestSource="false" />
|
||||||
|
</content>
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/debug" isTestSource="false" generated="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/debug" type="java-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/androidTest/debug" isTestSource="true" generated="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug" type="java-test-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/debug/shaders" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/resources" type="java-test-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/jni" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/shaders" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-classes" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-runtime-classes" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-safeguard" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-verifier" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant-run-resources" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant-run-support" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndkBuild" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/reload-dex" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/restart-dex" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/shaders" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/split-apk" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/transforms" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="jdk" jdkName="Android API 17 Platform" jdkType="Android SDK" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="library" exported="" name="support-v4-18.0.0" level="project" />
|
||||||
|
<orderEntry type="library" exported="" name="gridlayout-v7-18.0.0" level="project" />
|
||||||
|
</component>
|
||||||
|
</module>
|
|
@ -0,0 +1,33 @@
|
||||||
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 17
|
||||||
|
buildToolsVersion "25.0.2"
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId "com.oldestmonk.droidsudsolve"
|
||||||
|
minSdkVersion 8
|
||||||
|
targetSdkVersion 17
|
||||||
|
|
||||||
|
ndk {
|
||||||
|
moduleName "exactcaller"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
externalNativeBuild {
|
||||||
|
ndkBuild {
|
||||||
|
path '../../../Dropbox/workspace/DroidSudSolve/jni/Android.mk'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile 'com.android.support:gridlayout-v7:18.0.0'
|
||||||
|
compile 'com.android.support:support-v4:18.0.0'
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.oldestmonk.droidsudsolve"
|
||||||
|
android:versionCode="1"
|
||||||
|
android:versionName="1.0" >
|
||||||
|
|
||||||
|
<uses-sdk
|
||||||
|
android:minSdkVersion="8"
|
||||||
|
android:targetSdkVersion="17" />
|
||||||
|
<application
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:icon="@drawable/ic_launcher"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:theme="@style/AppTheme" >
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name="com.oldestmonk.droidsudsolve.MainActivity"
|
||||||
|
android:configChanges="orientation"
|
||||||
|
android:screenOrientation="portrait"
|
||||||
|
android:label="@string/app_name" >
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
|
@ -0,0 +1,495 @@
|
||||||
|
package com.oldestmonk.droidsudsolve;
|
||||||
|
|
||||||
|
import android.R.color;
|
||||||
|
import android.content.pm.ActivityInfo;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.text.style.EasyEditSpan;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.TableLayout;
|
||||||
|
import android.widget.TableRow;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.view.ViewGroup.LayoutParams;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
|
import com.oldestmonk.droidsudsolve.R;
|
||||||
|
|
||||||
|
public class MainActivity extends Activity {
|
||||||
|
private static final int MENU_CLEARALL = 1;
|
||||||
|
private static final int MENU_EXITAPP = 2;
|
||||||
|
private TextView[][] tvarray;
|
||||||
|
private Button[] numbtns;
|
||||||
|
int curposinmatrix;
|
||||||
|
protected static final int[] bresids={
|
||||||
|
R.drawable.back1,
|
||||||
|
R.drawable.back2,
|
||||||
|
R.drawable.back3,
|
||||||
|
R.drawable.back8,
|
||||||
|
R.drawable.back9,
|
||||||
|
R.drawable.back4,
|
||||||
|
R.drawable.back7,
|
||||||
|
R.drawable.back6,
|
||||||
|
R.drawable.back5
|
||||||
|
};
|
||||||
|
public MainActivity() {
|
||||||
|
tvarray = new TextView[9][9];
|
||||||
|
numbtns = new Button[10];
|
||||||
|
curposinmatrix = -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
public native int[] exactcaller(int[] jproblem);
|
||||||
|
static {
|
||||||
|
System.loadLibrary("exactcaller");
|
||||||
|
}
|
||||||
|
protected void setTvBack(int i, int j) {
|
||||||
|
|
||||||
|
int ii = i%3;
|
||||||
|
int jj = j%3;
|
||||||
|
int cresid = bresids[ii+jj*3];
|
||||||
|
tvarray[i][j].setBackgroundResource(cresid);
|
||||||
|
}
|
||||||
|
protected void deactivatePreviousTv(int cpinmat) {
|
||||||
|
int i = cpinmat/9;
|
||||||
|
int j = cpinmat%9;
|
||||||
|
tvarray[i][j].setBackgroundColor(Color.WHITE);
|
||||||
|
curposinmatrix = -1;
|
||||||
|
}
|
||||||
|
protected boolean alContainsVal(TreeSet<Integer> al, int val) {
|
||||||
|
for( int x : al )
|
||||||
|
{
|
||||||
|
if(x==val)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
protected void activateTv(int i, int j) {
|
||||||
|
if(curposinmatrix!=-1) {
|
||||||
|
deactivatePreviousTv(curposinmatrix);
|
||||||
|
}
|
||||||
|
tvarray[i][j].setBackgroundColor(Color.YELLOW);
|
||||||
|
curposinmatrix = i*9+j;
|
||||||
|
for(int u=0; u<9; u++) {
|
||||||
|
for(int v=0; v<9; v++) {
|
||||||
|
setTvBack(u,v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tvarray[i][j].setBackgroundColor(Color.YELLOW);
|
||||||
|
}
|
||||||
|
int getValAt(int i, int j) {
|
||||||
|
String str = tvarray[i][j].getText().toString();
|
||||||
|
if(str.equals("")) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return Integer.parseInt(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TreeSet<Integer> getErrors() {
|
||||||
|
TreeSet<Integer> retval = new TreeSet<Integer>();
|
||||||
|
int[][] curvalues = new int[9][9];
|
||||||
|
for(int i=0; i<9; i++) {
|
||||||
|
for(int j=0; j<9; j++) {
|
||||||
|
curvalues[i][j] = getValAt(i, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// row and column checks are done by the following for loop
|
||||||
|
for(int i=0; i<9; i++) {
|
||||||
|
//check for row i and column i
|
||||||
|
for(int j=0; j<9; j++) {
|
||||||
|
for(int k=j+1; k<9; k++) {
|
||||||
|
if(curvalues[i][j]!=0 && (curvalues[i][j]== curvalues[i][k])){
|
||||||
|
retval.add(i*9+j);
|
||||||
|
retval.add(i*9+k);
|
||||||
|
}
|
||||||
|
if(curvalues[j][i]!=0 && (curvalues[j][i]== curvalues[k][i])){
|
||||||
|
retval.add(j*9+i);
|
||||||
|
retval.add(k*9+i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(int ci=0; ci<3; ci++) {
|
||||||
|
for(int cj=0; cj<3; cj++) {
|
||||||
|
int cbegini = ci*3;
|
||||||
|
int cbeginj = cj*3;
|
||||||
|
for(int iti=cbegini; iti<cbegini+3; iti++) {
|
||||||
|
for(int itj = cbeginj; itj<cbeginj+3; itj++) {
|
||||||
|
if(curvalues[iti][itj]!=0) {
|
||||||
|
for(int itii =cbegini; itii<cbegini+3; itii++) {
|
||||||
|
for(int itjj = cbeginj; itjj<cbeginj+3; itjj++) {
|
||||||
|
if((!(iti==itii && itj==itjj))&&
|
||||||
|
(curvalues[itii][itjj]==curvalues[iti][itj])) {
|
||||||
|
retval.add(itii*9+itjj);
|
||||||
|
retval.add(iti*9+itj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void checkValuesAndWarn(int curi, int curj) {
|
||||||
|
for(int i=0; i<9; i++) {
|
||||||
|
for(int j=0; j<9; j++) {
|
||||||
|
setTvBack(i, j);
|
||||||
|
//tvarray[i][j].setBackgroundResource(R.drawable.back);
|
||||||
|
tvarray[i][j].setTextColor(Color.BLACK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TreeSet<Integer> al = getErrors();
|
||||||
|
for (Integer val : al)
|
||||||
|
{
|
||||||
|
int i = val/9;
|
||||||
|
int j = val%9;
|
||||||
|
tvarray[i][j].setTextColor(Color.RED);
|
||||||
|
}
|
||||||
|
if(alContainsVal(al, curi*9+curj)) {
|
||||||
|
activateTv(curi, curj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected void changeValueAt(int curposi, int curposj, int val) {
|
||||||
|
if(val==0) {
|
||||||
|
tvarray[curposi][curposj].setText("");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tvarray[curposi][curposj].setText(String.valueOf(val));
|
||||||
|
}
|
||||||
|
curposinmatrix = -1;
|
||||||
|
checkValuesAndWarn(curposi, curposj);
|
||||||
|
}
|
||||||
|
protected void handleBtnPress(int i) {
|
||||||
|
if(curposinmatrix==-1) {
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
|
builder.setMessage("Please click on a cell to select it, then click on a value to enter that value to the cell!")
|
||||||
|
.setCancelable(false)
|
||||||
|
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
dialog.cancel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
AlertDialog alert = builder.create();
|
||||||
|
alert.show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int curposi = curposinmatrix/9;
|
||||||
|
int curposj = curposinmatrix%9;
|
||||||
|
changeValueAt(curposi, curposj, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void fillSolution(int[] solution, boolean[] wasempty) {
|
||||||
|
for(int n=0; n<81; n++) {
|
||||||
|
int i = n/9;
|
||||||
|
int j = n%9;
|
||||||
|
tvarray[i][j].setText(String.valueOf(solution[n]));
|
||||||
|
if(wasempty[n]) {
|
||||||
|
tvarray[i][j].setTextColor(Color.GREEN);
|
||||||
|
}
|
||||||
|
setTvBack(i, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void fillCell(int i, int j, int val) {
|
||||||
|
tvarray[i][j].setText(String.valueOf(val));
|
||||||
|
tvarray[i][j].setBackgroundColor(Color.GREEN);
|
||||||
|
}
|
||||||
|
boolean isGoodSol(int[] sol) {
|
||||||
|
if(sol[0]==100)
|
||||||
|
return false;
|
||||||
|
for(int i=0; i<81; i++) {
|
||||||
|
if(sol[i]==0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
|
||||||
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
|
TableLayout tl = (TableLayout) findViewById(R.id.sudokutable);
|
||||||
|
|
||||||
|
for (int j = 0; j < 9; j++) {
|
||||||
|
TableRow tr = new TableRow(this);
|
||||||
|
// tr.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
|
||||||
|
// LayoutParams.WRAP_CONTENT));
|
||||||
|
tr.setLayoutParams(new TableRow.LayoutParams(
|
||||||
|
LayoutParams.MATCH_PARENT,0,0.1f));
|
||||||
|
for (int i = 0; i < 9; i++) {
|
||||||
|
TextView tView = new TextView(this);
|
||||||
|
|
||||||
|
tView.setLayoutParams(new TableRow.LayoutParams(0,
|
||||||
|
LayoutParams.WRAP_CONTENT, 1f));
|
||||||
|
//tView.setBackgroundResource(R.drawable.back);
|
||||||
|
tView.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL);
|
||||||
|
// tView.setLayoutParams(new LayoutParams(
|
||||||
|
// LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
|
||||||
|
//set it's height = width
|
||||||
|
|
||||||
|
tr.addView(tView);
|
||||||
|
tvarray[i][j] = tView;
|
||||||
|
|
||||||
|
int cellht = getResources().getDisplayMetrics().widthPixels/11;
|
||||||
|
tView.setHeight(cellht);
|
||||||
|
setTvBack(i,j);
|
||||||
|
final int finali = i;
|
||||||
|
final int finalj = j;
|
||||||
|
tvarray[i][j].setOnClickListener(new TextView.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
activateTv(finali,finalj);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
tl.addView(tr);
|
||||||
|
}
|
||||||
|
TableLayout tnt = (TableLayout) findViewById(R.id.numtable);
|
||||||
|
TableRow tr2 = new TableRow(this);
|
||||||
|
tr2.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
|
||||||
|
LayoutParams.WRAP_CONTENT));
|
||||||
|
int bside = getResources().getDisplayMetrics().widthPixels/10;
|
||||||
|
for(int i=1; i<6; i++) {
|
||||||
|
Button numbtn = new Button(this);
|
||||||
|
|
||||||
|
numbtn.setText(String.valueOf(i));
|
||||||
|
tr2.addView(numbtn);
|
||||||
|
numbtns[i] = numbtn;
|
||||||
|
}
|
||||||
|
tnt.addView(tr2);
|
||||||
|
TableRow tr3 = new TableRow(this);
|
||||||
|
tr3.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
|
||||||
|
LayoutParams.WRAP_CONTENT));
|
||||||
|
for(int i=6; i<10; i++) {
|
||||||
|
Button numbtn = new Button(this);
|
||||||
|
|
||||||
|
numbtn.setText(String.valueOf(i));
|
||||||
|
tr3.addView(numbtn);
|
||||||
|
numbtns[i] = numbtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
Button numbtn = new Button(this);
|
||||||
|
|
||||||
|
numbtn.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL);
|
||||||
|
numbtn.setText("X");
|
||||||
|
numbtn.setBackgroundColor(Color.RED);
|
||||||
|
tr3.addView(numbtn);
|
||||||
|
numbtns[0] = numbtn;
|
||||||
|
tnt.addView(tr3);
|
||||||
|
|
||||||
|
for(int i=0; i<10; i++) {
|
||||||
|
final int finali = i;
|
||||||
|
numbtns[i].setOnClickListener(new TextView.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
handleBtnPress(finali);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
TableRow tr4 = new TableRow(this);
|
||||||
|
tr4.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
|
||||||
|
LayoutParams.MATCH_PARENT));
|
||||||
|
Button hintbtn = new Button(this);
|
||||||
|
hintbtn.setText("Hint");
|
||||||
|
final Activity factivity = this;
|
||||||
|
hintbtn.setOnClickListener(new Button.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
TreeSet<Integer> el = getErrors();
|
||||||
|
if(!el.isEmpty()) {
|
||||||
|
//show alertdialog
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(factivity);
|
||||||
|
builder.setMessage("Error in your input. Please correct values marked in red!")
|
||||||
|
.setCancelable(false)
|
||||||
|
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
dialog.cancel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
AlertDialog alert = builder.create();
|
||||||
|
alert.show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(curposinmatrix==-1 || getValAt(curposinmatrix/9, curposinmatrix%9)!=0) {
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(factivity);
|
||||||
|
builder.setMessage(
|
||||||
|
"First click on an empty cell to select it," +
|
||||||
|
" then click on the Hint Button." +
|
||||||
|
" I will fill that cell with a correct value!")
|
||||||
|
.setCancelable(false)
|
||||||
|
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
dialog.cancel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
AlertDialog alert = builder.create();
|
||||||
|
alert.show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int ci = curposinmatrix/9;
|
||||||
|
int cj = curposinmatrix%9;
|
||||||
|
final int[] jproblem = new int[81];
|
||||||
|
for(int i=0; i<9; i++) {
|
||||||
|
|
||||||
|
for(int j=0; j<9; j++) {
|
||||||
|
jproblem[i*9+j] = getValAt(i, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int[] solution = exactcaller(jproblem);
|
||||||
|
if(isGoodSol(solution)) {
|
||||||
|
fillCell(ci, cj, solution[ci*9+cj]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(factivity);
|
||||||
|
builder.setMessage("The puzzle you entered has no solutions!")
|
||||||
|
.setCancelable(false)
|
||||||
|
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
dialog.cancel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
AlertDialog alert = builder.create();
|
||||||
|
alert.show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tr4.addView(hintbtn);
|
||||||
|
|
||||||
|
Button solvebtn = new Button(this);
|
||||||
|
solvebtn.setText("SOLVE!");
|
||||||
|
//final Activity factivity = this;
|
||||||
|
solvebtn.setOnClickListener(new Button.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
TreeSet<Integer> el = getErrors();
|
||||||
|
if(!el.isEmpty()) {
|
||||||
|
//show alertdialog
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(factivity);
|
||||||
|
builder.setMessage("Error in your input. Please correct values marked in red!")
|
||||||
|
.setCancelable(false)
|
||||||
|
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
dialog.cancel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
AlertDialog alert = builder.create();
|
||||||
|
alert.show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final int[] jproblem = new int[81];
|
||||||
|
for(int i=0; i<9; i++) {
|
||||||
|
|
||||||
|
for(int j=0; j<9; j++) {
|
||||||
|
jproblem[i*9+j] = getValAt(i, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final boolean[] wasempty = new boolean[81];
|
||||||
|
for(int i=0; i<81; i++) {
|
||||||
|
if(jproblem[i]==0) {
|
||||||
|
wasempty[i] = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
wasempty[i] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int[] solution = exactcaller(jproblem);
|
||||||
|
if(isGoodSol(solution)) {
|
||||||
|
fillSolution(solution, wasempty);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(factivity);
|
||||||
|
builder.setMessage("The puzzle you entered has no solutions!")
|
||||||
|
.setCancelable(false)
|
||||||
|
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
dialog.cancel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
AlertDialog alert = builder.create();
|
||||||
|
alert.show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tr4.addView(solvebtn);
|
||||||
|
TableLayout abtnt = (TableLayout) findViewById(R.id.actionbtntable);
|
||||||
|
abtnt.addView(tr4);
|
||||||
|
|
||||||
|
}
|
||||||
|
protected void clearAllCells() {
|
||||||
|
for(int i=0; i<9; i++) {
|
||||||
|
for(int j=0; j<9;j++) {
|
||||||
|
tvarray[i][j].setTextColor(Color.BLACK);
|
||||||
|
tvarray[i][j].setText("");
|
||||||
|
//tvarray[i][j].setBackgroundResource(R.drawable.back);
|
||||||
|
setTvBack(i, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
// Inflate the menu; this adds items to the action bar if it is present.
|
||||||
|
menu.add(0, MENU_CLEARALL, 0, "Clear All");
|
||||||
|
menu.add(0, MENU_EXITAPP, 0, "Exit App");
|
||||||
|
//getMenuInflater().inflate(R.menu.main, menu);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
|
||||||
|
case MENU_CLEARALL:
|
||||||
|
clearAllCells();
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case MENU_EXITAPP:
|
||||||
|
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
|
||||||
|
this);
|
||||||
|
// set title
|
||||||
|
alertDialogBuilder.setTitle("Quit?!");
|
||||||
|
|
||||||
|
alertDialogBuilder
|
||||||
|
.setMessage("Do you really want to quit?")
|
||||||
|
.setCancelable(false)
|
||||||
|
.setPositiveButton("Yes",
|
||||||
|
new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
// if this button is clicked, close
|
||||||
|
// current activity
|
||||||
|
MainActivity.this.finish();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setNegativeButton("No", new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
dialog.cancel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// create alert dialog
|
||||||
|
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||||
|
|
||||||
|
// show it
|
||||||
|
alertDialog.show();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Copyright (C) 2009 The Android Open Source Project
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
LOCAL_PATH := $(call my-dir)
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := exactcaller
|
||||||
|
LOCAL_SRC_FILES := exactcaller.c exact.c util.c
|
||||||
|
|
||||||
|
include $(BUILD_SHARED_LIBRARY)
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* libexact v1.0 --- a software library for solving combinatorial
|
||||||
|
* exact covering problems
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 Petteri Kaski <petteri.kaski@cs.helsinki.fi>
|
||||||
|
* Olli Pottonen <olli.pottonen@tkk.fi>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************** Library interface. */
|
||||||
|
|
||||||
|
#ifndef EXACT_READ
|
||||||
|
#define EXACT_READ
|
||||||
|
|
||||||
|
struct exact_struct;
|
||||||
|
typedef struct exact_struct exact_t;
|
||||||
|
typedef int exact_level_t (void *, int, const int *);
|
||||||
|
typedef int exact_filter_t (void *, int, const int *, int);
|
||||||
|
|
||||||
|
/* Initializing and releasing an instance. */
|
||||||
|
|
||||||
|
exact_t * exact_alloc (void);
|
||||||
|
void exact_free (exact_t *e);
|
||||||
|
|
||||||
|
/* Declaring an instance. */
|
||||||
|
|
||||||
|
void exact_declare_row (exact_t *e, int i, int b);
|
||||||
|
void exact_declare_col (exact_t *e, int j, int u);
|
||||||
|
void exact_declare_entry (exact_t *e, int i, int j);
|
||||||
|
int exact_can_declare (exact_t *e);
|
||||||
|
|
||||||
|
/* Iterating through the solutions. */
|
||||||
|
|
||||||
|
const int * exact_solve (exact_t *e, int *n);
|
||||||
|
void exact_reset_solve (exact_t *e);
|
||||||
|
|
||||||
|
/* Examining an instance. */
|
||||||
|
|
||||||
|
int exact_is_row (exact_t *e, int i);
|
||||||
|
int exact_is_col (exact_t *e, int j);
|
||||||
|
int exact_is_entry (exact_t *e, int i, int j);
|
||||||
|
int exact_num_rows (exact_t *e);
|
||||||
|
int exact_num_cols (exact_t *e);
|
||||||
|
int exact_get_rows (exact_t *e, int *i);
|
||||||
|
int exact_get_cols (exact_t *e, int *j);
|
||||||
|
|
||||||
|
/* Forcing a partial solution. */
|
||||||
|
|
||||||
|
void exact_push (exact_t *e, int j);
|
||||||
|
void exact_pop (exact_t *e);
|
||||||
|
int exact_pushable (exact_t *e, int j);
|
||||||
|
int exact_can_push (exact_t *e);
|
||||||
|
int exact_num_push (exact_t *e);
|
||||||
|
int exact_get_push (exact_t *e, int *j);
|
||||||
|
|
||||||
|
/* Controlling the search. */
|
||||||
|
|
||||||
|
void exact_level (exact_t *e, exact_level_t *l, void *p);
|
||||||
|
void exact_filter (exact_t *e, exact_filter_t *f, void *p);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,142 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <string.h>
|
||||||
|
#include <jni.h>
|
||||||
|
#include "exact.h"
|
||||||
|
|
||||||
|
/* This is a trivial JNI example where we use a native method
|
||||||
|
* to return a new VM String. See the corresponding Java source
|
||||||
|
* file located at:
|
||||||
|
*
|
||||||
|
* apps/samples/hello-jni/project/src/com/example/hellojni/HelloJni.java
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define UNDEF -1
|
||||||
|
static void solve_sudoku(int *a)
|
||||||
|
{
|
||||||
|
exact_t *e = exact_alloc();
|
||||||
|
|
||||||
|
/* Row--column */
|
||||||
|
int r, v, c, s;
|
||||||
|
for(r = 0; r < 9; r++)
|
||||||
|
for(c = 0; c < 9; c++)
|
||||||
|
exact_declare_row(e, 9*r+c, 1);
|
||||||
|
/* Row--value */
|
||||||
|
for(r = 0; r < 9; r++)
|
||||||
|
for(v = 0; v < 9; v++)
|
||||||
|
exact_declare_row(e, 81+9*r+v, 1);
|
||||||
|
/* Column--value */
|
||||||
|
for(c = 0; c < 9; c++)
|
||||||
|
for(v = 0; v < 9; v++)
|
||||||
|
exact_declare_row(e, 162+9*c+v, 1);
|
||||||
|
/* Subsquare--value */
|
||||||
|
for(s = 0; s < 9; s++)
|
||||||
|
for(v = 0; v < 9; v++)
|
||||||
|
exact_declare_row(e, 243+9*s+v, 1);
|
||||||
|
/* Row--column--value */
|
||||||
|
for(r = 0; r < 9; r++) {
|
||||||
|
for(c = 0; c < 9; c++) {
|
||||||
|
s = 3*(r/3)+c/3;
|
||||||
|
for(v = 0; v < 9; v++) {
|
||||||
|
exact_declare_col(e, 9*9*r+9*c+v, 1);
|
||||||
|
|
||||||
|
/* Row--column */
|
||||||
|
exact_declare_entry(e, 9*r+c, 9*9*r+9*c+v);
|
||||||
|
|
||||||
|
/* Row--value */
|
||||||
|
exact_declare_entry(e, 81+9*r+v, 9*9*r+9*c+v);
|
||||||
|
|
||||||
|
/* Column--value */
|
||||||
|
exact_declare_entry(e, 162+9*c+v, 9*9*r+9*c+v);
|
||||||
|
|
||||||
|
/* Subsquare--value */
|
||||||
|
exact_declare_entry(e, 243+9*s+v, 9*9*r+9*c+v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Push the columns corresponding to the given partial solution. */
|
||||||
|
for(r = 0; r < 9; r++) {
|
||||||
|
for(c = 0; c < 9; c++) {
|
||||||
|
if(a[9*r+c] != UNDEF) {
|
||||||
|
int j = 9*9*r+9*c+a[9*r+c];
|
||||||
|
if(!exact_pushable(e, j)) {
|
||||||
|
/* The partial solution is conflicting. */
|
||||||
|
a[0]=100;
|
||||||
|
goto solve_done;
|
||||||
|
}
|
||||||
|
exact_push(e, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* List all complete solutions. */
|
||||||
|
int n, i;
|
||||||
|
const int *b;
|
||||||
|
while((b = exact_solve(e, &n)) != NULL) {
|
||||||
|
/* Put the solution into matrix form. */
|
||||||
|
for(i = 0; i < n; i++) {
|
||||||
|
int r = b[i]/81;
|
||||||
|
int c = b[i]/9; c = c%9;
|
||||||
|
int v = b[i]%9;
|
||||||
|
a[9*r+c] = v;
|
||||||
|
}
|
||||||
|
return; /*added by ashik- since i need only one soltion */
|
||||||
|
/* Rewind the matrix. */
|
||||||
|
/* for(int i = exact_num_push(e); i < n; i++) { */
|
||||||
|
/* int r = b[i]/81; */
|
||||||
|
/* int c = b[i]/9; c = c%9; */
|
||||||
|
/* a[9*r+c] = UNDEF; */
|
||||||
|
/* } */
|
||||||
|
}
|
||||||
|
solve_done:
|
||||||
|
exact_free(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
jintArray
|
||||||
|
Java_com_oldestmonk_droidsudsolve_MainActivity_exactcaller( JNIEnv* env,
|
||||||
|
jobject thiz,
|
||||||
|
jintArray jproblem )
|
||||||
|
{
|
||||||
|
jintArray result;
|
||||||
|
int size = 81;
|
||||||
|
jint cproblem[81];
|
||||||
|
(*env)->GetIntArrayRegion(env, jproblem, 0, size, cproblem);
|
||||||
|
result = (*env)->NewIntArray(env, size);
|
||||||
|
if (result == NULL) {
|
||||||
|
return NULL; /* out of memory error thrown */
|
||||||
|
}
|
||||||
|
|
||||||
|
int a[81];
|
||||||
|
int i;
|
||||||
|
for(i=0; i<81; i++) {
|
||||||
|
a[i] = cproblem[i]-1;
|
||||||
|
}
|
||||||
|
solve_sudoku(a);
|
||||||
|
for(i=0; i<81; i++) {
|
||||||
|
cproblem[i] = a[i]+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fill a temp structure to use to populate the java int array
|
||||||
|
jint fill[81];
|
||||||
|
for (i = 0; i < size; i++) {
|
||||||
|
fill[i] = cproblem[i]; // put whatever logic you want.
|
||||||
|
}
|
||||||
|
// move from the temp structure to the java structure
|
||||||
|
(*env)->SetIntArrayRegion(env, result, 0, size, fill);
|
||||||
|
return result;
|
||||||
|
}
|
|
@ -0,0 +1,377 @@
|
||||||
|
/*
|
||||||
|
* libexact v1.0 --- a software library for solving combinatorial
|
||||||
|
* exact covering problems
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 Petteri Kaski <petteri.kaski@cs.helsinki.fi>
|
||||||
|
* Olli Pottonen <olli.pottonen@tkk.fi>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*********************************************** Internal utility functions. */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
int exact_mem_alloc_balance = 0;
|
||||||
|
|
||||||
|
void *exact_mem_alloc(size_t size)
|
||||||
|
{
|
||||||
|
exact_mem_alloc_balance++;
|
||||||
|
void *p = malloc(size);
|
||||||
|
if(p == NULL)
|
||||||
|
EXACT_ERROR("malloc fails");
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void exact_mem_free(void *p)
|
||||||
|
{
|
||||||
|
exact_mem_alloc_balance--;
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct exact_chunk_struct
|
||||||
|
{
|
||||||
|
int num_entries;
|
||||||
|
int num_alloc;
|
||||||
|
size_t entry_size;
|
||||||
|
void *data;
|
||||||
|
struct exact_chunk_struct *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
exact_chunk_t *exact_chunk_alloc(size_t entry, int entries)
|
||||||
|
{
|
||||||
|
exact_chunk_t *c = (exact_chunk_t *) EXACT_ALLOC(sizeof(exact_chunk_t));
|
||||||
|
c->num_entries = entries;
|
||||||
|
c->num_alloc = 0;
|
||||||
|
c->entry_size = entry;
|
||||||
|
c->data = EXACT_ALLOC(c->entry_size * c->num_entries);
|
||||||
|
c->next = NULL;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void exact_chunk_free(exact_chunk_t *c)
|
||||||
|
{
|
||||||
|
while(c != NULL) {
|
||||||
|
exact_chunk_t *t = c->next;
|
||||||
|
EXACT_FREE(c->data);
|
||||||
|
EXACT_FREE(c);
|
||||||
|
c = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *exact_chunk_get(exact_chunk_t *c)
|
||||||
|
{
|
||||||
|
if(c->num_alloc >= c->num_entries) {
|
||||||
|
exact_chunk_t *n =
|
||||||
|
(exact_chunk_t *) EXACT_ALLOC(sizeof(exact_chunk_t));
|
||||||
|
n->num_entries = c->num_entries;
|
||||||
|
n->num_alloc = c->num_alloc;
|
||||||
|
n->entry_size = c->entry_size;
|
||||||
|
n->data = c->data;
|
||||||
|
n->next = c->next;
|
||||||
|
c->next = n;
|
||||||
|
c->num_entries = 2*c->num_entries;
|
||||||
|
c->data = EXACT_ALLOC(c->entry_size * c->num_entries);
|
||||||
|
c->num_alloc = 0;
|
||||||
|
}
|
||||||
|
return ((char *) c->data) + c->entry_size*c->num_alloc++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void exact_error(const char *fn, int line, const char *func,
|
||||||
|
const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
fprintf(stderr,
|
||||||
|
"ERROR [detected by libexact interface; file = %s, line = %d]\n"
|
||||||
|
"%s: ",
|
||||||
|
fn,
|
||||||
|
line,
|
||||||
|
func);
|
||||||
|
vfprintf(stderr, format, args);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
va_end(args);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
void exact_internal_error(const char *fn, int line, const char *func,
|
||||||
|
const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
fprintf(stderr,
|
||||||
|
"ERROR [libexact internal error; file = %s, line = %d]\n"
|
||||||
|
"%s: ",
|
||||||
|
fn,
|
||||||
|
line,
|
||||||
|
func);
|
||||||
|
vfprintf(stderr, format, args);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
va_end(args);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************** Map from keys to values -- implemented as an AVL tree. */
|
||||||
|
|
||||||
|
struct avl_node_struct;
|
||||||
|
|
||||||
|
typedef struct avl_node_struct
|
||||||
|
{
|
||||||
|
void * key;
|
||||||
|
void * value;
|
||||||
|
struct avl_node_struct * left;
|
||||||
|
struct avl_node_struct * right;
|
||||||
|
int height;
|
||||||
|
} avl_node_t;
|
||||||
|
|
||||||
|
struct exact_map_struct
|
||||||
|
{
|
||||||
|
avl_node_t * root;
|
||||||
|
exact_chunk_t * node_chunk;
|
||||||
|
exact_chunk_t * key_chunk;
|
||||||
|
size_t key_size;
|
||||||
|
exact_map_cmp_t * cmp_f;
|
||||||
|
|
||||||
|
void * active_key;
|
||||||
|
void ** active_value_p;
|
||||||
|
int path_length;
|
||||||
|
int path_capacity;
|
||||||
|
avl_node_t *** path;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define AVL_CHUNK_SIZE 128
|
||||||
|
#define PATH_CAPACITY_START 32
|
||||||
|
|
||||||
|
static void enlarge_path(exact_map_t *m, int capacity)
|
||||||
|
{
|
||||||
|
EXACT_FREE(m->path);
|
||||||
|
m->path_capacity = capacity;
|
||||||
|
m->path = EXACT_ALLOC(sizeof(avl_node_t **)*m->path_capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void exact_map_init(exact_map_t *m, size_t key, exact_map_cmp_t *f)
|
||||||
|
{
|
||||||
|
m->key_size = key;
|
||||||
|
m->root = NULL;
|
||||||
|
m->active_value_p = NULL;
|
||||||
|
m->node_chunk = exact_chunk_alloc(sizeof(avl_node_t), AVL_CHUNK_SIZE);
|
||||||
|
m->key_chunk = exact_chunk_alloc(m->key_size, AVL_CHUNK_SIZE);
|
||||||
|
m->path_capacity = PATH_CAPACITY_START;
|
||||||
|
m->path = EXACT_ALLOC(sizeof(avl_node_t **)*m->path_capacity);
|
||||||
|
m->path_length = 0;
|
||||||
|
m->active_key = EXACT_ALLOC(m->key_size);
|
||||||
|
m->cmp_f = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void exact_map_release(exact_map_t *m)
|
||||||
|
{
|
||||||
|
EXACT_FREE(m->active_key);
|
||||||
|
EXACT_FREE(m->path);
|
||||||
|
exact_chunk_free(m->key_chunk);
|
||||||
|
exact_chunk_free(m->node_chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
exact_map_t *exact_map_alloc(size_t key, exact_map_cmp_t *f)
|
||||||
|
{
|
||||||
|
exact_map_t *m = (exact_map_t *) EXACT_ALLOC(sizeof(exact_map_t));
|
||||||
|
exact_map_init(m, key, f);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
void exact_map_free(exact_map_t *m)
|
||||||
|
{
|
||||||
|
exact_map_release(m);
|
||||||
|
EXACT_FREE(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int height(avl_node_t *n)
|
||||||
|
{
|
||||||
|
if(n == NULL)
|
||||||
|
return -1;
|
||||||
|
return n->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
int exact_map_find(exact_map_t *m, void *key)
|
||||||
|
{
|
||||||
|
memcpy(m->active_key, key, m->key_size);
|
||||||
|
avl_node_t *n = m->root;
|
||||||
|
int t = height(n)+2;
|
||||||
|
if(t > m->path_capacity)
|
||||||
|
enlarge_path(m, 2*t);
|
||||||
|
m->path_length = 1;
|
||||||
|
m->path[0] = &m->root;
|
||||||
|
while(n != NULL) {
|
||||||
|
t = m->cmp_f(n->key, m->active_key);
|
||||||
|
if(t == 0) {
|
||||||
|
m->active_value_p = &n->value;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(t > 0) {
|
||||||
|
m->path[m->path_length++] = &n->left;
|
||||||
|
n = n->left;
|
||||||
|
} else {
|
||||||
|
m->path[m->path_length++] = &n->right;
|
||||||
|
n = n->right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m->active_value_p = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *exact_map_value(exact_map_t *m)
|
||||||
|
{
|
||||||
|
void **av = m->active_value_p;
|
||||||
|
if(av == NULL)
|
||||||
|
EXACT_INTERNAL_ERROR("no value available");
|
||||||
|
return *av;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max(int a, int b)
|
||||||
|
{
|
||||||
|
return a > b ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* AVL outer rotation:
|
||||||
|
*
|
||||||
|
* d b
|
||||||
|
* / \ <--- left --- / \
|
||||||
|
* b E A d
|
||||||
|
* / \ --- right --> / \
|
||||||
|
* A C C E
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
static avl_node_t *rotate_outer_right(avl_node_t *d)
|
||||||
|
{
|
||||||
|
avl_node_t *b = d->left;
|
||||||
|
d->left = b->right;
|
||||||
|
b->right = d;
|
||||||
|
|
||||||
|
d->height = max(height(d->left), height(d->right)) + 1;
|
||||||
|
b->height = max(height(b->left), height(b->right)) + 1;
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static avl_node_t *rotate_outer_left(avl_node_t *b)
|
||||||
|
{
|
||||||
|
avl_node_t *d = b->right;
|
||||||
|
b->right = d->left;
|
||||||
|
d->left = b;
|
||||||
|
|
||||||
|
b->height = max(height(b->left), height(b->right)) + 1;
|
||||||
|
d->height = max(height(d->left), height(d->right)) + 1;
|
||||||
|
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* AVL inner rotation right:
|
||||||
|
*
|
||||||
|
* f f d
|
||||||
|
* / \ / \ / \
|
||||||
|
* b G --- b left --> d G -- f right --> / \
|
||||||
|
* / \ / \ b f
|
||||||
|
* A d b E / \ / \
|
||||||
|
* / \ / \ A C E G
|
||||||
|
* C E A C
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
static avl_node_t *rotate_inner_right(avl_node_t *f)
|
||||||
|
{
|
||||||
|
f->left = rotate_outer_left(f->left);
|
||||||
|
return rotate_outer_right(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* AVL inner rotation left:
|
||||||
|
*
|
||||||
|
* b b d
|
||||||
|
* / \ / \ / \
|
||||||
|
* A f -- f right --> A d --- b left --> / \
|
||||||
|
* / \ / \ b f
|
||||||
|
* d G C f / \ / \
|
||||||
|
* / \ / \ A C E G
|
||||||
|
* C E E G
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
static avl_node_t *rotate_inner_left(avl_node_t *b)
|
||||||
|
{
|
||||||
|
b->right = rotate_outer_right(b->right);
|
||||||
|
return rotate_outer_left(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void exact_map_associate(exact_map_t *m, void *v)
|
||||||
|
{
|
||||||
|
void **av = m->active_value_p;
|
||||||
|
if(av != NULL) {
|
||||||
|
*av = v;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(m->path_length == 0)
|
||||||
|
EXACT_INTERNAL_ERROR("no query issued");
|
||||||
|
|
||||||
|
avl_node_t *n = exact_chunk_get(m->node_chunk);
|
||||||
|
n->left = NULL;
|
||||||
|
n->right = NULL;
|
||||||
|
n->height = 0;
|
||||||
|
n->key = exact_chunk_get(m->key_chunk);
|
||||||
|
n->value = v;
|
||||||
|
memcpy(n->key, m->active_key, m->key_size);
|
||||||
|
|
||||||
|
m->active_value_p = &n->value;
|
||||||
|
avl_node_t **p = m->path[--m->path_length];
|
||||||
|
*p = n;
|
||||||
|
|
||||||
|
while(m->path_length > 0) {
|
||||||
|
p = m->path[--m->path_length];
|
||||||
|
avl_node_t *nn = n;
|
||||||
|
n = *p;
|
||||||
|
/* A child of n was updated to the value nn. */
|
||||||
|
if(n->left == nn) {
|
||||||
|
/* Left child of n was updated. */
|
||||||
|
if(height(n->left) - height(n->right) == 2) {
|
||||||
|
/* Left subtree is too high after update, must rebalance. */
|
||||||
|
if(height(n->left->left) + 1 == n->left->height) {
|
||||||
|
/* The cause is the left--left subtree. */
|
||||||
|
n = rotate_outer_right(n);
|
||||||
|
} else {
|
||||||
|
/* The cause is the left--right subtree. */
|
||||||
|
n = rotate_inner_right(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Right child of n was updated. */
|
||||||
|
if(height(n->right) - height(n->left) == 2) {
|
||||||
|
/* Right child is too high after update, must rebalance. */
|
||||||
|
if(height(n->right->right) + 1 == n->right->height) {
|
||||||
|
/* The cause is the right--right subtree. */
|
||||||
|
n = rotate_outer_left(n);
|
||||||
|
} else {
|
||||||
|
/* The cause is the right--left subtree. */
|
||||||
|
n = rotate_inner_left(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n->height = max(height(n->left),
|
||||||
|
height(n->right)) + 1;
|
||||||
|
*p = n;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
* libexact v1.0 --- a software library for solving combinatorial
|
||||||
|
* exact covering problems
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 Petteri Kaski <petteri.kaski@cs.helsinki.fi>
|
||||||
|
* Olli Pottonen <olli.pottonen@tkk.fi>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/************************************ Internal utility functions and macros. */
|
||||||
|
|
||||||
|
#ifndef EXACT_UTIL_READ
|
||||||
|
#define EXACT_UTIL_READ
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
void * exact_mem_alloc (size_t size);
|
||||||
|
void exact_mem_free (void *p);
|
||||||
|
|
||||||
|
#define EXACT_ALLOC(s) exact_mem_alloc(s)
|
||||||
|
#define EXACT_FREE(p) exact_mem_free(p)
|
||||||
|
|
||||||
|
struct exact_chunk_struct;
|
||||||
|
typedef struct exact_chunk_struct exact_chunk_t;
|
||||||
|
|
||||||
|
exact_chunk_t * exact_chunk_alloc (size_t entry, int entries);
|
||||||
|
void exact_chunk_free (exact_chunk_t *c);
|
||||||
|
void * exact_chunk_get (exact_chunk_t *c);
|
||||||
|
|
||||||
|
struct exact_map_struct;
|
||||||
|
typedef struct exact_map_struct exact_map_t;
|
||||||
|
typedef int exact_map_cmp_t (const void *, const void *);
|
||||||
|
|
||||||
|
exact_map_t * exact_map_alloc (size_t key, exact_map_cmp_t *f);
|
||||||
|
void exact_map_free (exact_map_t *m);
|
||||||
|
int exact_map_find (exact_map_t *m, void *k);
|
||||||
|
void * exact_map_value (exact_map_t *m);
|
||||||
|
void exact_map_associate (exact_map_t *m, void *v);
|
||||||
|
|
||||||
|
void exact_error (const char *fn,
|
||||||
|
int line,
|
||||||
|
const char *func,
|
||||||
|
const char *format, ...);
|
||||||
|
|
||||||
|
void exact_internal_error (const char *fn,
|
||||||
|
int line,
|
||||||
|
const char *func,
|
||||||
|
const char *format, ...);
|
||||||
|
|
||||||
|
#define EXACT_ERROR(...) exact_error(__FILE__,__LINE__,__func__,__VA_ARGS__);
|
||||||
|
#define EXACT_INTERNAL_ERROR(...) \
|
||||||
|
exact_internal_error(__FILE__,__LINE__,__func__,__VA_ARGS__);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||||
|
<item>
|
||||||
|
<shape
|
||||||
|
android:shape="rectangle">
|
||||||
|
<stroke android:width="1dp" android:color="#FF000000" />
|
||||||
|
<solid android:color="#FFDDDDDD" />
|
||||||
|
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
<item android:left="3dp" android:top="3dp">
|
||||||
|
<shape
|
||||||
|
android:shape="rectangle">
|
||||||
|
<stroke android:width="2dp" android:color="#000000" />
|
||||||
|
<solid android:color="#00000000" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
</layer-list>
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||||
|
<item>
|
||||||
|
<shape
|
||||||
|
android:shape="rectangle">
|
||||||
|
<stroke android:width="1dp" android:color="#FF000000" />
|
||||||
|
<solid android:color="#FFDDDDDD" />
|
||||||
|
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
<item android:top="3dp">
|
||||||
|
<shape
|
||||||
|
android:shape="rectangle">
|
||||||
|
<stroke android:width="2dp" android:color="#000000" />
|
||||||
|
<solid android:color="#00000000" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
</layer-list>
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||||
|
<item>
|
||||||
|
<shape
|
||||||
|
android:shape="rectangle">
|
||||||
|
<stroke android:width="1dp" android:color="#FF000000" />
|
||||||
|
<solid android:color="#FFDDDDDD" />
|
||||||
|
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
<item android:top="3dp" android:right="3dp">
|
||||||
|
<shape
|
||||||
|
android:shape="rectangle">
|
||||||
|
<stroke android:width="2dp" android:color="#000000" />
|
||||||
|
<solid android:color="#00000000" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
</layer-list>
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||||
|
<item>
|
||||||
|
<shape
|
||||||
|
android:shape="rectangle">
|
||||||
|
<stroke android:width="1dp" android:color="#FF000000" />
|
||||||
|
<solid android:color="#FFDDDDDD" />
|
||||||
|
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
<item android:right="3dp">
|
||||||
|
<shape
|
||||||
|
android:shape="rectangle">
|
||||||
|
<stroke android:width="2dp" android:color="#000000" />
|
||||||
|
<solid android:color="#00000000" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
</layer-list>
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||||
|
<item>
|
||||||
|
<shape
|
||||||
|
android:shape="rectangle">
|
||||||
|
<stroke android:width="1dp" android:color="#FF000000" />
|
||||||
|
<solid android:color="#FFDDDDDD" />
|
||||||
|
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
<item android:right="3dp" android:bottom="3dp">
|
||||||
|
<shape
|
||||||
|
android:shape="rectangle">
|
||||||
|
<stroke android:width="2dp" android:color="#000000" />
|
||||||
|
<solid android:color="#00000000" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
</layer-list>
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||||
|
<item>
|
||||||
|
<shape
|
||||||
|
android:shape="rectangle">
|
||||||
|
<stroke android:width="1dp" android:color="#FF000000" />
|
||||||
|
<solid android:color="#FFDDDDDD" />
|
||||||
|
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
<item android:bottom="3dp">
|
||||||
|
<shape
|
||||||
|
android:shape="rectangle">
|
||||||
|
<stroke android:width="2dp" android:color="#000000" />
|
||||||
|
<solid android:color="#00000000" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
</layer-list>
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||||
|
<item>
|
||||||
|
<shape
|
||||||
|
android:shape="rectangle">
|
||||||
|
<stroke android:width="1dp" android:color="#FF000000" />
|
||||||
|
<solid android:color="#FFDDDDDD" />
|
||||||
|
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
<item android:bottom="3dp" android:left="3dp">
|
||||||
|
<shape
|
||||||
|
android:shape="rectangle">
|
||||||
|
<stroke android:width="2dp" android:color="#000000" />
|
||||||
|
<solid android:color="#00000000" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
</layer-list>
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||||
|
<item>
|
||||||
|
<shape
|
||||||
|
android:shape="rectangle">
|
||||||
|
<stroke android:width="1dp" android:color="#FF000000" />
|
||||||
|
<solid android:color="#FFDDDDDD" />
|
||||||
|
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
<item android:left="3dp">
|
||||||
|
<shape
|
||||||
|
android:shape="rectangle">
|
||||||
|
<stroke android:width="2dp" android:color="#000000" />
|
||||||
|
<solid android:color="#00000000" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
</layer-list>
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||||
|
<item>
|
||||||
|
<shape
|
||||||
|
android:shape="rectangle">
|
||||||
|
<stroke android:width="1dp" android:color="#FF000000" />
|
||||||
|
<solid android:color="#FFDDDDDD" />
|
||||||
|
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<shape
|
||||||
|
android:shape="rectangle">
|
||||||
|
<stroke android:width="2dp" android:color="#000000" />
|
||||||
|
<solid android:color="#00000000" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</layer-list>
|
Binary file not shown.
After Width: | Height: | Size: 2.4 KiB |
|
@ -0,0 +1,31 @@
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||||
|
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||||
|
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||||
|
android:paddingTop="@dimen/activity_vertical_margin"
|
||||||
|
tools:context=".MainActivity" >
|
||||||
|
|
||||||
|
<TableLayout
|
||||||
|
android:id="@+id/sudokutable"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="64" >
|
||||||
|
</TableLayout>
|
||||||
|
|
||||||
|
<TableLayout
|
||||||
|
android:id="@+id/numtable"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="24" >
|
||||||
|
</TableLayout>
|
||||||
|
<TableLayout
|
||||||
|
android:id="@+id/actionbtntable"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="12" >
|
||||||
|
</TableLayout>
|
||||||
|
</LinearLayout>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_settings"
|
||||||
|
android:orderInCategory="100"
|
||||||
|
android:showAsAction="never"
|
||||||
|
android:title="@string/action_settings"/>
|
||||||
|
|
||||||
|
</menu>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Customize dimensions originally defined in res/values/dimens.xml (such as
|
||||||
|
screen margins) for sw600dp devices (e.g. 7" tablets) here.
|
||||||
|
-->
|
||||||
|
|
||||||
|
</resources>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Customize dimensions originally defined in res/values/dimens.xml (such as
|
||||||
|
screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here.
|
||||||
|
-->
|
||||||
|
<dimen name="activity_horizontal_margin">128dp</dimen>
|
||||||
|
|
||||||
|
</resources>
|
|
@ -0,0 +1,11 @@
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Base application theme for API 11+. This theme completely replaces
|
||||||
|
AppBaseTheme from res/values/styles.xml on API 11+ devices.
|
||||||
|
-->
|
||||||
|
<style name="AppBaseTheme" parent="android:Theme.Holo.Light">
|
||||||
|
<!-- API 11 theme customizations can go here. -->
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</resources>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Base application theme for API 14+. This theme completely replaces
|
||||||
|
AppBaseTheme from BOTH res/values/styles.xml and
|
||||||
|
res/values-v11/styles.xml on API 14+ devices.
|
||||||
|
-->
|
||||||
|
<style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
|
||||||
|
<!-- API 14 theme customizations can go here. -->
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</resources>
|
|
@ -0,0 +1,7 @@
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||||
|
<dimen name="activity_horizontal_margin">16dp</dimen>
|
||||||
|
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||||
|
|
||||||
|
</resources>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<string name="app_name">Monk\'s Sudoku Solver </string>
|
||||||
|
<string name="action_settings">Settings</string>
|
||||||
|
<string name="hello_world">Hello India!</string>
|
||||||
|
|
||||||
|
</resources>
|
|
@ -0,0 +1,20 @@
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Base application theme, dependent on API level. This theme is replaced
|
||||||
|
by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
|
||||||
|
-->
|
||||||
|
<style name="AppBaseTheme" parent="android:Theme.Light">
|
||||||
|
<!--
|
||||||
|
Theme customizations available in newer API levels can go in
|
||||||
|
res/values-vXX/styles.xml, while customizations related to
|
||||||
|
backward-compatibility can go here.
|
||||||
|
-->
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- Application theme. -->
|
||||||
|
<style name="AppTheme" parent="AppBaseTheme">
|
||||||
|
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</resources>
|
|
@ -0,0 +1,15 @@
|
||||||
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:2.3.2'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
include ':app'
|
Loading…
Reference in New Issue