I have a problem with a while-loop in kotlin.
The task i have to solve is to encode a binary-string in to a pseudo-string.
I've written a function that is supposed to receive and encode the binary string like "1000011" (7-bit) into "0 0 00 0000 0 00" in this case.
fun doEncode (input : String) : String {
var input = input
var result : MutableList<String> = mutableListOf()
var mOneActive = 0
var mNullActive = 0
var mNullCount = 0
var mOneCount = 0
var mIndexInput = 0
var mRangeInput = input.length-1
for (range in 0 until mRangeInput) {
while (input[mIndexInput] == '0' && mIndexInput < mRangeInput) {
mNullActive = 1
mNullCount += 1
mIndexInput += 1
}
if (mNullActive == 1) {
result.add("00")
result.add(" ")
for(range in 0 until mNullCount) {
result.add("0")
}
result.add(" ")
mNullActive = 0
mNullCount = 0
}
while (input[mIndexInput] == '1' && mIndexInput < mRangeInput) {
mOneActive = 1
mOneCount += 1
mIndexInput += 1
}
if (mOneActive == 1) {
result.add("0")
result.add(" ")
for(range in 0 until mOneCount) {
result.add("0")
}
result.add(" ")
mOneActive = 0
mOneCount = 0
}
}
var output = result.reduce { i, value -> i + value }
return output
}
But the function only encode the first 6 bit of the binary-string. The last on is missing.
I don´t see the mistake. When i increase the range (var mRangeInput) i get a "outofboundsexeption".
I have no further idea, so any help is welcome.
Look at these two lines.
var mRangeInput = input.length-1
for (range in 0 until mRangeInput) {
mRangeInput is the input length minus one. And until creates a range with an exclusive end. You have to choose one way or the other to exclude the final value of the range from 0 to the size, but you've done it both ways, so you've excluded one too many.
I didn't check anything else in your code. I don't know what the encoding is supposed to be.
Problem: https://leetcode.com/problems/coin-change/
Solution:
https://repl.it/#Stylebender/HatefulAliceblueTransversal#index.js
var coinChange = function(coins, amount) {
let dp = Array(amount + 1).fill(Infinity); //Fill dp array with dummy values
dp[0] = 0;
for (let i = 1; i <= amount; i++) {
for (let j = 0; j < coins.length; j++) { //Iterate through coin denominations
if (coins[j] <= i) { //Is current coin denomination less than amount?
dp[i] = Math.min(dp[i], 1 + dp[i - coins[j]]);
//dp array[current amount - coin denomination]
}
}
}
return dp[amount] === Infinity ? -1 : dp[amount];
};
I understand the general conceptual flow of the solution of building the dp array from button up but I was just wondering with respect to Line 10:
dp[i] = Math.min(dp[i], 1 + dp[i - coins[j]]);
Why is there a 1 + when you select the current j'th coin denomination for consideration?
Is it because since there is a valid coin denomination, we have unlocked a new method to make up the i'th amount?
Yes, that's right. We'd be approaching the target amount by that one increment.
If for instance 0.5 would be somehow the min increment, then that would have become 0.5 + the rest.
const coinChange = function(coins, amount) {
const inf = Math.pow(2, 31)
const dp = []
dp[0] = 0
while (dp.length <= amount) {
let curr = inf - 1
for (let index = 0; index < coins.length; index++) {
if (dp.length - coins[index] < 0) {
continue
}
curr = Math.min(curr, 1 + dp[dp.length - coins[index]])
}
dp.push(curr)
}
return dp[amount] == inf - 1 ? -1 : dp[amount]
};
Maybe it would be easier to grasp in Python:
class Solution:
def coinChange(self, coins, amount):
dp = [0] + [float('inf')] * amount
for index in range(1, amount + 1):
for coin in coins:
if index - coin > -1:
dp[index] = min(dp[index], dp[index - coin] + 1)
return -1 if dp[-1] == float('inf') else dp[-1]
I need to generate a list of numbers to put into an array. These number of times that they occur in the list is based on how important a certain property is.
E.g.
// importance ranges from 0 (no importance) to 5 (utmost importance)
maxNumbersInArray = 10;
propAImportance = 5; --> will put 1 into the array
propBImportance = 3; --> will put 2 into the array
propCImportance = 2; --> will put 3 into the array
// Output will be
array = [1,1,1,1,1,2,2,2,3,3]
How can i create a list where the importance of a value means that value is added to an array a greater number of times, or more specifically, how to calculate how ofter a value will be added into an array based on a properties importance
First ideas: (language SQF scripting)
_max = 10;
_weight1 = 3;
_weight2 = 2;
_weight3 = 0;
_weight4 = 1;
_weights = [_weight1,_weight2,_weight3,_weight4];
_arr = [];
for "_i" from 0 to (_max - 1) do {
{
while {_i <= _x} do {
_arr set [(count _arr),_forEachIndex];
} forEach _weights;
};
_arr; // Output
I believe that this is the algorithm to use:
_index = [];
_max = 10;
_weights = [5,2,1,1];
_count = 0;
_countWeight = 0;
while {(count _index ) < _max } do {
if (_count >= (count _weights)) then {_count = 0};
_weight = _weights select _count;
_countWeight = _countWeight + 1;
if (_countWeight > _weight) then {
_countWeight = 0;
_count = _count + 1;
} else {
_index set [(count _index ),_count];
};
};
I have seen this question for other languages but not for AS3... and I'm having a hard time understanding it...
I need to generate 3 numbers, randomly, from 0 to 2, but they cannot repeat (as in 000, 001, 222, 212 etc) and they cannot be in the correct order (0,1,2)...
Im using
for (var u: int = 0; u < 3; u++)
{
mcCor = new CorDaCarta();
mcCor.x = larguraTrio + (mcCor.width + 5) * (u % 3);
mcCor.y = alturaTrio + (mcCor.height + 5) * (Math.floor(u / 3));
mcCor.gotoAndStop((Math.random() * (2 - u + 1) + u) | 0); // random w/ repeats
//mcCor.gotoAndStop(Math.floor(Math.random() * (2 - u + 1) + u)); // random w/ repeats
//mcCor.gotoAndStop((Math.random() * 3) | 0); // crap....
//mcCor.gotoAndStop(Math.round(Math.random()*u)); // 1,1,1
//mcCor.gotoAndStop(u + 1); // 1,2,3
mcCor.buttonMode = true;
mcCor.addEventListener(MouseEvent.CLICK, cliquetrio);
mcExplic.addChild(mcCor);
trio.push(mcCor);
}
those are the codes i've been trying.... best one so far is the active one (without the //), but it still gives me duplicates (as 1,1,1) and still has a small chance to come 0,1,2....
BTW, what I want is to mcCor to gotoAndStop on frames 1, 2 or 3....without repeating, so THE USER can put it on the right order (1,2,3 or (u= 0,1,2), thats why I add + 1 sometimes there)
any thoughts?? =)
I've found that one way to ensure random, unique numbers is to store the possible numbers in an array, and then sort them using a "random" sort:
// store the numbers 0, 1, 2 in an array
var sortedNumbers:Array = [];
for(var i:int = 0; i < 3; i++)
{
sortedNumbers.push(i);
}
var unsortedNumbers:Array = sortedNumbers.slice(); // make a copy of the sorted numbers
trace(sortedNumbers); // 0,1,2
trace(unsortedNumbers); // 0,1,2
// randomly sort array until it no longer matches the sorted array
while(sortedNumbers.join() == unsortedNumbers.join())
{
unsortedNumbers.sort(function (a:int, b:int):int { return Math.random() > .5 ? -1 : 1; });
}
trace(unsortedNumbers); // [1,0,2], [2,1,0], [0,1,2], etc
for (var u: int = 0; u < 3; u++)
{
mcCor = new CorDaCarta();
mcCor.x = larguraTrio + (mcCor.width + 5) * (u % 3);
mcCor.y = alturaTrio + (mcCor.height + 5) * (Math.floor(u / 3));
// grab the corresponding value from the unsorted array
mcCor.gotoAndStop(unsortedNumbers[u] + 1);
mcCor.buttonMode = true;
mcCor.addEventListener(MouseEvent.CLICK, cliquetrio);
mcExplic.addChild(mcCor);
trio.push(mcCor);
}
Marcela is right. Approach with an Array is widely used for such task. Of course, you will need to check 0, 1, 2 sequence and this will be ugly, but in common code to get the random sequence of integers can look like this:
function getRandomSequence(min:int, max:int):Array
{
if (min > max) throw new Error("Max value should be greater than Min value!");
if (min == max) return [min];
var values:Array = [];
for (var i:int = min; i <= max; i++) values.push(i);
var result:Array = [];
while (values.length > 0) result = result.concat(values.splice(Math.floor(Math.random() * values.length), 1));
return result;
}
for (var i:uint = 0; i < 10; i++)
{
trace(getRandomSequence(1, 10));
}
You will get something like that:
2,9,3,8,10,6,5,1,4,7
6,1,2,4,8,9,5,10,7,3
3,9,10,6,8,2,5,4,1,7
7,6,1,4,3,8,9,2,10,5
4,6,7,1,3,2,9,10,8,5
3,10,5,9,1,7,2,4,8,6
1,7,9,6,10,3,4,5,2,8
4,10,8,9,3,2,6,1,7,5
1,7,8,9,10,6,4,3,2,5
7,5,4,2,8,6,10,3,9,1
I created this for you. It is working but it can be optimized...
Hope is good for you.
var arr : Array = [];
var r : int;
for (var i: int = 0; i < 3; i++){
r=rand(0,2);
if(i == 1){
if(arr[0] == r){
i--;
continue;
}
if(arr[0] == 0){
if(r==1){
i--;
continue;
}
}
}else if(i==2){
if(arr[0] == r || arr[1] == r){
i--;
continue;
}
}
arr[i] = r;
}
trace(arr);
for(var i=0;i<3;i++){
mcCor = new CorDaCarta();
mcCor.x = larguraTrio + (mcCor.width + 5) * (i % 3);
mcCor.y = alturaTrio + (mcCor.height + 5) * (Math.floor(i / 3));
mcCor.gotoAndStop(arr[i]);
mcCor.buttonMode = true;
mcCor.addEventListener(MouseEvent.CLICK, cliquetrio);
mcExplic.addChild(mcCor);
trio.push(mcCor);
}
function rand(min:int, max:int):int {
return Math.round(Math.random() * (max - min) + min);
}
try this...
For a mobile shop application, I need to validate an IMEI number. I know how to validate based on input length, but is their any other mechanism for validating the input number? Is there any built-in function that can achieve this?
Logic from any language is accepted, and appreciated.
A search suggests that there isn't a built-in function that will validate an IMEI number, but there is a validation method using the Luhn algorithm.
General process:
Input IMEI: 490154203237518
Take off the last digit, and remember it: 49015420323751 & 8. This last digit 8 is the validation digit.
Double each second digit in the IMEI: 4 18 0 2 5 8 2 0 3 4 3 14 5 2 (excluding the validation digit)
Separate this number into single digits: 4 1 8 0 2 5 8 2 0 3 4 3 1 4 5 2 (notice that 18 and 14 have been split).
Add up all the numbers: 4+1+8+0+2+5+8+2+0+3+4+3+1+4+5+2 = 52
Take your resulting number, remember it, and round it up to the nearest multiple of ten: 60.
Subtract your original number from the rounded-up number: 60 - 52 = 8.
Compare the result to your original validation digit. If the two numbers match, your IMEI is valid.
The IMEI given in step 1 above is valid, because the number found in step #7 is 8, which matches the validation digit.
According to the previous answer from Karl Nicoll i'm created this method in Java.
public static int validateImei(String imei) {
//si la longitud del imei es distinta de 15 es invalido
if (imei.length() != 15)
return CheckImei.SHORT_IMEI;
//si el imei contiene letras es invalido
if (!PhoneNumber.allNumbers(imei))
return CheckImei.MALFORMED_IMEI;
//obtener el ultimo digito como numero
int last = imei.charAt(14) - 48;
//duplicar cada segundo digito
//sumar cada uno de los digitos resultantes del nuevo imei
int curr;
int sum = 0;
for (int i = 0; i < 14; i++) {
curr = imei.charAt(i) - 48;
if (i % 2 != 0){
// sum += duplicateAndSum(curr);
// initial code from Osvel Alvarez Jacomino contains 'duplicateAndSum' method.
// replacing it with the implementation down here:
curr = 2 * curr;
if(curr > 9) {
curr = (curr / 10) + (curr - 10);
}
sum += curr;
}
else {
sum += curr;
}
}
//redondear al multiplo de 10 superior mas cercano
int round = sum % 10 == 0 ? sum : ((sum / 10 + 1) * 10);
return (round - sum == last) ? CheckImei.VALID_IMEI_NO_NETWORK : CheckImei.INVALID_IMEI;
}
IMEI can start with 0 digit. This is why the function input is string.
Thanks for the method #KarlNicol
Golang
func IsValid(imei string) bool {
digits := strings.Split(imei, "")
numOfDigits := len(digits)
if numOfDigits != 15 {
return false
}
checkingDigit, err := strconv.ParseInt(digits[numOfDigits-1], 10, 8)
if err != nil {
return false
}
checkSum := int64(0)
for i := 0; i < numOfDigits-1; i++ { // we dont need the last one
convertedDigit := ""
if (i+1)%2 == 0 {
d, err := strconv.ParseInt(digits[i], 10, 8)
if err != nil {
return false
}
convertedDigit = strconv.FormatInt(2*d, 10)
} else {
convertedDigit = digits[i]
}
convertedDigits := strings.Split(convertedDigit, "")
for _, c := range convertedDigits {
d, err := strconv.ParseInt(c, 10, 8)
if err != nil {
return false
}
checkSum = checkSum + d
}
}
if (checkSum+checkingDigit)%10 != 0 {
return false
}
return true
}
I think this logic is not right because this working only for the specific IMEI no - 490154203237518 not for other IMEI no ...I implement the code also...
var number = 490154203237518;
var array1 = new Array();
var array2 = new Array();
var specialno = 0 ;
var sum = 0 ;
var finalsum = 0;
var cast = number.toString(10).split('');
var finalnumber = '';
if(cast.length == 15){
for(var i=0,n = cast.length; i<n; i++){
if(i !== 14){
if(i == 0 || i%2 == 0 ){
array1[i] = cast[i];
}else{
array1[i] = cast[i]*2;
}
}else{
specialno = cast[14];
}
}
for(var j=0,m = array1.length; j<m; j++){
finalnumber = finalnumber.concat(array1[j]);
}
while(finalnumber){
finalsum += finalnumber % 10;
finalnumber = Math.floor(finalnumber / 10);
}
contno = (finalsum/10);
finalcontno = Math.round(contno)+1;
check_specialno = (finalcontno*10) - finalsum;
if(check_specialno == specialno){
alert('Imei')
}else{
alert('Not IMEI');
}
}else{
alert('NOT imei - length not matching');
}
//alert(sum);
According to the previous answer from Karl Nicoll i'm created this function in Python.
from typing import List
def is_valid_imei(imei: str) -> bool:
def digits_of(s: str) -> List[int]:
return [int(d) for d in s]
if len(imei) != 15 or not imei.isdecimal():
return False
digits = digits_of(imei)
last = digits.pop()
for i in range(1, len(digits), 2):
digits[i] *= 2
digits = digits_of(''.join(map(str, digits)))
return (sum(digits) + last) % 10 == 0
This one is working for me
try:
immie_procesed = list(
map(int, str(request.data.decode("utf-8").split(',')[0])))
last_number = immie_procesed[len(immie_procesed) - 1]
val = sum([sum(map(int, str(int(v)*2))) if i % 2 else int(v)
for i, v in enumerate(immie_procesed[: -1])])
round_value = math.ceil(val / 10) * 10
validation_value = round_value - val
if (validation_value == last_number):
IMEI = request.data.decode("utf-8").split(',')[0]
else:
return "INVALID IMEI"
except:
return 'Something goes wrong in validation process'
I don't believe there are any built-in ways to authenticate an IMEI number. You would need to verify against a third party database (googling suggests there are a number of such services, but presumably they also get their information from more centralised sources).