Grid Walking (Score 50 points):
You are situated in an N dimensional grid at position (x_1,x2,...,x_N). The dimensions of the grid are (D_1,D_2,...D_N). In one step, you can walk one step ahead or behind in any one of the N dimensions. (So there are always 2N possible different moves). In how many ways can you take M steps such that you do not leave the grid at any point? You leave the grid if you for any x_i, either x_i <= 0 or x_i > D_i.
Input:
The first line contains the number of test cases T. T test cases follow. For each test case, the first line contains N and M, the second line contains x_1,x_2...,x_N and the 3rd line contains D_1,D_2,...,D_N.
So, in the above solution I'm trying to take one dimensional array.
The website claims 38753340 to be the answer, but I'm not getting it.
public class GridWalking {
/**
* #param args
*/
public static void main(String[] args) {
try {
long arr[] = new long[78];
long pos = 44;
long totake = 287;
/*
* Double arr[] = new Double[3]; Double pos = 0; Double totake = 5;
*/
Double val = calculate(arr, pos, totake);
System.out.println(val % 1000000007);
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}
}
public static HashMap<String, Double> calculated = new HashMap<String, Double>();
private static Double calculate(long[] arr, long pos, long totake) {
if (calculated.containsKey(pos + "" + totake)) {
return calculated.get(pos + "" + totake);
}
if (0 == totake) {
calculated.put(pos + "" + totake, new Double(1));
return new Double(1);
}
if (pos == arr.length - 1) {
Double b = calculate(arr, pos - 1, totake - 1);
Double ret = b;
calculated.put(pos + "" + totake, new Double(ret));
return ret;
}
if (pos == 0) {
Double b = calculate(arr, pos + 1, totake - 1);
Double ret = b;
calculated.put(pos + "" + totake, new Double(ret));
return ret;
}
Double a = calculate(arr, pos + 1, totake - 1);
Double b = calculate(arr, pos - 1, totake - 1);
Double ret = (a + b);
calculated.put(pos + "" + totake, ret);
return ret;
}
}
You need to change key values as for pos + "_" + totake.
I have rewritten it but I'm not sure it working or not. It takes too much time to complete if ever.
public class GridWalking {
static long arr_length = 78;
static long pos = 44;
static long totake = 287;
static long count = 0;
/**
* #param args
*/
public static void main(String[] args) {
try {
calculate(pos, totake);
System.out.println(count % 1000000007);
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}
}
private static void calculate(long pos, long totake) {
if (pos < 0 || pos > arr_length - 1)
return;
if (0 == totake) {
count++;
return;
}
calculate(pos + 1, totake - 1);
calculate(pos - 1, totake - 1);
}
}
I have tried solving that Grid walking problem in Hackerrank. this is the code that had worked(in ecclipse atleast). but i donno why it does not match with given answers. Nut i think you can get the idea from it. Since it does not use recursion, no problem with execution time..
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution {
static int count=0;
public static void main(String[] args) throws FileNotFoundException {
String filename = "src/testcases.txt";//testcases is just a file containing input
File file = new File(filename);
Scanner in = new Scanner(file);
//in.useDelimiter("[^0-9]+");
//-----------------------------------------------------------------
int T=in.nextInt();
for(int t=0;t<1;t++){
int N=in.nextInt();
int M=in.nextInt();System.out.println("M="+M);
int[] X=new int[N];
long max=1000000007;
int[] D=new int[N];
for(int i=0;i<N;i++) X[i]=in.nextInt();
for(int i=0;i<N;i++) D[i]=in.nextInt();
int Dmax=D[0];
int Dtotal=1;
for(int i=0;i<N;i++) if(Dmax<D[i]) Dmax=D[i];
for(int i=0;i<N;i++) X[i]--;
for(int i=0;i<N;i++) Dtotal*=D[i];//total number of fields
long[] mainarray= new long[Dtotal];
long[] mainarraynext=new long[Dtotal];
int[][] ways=new int[N][Dmax];
set( X, mainarray,D, 1);
int temp[]=new int[N];
for(int h=0;h<10;h++){
for(int j=0;j<Dtotal;j++){
mainarraynext[j]=getsum(inverse(j,D),mainarray, D );
}
for(int j=0;j<Dtotal;j++){
mainarray[j]=mainarraynext[j];
mainarray[j]%=max;
}
System.out.println(Arrays.toString(mainarray));
}
long finalsum=0;
for(int j=0;j<Dtotal;j++){
finalsum+=mainarray[j];
//System.out.println(finalsum);
}
System.out.println(finalsum);
//System.out.println(Arrays.toString(inverse(44,D)));
}
}
public static long get(int[] x, long[] mainarray, int[] D){
for(int i=0;i<x.length;i++){
if(x[i]>=D[i]) return 0;
if(x[i]<0) return 0;
}
int index=0;
for(int i=0;i<D.length;i++){
index=(index*D[i])+x[i];
}
return mainarray[index];
}
public static int[] inverse(int index,int[] D){
int[] temp=new int[D.length];
for(int i=D.length-1;i>=0;i--){
temp[i]=index%D[i];
index=index/D[i];
}
return temp;
}
public static void set(int[] x, long[] mainarray, int[] D, int value){
int index=0;
for(int i=0;i<D.length;i++){
index=(index*D[i])+x[i];
}
mainarray[index]=value;
}
public static long getsum(int[] x,long[] mainarray, int[] D ){
int[] temp=new int[x.length];
long sum=0;
//for 2n different sides
for(int j=0;j<x.length;j++){//sum in each side
temp[j]=x[j];
}
for(int j=0;j<x.length;j++){//sum in each side
temp[j]--;
sum+=get(temp, mainarray, D);
temp[j]+=2;
sum+=get(temp, mainarray, D);
temp[j]--;
}
return sum;
}
}
Here's a Java solution I've built for the original hackerrank problem. For big grids runs forever. Probably some smart math is needed.
long compute(int N, int M, int[] positions, int[] dimensions) {
if (M == 0) {
return 1;
}
long sum = 0;
for (int i = 0; i < N; i++) {
if (positions[i] < dimensions[i]) {
positions[i]++;
sum += compute(N, M - 1, positions, dimensions);
positions[i]--;
}
if (positions[i] > 1) {
positions[i]--;
sum += compute(N, M - 1, positions, dimensions);
positions[i]++;
}
}
return sum % 1000000007;
}
Related
EDIT
try run in the main:
int[] arr = {646 ,94 ,366 ,754 ,948 ,678 ,121 ,320 ,528 ,36};
for(int i=0;i<10;i++){
System.out.println(randomizedSelect(arr,0,arr.length-1,5));
printArr(arr);
}
and see that i got diffrent outpot in each loop..
Got a little problem that I would like some help with, if anyone knows how.
I need to find the kth smallest value in an array by randomized partition.
I've got two problems:
I get array out of bounds with -1 and can't find a way to fix it.
Most of the time it works but sometimes it gives me wrong k place.
For example for array with length of 10, it tells me that 20 is in the 5th place but actually it should be in the 2nd place and it prints the array where not all the values on the left are smaller than 20 and not smaller than the 5th place.
Here is an example array:
{646 ,94 ,366 ,754 ,948 ,678 ,121 ,320 ,528 ,36}
The array input is done by a random number generator.
This is my code:
import java.util.Random;
import java.util.Scanner;
public class Main {
static Scanner scan = new Scanner(System.in);
static Random rand = new Random();
public static void main(String[] args) {
int nSize = askSizeN();
int kSize = askSizeK(nSize);
int[] arr = new int[nSize];
chose(arr);
int[] arrCopy = new int[nSize];
for (int i = 0; i < arrCopy.length; i++) {
arrCopy[i] = arr[i];
}
printArr(arrCopy);
System.out.println(randomizedSelect(arrCopy, 0, arr.length - 1, kSize));
printArr(arrCopy);
}
private static int partition(int[] arr, int p, int r) {
int x = arr[r];
int i = p - 1;
for (int j = p; j < r; j++) {
if (arr[j] <= x) {
i++;
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
int temp = arr[i + 1];
arr[i + 1] = arr[r];
arr[r] = temp;
return i + 1;
}
private static int randomizedPartition(int[] arr, int p, int r) {
int i = rand.nextInt(r - p);
int temp = arr[r];
arr[r] = arr[i];
arr[i] = temp;
return partition(arr, p, r);
}
private static int randomizedSelect(int[] arr, int p, int r, int i) {
if (p == r) {
return arr[p];
}
int q = randomizedPartition(arr, p, r);
int k = q - p + 1;
if (i == k) {
return arr[q];
}
else if (i < k) {
return randomizedSelect(arr, p, q - 1, i);
}
else {
return randomizedSelect(arr, q + 1, r, i - k);
}
}
private static int askSizeN() {
System.out.println("Please chose the size of the heap: \n" + "(the size of n)");
return scan.nextInt();
}
private static int askSizeK(int nSize) {
System.out.println(
"Please chose how much small values you want to see: \n" + "(the size of k)");
int kSize = scan.nextInt();
if (kSize > nSize) {
System.out.println("cant print more number then the size of the Heap..");
System.out.println("Please enter a number less then " + (nSize + 1));
askSizeK(nSize);
}
return kSize;
}
private static int[] chose(int[] a) {
System.out.println("Chose the option you want: \n" + "\t1. enter your own values."
+ "\n\t2. let me generate random values");
int chose = scan.nextInt();
if (chose == 1) {
for (int i = 0; i < a.length; i++) {
System.out.println("Enter value number " + (i + 1));
a[i] = scan.nextInt();
}
}
else if (chose == 2) {
System.out.println("Generate random numbers.");
for (int i = 0; i < a.length; i++) {
a[i] = rand.nextInt(1000);
}
}
else {
chose(a);
}
return a;
}
private static void printArr(int[] a){
for(int i=0;i<a.length;i++){
System.out.print(a[i] + " ");
}
System.out.println();
}
}
I've solved the problem.
Method randmizedPartition() was generating wrong random pivot for partition.
I solved it by changing the random line to:
int i = rand.nextInt((r - p) + 1) + p;
Algorithm:
Procedure SELECT( k,S)
{ if ISI =1 then return the single element in S
else { choose an element a randomly from S;
let S1,S2,and S3 be he sequences of elements in S
less than, equal to, and greater than m, respectively;
if IS1I >=k then return SELECT(k,S1)
else
if (IS1I + IS2I >=k then return m
else return SELECT(k-IS1I-IS2I , S3);
}
}
The question is to implement the first algorithm for finding the kth smallest integer in a set of integers and test your program for different sets of integers generated by a random number generator.
Below is my solution.
import java.util.Random;
import java.util.Scanner;
public class main {
private static Random rand = new Random();
private static Scanner keyboard = new Scanner(System.in);
public static int firstAlgorithm(int k, int[] S) {
int m = S[rand.nextInt(S.length)];
int[] S1 = new int[S.length];
int[] S2 = new int[S.length];
int[] S3 = new int[S.length];
int p = 0;
int q = 0;
int r = 0;
if (S.length == 1)
return S[0];
for (int i = 0; i < S.length; i++) {
if (S[i] < m) {
S1[p] = S[i];
p++;
} else if (S[i] == m) {
S2[q] = S[i];
q++;
} else {
S3[r] = S[i];
r++;
}
}
S1 = trimToSize(S1, p);
S2 = trimToSize(S2, q);
S3 = trimToSize(S3, r);
if (S1.length >= k)
return firstAlgorithm(k, S1);
else if (S1.length + S2.length >= k)
return m;
else
return firstAlgorithm(k - S1.length - S2.length, S3);
}
private static int[] trimToSize(int[] arr, int size) {
int[] temp = new int[size];
for (int i = 0; i < size; i++) {
temp[i] = arr[i];
}
return temp;
}
public static void printArray(int[] S) {
for (int i = 0; i < S.length; i++) {
System.out.print(S[i] + "\t");
if (i % 10 == 9)
System.out.println();
}
}
// start main method
public static void main(String[] args) {
System.out.print("Enter the size of an array: ");
int size = keyboard.nextInt();
while (size < 1) {
System.out.println("Size of the array should be greater than 0.");
System.out.print("Enter the size of an array: ");
size = keyboard.nextInt();
}
System.out.print("Enter the value of k: ");
int k = keyboard.nextInt();
while (k < 1 || k > size) {
System.out.println("Value of k should be in the range 1-" + size + ".");
System.out.print("Enter the value of k: ");
k = keyboard.nextInt();
}
int[] S = new int[size];
for (int i = 0; i < size; i++) {
S[i] = 100 + rand.nextInt(900);
}
System.out.println("\nRandom values generated in the array:");
printArray(S);
System.out.println();
System.out.println(k + "th smallest value in the array using Algorithm #1: " + firstAlgorithm(k, S));
}
}
But I need to implement the above algorithm without using a temporary array for partitioning. How can I do it?
The algorithm is Dijkstra's 3-way partition.
You will have to modify the original S.
Untested (pseudo) code ahead
public static int partition(int left, int right, int[] S) {
int m = rand.nextInt(right-left); // protect against malicious data
swap(S[left+m], S[right]);
int equal = left;
while (left < right) {
if (a[left] < a[n])
swap(S, left++, equal++)
else if (a[left] == a[n])
swap(S, left, --right);
else
left++;
}
return left, equal;
}
public static int firstAlgorithm(int k, int left, int right, int[] S) {
if (left == right)
return S[left];
int p, e = partition(left, right, S); // returns 2 values. S1=[0,p), S2=[p,e), S3=[e, n)
if (p >= k)
return firstAlgorithm(k, left, p, S);
else if (e >= k) // p < k
return S[p]; // p is the first equal, e is first larger than equal
else // e < k
return firstAlgorithm(k, e, right, S);
}
// test
S = {1, 4, 2, 6, 2};
k = 2;
int result = firstAlgorithm(2, 0, S.length-1, S);
assert(result == 2);
Warning syntax and off-by-one errors guarantied.
See here multiple ways to return 2 values in java.
I have wrote but I don't know what is wrong, it should return sum of the values of arrays if the array is not-empty but if array is empty it should return zero.
public class Calculation {
int findSum(int A[], int N) {
if (N <= 0)
return 0;
return (findSum(A, N - 1) + A[N - 1]);
}
int main() {
int A[] = {1, 2, 3, 4, 5};
int N = sizeof(A) / sizeof(A[0]);
System.out.print("Sum = " + findSum(A, N));
return 0;
}
}
You are using C/C++ code in Java. This is working for Java
public class Calculation {
static int findSum(int[] A, int N) {
if(N<=0) {
return 0;
}
int sum = 0;
for(int i:A) {
sum+=i;
}
return sum;
}
public static void main(String args[]) {
int[] A = {1,2,3,4,5};
int N = A.length;
System.out.println("Sum of x+y = " + findSum(A, N));
}
}
public class ArrayUtils {
static int sumOfArray(int[] arr) {
if(arr.length<=0) {
return 0;
}
int sumOfArray = 0;
for(int i:arr) {
sumOfArray+=i;
}
return sumOfArray;
}
public static void main(String args[]) {
int[] arr = {1,2,3,4,5};
System.out.println("Sum of all array elements = " + sumOfArray(arr));
}
}
I was trying to solve a problem based on value and weight. In the task i had to pick out the elements by their value and weight, and find the highest efficiency solution. I receive an answer, however i am having trouble outputting the elements that were used in order to get an answer.
I've tried creating a string in which i place the values, however it gives out an outofbounds error.
public static void main(String[] args) {
String z[] = new String[]{"a","b","c","d","e","f","g","h","l","m"};
int w[] = new int[]{10,2,4,6,8,1,7,11,4,5};
int c[] = new int[]{20,3,5,7,4,1,8,15,8,6};
int maxW = 50;
int n = c.length;
System.out.println("");
int a = Find(w,c,maxW,n,z);
System.out.println("max value is " + a);
}
static int max(int a, int b)
{
if(a>b)
{
return a;
}
return b;
}
public static int Find(int w[],int c[], int maxW,int n, String[]z)
{
int K[][] = new int[n + 1][maxW + 1];
String s = "";
// Build table K[][] in bottom up manner
for (int i = 0; i<= n; i++)
{
for(int j = 0; j<= maxW; j++)
{
if (i == 0 || j == 0)
{
K[i][j] = 0;
}
else if (w[i - 1]<= j)
{
K[i][j] = max(c[i - 1] + K[i - 1][j - w[i - 1]], K[i - 1][j]);
}
else
{
K[i][j] = K[i - 1][j];
}
}
}
return K[n][maxW];
}
}
i want to output the same index element in string z, as the index element that is used to find the efficiancy.
The ideal result would be something like this in a string:
a a a b c d e m
(Just an example)
Thank you in advance.
It is printing out a few permutations but the rest are null and I'm not sure why. I need to but all the permutations into String[] and I can't import any other package except for util.Arrays. Please help!
import java.util.Arrays;
public class DIE
{
public static String[] printPermutations(String s)
{
int l = s.length();
int f = factorial(l);
int count = 0;
String[] array = new String[f];
permute("", s, array, 0);
Arrays.sort(array);
return array;
}
private static String[] permute(String x, String s, String [] array, int count)
{
int l = s.length();
if (l == 0)
{
array[count] = (x + s);
}
for (int i = 0; i < l; i++)
{
permute(x + s.charAt(i), s.substring(0, i) +
s.substring(i +1, s.length()), array, count);
count++;
}
return array;
}
public static int factorial(int l)
{
if (l == 1)
{
return 1;
}
else
{
int result = l * factorial(l - 1);
return result;
}
}
/*
Do not edit anything below this comment.
*/
public static void main(String[] args)
{
String[] permutations = printPermutations(args[0]);
for(String p : permutations)
{
System.out.println(p);
}
}
}
Your count variable is wrong. Within the outermost call to permute("", "abc", ...) it is incremented only by one, even though the call to the next level permute("a", "bc", ...) creates two permutations!
There are two possible solutions:
Instead of a String[] to collect your result use a List<String>. Then you don't need to manually count the number of permutations.
let permute return the new count (instead of the result array, that one is never used anyway)
For permute to return the new count the method would look like this:
private static int permute(String x, String s, String [] array, int count)
{
int l = s.length();
if (l == 0)
{
array[count++] = x;
}
for (int i = 0; i < l; i++)
{
count = permute(x + s.charAt(i), s.substring(0, i) +
s.substring(i +1, s.length()), array, count);
}
return count;
}
Using a List<String> would need some more changes, but the permute function would be smaller:
public static List<String> printPermutations(String s)
{
int l = s.length();
int f = factorial(l);
List<String> result = new ArrayList<>(f);
permute("", s, result);
Collections.sort(result);
return result;
}
private static void permute(String x, String s, List<String> result)
{
int l = s.length();
if (l == 0)
{
result.add(x);
}
for (int i = 0; i < l; i++)
{
permute(x + s.charAt(i), s.substring(0, i) +
s.substring(i +1, s.length()), result);
}
}
And some small changes in the main method due to the changed result of printPermutations (IMHO a very bad named method: it prints out nothing, it creates the permutations together with a helper method)