Create Random Number List With No Repetition - random

I'm looking to create a list of 'random' numbers from 1 to 15 but without any repetition. I have created an array and looking to store each number in it but can't figure out how to do this. I've gotten as far as creating the random list and storing them in the array but can't quite get to ensure there are no repetitions. Any help would be appreciated. My code is as follows:
int[] myList = new int[15];
Random random = new Random();
for (int i = 0; myList.Length; i++)
{
myList[i] = random.Next(1, 15);
}

Because the size of your list is equal to the possible values, you can just create the list in normal order:
int[] myList = new int[15];
for (int i = 0; i < myList.Length; i++)
{
myList[i] = i + 1;
}
and then shuffle it, for example by assigning a random value to each entry and sort by that value:
Random random = new Random();
myList = myList.OrderBy(a => random.Next()).ToArray();

You can do it using Fisher–Yates shuffle.
Sample Implementation:
int n = 15;
int[] myList = new int[n];
Random random = new Random();
for (int i = 0; i < n; i++)
{
myList[i] = i + 1;
}
for (int i = n - 1; i >= 1; i--)
{
int j = random.Next(1, i);
int temp=myList[i];
myList[i]=myList[j];
myList[j]=temp;
}

You need to get the algorithm right.
Start from i=15
Pick a random number from 1 to i.
Append it to the list.
Swap it with (i-1)th index.
Decrement i by 1.
Repeat the above steps.
The code for above can be:
int[] myList = new int[15];
int[] original_list = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
Random random = new Random();
for (int i = myList.Length; i>=0; i--)
{int randNo = random.Next(0, i-1);
myList[i] = original_list[randNo];
swap(original_list[i-1],original_list[randNo]); //your swap method
}

Related

Why won't my random selection without replacement algorithm work?

I have made a very simple algorithm that picks a set of numToPick random numbers from the range 0 to batchMax, without replacement. Then it places each selected number in an array called numsPicked. For some reason I cannot explain, it isn't working on DartPad.
import 'dart:math';
void main() {
print(randNoReplace(2, 9));
}
List<int> randNoReplace(int numToPick, int batchMax) {
List<int> numsPicked = List(numToPick);
List<int> tmpArray = List(batchMax);
//this for loop creates the tmpArray from 0 to batchMax.
for (int i = 0; i <= batchMax; i++) {
tmpArray[i] = i;
}
//this for loop randomly scrambles said tmpArray.
for (int i = 0; i <= batchMax; i++) {
int randIndex = Random().nextInt(batchMax);
int tmp = tmpArray[i];
tmpArray[i] = tmpArray[randIndex];
tmpArray[randIndex] = tmp;
}
//finally, this for loop adds the first numToPick entries of the scrambled tmpArray and adds them to numsPicked.
for (int i = 0; i < numToPick; i++) {
numsPicked[i] = tmpArray[i];
}
return numsPicked;
}
So, for example, with 2 and 9 respectively, this algorithm should theoretically give me 2 random non-duplicate numbers in the range [0, 9].
I think the main issue in your code is that your first two for-loops are going from 0 to
batchMax including batchMax. This is a problem since you are using batchMax to specify the size of your tmpArray. Since the index of a List starts at 0, we cannot ask for the batchMax-element but at most batchMax - 1.
So you code should properly be (or `tmpArray should be one element bigger):
import 'dart:math';
void main() {
print(randNoReplace(2, 9));
}
List<int> randNoReplace(int numToPick, int batchMax) {
List<int> numsPicked = List(numToPick);
List<int> tmpArray = List(batchMax);
//this for loop creates the tmpArray from 0 to batchMax.
for (int i = 0; i < batchMax; i++) {
tmpArray[i] = i;
}
//this for loop randomly scrambles said tmpArray.
for (int i = 0; i < batchMax; i++) {
int randIndex = Random().nextInt(batchMax);
int tmp = tmpArray[i];
tmpArray[i] = tmpArray[randIndex];
tmpArray[randIndex] = tmp;
}
//finally, this for loop adds the first numToPick entries of the scrambled tmpArray and adds them to numsPicked.
for (int i = 0; i < numToPick; i++) {
numsPicked[i] = tmpArray[i];
}
return numsPicked;
}
Some other minor comments:
You should properly not initialize a new Random() object each time you need a random number. Instead, you should create one instance and reuse it.
Your code are not making much use of the Dart SDK. In fact, your code could properly be simplified into:
void main() {
print(randNoReplace(2, 9));
}
List<int> randNoReplace(int numToPick, int batchMax) =>
(List.generate(batchMax, (index) => index)..shuffle())
.sublist(0, numToPick);

Hockey stick pattern in pascal's triangle

I learnt about pascal's triangle and achieved to print one in Java with O(n2) complexity.
Now for the next part I have to find the sequences of numbers that form a hockey stick pattern and I am stuck here. Any help will be great!
Also this link will help you understand what a hockey stick pattern is in pascal's triangle.
Below is the code I wrote to return the triangle
int[][] printPascal(int n)
{
int[][] arr= new int[n][n];
for(int line=0;line<n;line++)
{
for(int i=0;i<=line;i++)
{
if(line==i|| i==0)
{
arr[line][i]=1;
}
else
{
arr[line][i]=arr[line-1][i-1]+arr[line-1][i];
}
System.out.print(arr[line][i]+" ");
}
System.out.println();
}
return arr;
}
I tried to do something but I am getting arrayIndexOutOfBound
void printSequence(int[][]arr)
{
int n= arr.length;
Map<Integer, List<Integer>> map =new HashMap<>();
List<Integer> sequence= new ArrayList<>();
for(int i=0;i<=n;i++)
{
int count=0;
int res=0;
for(int line=0;line<n;line++)
{
sequence.add(arr[line][i]);
res=sumList(sequence);
if(res!=arr[line+1][i+1])
{
sequence=new ArrayList<>();
continue;
}
else
{
List<Integer> resSeq= new ArrayList<>(sequence);
resSeq.add(arr[line+1][i+1]);
map.put(++count, resSeq);
res=0;
}
}
}
}
I need to find all the sequences that satisfies the rule
nCr+(n+1)Cr+(n+2)Cr+.....+(n+k)Cr=(n+k+1)Cr
And these sequences if marked on a Pascal's triangle will resemble a hockey stick.
Here is how my solution looks like
void hockeyNumbers(int[][] arr) {
int n = arr.length;
List<Integer> sequence;
Map<Integer, List<Integer>> map = new HashMap<>();
int count = 0;
for (int i = 0; i < n; i++) {
int res = 0;
sequence = new ArrayList<>();
for (int line = i; line < n - 1; line++) {
sequence.add(arr[line][i]);
res = sumList(sequence);
if (res == arr[line + 1][i + 1]) {
List<Integer> resSeq = new ArrayList<>(sequence);
resSeq.add(arr[line + 1][i + 1]);
if (resSeq.size() > 2) {
map.put(++count, resSeq);
}
res = 0;
}
}
}
}
I have worked the solution and it looks like below. I am storing all the sequences in a hashmap for later use.
void hockeyNumbers(int[][] arr) {
int n = arr.length;
List<Integer> sequence;
Map<Integer, List<Integer>> map = new HashMap<>();
int count = 0;
for (int i = 0; i < n; i++) {
int res = 0;
sequence = new ArrayList<>();
for (int line = i; line < n - 1; line++) {
sequence.add(arr[line][i]);
res = sumList(sequence);
if (res == arr[line + 1][i + 1]) {
List<Integer> resSeq = new ArrayList<>(sequence);
resSeq.add(arr[line + 1][i + 1]);
if (resSeq.size() > 2) {
map.put(++count, resSeq);
}
res = 0;
}
}
}
}
I have tried finding the hockey stick through Pascal's triangle with some boundary conditions.(0 < n <= 30000 && 0 < l <= 100) where n is the row number(rows starts with 0) and l is the length of the hockey stick(length starts with 0).But, these extreme conditions create timeout issues.
Now, one way to create Pascal's triangle is using Binomial coefficients.
Following the same thing, we can get the hockey stick. For this, we don't need to create the complete triangle. You just need the row number and the length of the hockey stick.
We know that hockey stick always starts with 1 and second index of that row will be the row number itself.
So now, we already have two values of the hockey stick 1 and (Row+1).
The next value can be generated through Binomial coefficients using the following :
C(line, i) = C(line, i-1) * (line - i + 1) / i
private static void hockeyStick(int row, int length) {
System.out.println("Hockey stick statring from " + row);
List<Integer> finalResult = new ArrayList<>(Arrays.asList(1, ++row));
int oldValue = 1;
int newValue = row;
int sum = row + 1;
for (int i = 2; i < length - 1; i++) {
finalResult.add(newValuebimialCoefficient(oldValue + newValue, i, ++row));
oldValue += newValue;
newValue = finalResult.get(i);
sum += newValue;
}
finalResult.add(sum);
System.out.println(finalResult);
}
private static int newValuebimialCoefficient(int oldValue, int index, int line) {
return (oldValue * (line - index + 1) / index);
}
I think this should be helpful.

Most efficient way to search through rows and change values in columns of a large array (50,000 by 50,000)

Say there is a large two dimensional array (50,000 by 50,000). Essentially all the elements in the array are 1s and 0s. I am try to figure out an efficient way to change values in columns (1s to 0s and 0s to 1s). But more importantly see which rows have matching elements (a row with all the same values).
I suppose you could do something like
int[][] data = new int[1000][1000];
// populate
final Random random = new Random();
for (int i = 0; i < data.length; i++) {
for (int j = 0; j < data[i].length; j++) {
final int value = random.nextInt();
data[i][j] = ((value % 2 == 0) ? 1 : 0);
}
}
final List<BigInteger> bitStrings = new ArrayList<>();
StringBuilder builder = null;
for (int i = 0; i < data.length; i++) {
builder = new StringBuilder();
for (int j = 0; j < data[i].length; j++) {
final int value = data[i][j];
builder.append(value);
}
final BigInteger bitString = new BigInteger(builder.toString(), 2);
bitStrings.add(bitString);
}
for (final BigInteger bitString : bitStrings) {
System.out.println(bitString.toString(2));
}
And use the BigInteger operations for bitwise operations.

interviewstreet Triplet challenge

There is an integer array d which does not contain more than two elements of the same value. How many distinct ascending triples (d[i] < d[j] < d[k], i < j < k) are present?
Input format:
The first line contains an integer N denoting the number of elements in the array. This is followed by a single line containing N integers separated by a single space with no leading/trailing spaces
Output format:
A single integer that denotes the number of distinct ascending triples present in the array
Constraints:
N <= 10^5
Every value in the array is present at most twice
Every value in the array is a 32-bit positive integer
Sample input:
6
1 1 2 2 3 4
Sample output:
4
Explanation:
The distinct triplets are
(1,2,3)
(1,2,4)
(1,3,4)
(2,3,4)
Another test case:
Input:
10
1 1 5 4 3 6 6 5 9 10
Output:
28
I tried to solve using DP. But out of 15 test cases only 7 test cases passed.
Please help solve this problem.
You should note that you only need to know the number of elements that are smaller/larger than a particular element to know how many triples it serves as the middle point for. Using this you can calculate the number of triples quite easily, the only remaining problem is to get rid of duplicates, but given that you are limited to at most 2 of the same element, this is trivial.
I solved using a Binary Index Tree http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=binaryIndexedTrees.
I also did a small write up, http://www.kesannmcclean.com/?p=223.
package com.jai;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.HashMap;
public class Triplets {
int[] lSmaller, rLarger, treeArray, dscArray, lFlags, rFlags;
int size, count = 0;
Triplets(int aSize, int[] inputArray) {
size = aSize;
lSmaller = new int[size];
rLarger = new int[size];
dscArray = new int[size];
int[] tmpArray = Arrays.copyOf(inputArray, inputArray.length);
Arrays.sort(tmpArray);
HashMap<Integer, Integer> tmpMap = new HashMap<Integer, Integer>(size);
for (int i = 0; i < size; i++) {
if (!tmpMap.containsKey(tmpArray[i])) {
count++;
tmpMap.put(tmpArray[i], count);
}
}
count++;
treeArray = new int[count];
lFlags = new int[count];
rFlags = new int[count];
for (int i = 0; i < size; i++) {
dscArray[i] = tmpMap.get(inputArray[i]);
}
}
void update(int idx) {
while (idx < count) {
treeArray[idx]++;
idx += (idx & -idx);
}
}
int read(int index) {
int sum = 0;
while (index > 0) {
sum += treeArray[index];
index -= (index & -index);
}
return sum;
}
void countLeftSmaller() {
Arrays.fill(treeArray, 0);
Arrays.fill(lSmaller, 0);
Arrays.fill(lFlags, 0);
for (int i = 0; i < size; i++) {
int val = dscArray[i];
lSmaller[i] = read(val - 1);
if (lFlags[val] == 0) {
update(val);
lFlags[val] = i + 1;
} else {
lSmaller[i] -= lSmaller[lFlags[val] - 1];
}
}
}
void countRightLarger() {
Arrays.fill(treeArray, 0);
Arrays.fill(rLarger, 0);
Arrays.fill(rFlags, 0);
for (int i = size - 1; i >= 0; i--) {
int val = dscArray[i];
rLarger[i] = read(count - 1) - read(val);
if (rFlags[val] == 0) {
update(val);
rFlags[val] = i + 1;
}
}
}
long countTriplets() {
long sum = 0;
for (int i = 0; i < size; i++) {
sum += lSmaller[i] * rLarger[i];
}
return sum;
}
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
int[] a = new int[N];
String[] strs = br.readLine().split(" ");
for (int i = 0; i < N; i++)
a[i] = Integer.parseInt(strs[i]);
Triplets sol = new Triplets(N, a);
sol.countLeftSmaller();
sol.countRightLarger();
System.out.println(sol.countTriplets());
}
}
For tentative algorithm that I came up with, it should be:
(K-1)!^2
where K is number of unique elements.
EDIT
After more thinking about this:
SUM[i=1,K-2] SUM[j=i+1,K-1] SUM[m=j+1,K] 1
=> SUM[i=1,K-2] (SUM[j=i+1,K-1] (K-j))
if the input is not sorted (the question is not clear about this): sort it
remove the duplicated items (this step could be conbined with the first step)
now pick 3 items. Since the items are already sorted, the three chosen items are ordered as well
IIRC there are (n!) / ((n-3)! * 3!) ways to pick the three items; with n := the number of unique items
#hadron: exactly, I couldn get my head around on why it should be 28 and not 35 for a set of 7 distinct numbers *
[Since the ques is about ascending triplets, repeated numbers can be discarded].
btw, here's a very bad Java solution(N^3):
I have also printed out the possible triplets:
I'm also thinking about some function that dictates the no: of triplets possible for input 'N'
4 4
5 10
6 20
7 35
8 56
9 84
package org.HackerRank.AlgoChallenges;
import java.util.Iterator;
import java.util.Scanner;
import java.util.TreeSet;
public class Triplets {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int result = 0;
int n = scanner.nextInt();
Object[] array = new Object[n];
TreeSet<Integer> treeSet = new TreeSet<Integer>();
/*
* for (int i = 0; i < n; i++) { array[i] = scanner.nextInt(); }
*/
while (n>0) {
treeSet.add(scanner.nextInt());
n--;
}
scanner.close();
Iterator<Integer> iterator = treeSet.iterator();
int i =0;
while (iterator.hasNext()) {
//System.out.println("TreeSet["+i+"] : "+iterator.next());
array[i] = iterator.next();
//System.out.println("Array["+i+"] : "+array[i]);
i++;
}
for (int j = 0; j < (array.length-2); j++) {
for (int j2 = (j+1); j2 < array.length-1; j2++) {
for (int k = (j2+1); k < array.length; k++) {
if(array[j]!=null && array[j2]!=null && array[k]!=null){
System.out.println("{ "+array[j]+", "+array[j2]+", "+array[k]+" }");
result++;
}
}
}
}
System.out.println(result);
}
One of solution in python:
from itertools import combinations as comb
def triplet(lis):
done = dict()
result = set()
for ind, num in enumerate(lis):
if num not in done:
index = ind+1
for elm in comb(lis[index:], 2):
s,t = elm[0], elm[1]
if (num < s < t):
done.setdefault(num, None)
fin = (num,s,t)
if fin not in result:
result.add(fin)
return len(result)
test = int(raw_input())
lis = [int(_) for _ in raw_input().split()]
print triplet(lis)
Do you care about complexity?
Is the input array sorted?
if you don't mind about complexity you can solve it in complexity of N^3.
The solution with complexity N^3:
If it not sorted, then sorted the array.
Use 3 for loops one inside the other and go threw the array 3 times for each number.
Use hash map to count all the triples. The key will be the triple it self and the value will be the number of occurences.
It should be something like this:
for (i1=0; i1<N; i1++) {
for (i2=i1; i2<N; i2++) {
for (i3=i2; i3<N; i3++) {
if (N[i1] < N[i2] < N[i3]) {
/* if the triple exists in the hash then
add 1 to its value
else
put new triple to the hash with
value 1
*/
}
}
}
}
Result = number of triples in the hash;
I didn't try it but I think it should work.

Longest Common Subsequence among 3 Strings

I've implemented the dynamic programming solution to find the longest common subsequence among 2 strings. There is apparently a way to generalize this algorithm to find the LCS among 3 strings, but in my research I have not found any information on how to go about this. Any help would be appreciated.
To find the Longest Common Subsequence (LCS) of 2 strings A and B, you can traverse a 2-dimensional array diagonally like shown in the Link you posted. Every element in the array corresponds to the problem of finding the LCS of the substrings A' and B' (A cut by its row number, B cut by its column number). This problem can be solved by calculating the value of all elements in the array. You must be certain that when you calculate the value of an array element, all sub-problems required to calculate that given value has already been solved. That is why you traverse the 2-dimensional array diagonally.
This solution can be scaled to finding the longest common subsequence between N strings, but this requires a general way to iterate an array of N dimensions such that any element is reached only when all sub-problems the element requires a solution to has been solved.
Instead of iterating the N-dimensional array in a special order, you can also solve the problem recursively. With recursion it is important to save the intermediate solutions, since many branches will require the same intermediate solutions. I have written a small example in C# that does this:
string lcs(string[] strings)
{
if (strings.Length == 0)
return "";
if (strings.Length == 1)
return strings[0];
int max = -1;
int cacheSize = 1;
for (int i = 0; i < strings.Length; i++)
{
cacheSize *= strings[i].Length;
if (strings[i].Length > max)
max = strings[i].Length;
}
string[] cache = new string[cacheSize];
int[] indexes = new int[strings.Length];
for (int i = 0; i < indexes.Length; i++)
indexes[i] = strings[i].Length - 1;
return lcsBack(strings, indexes, cache);
}
string lcsBack(string[] strings, int[] indexes, string[] cache)
{
for (int i = 0; i < indexes.Length; i++ )
if (indexes[i] == -1)
return "";
bool match = true;
for (int i = 1; i < indexes.Length; i++)
{
if (strings[0][indexes[0]] != strings[i][indexes[i]])
{
match = false;
break;
}
}
if (match)
{
int[] newIndexes = new int[indexes.Length];
for (int i = 0; i < indexes.Length; i++)
newIndexes[i] = indexes[i] - 1;
string result = lcsBack(strings, newIndexes, cache) + strings[0][indexes[0]];
cache[calcCachePos(indexes, strings)] = result;
return result;
}
else
{
string[] subStrings = new string[strings.Length];
for (int i = 0; i < strings.Length; i++)
{
if (indexes[i] <= 0)
subStrings[i] = "";
else
{
int[] newIndexes = new int[indexes.Length];
for (int j = 0; j < indexes.Length; j++)
newIndexes[j] = indexes[j];
newIndexes[i]--;
int cachePos = calcCachePos(newIndexes, strings);
if (cache[cachePos] == null)
subStrings[i] = lcsBack(strings, newIndexes, cache);
else
subStrings[i] = cache[cachePos];
}
}
string longestString = "";
int longestLength = 0;
for (int i = 0; i < subStrings.Length; i++)
{
if (subStrings[i].Length > longestLength)
{
longestString = subStrings[i];
longestLength = longestString.Length;
}
}
cache[calcCachePos(indexes, strings)] = longestString;
return longestString;
}
}
int calcCachePos(int[] indexes, string[] strings)
{
int factor = 1;
int pos = 0;
for (int i = 0; i < indexes.Length; i++)
{
pos += indexes[i] * factor;
factor *= strings[i].Length;
}
return pos;
}
My code example can be optimized further. Many of the strings being cached are duplicates, and some are duplicates with just one additional character added. This uses more space than necessary when the input strings become large.
On input: "666222054263314443712", "5432127413542377777", "6664664565464057425"
The LCS returned is "54442"

Resources