LeetCode Android Unlock problem 351 > Valid jumps - algorithm

One way to unlock an Android phone is through a pattern of swipes across a 1-9 keypad.
For a pattern to be valid, it must satisfy the following:
All of its keys must be distinct.
It must not connect two keys by jumping over a third key, unless that key has already been used.
For example, 4 - 2 - 1 - 7 is a valid pattern, whereas 2 - 1 - 7 is not.
Find the total number of valid unlock patterns of length N, where 1 <= N <= 9.
Invalid move: 4 - 1 - 3 - 6
Line 1 - 3 passes through key 2 which had not been selected in the pattern.
Invalid move: 4 - 1 - 9 - 2
Line 1 - 9 passes through key 5 which had not been selected in the pattern.
Valid move: 2 - 4 - 1 - 3 - 6
Line 1 - 3 is valid because it passes through key 2, which had been selected in the pattern
Valid move: 6 - 5 - 4 - 1 - 9 - 2
Line 1 - 9 is valid because it passes through key 5, which had been selected in the pattern.
| 1 | 2 | 3 |
| 4 | 5 | 6 |
| 7 | 8 | 9 |
I am able to solve the problem using DFS. But we have to also consider skip / jump. For solving it, i have seen people saving/using only the following combinations of valid jump.
for e.g
int skip[][] = new int[10][10];
skip[1][3] = skip[3][1] = 2;
skip[1][7] = skip[7][1] = 4;
skip[3][9] = skip[9][3] = 6;
skip[7][9] = skip[9][7] = 8;
skip[1][9] = skip[9][1] = skip[2][8] = skip[8][2] = skip[3][7] = skip[7][3] = skip[4][6] = skip[6][4] = 5;
Can someone help explain why the following combination is not included in skip/jump?
skip[1][6] = skip[6][1] = 2;
skip[1][6] = skip[6][1] = 5;
Example
https://medium.com/#rebeccahezhang/leetcode-351-android-unlock-patterns-d9bae4a8a958

Related

For loop variables get changed in Fortran

I am using the finite element method and separating a unit isosceles triangle into triangles with six nodes. While calculating coordinates of the nodes I noticed that the variables in the for loop get messed up for some reason and I cannot figure out why. Here is my code:
PROGRAM triangle
IMPLICIT NONE
INTEGER, PARAMETER :: stepSize = 4
INTEGER, PARAMETER :: numberOfNodes = ((2*stepSize - 1) * (2*stepSize)) / 2
INTEGER :: i, j, counter
REAL, DIMENSION(2, numberOfNodes) :: nodeCoordinates
counter = 0
DO j = 1, 2*stepSize - 1
DO i = 1, 2*stepSize - 1 - counter
nodeCoordinates(1, i + (j-1)*(2*stepSize - 1)) = ((REAL(i-1)) / REAL(2*stepSize - 2))
nodeCoordinates(2, i + (j-1)*(2*stepSize - 1)) = ((REAL(j-1)) / REAL(2*stepSize - 2))
END DO
counter = counter + 1
END DO
END PROGRAM triangle
When I print the variable j in the inner for loop, the following is shown:
1
1
1
1
1
1
1
2
2
2
2
2
2
3
3
3
3
3
4
4
4
4
0
0
0
1
1
2

Coding for LINGO/LINDO (Integer Linear Programming)

I'm confused how to write the code on LINGO for this model (the model is on pic). I want the "Periode" (period on English) to be consecutive. I tried this code, it's feasible but it's not in consecutive periods. Can someone help me with this problem?
(here's the code that i tried)
SETS:
HARI/I1..I3/;
PERIODE/J1..J4/;
PERIOD/P1..P3/;
SKS/T1..T2/;
KM/K1..K4/:A;
DOSEN/L1..L4/:G;
MK/M1..M8/:H, B;
RUANGAN/N1..N3/;
JADWAL(HARI, PERIODE, KM, DOSEN, MK, RUANGAN):X;
PREFERENSI(HARI, PERIODE, DOSEN):Y;
ULANG(HARI, PERIODE, KM):Z;
CONSECUTIVE(HARI, PERIOD, KM, SKS, MK, RUANGAN):W;
ENDSETS
DATA:
H = 2 2 2 2 2 2 2 2;
B = 1 1 1 1 1 1 1 1;
G = 4 4 4 4;
A = 4 4 4 4;
ENDDATA
#FOR(HARI(I): #FOR(KM(K): #FOR(DOSEN(L): #FOR(MK(M): #FOR(RUANGAN(N): #FOR(SKS(T)|T#EQ#2: X(I,1,K,L,M,N) - X(I,T,K,L,M,N)<=0))))));
#FOR(HARI(I): #FOR(KM(K): #FOR(DOSEN(L): #FOR(MK(M): #FOR(RUANGAN(N): #FOR(PERIOD(P)|P#EQ#1#AND#P#EQ#2#AND#P#EQ#3: #FOR(SKS(T)|T#EQ#2:T+P<=4)))))));
#FOR(HARI(I): #FOR(KM(K): #FOR(DOSEN(L): #FOR(MK(M): #FOR(RUANGAN(N): #FOR(PERIOD(P)|P#EQ#1#AND#P#EQ#2#AND#P#EQ#3: #FOR(SKS(T)|T#EQ#2:-X(I,J,K,L,M,N)+X(I,P+1,K,L,M,N)-X(I,P+T,K,L,M,N)<=0)))))));
#FOR(HARI(I): #FOR(KM(K): #FOR(DOSEN(L): #FOR(MK(M): #FOR(RUANGAN(N): #FOR(SKS(T)|T#EQ#2: X(I,4,K,L,M,N) - X(I,4-T,K,L,M,N)<=0))))));

How can I improve my Countdown Numbers Solver algorithm to find more solutions?

As my school Project, I need to build a solver for Countdown Numbers & Letters rounds. I wanted to develop a structure which I can use to build both solvers, and I first developed a Numbers solver. However, before using this solution for Letters, I need to improve my current algorithm. I think I'm wrong somewhere, because I don't get the same results with other tools I am using to compare my program. Here is program for my solver;
/// numbers_game_solver.dart
import 'dart:collection';
import 'package:trotter/trotter.dart';
/* Import statements was package-based, I turned them into relative paths for question. */
import 'number_generator.dart';
import 'operation.dart';
import 'solution.dart';
import 'solutions.dart';
/* Will try to combine numbers with operations, as shown below;
* List<List<Operation>> operations = <Operations>[a, ,b, ,c, ,d, ,e, ,f
* + - + * / ]
* Then if last operations result is equal to target, will result it.
* If not will show closest result.
*/
const List<String> kOperators = const <String>[kOpAdd, kOpDiv, kOpMul, kOpSub];
class NumbersGameSolver {
NumbersGameSolver()
: this.solutions = Solutions(_expectedResult);
/* TODO: Do tests with smaller numbers and targets. */
final List<int> _numbers = const <int>[1, 2, 3, 4]; // NumberGenerator.numbers;
static final int _expectedResult = 15; //NumberGenerator.expectedResult;
final Solutions solutions;
void solve() {
/* All permutations of operators with replacement, which will be inserted between numbers. */
final Set<List<String>> amalgamsOperators = Amalgams<String>(_numbers.length - 1, kOperators)().toSet();
/* There may duplicates occur in numbers list, because of this, numbers will be mapped
using permutations of indices. */
final List<int> indices = List<int>.generate(_numbers.length, (int index) => index);
final Iterable<List<int>> permutationsIndices = Permutations<int>(indices.length, indices)();
final Set<List<int>>
permutationsNumbers = permutationsIndices.map(
(List<int> listPerm) => listPerm.map(
(int index) => _numbers[index]
).toList()
).toSet();
for (final List<int> numbers in permutationsNumbers) {
for (final List<String> operators in amalgamsOperators) {
Queue<int> stackNums = Queue<int>.from(numbers);
Queue<String> stackOprts = Queue<String>.from(operators);
Solution tempSolution = Solution(_expectedResult);
do {
int left = stackNums.removeFirst(), right = stackNums.removeFirst();
Operation tempOperation = Operation(stackOprts.removeFirst(), left, right);
/* Record solutions current state. */
SolutionState solutionState = tempSolution.addOperation(tempOperation);
if (solutionState == SolutionState.currentlyValid) {
/* If valid, add result to the current numbers stack. */
stackNums.addFirst(tempOperation.result);
} else if (solutionState == SolutionState.lastOperationRedundant) {
/* If operation is redundant, dispose it and continue. */
continue;
} else if (solutionState == SolutionState.lastResultInvalid) {
/* If results is invalid at any stage, dispose whole solution. */
break;
}
if (solutions.addSolution(tempSolution) == true) break;
} while (stackNums.length > 1);
}
}
/* Will show only accurate solutions.
* If there is no accurate solutions, will show solutions which results
* are closest to the expected result.
*/
solutions.showSolutions();
}
}
There are 5 classes, to shorten the question I added them in this Gist.
My algorithm is as follows;
Rules for this Project are; program must randomly generate 5 single digit number and 1 two digit number where twoDigitNumber % 10 == 0 and a three digit number as target.
I get permutations of 4 operators and numbers that will be used in operations (Using trotter package.)
For each permutation of numbers, I apply each permutation of operators; using Operation class and add them into a Solution instance for each permutation.
I pass some redundant operations in each iteration, and if there is an invalid result at any stage, I dispose that solution and continue. (I'm taking this DataGenetics blog about this topic as a reference.)
To test my algorithm I used numbers 1, 2, 3, 4 and set target as 15. The results from dcode.fr Solver are as is;
15 (2 op.)
4 + 1 = 5
5 x 3 = 15
15 (3 op.)
4 + 3 = 7
7 x 2 = 14
14 + 1 = 15
15 (3 op.)
4 x 3 = 12
12 + 2 = 14
14 + 1 = 15
15 (3 op.)
4 x 3 = 12
2 + 1 = 3
12 + 3 = 15
15 (3 op.)
3 + 2 = 5
4 - 1 = 3
5 x 3 = 15
15 (3 op.)
4 x 3 = 12
12 + 1 = 13
13 + 2 = 15
15 (3 op.)
4 - 1 = 3
3 + 2 = 5
5 x 3 = 15
15 (3 op.)
4 + 2 = 6
6 - 1 = 5
5 x 3 = 15
15 (3 op.)
2 + 1 = 3
4 x 3 = 12
12 + 3 = 15
15 (3 op.)
2 - 1 = 1
4 + 1 = 5
5 x 3 = 15
(A total of 10 solutions.)
and the solutions my program found are as is;
> SOLUTION 1 ~
4 - 1 = 3
3 + 2 = 5
5 x 3 = 15
> SOLUTION 2 ~
4 + 1 = 5
5 x 3 = 15
(A total of 2 solutions.)
Can you tell me what am I thinking wrongly; Why can't I find all solutions? What are alternative approaches I can take to solve this problem? Is there anything I'm missing?
TY for taking time.

Analyzing a recursive algorithm

I'm trying to figure out this algorithm that accepts an input of an int and should return an output of the sum of each element in the int.
# Input -> 4321
# output -> 10 (4+3+2+1)
def sum_func(n):
# Base case
if len(str(n)) == 1:
return n
# Recursion
else:
return n%10 + sum_func(n/10)
When Trying to break apart this algorithm this is what I come up with
1st loop -> 1 + 432 = 433
2nd loop -> 2 + 43 = 45
3rd loop -> 3 + 4 = 7
4th loop -> 4 + 4 = 8
How was it able to come up with the result of 10?
Unwinding, it would look like this:
sum_func(4321)
= 1 + sum_func(432)
= 1 + 2 + sum_func(43)
= 1 + 2 + 3 + sum_func(4)
= 1 + 2 + 3 + 4
When trying to understand recursion you'll have to clearly understand what is returned.
In this case function sum_func(n) returns the sum of the digits in it's argument n.
For concrete n task is divided into last_digit_of_n + sum_func(n_without_last_digit).
For example,
sum_func(4321) =
sum_func(432) + 1 =
sum_func(43) + 2 + 1 =
sum_func(4) + 3 + 2 + 1 =
4 + 3 + 2 + 1
Hope this helps.
(As a side note, checking if n has more than one digit using str is a bad idea. Better just to check if n <= 9)
You must reach the base case before the summation occurs:
Iteration 1: 1 + sum_func(432)
Iteration 2: 1 + 2 + sum_func(43)
Iteration 3: 1 + 2 + 3 + sum_func(4) = 1 + 2 + 3 + 4 = 10

How to increment by group

There is a table and now add a new column -- sort_num int default 0
id level sort_num
1 1 0
2 1 0
3 2 0
4 2 0
5 2 0
6 3 0
7 3 0
8 3 0
9 3 0
Now I want to set sort_num values like below
id level sort_num
1 1 1
2 1 2
3 2 1
4 2 2
5 2 3
6 3 1
7 3 2
8 3 3
9 3 4
The Java code implement above requirement is
int sortNum = 0;
int currentLevel = fooList.get(0).getLevel();
for (RuleConf foo : fooList) {
if(currentLevel != foo.getLevel()){
sortNum = 0;
currentLevel = foo.getLevel();
}
foo.setSortNum(++sortNum);
}
I want to know if Java8 could simplify above code?
PS. Use mysql to implement this requirement
set #index:=0; update t set sort_num = (#index:=#index+1) where level = 1 order by id;
set #index:=0; update t set sort_num = (#index:=#index+1) where level = 2 order by id;
set #index:=0; update t set sort_num = (#index:=#index+1) where level = 3 order by id;
The best approach is to stick to your plain enhanced for loop. I don't think it is possible to come up with a single Stream solution, since you need to have intermediate values. Like:
Map<Integer, List<RuleConf>> levels = fooList.stream()
.collect(Collectors.groupingBy(RuleConf::getLevel));
levels.values().forEach(v ->
IntStream.range(0, v.size()).forEach(i -> v.get(i).setSortNum(i + 1))
);
If you keep track of the next order numbers yourself, you may do it with one stream. This solution is thread safe as well, hence should work with parallel streams:
Map<Integer, AtomicInteger> orders = new ConcurrentHashMap<>();
fooList.stream().forEachOrdered(foo -> {
orders.putIfAbsent(foo.getLevel(), new AtomicInteger());
foo.setOrder(orders.get(foo.getLevel()).incrementAndGet());
});
It should outperform the other stream-solutions, because it requires to iterate over the list only ones.

Resources