Related
Thanks to #axtck for the help for the Fisher Yates randomization, he helped me to change number into words here :
Since the shuffle functions shuffle the arrays indexes, you can just shuffle the array the same way you did but add name strings in the array.
The code is now showing a string of words with commas as separation between the words, its working well!
Now I want to replace commas, with spaces (example : Histoire Chien Koala Arbre Italique Lampadaire Docteur Boulet Maison Forge Gagnant Ennui)
Can somebody help me to change these commas with blank spaces?
Thanks
// replace numbers with names
const inputArray = ["Arbre", "Boulet", "Chien", "Docteur", "Ennui", "Forge", "Gagnant", "Histoire", "Italique", "Koala", "Lampadaire", "Maison"];
//define Fisher-Yates shuffle
const fisherShuffle = function(array) {
let currentIndex = array.length,
temporaryValue,
randomIndex;
while (0 !== currentIndex) {
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
document.getElementById("fyresults").append(array.toString());
};
fisherShuffle(inputArray);
<p><span id="fyresults"></span></p>
Calling toString() on an array will return the string representation of the array which is item1,item2,....
If you want to join the array in another way, you can use array method join(), it takes a separator string, which in your case would be a space join(" ").
Some examples:
const testArr = ["first", "second", "..."]; // example array
const arrString = testArr.toString(); // calling toString() on it
const arrJoinedX = testArr.join("X"); // joining by X
const arrJoinedSpace = testArr.join(" "); // joining by space
// logging
console.log("Array:", testArr);
console.log("Array toString():", arrString);
console.log("Array joined with X:", arrJoinedX);
console.log("Array joined with space:", arrJoinedSpace);
So to apply this to your example, you can do:
// replace numbers with names
const inputArray = ["Arbre", "Boulet", "Chien", "Docteur", "Ennui", "Forge", "Gagnant", "Histoire", "Italique", "Koala", "Lampadaire", "Maison"];
//define Fisher-Yates shuffle
const fisherShuffle = function(array) {
let currentIndex = array.length,
temporaryValue,
randomIndex;
while (0 !== currentIndex) {
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
const joinedBySpace = array.join(" "); // join by space
document.getElementById("fyresults").append(joinedBySpace); // append to element
};
fisherShuffle(inputArray);
<p><span id="fyresults"></span></p>
I'm trying to solve DNA problem which is more of improved(?) version of LCS problem.
In the problem, there is string which is string and semi-substring which allows part of string to have one or no letter skipped. For example, for string "desktop", it has semi-substring {"destop", "dek", "stop", "skop","desk","top"}, all of which has one or no letter skipped.
Now, I am given two DNA strings consisting of {a,t,g,c}. I"m trying to find longest semi-substring, LSS. and if there is more than one LSS, print out the one in the fastest order.
For example, two dnas {attgcgtagcaatg, tctcaggtcgatagtgac} prints out "tctagcaatg"
and aaaattttcccc, cccgggggaatatca prints out "aattc"
I'm trying to use common LCS algorithm but cannot solve it with tables although I did solve the one with no letter skipped. Any advice?
This is a variation on the dynamic programming solution for LCS, written in Python.
First I'm building up a Suffix Tree for all the substrings that can be made from each string with the skip rule. Then I'm intersecting the suffix trees. Then I'm looking for the longest string that can be made from that intersection tree.
Please note that this is technically O(n^2). Its worst case is when both strings are the same character, repeated over and over again. Because you wind up with a lot of what logically is something like, "an 'l' at position 42 in the one string could have matched against position l at position 54 in the other". But in practice it will be O(n).
def find_subtree (text, max_skip=1):
tree = {}
tree_at_position = {}
def subtree_from_position (position):
if position not in tree_at_position:
this_tree = {}
if position < len(text):
char = text[position]
# Make sure that we've populated the further tree.
subtree_from_position(position + 1)
# If this char appeared later, include those possible matches.
if char in tree:
for char2, subtree in tree[char].iteritems():
this_tree[char2] = subtree
# And now update the new choices.
for skip in range(max_skip + 1, 0, -1):
if position + skip < len(text):
this_tree[text[position + skip]] = subtree_from_position(position + skip)
tree[char] = this_tree
tree_at_position[position] = this_tree
return tree_at_position[position]
subtree_from_position(0)
return tree
def find_longest_common_semistring (text1, text2):
tree1 = find_subtree(text1)
tree2 = find_subtree(text2)
answered = {}
def find_intersection (subtree1, subtree2):
unique = (id(subtree1), id(subtree2))
if unique not in answered:
answer = {}
for k, v in subtree1.iteritems():
if k in subtree2:
answer[k] = find_intersection(v, subtree2[k])
answered[unique] = answer
return answered[unique]
found_longest = {}
def find_longest (tree):
if id(tree) not in found_longest:
best_candidate = ''
for char, subtree in tree.iteritems():
candidate = char + find_longest(subtree)
if len(best_candidate) < len(candidate):
best_candidate = candidate
found_longest[id(tree)] = best_candidate
return found_longest[id(tree)]
intersection_tree = find_intersection(tree1, tree2)
return find_longest(intersection_tree)
print(find_longest_common_semistring("attgcgtagcaatg", "tctcaggtcgatagtgac"))
Let g(c, rs, rt) represent the longest common semi-substring of strings, S and T, ending at rs and rt, where rs and rt are the ranked occurences of the character, c, in S and T, respectively, and K is the number of skips allowed. Then we can form a recursion which we would be obliged to perform on all pairs of c in S and T.
JavaScript code:
function f(S, T, K){
// mapS maps a char to indexes of its occurrences in S
// rsS maps the index in S to that char's rank (index) in mapS
const [mapS, rsS] = mapString(S)
const [mapT, rsT] = mapString(T)
// h is used to memoize g
const h = {}
function g(c, rs, rt){
if (rs < 0 || rt < 0)
return 0
if (h.hasOwnProperty([c, rs, rt]))
return h[[c, rs, rt]]
// (We are guaranteed to be on
// a match in this state.)
let best = [1, c]
let idxS = mapS[c][rs]
let idxT = mapT[c][rt]
if (idxS == 0 || idxT == 0)
return best
for (let i=idxS-1; i>=Math.max(0, idxS - 1 - K); i--){
for (let j=idxT-1; j>=Math.max(0, idxT - 1 - K); j--){
if (S[i] == T[j]){
const [len, str] = g(S[i], rsS[i], rsT[j])
if (len + 1 >= best[0])
best = [len + 1, str + c]
}
}
}
return h[[c, rs, rt]] = best
}
let best = [0, '']
for (let c of Object.keys(mapS)){
for (let i=0; i<(mapS[c]||[]).length; i++){
for (let j=0; j<(mapT[c]||[]).length; j++){
let [len, str] = g(c, i, j)
if (len > best[0])
best = [len, str]
}
}
}
return best
}
function mapString(s){
let map = {}
let rs = []
for (let i=0; i<s.length; i++){
if (!map[s[i]]){
map[s[i]] = [i]
rs.push(0)
} else {
map[s[i]].push(i)
rs.push(map[s[i]].length - 1)
}
}
return [map, rs]
}
console.log(f('attgcgtagcaatg', 'tctcaggtcgatagtgac', 1))
console.log(f('aaaattttcccc', 'cccgggggaatatca', 1))
console.log(f('abcade', 'axe', 1))
We have a HashMap Integer/String and in Java we would iterate over the HashMap and display 3 key value pairs at a time with the click of a button. Java Code Below
hm.put(1, "1");
hm.put(2, "Dwight");
hm.put(3, "Lakeside");
hm.put(4, "2");
hm.put(5, "Billy");
hm.put(6, "Georgia");
hm.put(7, "3");
hm.put(8, "Sam");
hm.put(9, "Canton");
hm.put(10, "4");
hm.put(11, "Linda");
hm.put(12, "North Canton");
hm.put(13, "5");
hm.put(14, "Lisa");
hm.put(15, "Phoenix");
onNEXT(null);
public void onNEXT(View view){
etCity.setText("");
etName.setText("");
etID.setText("");
X = X + 3;
for(int L = 1; L <= X; L++ ){
String id = hm.get(L);
String name = hm.get(L = L + 1);
String city = hm.get(L = L + 1);
etID.setText(id);
etName.setText(name);
etCity.setText(city);
}
if(X == hm.size()){
X = 0;
}
}
We decoded to let Android Studio convert the above Java Code to Kotlin
The converter decide to change the for(int L = 1; L <= X; L++) loop to a while loop which seemed OK at first then we realized the while loop was running for 3 loops with each button click. Also Kotlin complained a lot about these line of code String name = hm.get(L = L + 1); String city = hm.get(L = L + 1);
We will post the Kotlin Code below and ask the question
fun onNEXT(view: View?) {
etCity.setText("")
etName.setText("")
etID.setText("")
X = X + 3
var L = 0
while (L <= X) {
val id = hm[L - 2]
val name = hm.get(L - 1)
val city = hm.get(L)
etID.setText(id)
etName.setText(name)
etCity.setText(city)
L++
}
if (X == hm.size) {
X = 0
}
}
We tried to write a For Next Loop like this for (L in 15 downTo 0 step 1)
it seems you can not count upTo so we thought we would use the hm:size for the value 15 and just use downTo
So the questions are
How do we use the Kotlin For Next Loop syntax and include the hm:size in the construct?
We have L declared as a integer but Kotlin will not let us use
L = L + 1 in the While loop nor the For Next Loop WHY ?
HERE is the strange part notice we can increment X by using X = X + 3
YES X was declared above as internal var X = 0 as was L the same way
Okay, I'll bite.
The following code will print your triples:
val hm = HashMap<Int, String>()
hm[1] = "1"
hm[2] = "Dwight"
hm[3] = "Lakeside"
hm[4] = "2"
hm[5] = "Billy"
hm[6] = "Georgia"
hm[7] = "3"
hm[8] = "Sam"
hm[9] = "Canton"
hm[10] = "4"
hm[11] = "Linda"
hm[12] = "North Canton"
hm[13] = "5"
hm[14] = "Lisa"
hm[15] = "Phoenix"
for (i in 1..hm.size step 3) {
println(Triple(hm[i], hm[i + 1], hm[i + 2]))
}
Now let's convert the same idea into a function:
var count = 0
fun nextTriplet(hm: HashMap<Int, String>): Triple<String?, String?, String?> {
val result = mutableListOf<String?>()
for (i in 1..3) {
result += hm[(count++ % hm.size) + 1]
}
return Triple(result[0], result[1], result[2])
}
We used a far from elegant set of code to accomplish an answer to the question.
We used a CharArray since Grendel seemed OK with that concept of and Array
internal var YY = 0
val CharArray = arrayOf(1, "Dwight", "Lakeside",2,"Billy","Georgia",3,"Sam","Canton")
In the onCreate method we loaded the first set of data with a call to onCO(null)
Here is the working code to iterate over the CharArray that was used
fun onCO(view: View?){
etCity.setText("")
etName.setText("")
etID.setText("")
if(CharArray.size > YY){
val id = CharArray[YY]
val name = CharArray[YY + 1]
val city = CharArray[YY + 2]
etID.setText(id.toString())
etName.setText(name.toString())
etCity.setText(city.toString())
YY = YY + 3
}else{
YY = 0
val id = CharArray[YY]
val name = CharArray[YY + 1]
val city = CharArray[YY + 2]
etID.setText(id.toString())
etName.setText(name.toString())
etCity.setText(city.toString())
YY = YY + 3
}
Simple but not elegant. Seems the code is a better example of a counter than iteration.
Controlling the For Next Look may involve less lines of code. Control of the look seemed like the wrong direction. We might try to use the KEY WORD "when" to apply logic to this question busy at the moment
After some further research here is a partial answer to our question
This code only show how to traverse a hash map indexing this traverse every 3 records needs to be added to make the code complete. This answer is for anyone who stumbles upon the question. The code and a link to the resource is provide below
fun main(args: Array<String>) {
val map = hashMapOf<String, Int>()
map.put("one", 1)
map.put("two", 2)
for ((key, value) in map) {
println("key = $key, value = $value")
}
}
The link will let you try Kotlin code examples in your browser
LINK
We only did moderate research before asking this question. Our Appoligies. If anyone is starting anew with Kotlin this second link may be of greater value. We seldom find understandable answers in the Android Developers pages. The Kotlin and Android pages are beginner friendlier and not as technical in scope. Enjoy the link
Kotlin and Android
I have the following code:
public class Testcode {
private static final Long[] P = new Long[18];
public void setKey( string key )
{
integer i, j, k;
long data;
integer N = 16;
string[] keytemp = new string[]{}; keytemp.add(key);
// Initialize P and S.
for ( i = 0; i < N + 2; ++i ){
P[i] = Pinit[i];
}
// XOR the key into P.
j = 0;
for ( i = 0; i < N + 2; ++i )
{
data = 0;
for ( k = 0; k < 4; ++k )
{
data = ( data << 8 ) | keytemp[j];
++j;
}
P[i] ^= data;
}
}
private static final long[] Pinit = new Long[] {
604135516L, 2242044355L, 320440478L , 57401183L,
2732047618L, 698298832L, 137296536L , 3964563569L,
1163258022L, 954160567L, 3193502383L, 887688400L,
3234508543L, 3380367581L, 1065660069L, 3041631479L,
2420952273L, 2306437331L
};
}
im getting the following error:
Error: Compile Error: OR operator can only be applied to Boolean expressions or to Integer or Long expressions at line 36 column 18
which is in this line:
data = ( data << 8 ) | keytemp[j];
Is there another way to write this line of code?
Thanks
I'm assuming that the keytemp array contains strings of length 1 since Apex doesn't have a Character primitive. You'll have to convert the first character of each string to an integer and then perform the OR.
Unfortunately Apex doesn't appear to have a built-in way of getting the ASCII value of a single-character String. You may have to write your own convertor function. Here are some people with the same issue with some proposed solutions:
Discussion of how to convert strings to ASCII values
Something like that?
No loops except for the initial priming of the array ... And later we have to get each character separately but looks like your algorithm needs 1-char long strings anyway?
List<Integer> ints = new List<Integer>();
for(Integer i =0; i < 256; ++i){
ints.add(i);
}
String allAscii = String.fromCharArray(ints);
// System.debug(allAscii); // funny result if you really want to start from 0x00 character
System.debug(allAscii.substring(1)); // for demo purposes we'll show only from 0x01 though
String text = 'Hi StackOverflow.com!';
for(Integer i =0; i < text.length(); ++i){
String oneChar = text.mid(i, 1);
System.debug(oneChar + ' => ' + allAscii.indexOf(oneChar));
}
Output:
!"#$%&'()*+,-./0123456789:;<=>?#ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ
H => 72
i => 105
=> 32
S => 83
t => 116
a => 97
c => 99
k => 107
O => 79
v => 118
e => 101
r => 114
f => 102
l => 108
o => 111
w => 119
. => 46
c => 99
o => 111
m => 109
! => 33
Looks good to me (space is # 32 etc).
Could be further optimized to a linear search if you'd build a Map<String, Integer> instead of indexOf but I'd say it's good enough?
Given a Map of objects and designated proportions (let's say they add up to 100 to make it easy):
val ss : Map[String,Double] = Map("A"->42, "B"->32, "C"->26)
How can I generate a sequence such that for a subset of size n there are ~42% "A"s, ~32% "B"s and ~26% "C"s? (Obviously, small n will have larger errors).
(Work language is Scala, but I'm just asking for the algorithm.)
UPDATE: I resisted a random approach since, for instance, there's ~16% chance that the sequence would start with AA and ~11% chance it would start with BB and there would be very low odds that for n precisely == (sum of proportions) the distribution would be perfect. So, following #MvG's answer, I implemented as follows:
/**
Returns the key whose achieved proportions are most below desired proportions
*/
def next[T](proportions : Map[T, Double], achievedToDate : Map[T,Double]) : T = {
val proportionsSum = proportions.values.sum
val desiredPercentages = proportions.mapValues(v => v / proportionsSum)
//Initially no achieved percentages, so avoid / 0
val toDateTotal = if(achievedToDate.values.sum == 0.0){
1
}else{
achievedToDate.values.sum
}
val achievedPercentages = achievedToDate.mapValues(v => v / toDateTotal)
val gaps = achievedPercentages.map{ case (k, v) =>
val gap = desiredPercentages(k) - v
(k -> gap)
}
val maxUnder = gaps.values.toList.sortWith(_ > _).head
//println("Max gap is " + maxUnder)
val gapsForMaxUnder = gaps.mapValues{v => Math.abs(v - maxUnder) < Double.Epsilon }
val keysByHasMaxUnder = gapsForMaxUnder.map(_.swap)
keysByHasMaxUnder(true)
}
/**
Stream of most-fair next element
*/
def proportionalStream[T](proportions : Map[T, Double], toDate : Map[T, Double]) : Stream[T] = {
val nextS = next(proportions, toDate)
val tailToDate = toDate + (nextS -> (toDate(nextS) + 1.0))
Stream.cons(
nextS,
proportionalStream(proportions, tailToDate)
)
}
That when used, e.g., :
val ss : Map[String,Double] = Map("A"->42, "B"->32, "C"->26)
val none : Map[String,Double] = ss.mapValues(_ => 0.0)
val mySequence = (proportionalStream(ss, none) take 100).toList
println("Desired : " + ss)
println("Achieved : " + mySequence.groupBy(identity).mapValues(_.size))
mySequence.map(s => print(s))
println
produces :
Desired : Map(A -> 42.0, B -> 32.0, C -> 26.0)
Achieved : Map(C -> 26, A -> 42, B -> 32)
ABCABCABACBACABACBABACABCABACBACABABCABACABCABACBA
CABABCABACBACABACBABACABCABACBACABABCABACABCABACBA
For a deterministic approach, the most obvious solution would probably be this:
Keep track of the number of occurrences of each item in the sequence so far.
For the next item, choose that item for which the difference between intended and actual count (or proportion, if you prefer that) is maximal, but only if the intended count (resp. proportion) is greater than the actual one.
If there is a tie, break it in an arbitrary but deterministic way, e.g. choosing the alphabetically lowest item.
This approach would ensure an optimal adherence to the prescribed ratio for every prefix of the infinite sequence generated in this way.
Quick & dirty python proof of concept (don't expect any of the variable “names” to make any sense):
import sys
p = [0.42, 0.32, 0.26]
c = [0, 0, 0]
a = ['A', 'B', 'C']
n = 0
while n < 70*5:
n += 1
x = 0
s = n*p[0] - c[0]
for i in [1, 2]:
si = n*p[i] - c[i]
if si > s:
x = i
s = si
sys.stdout.write(a[x])
if n % 70 == 0:
sys.stdout.write('\n')
c[x] += 1
Generates
ABCABCABACABACBABCAABCABACBACABACBABCABACABACBACBAABCABCABACABACBABCAB
ACABACBACABACBABCABACABACBACBAABCABCABACABACBABCAABCABACBACABACBABCABA
CABACBACBAABCABCABACABACBABCABACABACBACBAACBABCABACABACBACBAABCABCABAC
ABACBABCABACABACBACBAACBABCABACABACBACBAABCABCABACABACBABCABACABACBACB
AACBABCABACABACBACBAABCABCABACABACBABCAABCABACBACBAACBABCABACABACBACBA
For every item of the sequence, compute a (pseudo-)random number r equidistributed between 0 (inclusive) and 100 (exclusive).
If 0 ≤ r < 42, take A
If 42 ≤ r < (42+32), take B
If (42+32) ≤ r < (42+32+26)=100, take C
The number of each entry in your subset is going to be the same as in your map, but with a scaling factor applied.
The scaling factor is n/100.
So if n was 50, you would have { Ax21, Bx16, Cx13 }.
Randomize the order to your liking.
The simplest "deterministic" [in terms of #elements of each category] solution [IMO] will be: add elements in predefined order, and then shuffle the resulting list.
First, add map(x)/100 * n elements from each element x chose how you handle integer arithmetics to avoid off by one element], and then shuffle the resulting list.
Shuffling a list is simple with fisher-yates shuffle, which is implemented in most languages: for example java has Collections.shuffle(), and C++ has random_shuffle()
In java, it will be as simple as:
int N = 107;
List<String> res = new ArrayList<String>();
for (Entry<String,Integer> e : map.entrySet()) { //map is predefined Map<String,Integer> for frequencies
for (int i = 0; i < Math.round(e.getValue()/100.0 * N); i++) {
res.add(e.getKey());
}
}
Collections.shuffle(res);
This is nondeterministic, but gives a distribution of values close to MvG's. It suffers from the problem that it could give AAA right at the start. I post it here for completeness' sake given how it proves my dissent with MvG was misplaced (and I don't expect any upvotes).
Now, if someone has an idea for an expand function that is deterministic and won't just duplicate MvG's method (rendering the calc function useless), I'm all ears!
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>ErikE's answer</title>
</head>
<body>
<div id="output"></div>
<script type="text/javascript">
if (!Array.each) {
Array.prototype.each = function(callback) {
var i, l = this.length;
for (i = 0; i < l; i += 1) {
callback(i, this[i]);
}
};
}
if (!Array.prototype.sum) {
Array.prototype.sum = function() {
var sum = 0;
this.each(function(i, val) {
sum += val;
});
return sum;
};
}
function expand(counts) {
var
result = "",
charlist = [],
l,
index;
counts.each(function(i, val) {
char = String.fromCharCode(i + 65);
for ( ; val > 0; val -= 1) {
charlist.push(char);
}
});
l = charlist.length;
for ( ; l > 0; l -= 1) {
index = Math.floor(Math.random() * l);
result += charlist[index];
charlist.splice(index, 1);
}
return result;
}
function calc(n, proportions) {
var percents = [],
counts = [],
errors = [],
fnmap = [],
errorSum,
worstIndex;
fnmap[1] = "min";
fnmap[-1] = "max";
proportions.each(function(i, val) {
percents[i] = val / proportions.sum() * n;
counts[i] = Math.round(percents[i]);
errors[i] = counts[i] - percents[i];
});
errorSum = counts.sum() - n;
while (errorSum != 0) {
adjust = errorSum < 0 ? 1 : -1;
worstIndex = errors.indexOf(Math[fnmap[adjust]].apply(0, errors));
counts[worstIndex] += adjust;
errors[worstIndex] = counts[worstIndex] - percents[worstIndex];
errorSum += adjust;
}
return expand(counts);
}
document.body.onload = function() {
document.getElementById('output').innerHTML = calc(99, [25.1, 24.9, 25.9, 24.1]);
};
</script>
</body>
</html>