Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ android {

defaultConfig {
applicationId "atorch.statspuzzles"
minSdkVersion 19
minSdkVersion 21
targetSdkVersion 35
versionCode 32
versionName "4.0"
Expand All @@ -51,18 +51,18 @@ android {
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'org.mariuszgromada.math:MathParser.org-mXparser:6.1.0'

implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.9.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.navigation:navigation-fragment:2.5.3'
implementation 'androidx.navigation:navigation-ui:2.5.3'
implementation 'androidx.appcompat:appcompat:1.7.1'
implementation 'com.google.android.material:material:1.12.0'
implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
implementation 'androidx.navigation:navigation-fragment:2.9.5'
implementation 'androidx.navigation:navigation-ui:2.9.5'
implementation 'androidx.viewpager2:viewpager2:1.1.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.6.1'
implementation fileTree(dir: 'libs', include: ['*.aar', '*.jar'], exclude: [])
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The module still includes a local fileTree(dir: 'libs', include: ['*.aar', '*.jar']) dependency, but there is no app/libs directory in the repo. Since this PR migrates mXparser to Maven, consider removing this fileTree (or narrowing it to specific artifacts) to avoid confusion and accidental re-introduction of local JARs later.

Suggested change
implementation fileTree(dir: 'libs', include: ['*.aar', '*.jar'], exclude: [])

Copilot uses AI. Check for mistakes.
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.10"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.2.20"
}
Binary file removed app/libs/mXparser-v.4.2.0-jdk.1.7.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<string name="app_name">Probability Puzzles</string>
<string name="new_in_this_update">This is version 4.0, released in October 2025 &#8212; now with over ninety puzzles, zero ads, and translations in Spanish, German, and Arabic. Enjoy!
\n\nSome of the puzzles in this app will be difficult if you haven\'t studied probability. Need to brush up? Have a look at this\u00A0<a href="https://chance.dartmouth.edu/teaching_aids/books_articles/probabilityccc_book/book-5-17-03.pdf">Dartmouth book</a> and these\u00A0<a href="https://ocw.mit.edu/courses/mathematics/18-440-probability-and-random-variables-spring-2014/lecture-notes/">MIT notes</a>. You could also read through some probability problems at\u00A0<a href="https://math.stackexchange.com/questions/tagged/probability">math.stackexchange.com</a>. If you prefer to watch lectures on youtube, try\u00A0<a href="https://www.youtube.com/playlist?list=PLUl4u3cNGP60hI9ATjSFgLZpbNJ7myAg6">these</a> or\u00A0<a href="https://www.youtube.com/playlist?list=PLUl4u3cNGP60A3XMwZ5sep719_nh95qOe">these</a>.
\n\nThis app is full of math puzzles, and uses Mariusz Gromada\'s mXparser version 4.2.0 to translate mathematical expressions to numbers: it\'ll understand .2, 0.2, 20\%, or 1/5. The parser also understands factorials and binomial coefficients: try typing 5!/(3!*2!) or\u00A0<a href="https://en.wikipedia.org/wiki/Binomial_coefficient">C(5,3)</a> with a capital C for \"5 choose 3.\" You can also type lowercase e for the base of the natural logarithm. Visit\u00A0<a href="http://mathparser.org">mathparser.org</a> for more information.
\n\nThis app is full of math puzzles, and uses Mariusz Gromada\'s mXparser version 6.1.0 to translate mathematical expressions to numbers: it\'ll understand .2, 0.2, 20\%, or 1/5. The parser also understands factorials and binomial coefficients: try typing 5!/(3!*2!) or\u00A0<a href="https://en.wikipedia.org/wiki/Binomial_coefficient">C(5,3)</a> with a capital C for \"5 choose 3.\" You can also type lowercase e for the base of the natural logarithm. Visit\u00A0<a href="http://mathparser.org">mathparser.org</a> for more information.
\n\nIf you\'d like to contribute to the app (or peek at solutions), have a look at its\u00A0<a href="https://github.com/atorch/probability_puzzles">github repo</a>!</string>

<string name="app_link">Challenge yourself with probability puzzles &#8212; install the app at https://play.google.com/store/apps/details?id=atorch.statspuzzles</string>
Expand Down
83 changes: 81 additions & 2 deletions app/src/test/java/atorch/statspuzzles/AnswerCheckerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,93 @@ public class AnswerCheckerTest {

@Test
public void testCorrectAnswer() {
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("2+2", "4"));
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("1/2", "0.5"));
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("2 + 2", "4"));
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("1/ 2", "0.5"));
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("3!", "6.0"));
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("1/(3!)", "0.16666666"));
// Note that we have a Result.INACCURATE version of this test as well
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("1/3", "0.33333333333333"));
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("C(5, 3)", "10"));
}

@Test
public void testCombinations() {
// Test various combination expressions that users might enter
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("C(8, 6)", "28"));
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("C(10, 2)", "45"));
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("C(52, 5)", "2598960"));
}

@Test
public void testEulersNumber() {
// Test expressions involving e
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("1/e", "0.36787944"));
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("e^2", "7.389056"));
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("1-1/e", "0.63212056"));
}

@Test
public void testNegativeExponents() {
// Test negative exponents that users might enter
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("4^-1", "0.25"));
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("2^-3", "0.125"));
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("10 ^ -2", "0.01"));
}

@Test
public void testPercentages() {
// Test percentage expressions
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("50%", "0.5"));
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("25%", "0.25"));
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("100%", "1"));
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("1%", "0.01"));
}

@Test
public void testSpacingAndEquivalentExpressions() {
// Test that spacing variations and mathematically equivalent expressions are accepted
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("C(7,3)", "C(7, 3)"));
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("C(7, 3)", "C(7,4)"));
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("4!", "4 * 3!"));
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("12!/(4!*4!*4!)", "12! / ((4!)^3)"));
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("1/2 + (1/2)*49/99", "1/2+(49/2) * 1/99"));
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("(4/52)*(3/51)", "( 4 * 3 ) / (51 *52)"));
}

@Test
public void testEquivalentFormats() {
// Test that the app accepts equivalent formats as documented in the intro
// .2, 0.2, 20%, and 1/5 should all be equivalent
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("0.2", ".2"));
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("0.2", "20%"));
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("0.2", "1/5"));
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("1/5", "20%"));

// .4, 0.4, 40%, 4/10, and 2*1/5 should all be equivalent
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("0.4", ".4"));
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("0.4", "40%"));
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("0.4", "4/10"));
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("0.4", "2*1/5"));

// Factorial equivalents: 4! = 4*3*2 = 24
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("4!", "4*3*2"));
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("4!", "24"));

// Combination equivalents: C(5,3) = 5!/(3!*2!)
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("C(5,3)", "5!/(3!*2!)"));

// Exponent equivalents: .49^3 = .49*.49*.49
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer(".49^3", ".49*.49*.49"));
}

@Test
public void testPiConstant() {
// Test that pi constant works
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("pi", "3.14159265"));
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("pi / 4", "0.78539816"));
assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("2*pi", "6.28318531"));
}

@Test
public void testInaccurateAnswer() {
assertEquals(AnswerChecker.Result.INACCURATE, AnswerChecker.checkAnswer("1/3", "0.333"));
Expand All @@ -24,6 +102,7 @@ public void testInaccurateAnswer() {
@Test
public void testIncorrectAnswer() {
assertEquals(AnswerChecker.Result.INCORRECT, AnswerChecker.checkAnswer("1", "2"));
assertEquals(AnswerChecker.Result.INCORRECT, AnswerChecker.checkAnswer("0.50", "0.49"));
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a stray tab-indented assertion here; it’s inconsistent with the surrounding indentation and may fail style checks. Please align it with the other assertEquals lines (spaces, same indent level).

Suggested change
assertEquals(AnswerChecker.Result.INCORRECT, AnswerChecker.checkAnswer("0.50", "0.49"));
assertEquals(AnswerChecker.Result.INCORRECT, AnswerChecker.checkAnswer("0.50", "0.49"));

Copilot uses AI. Check for mistakes.
// The user's answer is not close enough to be considered merely inaccurate.
assertEquals(AnswerChecker.Result.INCORRECT, AnswerChecker.checkAnswer("1/3", "0.33"));
}
Expand Down
Loading