Skip to content

Commit

Permalink
Merge pull request #66 from arnaud-m/v0.5.0-beta
Browse files Browse the repository at this point in the history
Format the code, fix checkstyle errors, and improve code coverage
close #58
  • Loading branch information
arnaud-m authored Nov 23, 2022
2 parents 265e6a2 + 7324084 commit 2bd8893
Show file tree
Hide file tree
Showing 86 changed files with 4,761 additions and 4,416 deletions.
199 changes: 199 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
# Contributing to Cryptator

The Cryptator team encourages community feedback and contributions.
Thank you for your interest in making Dux Machina better! There are several ways you can get involved.

If you are looking for a good way to contribute to the project, please:

* have a look at the [available issue templates](https://github.com/arnaud-m/cryptator/issues/new/choose)
and checkout the [examples of good first issues](https://github.com/arnaud-m/cryptator/contribute)
(or [click here](https://github.com/arnaud-m/cryptator/labels/good%20first%20issue)).

* look through the [issues that need help](https://github.com/arnaud-m/cryptator/labels/help%20wanted).

* take a look at a [Pull Request template](PULL_REQUEST_TEMPLATE.md) to get yourself
started.

## Reporting issues and suggesting new features

If you find that the project is not working properly, please file a report using
the [Bug Report template](https://github.com/arnaud-m/cryptator/issues/new?assignees=&labels=bug&template=bug_report.md&title=[BUG]).
Should the template provided not suit your needs, feel free to make a
[custom Bug Report](https://github.com/arnaud-m/cryptator/issues/new/choose),
but please label it accordingly.

We are happy to hear your ideas for how to further improve cryptator,
ensuring it suits your needs. Check the [Issues](https://github.com/arnaud-m/cryptator/issues)
and see if others have submitted similar feedback. You can upvote existing feedback
(using the thumbs up reaction/by commenting) or [submit a new suggestion](https://github.com/arnaud-m/cryptator/labels/feature).

We always look at upvoted items in [Issues](https://github.com/arnaud-m/cryptator/issues)
when we decide what to work on next. We read the comments and we look forward to
hearing your input.

## Finding issues you can help with

Looking for something to work on?
Issues marked [`good first issue`](https://github.com/arnaud-m/cryptator/labels/good%20first%20issue)
are a good place to start.

You can also check the [`help wanted`](https://github.com/arnaud-m/cryptator/labels/help%20wanted)
tag to find other issues to help with. If you're interested in working on a fix,
leave a comment to let everyone know and to help avoid duplicated effort from others.

## Contributions we accept

We highly appreciate any contributions that help us improve the end product, with
a high emphasis being put on any bug fixes you can manage to create and direct
improvements which address the top issues reported by Calculator users. Some general
guidelines:

### DOs

* **DO** create one pull request per Issue, and ensure that the Issue is linked
in the pull request. You can follow the [Pull Request Template](PULL_REQUEST_TEMPLATE.md)
for this.

* **DO** follow our [Coding and Style](#style-guidelines) guidelines, and keep code
changes as small as possible.

* **DO** include corresponding tests whenever possible.

* **DO** check for additional occurrences of the same problem in other parts of the
codebase before submitting your PR.

* **DO** link the issue you are addressing in the pull request.

* **DO** write a good description for your pull request. More detail is better.
Describe *why* the change is being made and *why* you have chosen a particular solution.
Describe any manual testing you performed to validate your change.

### DO NOTs

* **DO NOT** merge multiple changes into one PR unless they have the same root cause.
* **DO NOT** merge directly into the master branch.

> Submitting a pull request for an approved Issue is not a guarantee it will be approved.
> The change must meet our high bar for code quality, architecture and performance.
## Making changes to the code

### Preparing your development environment

To learn how to build the code and run tests, follow the instructions in the [README](README.md).

### Style guidelines

The code in this project uses several different coding styles, depending on the
age and history of the code. Please attempt to match the style of surrounding
code as much as possible.

<!--
In new components, prefer the patterns described in the
[C++ core guidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines).
-->
### Code formatting


The code follows eclipse convention with the exception of spaces for tab.

#### Eclipse configuration

To configure eclipse, open the preferences and follow the instructions.

- General -> Editors -> Text Editors: check 'insert spaces for tab'
- Java -> Formater; new style 'Eclipse [modified]'
- Indentation -> Tab policy: select 'Spaces only'
- Whitespace -> Arrays -> Array Initializer: uncheck 'After opening brace' and 'Before closing brace'
- Whitespace -> Declarations -> Constructors -> unchceck 'Before opening parenthesis'.
- New Lines: check 'At end of file'
- Java -> Code Style -> Clean Up: new style 'Eclipse [modified]'
- Check always 'use block in if/while/do statements'
- Check always 'use parentheses in expressions'
- Unecessary code : check 'Avoid double negation' and 'Remove redundant modifiers'
- Java -> Editor -> Save Action: check 'Perform the selected actions on save' and 'Format source code'
- Checkstyle: new style Sun Checks [modified]'
- SizeViolations -> LineLength : set max to 120
- Workaround for potential error message: 'Checkstyle execution failed due to an internal error. Please check error log for details'
- Remove BOTH modules "SuppressionXpathFilter" and "SuppressionFilter" from the configuration

<!--
- Right-click on your project in the Package view and select Checkstyle -> Create Formatter-Profile. The following files will be created in you project:
- my-project-cs-cleanup.xml
- my-project-cs-formatter.xml
- Add the generated my-project-cs-formatter.xml as a formatter: Windows -> Preferences -> Java -> Code Style -> Formatter -> Import
-->

### Testing

Your change should include tests to verify new functionality wherever possible.
Code should be structured so that it can be unit tested independently of the UI.
Manual test cases should be used where automated testing is not feasible.

### Git workflow

The core principle of the project, when it comes to Git workflows is that the
`master` branch should always be in a healthy state which is ready for release.
Every commit on master should be deployable on push. To ensure this, pull request
**must not** be made directly on master. **Each change** should either be made in
the **development branch** (named a variation of development, i.e. `dev`) or in a
separate branch, named as a short summary of the change.

If your change is complex, please clean up the branch history before submitting a
pull request. You can use [git rebase](https://git-scm.com/book/en/v2/Git-Branching-Rebasing)
to group your changes into a small number of commits which we can review one at a
time.

When completing a pull request, we will generally squash your changes into a single
commit. After confirming that the change works as intended, the branch *might* be
deleted, in order to prevent branch polluting. Please let us know if your pull request
needs to be merged as separate commits.

### Continuous Integration

For this project, CI is provided by [GitHub Actions](https://github.com/features/actions),
with workflows found in the [`.github/workflows` folder](.github/workflows). Workflows
are run automatically on every commit made on the master branch, unless told to skip
for that particular commit.
<!--
To skip CI runs on a particular commit, include either `[skip ci]` or `[ci skip]`
in the commit message.
```bash
# an example of a commit message that would not trigger CI workflows
git commit -m "my normal commit message [skip ci]"
# or
git commit -m "my normal commit message [ci skip]"
```
-->
## Review process

After submitting a pull request, members of the team will review your code. We will
assign the request to an appropriate reviewer (if applicable). Any member of the
community may participate in the review, but at least one member of the project team
will ultimately approve the request.

Often, multiple iterations or discussions will be needed to responding to feedback
from reviewers. Try looking at [past pull requests](https://github.com/arnaud-m/cryptator/pulls?q=is%3Apr+is%3Aclosed)
to see what the experience might be like.

<!--
## Contributor License Agreement
Before we can review and accept a pull request from you, you'll need to sign a
Contributor License Agreement (CLA). The CLA ensures that the community is free
to use your contributions. Signing the CLA is a manual process, and you need to
do it for each pull request made. This is done by checking the boxes in the
[Pull Request Readiness Checklist of a Pull Request](PULL_REQUEST_TEMPLATE.md#Pull-Request-Readiness-Checklist).
### IMPORTANT
***Checking the aforementioned boxes means that you agree to provide your change
and/or code FREE TO USE and SUBJECT TO CHANGES for the entire community!***
You don't need to sign a CLA until you're ready to create a pull request. When your
pull request is created, it is reviewed by a team member which, if the change is
trivial (i.e. you just fixed a typo) will be labelled as `cla-not-required`.
Otherwise, it's classified as `cla-required`, if not already signed.
-->
22 changes: 20 additions & 2 deletions README.org
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@

[[https://github.com/arnaud-m/cryptator/actions/workflows/CryptatorTest.yml][file:https://github.com/arnaud-m/cryptator/actions/workflows/CryptatorTest.yml/badge.svg]]

Cryptator is distributed under BSD 3-Clause License (Copyright (c) 2022, Université Côte d'Azur).

Cryptator is a cryptarithm solver using [[https://en.wikipedia.org/wiki/Constraint_programming][Constraint Programming]].\\
It is based on [[https://github.com/chocoteam/choco-solver][choco-solver]] which is an open-source Java library for Constraint Programming.

Expand Down Expand Up @@ -78,3 +76,23 @@ It is based on [[https://github.com/chocoteam/choco-solver][choco-solver]] which
Just include it manually by feeding it as a parameter to the runner.

: mvn test -Dtest=ExtensiveTesting



* Contributing

Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our how you can
become a contributor and the process for submitting pull requests to us.

* Versioning

This project makes use of [SemVer](http://semver.org/) for versioning. A list of
existing versions can be found in the [project's releases]().

* Authors

See [AUTHORS](AUTHORS) and [CONTRIBUTORS](CONTRIBUTORS) files.

* License

This project is licensed under the [3-Clause BSD License](https://opensource.org/licenses/BSD-3-Clause/) - see the [LICENSE](LICENSE) file for details.
44 changes: 22 additions & 22 deletions src/main/java/cryptator/CryptaJson.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,26 @@
import cryptator.specs.ICryptaSolver;
import cryptator.tree.TreeUtils;

public class CryptaJson {

private CryptaJson() {
super();
}
public static SolveOutput solve(SolveInput input) throws CryptaModelException, CryptaSolverException {
final CryptaParserWrapper parser = new CryptaParserWrapper();
final ICryptaNode node = parser.parse(input.getCryptarithm());
final CryptatorConfig config = input.getConfig();
final SolveOutput output = new SolveOutput(input);
output.setSymbols(TreeUtils.computeSymbols(node));
final ICryptaSolver solver = new AdaptiveSolver();
solver.limitSolution(config.getSolutionLimit());
solver.limitTime(config.getTimeLimit());
solver.solve(node, input.getConfig(), s -> output.accept(node, s));
return output;
}
public final class CryptaJson {

private CryptaJson() {
super();
}

public static SolveOutput solve(final SolveInput input) throws CryptaModelException, CryptaSolverException {
final CryptaParserWrapper parser = new CryptaParserWrapper();
final ICryptaNode node = parser.parse(input.getCryptarithm());
final CryptatorConfig config = input.getConfig();

final SolveOutput output = new SolveOutput(input);
output.setSymbols(TreeUtils.computeSymbols(node));

final ICryptaSolver solver = new AdaptiveSolver();
solver.limitSolution(config.getSolutionLimit());
solver.limitTime(config.getTimeLimit());
solver.solve(node, input.getConfig(), s -> output.accept(node, s));

return output;
}

}
60 changes: 33 additions & 27 deletions src/main/java/cryptator/CryptaOperator.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,65 +8,71 @@
*/
package cryptator;

import java.math.BigInteger;
import java.util.function.BinaryOperator;

import org.chocosolver.solver.expression.discrete.arithmetic.ArExpression;
import org.chocosolver.solver.expression.discrete.relational.ReExpression;
import org.chocosolver.solver.variables.IntVar;
import org.chocosolver.util.tools.VariableUtils;

import java.math.BigInteger;
import java.util.function.BinaryOperator;

/**
* @see https://en.wikipedia.org/wiki/Relational_operator
*/
public enum CryptaOperator {
ADD("+", (a, b) -> a.add(b), (a, b) -> a.add(b)),
SUB("-", (a, b) -> a.subtract(b), (a, b) -> a.sub(b)),
MUL("*", (a, b) -> a.multiply(b), (a, b) -> a.mul(b)),
DIV("//", (a, b) -> a.divide(b), (a, b) -> a.div(b)),
FDIV("/", (a, b) -> fdiv(a, b), (a, b) -> fdiv(a, b)),
MOD("%", (a, b) -> a.mod(b), (a, b) -> a.mod(b)),
POW("^", (a, b) -> a.pow(b.intValue()), (a, b) -> a.pow(b)),
ID("", (a, b) -> BigInteger.ZERO, (a, b) -> null),
ADD("+", (a, b) -> a.add(b), (a, b) -> a.add(b)), SUB("-", (a, b) -> a.subtract(b), (a, b) -> a.sub(b)),
MUL("*", (a, b) -> a.multiply(b), (a, b) -> a.mul(b)), DIV("//", (a, b) -> a.divide(b), (a, b) -> a.div(b)),
FDIV("/", (a, b) -> fdiv(a, b), (a, b) -> fdiv(a, b)), MOD("%", (a, b) -> a.mod(b), (a, b) -> a.mod(b)),
POW("^", (a, b) -> a.pow(b.intValue()), (a, b) -> a.pow(b)), ID("", (a, b) -> BigInteger.ZERO, (a, b) -> null),
EQ("=", (a, b) -> toBigInt(a.compareTo(b) == 0), (a, b) -> a.eq(b)),
NE("!=", (a, b) -> toBigInt(a.compareTo(b) != 0), (a, b) -> a.ne(b)),
LT("<", (a, b) -> toBigInt(a.compareTo(b) < 0), (a, b) -> a.lt(b)),
GT(">", (a, b) -> toBigInt(a.compareTo(b) > 0), (a, b) -> a.gt(b)),
LE("<=", (a, b) -> toBigInt(a.compareTo(b) <= 0), (a, b) -> a.le(b)),
GE(">=", (a, b) -> toBigInt(a.compareTo(b) >= 0), (a, b) -> a.ge(b)),

AND("&&", (a, b) -> toBigInt(!a.equals(BigInteger.ZERO) && !b.equals(BigInteger.ZERO)), (a, b) -> ((ReExpression) a).and((ReExpression) b));
public final String token;
AND("&&", (a, b) -> toBigInt(!a.equals(BigInteger.ZERO) && !b.equals(BigInteger.ZERO)),
(a, b) -> ((ReExpression) a).and((ReExpression) b));

private final String token;

public final BinaryOperator<BigInteger> function;
private final BinaryOperator<BigInteger> function;

public final BinaryOperator<ArExpression> expression;
private final BinaryOperator<ArExpression> expression;

CryptaOperator(String token, BinaryOperator<BigInteger> function, BinaryOperator<ArExpression> expression) {
CryptaOperator(final String token, final BinaryOperator<BigInteger> function,
final BinaryOperator<ArExpression> expression) {
this.token = token;
this.function = function;
this.expression = expression;
}

public static CryptaOperator valueOfToken(String token) {
if (token == null) return null;
public static CryptaOperator valueOfToken(final String token) {
if (token == null) {
return null;
}
for (CryptaOperator operator : CryptaOperator.values()) {
if (token.equals(operator.getToken())) return operator;
if (token.equals(operator.getToken())) {
return operator;
}
}
throw new IllegalArgumentException("Unknown token: " + token);
}

private static final BigInteger toBigInt(boolean b) {
private static BigInteger toBigInt(final boolean b) {
return b ? BigInteger.ONE : BigInteger.ZERO;
}

private static final BigInteger fdiv(BigInteger a, BigInteger b) {
private static BigInteger fdiv(final BigInteger a, final BigInteger b) {
final BigInteger[] r = a.divideAndRemainder(b);
if (r[1].equals(BigInteger.ZERO)) return r[0];
else throw new ArithmeticException("The remainder of the division is non-zero.");
if (r[1].equals(BigInteger.ZERO)) {
return r[0];
} else {
throw new ArithmeticException("The remainder of the division is non-zero.");
}
}

private static final ArExpression fdiv(ArExpression a, ArExpression b) {
private static ArExpression fdiv(final ArExpression a, final ArExpression b) {
final IntVar va = a.intVar();
final IntVar vb = b.intVar();
final int[] bounds = VariableUtils.boundsForDivision(va, vb);
Expand All @@ -76,15 +82,15 @@ private static final ArExpression fdiv(ArExpression a, ArExpression b) {
return q;
}

public final String getToken() {
public String getToken() {
return token;
}

public final BinaryOperator<BigInteger> getFunction() {
public BinaryOperator<BigInteger> getFunction() {
return function;
}

public final BinaryOperator<ArExpression> getExpression() {
public BinaryOperator<ArExpression> getExpression() {
return expression;
}
}
Loading

0 comments on commit 2bd8893

Please sign in to comment.