Compute Prefix Function in String Matching - java

What am i doing wrong here?
Java code for computing prefix function. Two input are right but the last one is wrong.
Here's the pseudocode:
Java code:
class Main {
// compute prefix function
public static void main(String[] args) {
String p = "422213422153342";
String x = "ababbabbabbababbabb";
String y = "ababaca";
printOutput(p);
printOutput(y);
System.out.println();System.out.println();
System.out.println("the prefix func below is wrong. I am not sure why.");
System.out.print("answer should be: 0 0 1 2 0 1 2 0 1 2 0 1 2 3 4 5 6 7 8");
printOutput(x);
}
static void printOutput(String P){
System.out.println();System.out.println();
System.out.print("p[i]: ");
for(int i = 0; i < P.length(); i++)System.out.print(P.charAt(i) + " ");
System.out.println();
System.out.print("Pi[i]: ");
compute_prefix_func(P);
}
public static void compute_prefix_func(String P){
int m = P.length();
int pi[] = new int[m];
for(int i = 0; i < pi.length; i++){
pi[i] = 0;
}
pi[0] = 0;
int k = 0;
for(int q = 2; q < m; q++){
while(k > 0 && ( ((P.charAt(k) + "").equals(P.charAt(q) + "")) == false)){
k = pi[k];
}
if ((P.charAt(k) + "").equals(P.charAt(q) + "")){
k = k + 1;
}
pi[q] = k;
}
for(int i = 0; i < pi.length; i++){
System.out.print(pi[i] + " ");
}
}
}

Okay, let's start off by making the code much easier to read. This:
if ((P.charAt(k) + "").equals(P.charAt(q) + ""))
can be simplified to:
if (P.charAt(k) == P.charAt(q))
... and you've done that in multiple places.
Likewise here:
int pi[] = new int[m];
for(int i = 0; i < pi.length; i++){
pi[i] = 0;
}
pi[0] = 0;
... you don't need the explicit initialization. Variables are 0-initialized by default. (It's unclear why you're then setting pi[0] again, although I note that if P.length() is 0, this will throw an exception.)
Next is to remove the explicit comparison with false, instead just using ! so we have:
while(k > 0 && P.charAt(k) != P.charAt(q))
Finally, let's restructure the code a bit to make it easier to follow, use more conventional names, and change int pi[] to the more idiomatic int[] pi:
class Main {
public static void main(String[] args) {
String x = "ababbabbabbababbabb";
int[] prefix = computePrefix(x);
System.out.println("Prefix series for " + x);
for (int p : prefix) {
System.out.print(p + " ");
}
System.out.println();
}
public static int[] computePrefix(String input) {
int[] pi = new int[input.length()];
int k = 0;
for(int q = 2; q < input.length(); q++) {
while (k > 0 && input.charAt(k) != input.charAt(q)) {
k = pi[k];
}
if (input.charAt(k) == input.charAt(q)) {
k = k + 1;
}
pi[q] = k;
}
return pi;
}
}
That's now much easier to follow, IMO.
We can now look back to the pseudocode and see that it appears to be using 1-based indexing for both arrays and strings. That makes life slightly tricky. We could mimic that throughout the code, changing every array access and charAt call to just subtract 1.
(I've extracted the common subexpression of P[q] to a variable target within the loop.)
public static int[] computePrefix(String input) {
int[] pi = new int[input.length()];
int k = 0;
for (int q = 2; q <= input.length(); q++) {
char target = input.charAt(q - 1);
while (k > 0 && input.charAt(k + 1 - 1) != target) {
k = pi[k - 1];
}
if (input.charAt(k + 1 - 1) == target) {
k++;
}
pi[q - 1] = k;
}
return pi;
}
That now gives your desired results, but it's really ugly. We can shift q very easily, and remove the + 1 - 1 parts:
public static int[] computePrefix(String input) {
int[] pi = new int[input.length()];
int k = 0;
for (int q = 1; q < input.length(); q++) {
char target = input.charAt(q);
while (k > 0 && input.charAt(k) != target) {
k = pi[k - 1];
}
if (input.charAt(k) == target) {
k++;
}
pi[q] = k;
}
return pi;
}
It's still not entirely pleasant, but I think it's what you want. Make sure you understand why I had to make the changes I did.

public static int[] computePrefix(String input) {
int[] pi = new int[input.length()];
pi[0] = -1;
int k = -1;
for (int q = 1; q < input.length(); q++) {
char target = input.charAt(q);
while (k > 0 && input.charAt(k + 1) != target) {
k = pi[k];
}
if (input.charAt(k + 1) == target) {
k++;
}
pi[q] = k;
}
return pi;
}

Related

Solving this cryptarithmetic program gives infinite results [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 months ago.
Improve this question
I am doing the EAT+ THAT= APPLE, where each letter represents a different number from 0-9. I need to find all combinations. I was wondering if there is a better way to write it, especially 'if' and 'for'
I've tried writing it like this but it gave me infinite results
public class Main {
public static void main(String[] args) {
int count = 0;
int E,A,T,P,L,H;
for (E = 0; E <=9; E++)
{
for (A = 0; A <=9; A++)
for (T = 0; T <=9; T++)
for (P = 0; P <=9; P++)
for (L = 0; L <=9; L++)
for (H = 0; H <=9; H++)
if (((E != A) && (E != L) && (E != T)&&(E !=P) &&(E!=L)&&(E!=H) &&
(T != A) && (T != L) && (T != E) &&(T!=P)&&(T!=L)&&(T!=H)))
{
System.out.println("A"+A+"P"+P+"P"+P+"L"+L+"E"+E);
}
else count = count +1;
}
System.out.println(count);
}
}
When facing such problems it is of great importance to simplify the problem as much as possible.
Let's create a sub problem:
Assume that THAT must equal 8208. What are the values of each character?
You can notice that you are just solving an equation:
T * 1000 + H * 100 + A * 10 + T = 8208
(The only solution is T = 8, H = 2, A = 0)
Back to our main problem:
Using the logic above simplify the main problem to an equation,
EAT + THAT= APPLE => EAT + THAT - APPLE = 0;
That in fact means:
E * 100 + A * 10 + T + T * 1000 + H * 100 + A * 10 + T - A * 10000 - P * 1000 - P * 1000 - L * 10 - E = 0
After simplification you get:
-9980 * A - 1100 * P + 1002 * T + 100 * H + 99 * E - 10 * L = 0
As the values for each variable are very limited we are free to brute force the solution.
public class MyClass {
public static int[] calc(){
for(int A = 0; A < 10; A++){
for(int P = 0; P < 10; P++){
for(int T = 0; T < 10; T++){
for(int H = 0; H < 10; H++){
for(int E = 0; E < 10; E++){
for(int L = 0; L < 10; L++){
if(A!=P && A != T && A != H && A != E && A != L && P != T && P != H && P != E && P != L && T != H && T != E && T != L && H != E && H != L && E != L){
//In your code you are lacking this statment, it checks whether values are indeed a solution of the equation
if(-9980 * A - 1100 * P + 1002 * T + 100 * H + 99 * E - 10 * L == 0){
int[] outArr = {A, P, T, H, E, L};
return outArr;
}
}
}
}
}
}
}
}
return null;
}
public static void main(String args[]) {
int[] answer = calc();
System.out.println("A" + answer[0] + " P" + answer[1] + " P" + answer[1] + " L" + answer[5] + " E" + answer[4]);
}
}
If you don't want your if statement to be this massive, you can always create an array of size 10 filled with zeroes and for each variable (let's call it i) increase the value for the given index with array[i]++;, if at any point at any index array[x] > 1 you will know that values repeat.
There are ways of optimizing how the script works, by acknowledging the relations between digits (for example you can observe that A can only equal either 0 or 1, whereas 0 leads up to a contradictory equation, so A must equal 1 and so on and so forth until you find the exact value for each digit just by using logic), but in the end you will end up with purely mathematical solution and I don't think that's what you want to end up with.
**Second Version of Code**
public class EatingApple {
ArrayList<Permutation> eat = new ArrayList();
static ArrayList<Permutation> that = new ArrayList();
static ArrayList<Permutation> apples = new ArrayList();
public static void main(String[] args) throws IOException {
EatingApple apples = new EatingApple();
apples.makePermutation();
apples.searchAppleEqualsSum();
}
public void searchAppleEqualsSum()
{
for(Permutation eatP : eat)
{
int E_eat = (Integer) eatP.getCharacterValue("E");
int A_eat = (Integer) eatP.getCharacterValue("A");
int T_eat = (Integer) eatP.getCharacterValue("T");
for(Permutation thatP : that)
{
int T_that = (Integer) thatP.getCharacterValue("T");
int A_that = (Integer) thatP.getCharacterValue("A");
if(T_eat == T_that&&A_eat ==A_that)
for(Permutation apple : apples)
{
int A_apple = (Integer) apple.getCharacterValue("A");
int E_apple = (Integer) apple.getCharacterValue("E");
if(A_apple==E_eat&&E_apple==E_eat)
{
int eat_value = Integer.parseInt(eatP.permutationString);
int that_value = Integer.parseInt(thatP.permutationString);
int apple_value = Integer.parseInt(apple.permutationString);
if(apple_value == (that_value + eat_value)&&apple_value!=0)
{
System.out.println("EAT :" + eatP.permutationString);
System.out.println("THAT :" + thatP.permutationString);
System.out.println("Apple :" + apple.permutationString);
System.out.println(".............");
}
}
}
}
}
}
public void makePermutation()
{
for(int e=0;e<10;e++)
for(int a=0;a<10;a++)
for(int t=0;t<10;t++)
{
String permutationString = ""+e+a+t;
int value = e+a+t;
Permutation eatCombination = new Permutation(permutationString,value);
eatCombination.addCharToMap("E", e);
eatCombination.addCharToMap("A", a);
eatCombination.addCharToMap("T", t);
eatCombination.permutationValue=value;
eat.add(eatCombination);
}
for (int t = 0; t < 10; t++)
for (int h = 0; h < 10; h++)
for(int a = 0; a < 10;a++)
{
String permutationString = ""+t+h+a+t;
int value = t + h + a + t;
Permutation thatCombination = new Permutation(permutationString,value);
thatCombination.addCharToMap("T", t);
thatCombination.addCharToMap("H", h);
thatCombination.addCharToMap("A", a);
thatCombination.permutationValue=value;
that.add(thatCombination);
}
for (int a = 0; a < 10; a++)
for (int p = 0; p < 10; p++)
for(int l = 0; l <10;l++)
for(int e = 0; e < 10; e++)
{
String permutationString = ""+a+p+p+l+e;
int value = a+p+p+l+e;
Permutation appleCombination = new Permutation(permutationString,value);
appleCombination.addCharToMap("A", a);
appleCombination.addCharToMap("P", p);
appleCombination.addCharToMap("L", l);
appleCombination.addCharToMap("E", e);
appleCombination.permutationValue=value;
apples.add(appleCombination);
}
}
class Permutation
{
String permutationString="";
int permutationValue =0;
HashMap wordMap;
public int getPermuttionValue() {
return permutationValue;
}
Permutation(String pString, int pValue)
{
this.wordMap = new HashMap();
this.permutationString=pString;
this.permutationValue=pValue;
}
public int getCharacterValue(String character)
{
if(wordMap.get(character)==null)
return -1;
return (Integer) wordMap.get(character);
}
public void addCharToMap(String character, int value)
{
wordMap.put(character, value);
}
}
}

How to find the subsequence of number in java in simplest way

I am using below program for printing all possible sub sequence
class Test {
static void printSubSeqRec(String str, int n, int index, String curr) {
if (index == n) {
return;
}
System.out.println(curr);
for (int i = index + 1; i < n; i++) {
curr += str.charAt(i);
printSubSeqRec(str, n, i, curr);
curr = curr.substring(0, curr.length() - 1);
}
}
static void printSubSeq(String str) {
int index = -1;
String curr = "";
printSubSeqRec(str, str.length(), index, curr);
}
public static void main(String[] args) {
String str = "24";
printSubSeq(str);
}
}
Output:
2
4
24
Is there any other way for getting the same result?
In solving this I figured I wanted to generate the following pairs of indices in the given order. The first element is the start of the substring and the second is the limit for a four character string.
[0,1], [1,2], [2,3], [3,4], [0,2], [1,3], [2,4], [0,3], [1,4], [0,4]
This is the simplest way I could come up with.
String numb = "1234";
for (int z = 1; z <= numb.length(); z++) {
for (int k = z; k <= numb.length(); k++) {
System.out.println(numb.substring(k - z, k));
}
}
If you want to do it recursively, here is one way.
String numb = "1234";
subseq(numb, 0, 1, 1);
public static void subseq(String v, int z, int k, int i) {
System.out.println(v.substring(z, k));
if (k < v.length()) {
subseq(v, z + 1, k + 1, i);
}
else if (z > 0) {
subseq(v, 0, 1 + i, i + 1);
}
}
The first recursive call to subseq is such that z and k are incremented by 1 each.
The i serves as the next amount to increment k
So the second call to subseq calls with z back to 0 and k to 1+i
In that second call, i is also increased by 1
This continues until k >= length of string and z = 0 which is the entire
String and the last string printed.
But I prefer the nested loops solution.
public class main {
public static void main(String[] args) {
String str= "243";
for(int i = 1; i<= str.length();i++){
int m = 0;
for(int j =0;j < str.length() && m+i <= str.length();j++){
System.out.println(str.substring(j,m+i));
m++;
}
}
}
}
result :
2 4 3 24 43 243
In case you prefer doing it without recursion:
static void printSubSeq(String str) {
for(int i = 1; i <= str.length(); i++) {
for(int j = 0; j <= str.length() - i; j++) {
int k = j + i - 1;
for(int l = j; l <= k; l++) System.out.print(str.charAt(l));
System.out.println();
}
}
}

Count the minimum number of jumps required for a frog to get to the other side of a river

I work with a Codility problem provided below,
The Fibonacci sequence is defined using the following recursive formula:
F(0) = 0
F(1) = 1
F(M) = F(M - 1) + F(M - 2) if M >= 2
A small frog wants to get to the other side of a river. The frog is initially located at one bank of the river (position −1) and wants to get to the other bank (position N). The frog can jump over any distance F(K), where F(K) is the K-th Fibonacci number. Luckily, there are many leaves on the river, and the frog can jump between the leaves, but only in the direction of the bank at position N.
The leaves on the river are represented in an array A consisting of N integers. Consecutive elements of array A represent consecutive positions from 0 to N − 1 on the river. Array A contains only 0s and/or 1s:
0 represents a position without a leaf;
1 represents a position containing a leaf.
The goal is to count the minimum number of jumps in which the frog can get to the other side of the river (from position −1 to position N). The frog can jump between positions −1 and N (the banks of the river) and every position containing a leaf.
For example, consider array A such that:
A[0] = 0
A[1] = 0
A[2] = 0
A[3] = 1
A[4] = 1
A[5] = 0
A[6] = 1
A[7] = 0
A[8] = 0
A[9] = 0
A[10] = 0
The frog can make three jumps of length F(5) = 5, F(3) = 2 and F(5) = 5.
Write a function:
class Solution { public int solution(int[] A); }
that, given an array A consisting of N integers, returns the minimum number of jumps by which the frog can get to the other side of the river. If the frog cannot reach the other side of the river, the function should return −1.
For example, given:
A[0] = 0
A[1] = 0
A[2] = 0
A[3] = 1
A[4] = 1
A[5] = 0
A[6] = 1
A[7] = 0
A[8] = 0
A[9] = 0
A[10] = 0
the function should return 3, as explained above.
Assume that:
N is an integer within the range [0..100,000];
each element of array A is an integer that can have one of the following values: 0, 1.
Complexity:
expected worst-case time complexity is O(N*log(N));
expected worst-case space complexity is O(N) (not counting the storage required for input arguments).
I wrote the following solution,
class Solution {
private class Jump {
int position;
int number;
public int getPosition() {
return position;
}
public int getNumber() {
return number;
}
public Jump(int pos, int number) {
this.position = pos;
this.number = number;
}
}
public int solution(int[] A) {
int N = A.length;
List<Integer> fibs = getFibonacciNumbers(N + 1);
Stack<Jump> jumps = new Stack<>();
jumps.push(new Jump(-1, 0));
boolean[] visited = new boolean[N];
while (!jumps.isEmpty()) {
Jump jump = jumps.pop();
int position = jump.getPosition();
int number = jump.getNumber();
for (int fib : fibs) {
if (position + fib > N) {
break;
} else if (position + fib == N) {
return number + 1;
} else if (!visited[position + fib] && A[position + fib] == 1) {
visited[position + fib] = true;
jumps.add(new Jump(position + fib, number + 1));
}
}
}
return -1;
}
private List<Integer> getFibonacciNumbers(int N) {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 2; i++) {
list.add(i);
}
int i = 2;
while (list.get(list.size() - 1) <= N) {
list.add(i, (list.get(i - 1) + list.get(i - 2)));
i++;
}
for (i = 0; i < 2; i++) {
list.remove(i);
}
return list;
}
public static void main(String[] args) {
int[] A = new int[11];
A[0] = 0;
A[1] = 0;
A[2] = 0;
A[3] = 1;
A[4] = 1;
A[5] = 0;
A[6] = 1;
A[7] = 0;
A[8] = 0;
A[9] = 0;
A[10] = 0;
System.out.println(solution(A));
}
}
However, while the correctness seems good, the performance is not high enough. Is there a bug in the code and how do I improve the performance?
Got 100% with simple BFS:
public class Jump {
int pos;
int move;
public Jump(int pos, int move) {
this.pos = pos;
this.move = move;
}
}
public int solution(int[] A) {
int n = A.length;
List < Integer > fibs = fibArray(n + 1);
Queue < Jump > positions = new LinkedList < Jump > ();
boolean[] visited = new boolean[n + 1];
if (A.length <= 2)
return 1;
for (int i = 0; i < fibs.size(); i++) {
int initPos = fibs.get(i) - 1;
if (A[initPos] == 0)
continue;
positions.add(new Jump(initPos, 1));
visited[initPos] = true;
}
while (!positions.isEmpty()) {
Jump jump = positions.remove();
for (int j = fibs.size() - 1; j >= 0; j--) {
int nextPos = jump.pos + fibs.get(j);
if (nextPos == n)
return jump.move + 1;
else if (nextPos < n && A[nextPos] == 1 && !visited[nextPos]) {
positions.add(new Jump(nextPos, jump.move + 1));
visited[nextPos] = true;
}
}
}
return -1;
}
private List < Integer > fibArray(int n) {
List < Integer > fibs = new ArrayList < > ();
fibs.add(1);
fibs.add(2);
while (fibs.get(fibs.size() - 1) + fibs.get(fibs.size() - 2) <= n) {
fibs.add(fibs.get(fibs.size() - 1) + fibs.get(fibs.size() - 2));
}
return fibs;
}
You can apply knapsack algorithms to solve this problem.
In my solution I precomputed fibonacci numbers. And applied knapsack algorithm to solve it. It contains duplicate code, did not have much time to refactor it. Online ide with the same code is in repl
import java.util.*;
class Main {
public static int solution(int[] A) {
int N = A.length;
int inf=1000000;
int[] fibs={1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025};
int[] moves = new int[N+1];
for(int i=0; i<=N; i++){
moves[i]=inf;
}
for(int i=0; i<fibs.length; i++){
if(fibs[i]-1<N && A[fibs[i]-1]==1){
moves[ fibs[i]-1 ] = 1;
}
if(fibs[i]-1==N){
moves[N] = 1;
}
}
for(int i=0; i<N; i++){
if(A[i]==1)
for(int j=0; j<fibs.length; j++){
if(i-fibs[j]>=0 && moves[i-fibs[j]]!=inf && moves[i]>moves[i-fibs[j]]+1){
moves[i]=moves[i-fibs[j]]+1;
}
}
System.out.println(i + " => " + moves[i]);
}
for(int i=N; i<=N; i++){
for(int j=0; j<fibs.length; j++){
if(i-fibs[j]>=0 && moves[i-fibs[j]]!=inf && moves[i]>moves[i-fibs[j]]+1){
moves[i]=moves[i-fibs[j]]+1;
}
}
System.out.println(i + " => " + moves[i]);
}
if(moves[N]==inf) return -1;
return moves[N];
}
public static void main(String[] args) {
int[] A = new int[4];
A[0] = 0;
A[1] = 0;
A[2] = 0;
A[3] = 0;
System.out.println(solution(A));
}
}
Javascript 100%
function solution(A) {
function fibonacciUntilNumber(n) {
const fib = [0,1];
while (true) {
let newFib = fib[fib.length - 1] + fib[fib.length - 2];
if (newFib > n) {
break;
}
fib.push(newFib);
}
return fib.slice(2);
}
A.push(1);
const fibSet = fibonacciUntilNumber(A.length);
if (fibSet.includes(A.length)) return 1;
const reachable = Array.from({length: A.length}, () => -1);
fibSet.forEach(jump => {
if (A[jump - 1] === 1) {
reachable[jump - 1] = 1;
}
})
for (let index = 0; index < A.length; index++) {
if (A[index] === 0 || reachable[index] > 0) {
continue;
}
let minValue = 100005;
for (let jump of fibSet) {
let previousIndex = index - jump;
if (previousIndex < 0) {
break;
}
if (reachable[previousIndex] > 0 && minValue > reachable[previousIndex]) {
minValue = reachable[previousIndex];
}
}
if (minValue !== 100005) {
reachable[index] = minValue + 1;
}
}
return reachable[A.length - 1];
}
Python 100% answer.
For me the easiest solution was to locate all leaves within one fib jump of -1. Then consider each of these leaves to be index[0] and find all jumps from there.
Each generation or jump is recorded in a set until a generation contains len(A) or no more jumps can be found.
def gen_fib(n):
fn = [0,1]
i = 2
s = 2
while s < n:
s = fn[i-2] + fn[i-1]
fn.append(s)
i+=1
return fn
def new_paths(A, n, last_pos, fn):
"""
Given an array A of len n.
From index last_pos which numbers in fn jump to a leaf?
returns list: set of indexes with leaves.
"""
paths = []
for f in fn:
new_pos = last_pos + f
if new_pos == n or (new_pos < n and A[new_pos]):
paths.append(new_pos)
return path
def solution(A):
n = len(A)
if n < 3:
return 1
# A.append(1) # mark final jump
fn = sorted(gen_fib(100000)[2:]) # Fib numbers with 0, 1, 1, 2.. clipped to just 1, 2..
# print(fn)
paths = set([-1]) # locate all the leaves that are one fib jump from the start position.
jump = 1
while True:
# Considering each of the previous jump positions - How many leaves from there are one fib jump away
paths = set([idx for pos in paths for idx in new_paths(A, n, pos, fn)])
# no new jumps means game over!
if not paths:
break
# If there was a result in the new jumps record that
if n in paths:
return jump
jump += 1
return -1
https://app.codility.com/demo/results/training4GQV8Y-9ES/
https://github.com/niall-oc/things/blob/master/codility/fib_frog.py
Got 100%- solution in C.
typedef struct state {
int pos;
int step;
}state;
int solution(int A[], int N) {
int f1 = 0;
int f2 = 1;
int count = 2;
// precalculating count of maximum possible fibonacci numbers to allocate array in next loop. since this is C language we do not have flexible dynamic structure as in C++
while(1)
{
int f3 = f2 + f1;
if(f3 > N)
break;
f1 = f2;
f2 = f3;
++count;
}
int fib[count+1];
fib[0] = 0;
fib[1] = 1;
int i = 2;
// calculating fibonacci numbers in array
while(1)
{
fib[i] = fib[i-1] + fib[i-2];
if(fib[i] > N)
break;
++i;
}
// reversing the fibonacci numbers because we need to create minumum jump counts with bigger jumps
for(int j = 0, k = count; j < count/2; j++,k--)
{
int t = fib[j];
fib[j] = fib[k];
fib[k] = t;
}
state q[N];
int front = 0 ;
int rear = 0;
q[0].pos = -1;
q[0].step = 0;
int que_s = 1;
while(que_s > 0)
{
state s = q[front];
front++;
que_s--;
for(int i = 0; i <= count; i++)
{
int nextpo = s.pos + fib[i];
if(nextpo == N)
{
return s.step+1;
}
else if(nextpo > N || nextpo < 0 || A[nextpo] == 0){
continue;
}
else
{
q[++rear].pos = nextpo;
q[rear].step = s.step + 1;
que_s++;
A[nextpo] = 0;
}
}
}
return -1;
}
//100% on codility Dynamic Programming Solution. https://app.codility.com/demo/results/training7WSQJW-WTX/
class Solution {
public int solution(int[] A) {
int n = A.length + 1;
int dp[] = new int[n];
for(int i=0;i<n;i++) {
dp[i] = -1;
}
int f[] = new int[100005];
f[0] = 1;
f[1] = 1;
for(int i=2;i<100005;i++) {
f[i] = f[i - 1] + f[i - 2];
}
for(int i=-1;i<n;i++) {
if(i == -1 || dp[i] > 0) {
for(int j=0;i+f[j] <n;j++) {
if(i + f[j] == n -1 || A[i+f[j]] == 1) {
if(i == -1) {
dp[i + f[j]] = 1;
} else if(dp[i + f[j]] == -1) {
dp[i + f[j]] = dp[i] + 1;
} else {
dp[i + f[j]] = Math.min(dp[i + f[j]], dp[i] + 1);
}
}
}
}
}
return dp[n - 1];
}
}
Ruby 100% solution
def solution(a)
f = 2.step.inject([1,2]) {|acc,e| acc[e] = acc[e-1] + acc[e-2]; break(acc) if acc[e] > a.size + 1;acc }.reverse
mins = []
(a.size + 1).times do |i|
next mins[i] = -1 if i < a.size && a[i] == 0
mins[i] = f.inject(nil) do |min, j|
k = i - j
next min if k < -1
break 1 if k == -1
next min if mins[k] < 0
[mins[k] + 1, min || Float::INFINITY].min
end || -1
end
mins[a.size]
end
I have translated the previous C solution to Java and find the performance is improved.
import java.util.*;
class Solution {
private static class State {
int pos;
int step;
public State(int pos, int step) {
this.pos = pos;
this.step = step;
}
}
public static int solution(int A[]) {
int N = A.length;
int f1 = 0;
int f2 = 1;
int count = 2;
while (true) {
int f3 = f2 + f1;
if (f3 > N) {
break;
}
f1 = f2;
f2 = f3;
++count;
}
int[] fib = new int[count + 1];
fib[0] = 0;
fib[1] = 1;
int i = 2;
while (true) {
fib[i] = fib[i - 1] + fib[i - 2];
if (fib[i] > N) {
break;
}
++i;
}
for (int j = 0, k = count; j < count / 2; j++, k--) {
int t = fib[j];
fib[j] = fib[k];
fib[k] = t;
}
State[] q = new State[N];
for (int j = 0; j < N; j++) {
q[j] = new State(-1,0);
}
int front = 0;
int rear = 0;
// q[0].pos = -1;
// q[0].step = 0;
int que_s = 1;
while (que_s > 0) {
State s = q[front];
front++;
que_s--;
for (i = 0; i <= count; i++) {
int nextpo = s.pos + fib[i];
if (nextpo == N) {
return s.step + 1;
}
//
else if (nextpo > N || nextpo < 0 || A[nextpo] == 0) {
continue;
}
//
else {
q[++rear].pos = nextpo;
q[rear].step = s.step + 1;
que_s++;
A[nextpo] = 0;
}
}
}
return -1;
}
}
JavaScript with 100%.
Inspired from here.
function solution(A) {
const createFibs = n => {
const fibs = Array(n + 2).fill(null)
fibs[1] = 1
for (let i = 2; i < n + 1; i++) {
fibs[i] = fibs[i - 1] + fibs[i - 2]
}
return fibs
}
const createJumps = (A, fibs) => {
const jumps = Array(A.length + 1).fill(null)
let prev = null
for (i = 2; i < fibs.length; i++) {
const j = -1 + fibs[i]
if (j > A.length) break
if (j === A.length || A[j] === 1) {
jumps[j] = 1
if (prev === null) prev = j
}
}
if (prev === null) {
jumps[A.length] = -1
return jumps
}
while (prev < A.length) {
for (let i = 2; i < fibs.length; i++) {
const j = prev + fibs[i]
if (j > A.length) break
if (j === A.length || A[j] === 1) {
const x = jumps[prev] + 1
const y = jumps[j]
jumps[j] = y === null ? x : Math.min(y, x)
}
}
prev++
while (prev < A.length) {
if (jumps[prev] !== null) break
prev++
}
}
if (jumps[A.length] === null) jumps[A.length] = -1
return jumps
}
const fibs = createFibs(26)
const jumps = createJumps(A, fibs)
return jumps[A.length]
}
const A = [0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0]
console.log(A)
const s = solution(A)
console.log(s)
You should use a QUEUE AND NOT A STACK. This is a form of breadth-first search and your code needs to visit nodes that were added first to the queue to get the minimum distance.
A stack uses the last-in, first-out mechanism to remove items while a queue uses the first-in, first-out mechanism.
I copied and pasted your exact code but used a queue instead of a stack and I got 100% on codility.
100% C++ solution
More answers in my github
Inspired from here
Solution1 : Bottom-Top, using Dynamic programming algorithm (storing calculated values in an array)
vector<int> getFibonacciArrayMax(int MaxNum) {
if (MaxNum == 0)
return vector<int>(1, 0);
vector<int> fib(2, 0);
fib[1] = 1;
for (int i = 2; fib[fib.size()-1] + fib[fib.size() - 2] <= MaxNum; i++)
fib.push_back(fib[i - 1] + fib[i - 2]);
return fib;
}
int solution(vector<int>& A) {
int N = A.size();
A.push_back(1);
N++;
vector<int> f = getFibonacciArrayMax(N);
const int oo = 1'000'000;
vector<int> moves(N, oo);
for (auto i : f)
if (i - 1 >= 0 && A[i-1])
moves[i-1] = 1;
for (int pos = 0; pos < N; pos++) {
if (A[pos] == 0)
continue;
for (int i = f.size()-1; i >= 0; i--) {
if (pos + f[i] < N && A[pos + f[i]]) {
moves[pos + f[i]] = min(moves[pos]+1, moves[pos + f[i]]);
}
}
}
if (moves[N - 1] != oo) {
return moves[N - 1];
}
return -1;
}
Solution2: Top-Bottom using set container:
#include <set>
int solution2(vector<int>& A) {
int N = A.size();
vector<int> fib = getFibonacciArrayMax(N);
set<int> positions;
positions.insert(N);
for (int jumps = 1; ; jumps++)
{
set<int> new_positions;
for (int pos : positions)
{
for (int f : fib)
{
// return jumps if we reach to the start point
if (pos - (f - 1) == 0)
return jumps;
int prev_pos = pos - f;
// we do not need to calculate bigger jumps.
if (prev_pos < 0)
break;
if (prev_pos < A.size() && A[prev_pos])
new_positions.insert(prev_pos);
}
}
if (new_positions.size() == 0)
return -1;
positions = new_positions;
}
return -1;
}

How to generate combinations obtained by permuting 2 positions in Java

I have this problem, I need to generate from a given permutation not all combinations, but just those obtained after permuting 2 positions and without repetition. It's called the region of the a given permutation, for example given 1234 I want to generate :
2134
3214
4231
1324
1432
1243
the size of the region of any given permutation is , n(n-1)/2 , in this case it's 6 combinations .
Now, I have this programme , he does a little too much then what I want, he generates all 24 possible combinations :
public class PossibleCombinations {
public static void main(String[] args) {
Scanner s=new Scanner(System.in);
System.out.println("Entrer a mumber");
int n=s.nextInt();
int[] currentab = new int[n];
// fill in the table 1 TO N
for (int i = 1; i <= n; i++) {
currentab[i - 1] = i;
}
int total = 0;
for (;;) {
total++;
boolean[] used = new boolean[n + 1];
Arrays.fill(used, true);
for (int i = 0; i < n; i++) {
System.out.print(currentab[i] + " ");
}
System.out.println();
used[currentab[n - 1]] = false;
int pos = -1;
for (int i = n - 2; i >= 0; i--) {
used[currentab[i]] = false;
if (currentab[i] < currentab[i + 1]) {
pos = i;
break;
}
}
if (pos == -1) {
break;
}
for (int i = currentab[pos] + 1; i <= n; i++) {
if (!used[i]) {
currentab[pos] = i;
used[i] = true;
break;
}
}
for (int i = 1; i <= n; i++) {
if (!used[i]) {
currentab[++pos] = i;
}
}
}
System.out.println(total);
}
}
the Question is how can I fix this programme to turn it into a programme that generates only the combinations wanted .
How about something simple like
public static void printSwapTwo(int n) {
int count = 0;
StringBuilder sb = new StringBuilder();
for(int i = 0; i < n - 1;i++)
for(int j = i + 1; j < n; j++) {
// gives all the pairs of i and j without repeats
sb.setLength(0);
for(int k = 1; k <= n; k++) sb.append(k);
char tmp = sb.charAt(i);
sb.setCharAt(i, sb.charAt(j));
sb.setCharAt(j, tmp);
System.out.println(sb);
count++;
}
System.out.println("total=" + count+" and should be " + n * (n - 1) / 2);
}

Java permutations 2

I asked a question on helping me with this question about a week ago
Java permutations
, with a problem in the print permutation method. I have tidied up my code and have a working example that now works although if 5 is in the 5th position in the array it doesn't print it. Any help would be really appreciated.
package permutation;
public class Permutation {
static int DEFAULT = 100;
public static void main(String[] args) {
int n = DEFAULT;
if (args.length > 0)
n = Integer.parseInt(args[0]);
int[] OA = new int[n];
for (int i = 0; i < n; i++)
OA[i] = i + 1;
System.out.println("The original array is:");
for (int i = 0; i < OA.length; i++)
System.out.print(OA[i] + " ");
System.out.println();
System.out.println("A permutation of the original array is:");
OA = generateRandomPermutation(n);
printArray(OA);
printPermutation(OA);
}
static int[] generateRandomPermutation(int n)// (a)
{
int[] A = new int[n];
for (int i = 0; i < n; i++)
A[i] = i + 1;
for (int i = 0; i < n; i++) {
int r = (int) (Math.random() * (n));
int swap = A[r];
A[r] = A[i];
A[i] = swap;
}
return A;
}
static void printArray(int A[]) {
for (int i = 0; i < A.length; i++)
System.out.print(A[i] + " ");
System.out.println();
}
static void printPermutation(int[] p)
{
int n = p.length-1;
int j = 0;
int m;
int f = 0;
System.out.print("(");
while (f < n) {
m = p[j];
if (m == 0) {
do
f++;
while (p[f] == 0 && f < n);
j = f;
if (f != n)
System.out.print(")(");
}
else {
System.out.print(" " + m);
p[j] = 0;
j = m - 1;
}
}
System.out.print(" )");
}
}
I'm not too crazy about
int n = p.length-1;
followed by
while (f < n) {
So if p is 5 units long, and f starts at 0, then the loop will be from 0 to 3. That would seem to exclude the last element in the array.
You can use the shuffle method of the Collections class
Integer[] arr = new Integer[] { 1, 2, 3, 4, 5 };
List<Integer> arrList = Arrays.asList(arr);
Collections.shuffle(arrList);
System.out.println(arrList);
I don't think swapping each element with a random other element will give a uniform distribution of permutations. Better to select uniformly from the remaining values:
Random rand = new Random();
ArrayList<Integer> remainingValues = new ArrayList<Integer>(n);
for(int i = 0; i < n; i++)
remainingValues.add(i);
for(int i = 0; i < n; i++) {
int next = rand.nextInt(remainingValues.size());
result[i] = remainingValues.remove(next);
}
Note that if order of running-time is a concern, using an ArrayList in this capacity is n-squared time. There are data-structures which could handle this task in n log n time but they are very non-trivial.
This does not answer the problem you have identified.
Rather i think it identifies a mistake with your generateRandomPermutation(int n) proc.
If you add a print out of the random numbers generated (as i did below) and run the proc a few times it allows us to check if all the elements in the ARRAY TO BE permed are being randomly selected.
static int[] generateRandomPermutation(int n)
{
int[] A = new int[n];
for (int i = 0; i < n; i++)
A[i] = i + 1;
System.out.println("random nums generated are: ");
for (int i = 0; i < n; i++) {
int r = (int) (Math.random() * (n));
System.out.print(r + " ");
Run the proc several times.
Do you see what i see?
Jerry.

Categories

Resources