Conditions of the 6-digit code:
None of the digits are 0
Each digit of the combination is different
The 6-digit number is divisible by each one of the digits
Input:
Two integers, L and H
L is the limit on the smallest number on the range
H is the limit on the largest number on the range
Output:
C, which defines the number of possible combinations where L<=c<=H
I thought I could use arrays as the condition check, then realized I couldn't use it to find the number of possible combinations. Tried using loops, but couldn't figure it out, all I got for the pseudocode is the input, then a condition if L is less or equal to H. Then I sort of ran to a brick wall.
Here's the code.
''''''''
public static void main(String[] args) {
Scanner FF = new Scanner(System.in);
List<Integer> result = new ArrayList<>();
int l = FF.nextInt();
int h = FF.nextInt();
for (int i = l; i <= h; i++) {
result.add(i);
}
for (int i=l; i<=h; i++){
if (result.get(i) == result.get(i)){
result.remove(i);
}
int temp = result.get(i);
while (result.get(i)>0){
int k = result.get(i)%10;
if (temp % k != 0){
result.remove(i);
}
}
if (String.valueOf(result.get(i)).contains("0")){
result.remove(i);
}
}
System.out.println(result);
}
}
You can create a stream of integers, here 111111 to 1000000 and then filter out everything what doesnot meet your conditions.
public class SixDigitCode {
public static void main(String[] args) {
IntStream.iterate(111111, i -> i < 1000000, i -> i + 1)
.filter(containsZero.negate())
.filter(digitDifferent)
.filter(divideByDigits)
.forEach(System.out::println);
}
static IntPredicate containsZero = i -> Integer.toString(i).contains("0");
static IntPredicate digitDifferent = i -> Integer.toString(i).chars().boxed().collect(Collectors.toSet()).size() == 6;
static IntPredicate divideByDigits = i -> Integer.toString(i).chars().boxed()
.filter( x -> i%Character.getNumericValue(x) ==0)
.count() ==6;
}
There are multiple ways to solve this problem.
Let's start with an easy, but inefficient one:
boolean isOk(int number){
String numberStr = Integer.toString(number);
if(numberStr.contains("0"))
return false;
for(int i = 0; i < numberStr.length(); i++){
for(int j = i + 1; j < numberStr.length(); j++){
if(numberStr.charAt(i) == numberStr.charAt(j))
return false;
}
}
return true;
}
...
int count = 0;
for(int i = L; i <= H; i++){
if(isOk(i))
count ++;
}
Note: this code is by no means optimal, but I think it is a straight forward easy to understand solution.
However, I cannot test it right now, so it may contain minor issues.
Ok so I been working on this assignment all day for the past 3 days but I haven't had any luck. I wasn't going to ask for help but I finally gave up. But there is also one more thing I need to implement to the code. This is what I gotta implement "Find the length of the longest continuous series of positive numbers in the array data. If the contents were: 4 5 0 2 . . . -1 88 78 66 -6. The length would be 3. For this problem, 0 is considered non-negative but not positive". Plus I have an issue where I can't print the largest int in the array of 20.
import java.util.Random;
import java.util.ArrayList;
public class arrayops {
public static int findLargest(ArrayList<Integer> nums) {
int greatestnum = nums.get(0);
for (Integer item : nums) {
if (item > greatestnum) {
greatestnum = item;
}
}
return greatestnum;
}
public static int randomData(ArrayList<Integer> nums) {
int[] array = new int [20];
Random random = new Random();
for (int i = 0; i < array.length; i++) {
array[i] = -100 + random.nextInt(201);
}
return -100 + random.nextInt(201);
}
public static void main(String[] args) {
ArrayList<Integer> nums = new ArrayList<Integer>();
nums.add(1);
nums.add(4);
nums.add(13);
nums.add(43);
nums.add(-25);
nums.add(17);
nums.add(22);
nums.add(-37);
nums.add(29);
System.out.println("The Greatest Number from the hardcoded numbers " + findLargest(nums));
System.out.println("The Greatest number from the random numbers " + randomData(nums));
}
}
The findLargest method:
public static int findLargest(ArrayList<Integer> nums) {
int greatestnum = 0;
int greatestLen = 0;
for (Integer item : nums) {
if (item > 0) {
greatestLen++ ;
if(greatestLen > greatestnum)
greatestnum = greatestLen;
}
else
greatestLen = 0;
}
return greatestnum;
}
Logic used:
Keep the length of the longest chain encountered, and the length of current chain, in two separate variables (greatestnum and greatestLen respectively)
Increment greatestLen every time a positive number is encountered. If the number if less than or equal to zero, reset this count.
If the length of current chain is greater than the previous longest chain, sent the longest chain size to current chain size.
The problem is you created a list with random numbers but never put that list into the findLargest method. You also never created a method to find the consecutive positive numbers. If you didn't know how to go about coding it, I recommend drawing out an algorithm on paper.
Largest value in ArrayList...
public static int findL(ArrayList<Integer> nums)
{
int top = nums.get(0);
for(int i = 0; i<nums.size(); i++)
{
if(nums.get(i)>top)
{
top = nums.get(i);
}
}
return top;
}
Largest number of consecutive positives...
public static int positiveString(ArrayList<Integer> nums)
{
int longest = 0;
int count = 0;
for(int i = 0; i<nums.size(); i++)
{
if(nums.get(i) > 0)
{
count++;
}
else
{
if(longest<count)
{
longest = count;
}
count = 0;
}
}
return longest;
}
If you want to arrange the numbers into order you can simply use java.util.TreeSet. Then use the method last() to get the largest number.
public static int findLargest(ArrayList<Integer> nums) {
return new TreeSet<Integer>(nums).last();
}
I seem to be having an issue regarding implementing a power set algorithm using backtrack. What I am trying to achieve is rather simple, generate the power set of any given numbers:
Ex. [1 2 3] => [1] [2] [3] ; [1,2] [1,3] [2,3] ; [1,2,3]
My algorithm is using a stack to place the numbers, it adds the numbers to the stack and sends them for calculations. The code is as follows:
public int calculatePowerSet(int x, LinkedList<Integer> arr)
{
int size = 1;
int nrOfTimes=0;
int calculate =0;
boolean goOn=true;
Stack<Integer> stack = new Stack<Integer>();
int k=0, len = arr.size();
double temp=0.0f;
while(size<=len)
{
goOn=true;
stack.push(arr.get(0));
k = arr.indexOf(stack.peek());
temp = size; //ignore these as they are for calculating time
temp/=len; //ignore these as they are for calculating time
temp*=100; //ignore these as they are for calculating time
setPowerSetPrecentage((int)temp);
while(goOn)
{
if(isStopProcess())return 0;
if((k==len)&&(stack.size()==0)) goOn=false;
else if(stack.size()==size)
{
String sign = "";
if((stack.size()%2)==0) sign="+";
else sign="-";
calculate =calculateSets(stack.toArray(), sign, calculate, x);
k = arr.indexOf(stack.pop())+1;
}
else if(k==len)
k = arr.indexOf(stack.pop())+1;
else
{
prepereStack(stack,arr.get(k));
k++;
}
}
size++;
}
return calculate;
}
Here is the calculate method:
private int calculate(int[] arr2, int x)
{
int calc=1;
float rez = 0;
for(int i=0;i<arr2.length;i++)
calc*=arr2[i];
rez = (float)(x/calc);
calc = (int) (rez+0.5d);
return calc;
}
The code seems to be working perfectly for all numbers bellow 20, but after that i seem to be getting wrong results. I cannot check manually through the numbers as there are hundreds of combinations. For example for one input of 25 numbers i should get a result of 1229, instead i get 1249. I am not sure what i am missing as i think the algorithm should be working in theory, so if anyone has any suggestions that would be great.
I would recommend separating out the generation of the power sets from your calculation. While there are some very efficient algorithms for generating power sets I would suggest keeping it quite simple until you need the efficiency.
private void forEachSet(List<Integer> currentSet, List<Integer> rest) {
if (rest.isEmpty()) {
process(currentSet);
} else {
Integer nextInt = rest.remove(0);
forEachSet(currentSet, rest);
currentSet.add(nextInt);
forEachSet(currentSet, rest);
current.remove(nextInt);
rest.add(nextInt);
}
}
public forEachSet(List<Integer> set) {
forEachSet(new ArrayList<>(), new ArrayList<>(set));
}
If the input is 'abba' then the possible palindromes are a, b, b, a, bb, abba.
I understand that determining if string is palindrome is easy. It would be like:
public static boolean isPalindrome(String str) {
int len = str.length();
for(int i=0; i<len/2; i++) {
if(str.charAt(i)!=str.charAt(len-i-1) {
return false;
}
return true;
}
But what is the efficient way of finding palindrome substrings?
This can be done in O(n), using Manacher's algorithm.
The main idea is a combination of dynamic programming and (as others have said already) computing maximum length of palindrome with center in a given letter.
What we really want to calculate is radius of the longest palindrome, not the length.
The radius is simply length/2 or (length - 1)/2 (for odd-length palindromes).
After computing palindrome radius pr at given position i we use already computed radiuses to find palindromes in range [i - pr ; i]. This lets us (because palindromes are, well, palindromes) skip further computation of radiuses for range [i ; i + pr].
While we search in range [i - pr ; i], there are four basic cases for each position i - k (where k is in 1,2,... pr):
no palindrome (radius = 0) at i - k
(this means radius = 0 at i + k, too)
inner palindrome, which means it fits in range
(this means radius at i + k is the same as at i - k)
outer palindrome, which means it doesn't fit in range
(this means radius at i + k is cut down to fit in range, i.e because i + k + radius > i + pr we reduce radius to pr - k)
sticky palindrome, which means i + k + radius = i + pr
(in that case we need to search for potentially bigger radius at i + k)
Full, detailed explanation would be rather long. What about some code samples? :)
I've found C++ implementation of this algorithm by Polish teacher, mgr Jerzy WaĆaszek.
I've translated comments to english, added some other comments and simplified it a bit to be easier to catch the main part.
Take a look here.
Note: in case of problems understanding why this is O(n), try to look this way:
after finding radius (let's call it r) at some position, we need to iterate over r elements back, but as a result we can skip computation for r elements forward. Therefore, total number of iterated elements stays the same.
Perhaps you could iterate across potential middle character (odd length palindromes) and middle points between characters (even length palindromes) and extend each until you cannot get any further (next left and right characters don't match).
That would save a lot of computation when there are no many palidromes in the string. In such case the cost would be O(n) for sparse palidrome strings.
For palindrome dense inputs it would be O(n^2) as each position cannot be extended more than the length of the array / 2. Obviously this is even less towards the ends of the array.
public Set<String> palindromes(final String input) {
final Set<String> result = new HashSet<>();
for (int i = 0; i < input.length(); i++) {
// expanding even length palindromes:
expandPalindromes(result,input,i,i+1);
// expanding odd length palindromes:
expandPalindromes(result,input,i,i);
}
return result;
}
public void expandPalindromes(final Set<String> result, final String s, int i, int j) {
while (i >= 0 && j < s.length() && s.charAt(i) == s.charAt(j)) {
result.add(s.substring(i,j+1));
i--; j++;
}
}
So, each distinct letter is already a palindrome - so you already have N + 1 palindromes, where N is the number of distinct letters (plus empty string). You can do that in single run - O(N).
Now, for non-trivial palindromes, you can test each point of your string to be a center of potential palindrome - grow in both directions - something that Valentin Ruano suggested.
This solution will take O(N^2) since each test is O(N) and number of possible "centers" is also O(N) - the center is either a letter or space between two letters, again as in Valentin's solution.
Note, there is also O(N) solution to your problem, based on Manacher's algoritm (article describes "longest palindrome", but algorithm could be used to count all of them)
I just came up with my own logic which helps to solve this problem.
Happy coding.. :-)
System.out.println("Finding all palindromes in a given string : ");
subPal("abcacbbbca");
private static void subPal(String str) {
String s1 = "";
int N = str.length(), count = 0;
Set<String> palindromeArray = new HashSet<String>();
System.out.println("Given string : " + str);
System.out.println("******** Ignoring single character as substring palindrome");
for (int i = 2; i <= N; i++) {
for (int j = 0; j <= N; j++) {
int k = i + j - 1;
if (k >= N)
continue;
s1 = str.substring(j, i + j);
if (s1.equals(new StringBuilder(s1).reverse().toString())) {
palindromeArray.add(s1);
}
}
}
System.out.println(palindromeArray);
for (String s : palindromeArray)
System.out.println(s + " - is a palindrome string.");
System.out.println("The no.of substring that are palindrome : "
+ palindromeArray.size());
}
Output:-
Finding all palindromes in a given string :
Given string : abcacbbbca
******** Ignoring single character as substring palindrome ********
[cac, acbbbca, cbbbc, bb, bcacb, bbb]
cac - is a palindrome string.
acbbbca - is a palindrome string.
cbbbc - is a palindrome string.
bb - is a palindrome string.
bcacb - is a palindrome string.
bbb - is a palindrome string.
The no.of substring that are palindrome : 6
I suggest building up from a base case and expanding until you have all of the palindomes.
There are two types of palindromes: even numbered and odd-numbered. I haven't figured out how to handle both in the same way so I'll break it up.
1) Add all single letters
2) With this list you have all of the starting points for your palindromes. Run each both of these for each index in the string (or 1 -> length-1 because you need at least 2 length):
findAllEvenFrom(int index){
int i=0;
while(true) {
//check if index-i and index+i+1 is within string bounds
if(str.charAt(index-i) != str.charAt(index+i+1))
return; // Here we found out that this index isn't a center for palindromes of >=i size, so we can give up
outputList.add(str.substring(index-i, index+i+1));
i++;
}
}
//Odd looks about the same, but with a change in the bounds.
findAllOddFrom(int index){
int i=0;
while(true) {
//check if index-i and index+i+1 is within string bounds
if(str.charAt(index-i-1) != str.charAt(index+i+1))
return;
outputList.add(str.substring(index-i-1, index+i+1));
i++;
}
}
I'm not sure if this helps the Big-O for your runtime, but it should be much more efficient than trying each substring. Worst case would be a string of all the same letter which may be worse than the "find every substring" plan, but with most inputs it will cut out most substrings because you can stop looking at one once you realize it's not the center of a palindrome.
I tried the following code and its working well for the cases
Also it handles individual characters too
Few of the cases which passed:
abaaa --> [aba, aaa, b, a, aa]
geek --> [g, e, ee, k]
abbaca --> [b, c, a, abba, bb, aca]
abaaba -->[aba, b, abaaba, a, baab, aa]
abababa -->[aba, babab, b, a, ababa, abababa, bab]
forgeeksskeegfor --> [f, g, e, ee, s, r, eksske, geeksskeeg,
o, eeksskee, ss, k, kssk]
Code
static Set<String> set = new HashSet<String>();
static String DIV = "|";
public static void main(String[] args) {
String str = "abababa";
String ext = getExtendedString(str);
// will check for even length palindromes
for(int i=2; i<ext.length()-1; i+=2) {
addPalindromes(i, 1, ext);
}
// will check for odd length palindromes including individual characters
for(int i=1; i<=ext.length()-2; i+=2) {
addPalindromes(i, 0, ext);
}
System.out.println(set);
}
/*
* Generates extended string, with dividors applied
* eg: input = abca
* output = |a|b|c|a|
*/
static String getExtendedString(String str) {
StringBuilder builder = new StringBuilder();
builder.append(DIV);
for(int i=0; i< str.length(); i++) {
builder.append(str.charAt(i));
builder.append(DIV);
}
String ext = builder.toString();
return ext;
}
/*
* Recursive matcher
* If match is found for palindrome ie char[mid-offset] = char[mid+ offset]
* Calculate further with offset+=2
*
*
*/
static void addPalindromes(int mid, int offset, String ext) {
// boundary checks
if(mid - offset <0 || mid + offset > ext.length()-1) {
return;
}
if (ext.charAt(mid-offset) == ext.charAt(mid+offset)) {
set.add(ext.substring(mid-offset, mid+offset+1).replace(DIV, ""));
addPalindromes(mid, offset+2, ext);
}
}
Hope its fine
public class PolindromeMyLogic {
static int polindromeCount = 0;
private static HashMap<Character, List<Integer>> findCharAndOccurance(
char[] charArray) {
HashMap<Character, List<Integer>> map = new HashMap<Character, List<Integer>>();
for (int i = 0; i < charArray.length; i++) {
char c = charArray[i];
if (map.containsKey(c)) {
List list = map.get(c);
list.add(i);
} else {
List list = new ArrayList<Integer>();
list.add(i);
map.put(c, list);
}
}
return map;
}
private static void countPolindromeByPositions(char[] charArray,
HashMap<Character, List<Integer>> map) {
map.forEach((character, list) -> {
int n = list.size();
if (n > 1) {
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
if (list.get(i) + 1 == list.get(j)
|| list.get(i) + 2 == list.get(j)) {
polindromeCount++;
} else {
char[] temp = new char[(list.get(j) - list.get(i))
+ 1];
int jj = 0;
for (int ii = list.get(i); ii <= list
.get(j); ii++) {
temp[jj] = charArray[ii];
jj++;
}
if (isPolindrome(temp))
polindromeCount++;
}
}
}
}
});
}
private static boolean isPolindrome(char[] charArray) {
int n = charArray.length;
char[] temp = new char[n];
int j = 0;
for (int i = (n - 1); i >= 0; i--) {
temp[j] = charArray[i];
j++;
}
if (Arrays.equals(charArray, temp))
return true;
else
return false;
}
public static void main(String[] args) {
String str = "MADAM";
char[] charArray = str.toCharArray();
countPolindromeByPositions(charArray, findCharAndOccurance(charArray));
System.out.println(polindromeCount);
}
}
Try out this. Its my own solution.
// Maintain an Set of palindromes so that we get distinct elements at the end
// Add each char to set. Also treat that char as middle point and traverse through string to check equality of left and right char
static int palindrome(String str) {
Set<String> distinctPln = new HashSet<String>();
for (int i=0; i<str.length();i++) {
distinctPln.add(String.valueOf(str.charAt(i)));
for (int j=i-1, k=i+1; j>=0 && k<str.length(); j--, k++) {
// String of lenght 2 as palindrome
if ( (new Character(str.charAt(i))).equals(new Character(str.charAt(j)))) {
distinctPln.add(str.substring(j,i+1));
}
// String of lenght 2 as palindrome
if ( (new Character(str.charAt(i))).equals(new Character(str.charAt(k)))) {
distinctPln.add(str.substring(i,k+1));
}
if ( (new Character(str.charAt(j))).equals(new Character(str.charAt(k)))) {
distinctPln.add(str.substring(j,k+1));
} else {
continue;
}
}
}
Iterator<String> distinctPlnItr = distinctPln.iterator();
while ( distinctPlnItr.hasNext()) {
System.out.print(distinctPlnItr.next()+ ",");
}
return distinctPln.size();
}
Code is to find all distinct substrings which are palindrome.
Here is the code I tried. It is working fine.
import java.util.HashSet;
import java.util.Set;
public class SubstringPalindrome {
public static void main(String[] args) {
String s = "abba";
checkPalindrome(s);
}
public static int checkPalindrome(String s) {
int L = s.length();
int counter =0;
long startTime = System.currentTimeMillis();
Set<String> hs = new HashSet<String>();
// add elements to the hash set
System.out.println("Possible substrings: ");
for (int i = 0; i < L; ++i) {
for (int j = 0; j < (L - i); ++j) {
String subs = s.substring(j, i + j + 1);
counter++;
System.out.println(subs);
if(isPalindrome(subs))
hs.add(subs);
}
}
System.out.println("Total possible substrings are "+counter);
System.out.println("Total palindromic substrings are "+hs.size());
System.out.println("Possible palindromic substrings: "+hs.toString());
long endTime = System.currentTimeMillis();
System.out.println("It took " + (endTime - startTime) + " milliseconds");
return hs.size();
}
public static boolean isPalindrome(String s) {
if(s.length() == 0 || s.length() ==1)
return true;
if(s.charAt(0) == s.charAt(s.length()-1))
return isPalindrome(s.substring(1, s.length()-1));
return false;
}
}
OUTPUT:
Possible substrings:
a
b
b
a
ab
bb
ba
abb
bba
abba
Total possible substrings are 10
Total palindromic substrings are 4
Possible palindromic substrings: [bb, a, b, abba]
It took 1 milliseconds
I was trying to solve this practice problem, it is also quoted below.
The Chef is planning a buffet for the DirectiPlex inauguration party,
and everyone is invited. On their way in, each guest picks up a sheet
of paper containing a random number (this number may be repeated). The
guests then sit down on a round table with their friends.
The Chef now decides that he would like to play a game. He asks you to pick a random person from your table and have them read their
number out loud. Then, moving clockwise around the table, each person
will read out their number. The goal is to find that set of numbers
which forms an increasing subsequence. All people owning these
numbers will be eligible for a lucky draw! One of the software
developers is very excited about this prospect, and wants to maximize
the number of people who are eligible for the lucky draw. So, he
decides to write a program that decides who should read their number
first so as to maximize the number of people that are eligible for the
lucky draw. Can you beat him to it?
Input The first line contains t, the number of test cases (about 15). Then t test cases follow. Each test case consists of two
lines:
The first line contains a number N, the number of guests invited to
the party.
The second line contains N numbers a1, a2, ..., an separated by
spaces, which are the numbers written on the sheets of paper in
clockwise order.
Output For each test case, print a line containing a single number which is the maximum number of guests that can be eligible for
participating the the lucky draw.
Here's the solution that I have come up with
// http://www.codechef.com/problems/D2/
import java.io.*;
import java.util.*;
public class D2
{
public static void main(String [] args)
throws IOException
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int numTestCases = Integer.parseInt(br.readLine());
for(int _t=0; _t<numTestCases; ++_t)
{
int N = Integer.parseInt(br.readLine());
StringTokenizer strtok = new StringTokenizer(br.readLine());
int [] originalArray = new int[N*2];
for(int i=0; i<N; ++i)
{
//this concatenates the array with itself at the time of reading the input itself
originalArray[i] = originalArray[N+i] = Integer.parseInt(strtok.nextToken());
}
//Now we calculate the length of the longest increasing sequence
int maxWinners = new LongestIncreasingSequence(originalArray).lengthOfLongestIncreasingSequence();
System.out.println(maxWinners);
}
}
}
class LongestIncreasingSequence
{
private int [] array;
private int [] longest;
private int subsequence_size;
public LongestIncreasingSequence(int [] A)
{
array = A;
longest = new int[array.length / 2];
longest[0] = array[0];
subsequence_size = 1;
}
public int lengthOfLongestIncreasingSequence()
{
for(int i=1; i<array.length; ++i)
{
if(array[i] < longest[0])
{
longest[0] = array[i];
}
else if(array[i] > longest[subsequence_size - 1])
{
longest[subsequence_size++] = array[i];
}
else
{
//Make the replacement with binary search
longest[getReplacementIndex(array[i])] = array[i];
}
}
return subsequence_size;
}
//Method to find the correct index using binary search
private int getReplacementIndex(int elem)
{
int left, right, mid;
left = 0; right = subsequence_size - 1;
while(right - left > 1)
{
mid = 1 + (right - left) / 2;
if(array[mid] >= elem)
{
if(mid != right) right = mid;
else --right;
}
else
{
left = mid;
}
}
return right;
}
}
The complexity is O(n(log(n)) I'm finding the Longest Increasing Sequence by concatenating the array with itself.
This however doesn't pass the time requirement, can someone help me speed up this implementation.
I would not do N rotations, but instead determine the longest (cyclic) run in one go. It is certainly doable, you just have to take care warping around at the end of the array.