Countdown Until Matching Digits

How to design an algorithm to calculate countdown style maths number puzzle

Very quick and dirty solution in Java:

public class JavaApplication1
{

public static void main(String[] args)
{
List<Integer> list = Arrays.asList(1, 3, 7, 6, 8, 3);
for (Integer integer : list) {
List<Integer> runList = new ArrayList<>(list);
runList.remove(integer);
Result result = getOperations(runList, integer, 348);
if (result.success) {
System.out.println(integer + result.output);
return;
}
}
}

public static class Result
{

public String output;
public boolean success;
}

public static Result getOperations(List<Integer> numbers, int midNumber, int target)
{
Result midResult = new Result();
if (midNumber == target) {
midResult.success = true;
midResult.output = "";
return midResult;
}
for (Integer number : numbers) {
List<Integer> newList = new ArrayList<Integer>(numbers);
newList.remove(number);
if (newList.isEmpty()) {
if (midNumber - number == target) {
midResult.success = true;
midResult.output = "-" + number;
return midResult;
}
if (midNumber + number == target) {
midResult.success = true;
midResult.output = "+" + number;
return midResult;
}
if (midNumber * number == target) {
midResult.success = true;
midResult.output = "*" + number;
return midResult;
}
if (midNumber / number == target) {
midResult.success = true;
midResult.output = "/" + number;
return midResult;
}
midResult.success = false;
midResult.output = "f" + number;
return midResult;
} else {
midResult = getOperations(newList, midNumber - number, target);
if (midResult.success) {
midResult.output = "-" + number + midResult.output;
return midResult;
}
midResult = getOperations(newList, midNumber + number, target);
if (midResult.success) {
midResult.output = "+" + number + midResult.output;
return midResult;
}
midResult = getOperations(newList, midNumber * number, target);
if (midResult.success) {
midResult.output = "*" + number + midResult.output;
return midResult;
}
midResult = getOperations(newList, midNumber / number, target);
if (midResult.success) {
midResult.output = "/" + number + midResult.output;
return midResult
}
}

}
return midResult;
}
}

UPDATE

It's basically just simple brute force algorithm with exponential complexity.
However you can gain some improvemens by leveraging some heuristic function which will help you to order sequence of numbers or(and) operations you will process in each level of getOperatiosn() function recursion.

Example of such heuristic function is for example difference between mid result and total target result.

This way however only best-case and average-case complexities get improved. Worst case complexity remains untouched.

Worst case complexity can be improved by some kind of branch cutting. I'm not sure if it's possible in this case.

jQuery Deferred usage

Your asyncCallWrapper function should return a promise instead of a deferred. Deferreds are meant to be used internally to control when/how the code completes.

function asyncCallWrapper () {
return $.Deferred(function(def) { asyncCallFunction(arg1, function ( //Fires a callback when completed
def.resolve(data);
))).promise();//return the deferred's promise instead of the deferred itself.
}

$.when is a utility function intended for wrapping multiple promises in a deferred.

$.when(asyncCallWrapper(), asyncCallWrapper(), asyncCallWrapper())
.done(function(dataFromAsyncCall1, dataFromAsyncCall2, dataFromAsyncCall3) {
console.log("<ALL> three async calls are successful");
});

Therefore, it isn't needed and you can just write

asyncCallWrapper()
.done(function(dataFromAsyncCall) {
alert(dataFromAsyncCall);
result = dataFromAsyncCall;
});

The reason alert(result) is an Empty string is because the actual work hasn't happened yet. At that point in the code, you simply told the application what it should do when the asyncCallWrapper finishes. It hasn't finished it's work at this point.

In your case, you want to read the data after it has been set sometime later. This is what deferred are good for.

asyncCallWrapper()
.done(function(dataFromAsyncCall) {
alert(dataFromAsyncCall);
result = dataFromAsyncCall;
})
.then(function() {
alert(result);//should be dataFromAsyncCall
});

After reading your comments, I saw you wanted to use the result immediately. This isn't possible with deferreds. You will have to refactor the code that needs the value to call then on the promise.

create countdown based on server hour

The only way to get your updated server hour is using an ajax call.
The problem is that the request to the server is not immediate so you will have a delay.

Maybe it would be better to get the user timezone and calculate the promo ending with this information.

You can get the user timezone offset using:

var offset = new Date().getTimezoneOffset();

How to improve this regular expression to work in other situations?

I don't know exactly what it is you are trying to do but your regex is not very specific as it stands. Below is a suggested solution of what could be an improvement. It looks complicated but it isn't really too bad once broken down.

^(\b(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b|\w+\.\w+\.(?:net|com|gov|edu))\s-\s-\s(\[[0-9]{2}\/\w{3}\/[0-9]{4}:[0-9]{2}:[0-9]{2}:[0-9]{2}\s-[0-9]{4}\])\s(\"[^\"]+\")\s(.*)$

Check out https://regex101.com/r/ojIGIA/3 to see it in action and for explanations read the right hand side bar.

Edit: I realised I missed out a ? in the IP address part of the regex.I also forgot to escape a " since I didn't take into account the python flavour. Fixed and updated the Regex and the link.

Now I have a little more time I'll explain a bit further what I've done. The above Regex can be split up as follows.

^ start of line

( start capture group 1

\b(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b This is capturing the IP address. Depends on how precise you want to be, you could just get away with doing something like \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} if you aren't too worried about it. That will match all valid IP addresses too but it also will match some invalid ones.

| OR operator

\w+\.\w+\.(?:net|com|gov|edu) This is a very basic example of what a URL capture could look like.

) End capture group 1

\s-\s-\s Matches your " - - " exactly

(\[[0-9]{2}\/\w{3}\/[0-9]{4}:[0-9]{2}:[0-9]{2}:[0-9]{2}\s-[0-9]{4}\]) This is my suggestion for capturing the date and other stuff in the middle. It will need tweaking depending on exactly what you want. This is also capture group 2.

\s A space

(\"[^\"]+\") Matches everything within inverted commas at this point in the match. Capture group 3.

\s a space

(.*) Matches everything else up until the end and puts in capture group 4.

$ End of line

Now these are all just suggestions since I don't know what exactly you are trying to do but hopefully this helps out and gives you some ideas.

One note is that I use \s instead of a space. There is nothing wrong with using a space, I personally like using \s because it is easier to read for me.



Related Topics



Leave a reply



Submit