Czech national identity card validation - algorithm

I'm looking for CZ national idenity card number validation algorithm. There can be 9 or 10 digits sequenced by special algoritm, but there are not just numbers :) I've found this function:
function checkId(id) {
var x, sum_nb=0, check;
var steps = new Array(7,3,1,7,3,1,7,3);
id = id.toUpperCase(),
splitted = id.split("");
if (splitted.length != 9 && splitted.length != 10) {return false;}
for (x = 0; x < 9; x++)
{
if (x == 0 || x == 1 || x == 2) {
sum_nb += steps[x] * parseInt(id.charCodeAt(x)-55);
}
if (x > 3) {
sum_nb += steps[x-1] * parseInt(id.charAt(x));
}
}
check = sum_nb % 10;
if (check == id.charAt(3))
return true;
else
return false;
}
But I'm not sure that it's correct. Is anyone knows correct algoritm? It can be written on any language, it does not matter.

Related

implement divide algorithm without using "/" for floating point

please if there is any specific algorithm for implementing the divide operator as a function, guide me about their name. I want to implement a function that takes two floating number and return the result of the divide, but in implementation, I won't use "/".
I have done this in a much simpler version when we want just the q in integer,
function divide(num0, num1) {
if ("bigint" != typeof num0 || "bigint" != typeof num1) {
throw new TypeError("The arguments should be bigint.");
}
if (num1 > num0) {
return 0;
}
for (var i = 0n; num0 >= num1; i++) {
num0 -= num1;
}
return i;
}
"I use bigint numeric type just two restrict to integer"
but I think this approach couldn't extend two return floating results. my guess is I approach binary level operation or so; thanks if learning me about any flowchart, pseudo-code, or code-snippet "in any language" to deal with this problem
I wrote this one for this question in js:
function justIntegerDivide(num0, num1) {
for (var q = 0; num0 >= num1; q++) {
num0 -= num1;
}
return [q, num0];
}
const divide = (n0, n1, afterPoint = 10) => {
if ((0 == n1 || 0n == n1) && 0 < n0) return Infinity;
if ((0 == n1 || 0n == n1) && 0 > n0) return -Infinity;
if ((0 == n1 || 0n == n1) && 0 == n0) return NaN;
if ("number" == typeof n0 && "number" == typeof n1) {
let sign = Math.sign(n0) * Math.sign(n1);
let num0 = Math.abs(n0),
num1 = Math.abs(n1);
let counter = 0;
let [q, r] = justIntegerDivide(num0, num1);
result = `${q}.`;
for (counter = 1; counter < afterPoint; counter++) {
var newReminder;
let qAfter;
previousReminder = 1 == counter ? r : newReminder;
[qAfter, newReminder] = justIntegerDivide(previousReminder * 10, num1);
result += qAfter;
if (0 == newReminder) {
return +result * sign;
}
}
return +result * sign;
} else if ("bigint" == typeof n0 && "bigint" == typeof n1) {
let sign = (n0 > 0 && n1 > 0) || (n0 < 0 && n1 < 0) ? 1n : -1n;
let num0 = n0 > 0 ? n0 : -n0;
let num1 = n1 > 0 ? n1 : -n1;
if (num0 < num1) {
return 0n;
}
for (var i = 0n; num0 >= num1; i++) {
num0 -= num1;
}
return i * sign;
} else {
throw new TypeError("Both arguments should be number or bigint");
}
};

The minimum number of moves for which two knights will meet

On a chessboard consisting of M rows and N columns (for example, 8x10), there are two knights, the user enters their coordinates himself (for example, (2, 4) is a white knight and (7, 9) is a black knight). Each knight is located in the it's cell, but it is possible that both knights are in the same cell.
The knights take turns making moves in accordance with the rules of the chess knight's movement (the white knight goes first). The goal of the game is to place both horses in the same cell as quickly as possible.
Input format
The first line of the file contains the values M and N (2≤M,N≤1000). The second and third lines contain the coordinates of the cells in which the white and black knight are located, respectively. The first coordinate is in the range from 1 to M, the second is in the range from 1 to N.
Output format
Print a single number — the number of moves required to complete the game. If the knights can never be placed in the same square, print -1.
Since I'm new to algorithms and data structures, I tried to solve this problem like this: run for loop on all 64 possible combinations of two moves of a white and black knight, make a move for each knight (checking if it goes beyond the scope), check if there is a match and, if there is, then output it. Then run the same cycle inside of the current. At the same time, the moves are counted and it is also output. However, I have encountered such a problem that I cannot automate the process of running this loop inside the loop, I cannot know the number of times that this loop needs to be run. I tried to create a function with recursion in which it was possible to call this loop if a match has not yet been found, but I failed.
I decided that it would not work that way to solve this problem, so I looked at the algorithms that are usually used in such tasks. I was thinking of somehow creating an adjacency list for two horses, where the vertices are all the calculated positions of the horse; use BFS, or the Dijkstra algorithm.
Solved.
Here is my swift code:
import Foundation
let mnstr = readLine()?.components(separatedBy: " ")
let m = Int(mnstr![0])!
let n = Int(mnstr![1])!
let wstr = readLine()?.components(separatedBy: " ")
let bstr = readLine()?.components(separatedBy: " ")
var w: [Int] = []
var b: [Int] = []
var count: Int = 0
let moves: [[Int]] = [[2, -1], [1, 2], [-2, -1], [1, -2], [2, 1], [-1, 2], [-2, 1], [-1, -2]]
w.append(Int(wstr![0])!)
w.append(Int(wstr![1])!)
b.append(Int(bstr![0])!)
b.append(Int(bstr![1])!)
var wp: Set = [w]
var bp: Set = [b]
func oneMove(lst: Set<[Int]>) -> Set<[Int]>{
let curr = lst
var out = lst
for i in curr {
for move in moves {
let item = [i[0] + move[0], i[1] + move[1]]
if item[0] < 1 || item[0] > m || item[1] < 1 || item[1] > n {
continue
}
out.insert(item)
}
}
return out
}
while bp.intersection(wp).isEmpty == true {
wp = oneMove(lst: wp)
count += 1
if wp.intersection(bp).isEmpty != true {
break
}
bp = oneMove(lst: bp)
count += 1
if wp.intersection(bp).isEmpty != true {
break
}
if wp.count == 1 || bp.count == 1 {
count = -1
break
}
}
print(count)
I know that an answer was already accepted, but for large distances between the pieces a BFS or Dijkstra's algorithm will use considerable time and resources.
There is however a pattern: when there is enough distance between the pieces (both in X and Y direction), an optimal path can be found within the bounding box of the two pieces and can be derived by a closed formula. And the more constrained or unsolvable situations can be identified also in constant time. The code for distinguishing the different patterns is quite "dull", but it will certainly run faster for when the paths are long: in constant time (if we assume arithmetic operations use constant time).
Here is some JavaScript code, which also includes the BFS algorithm so the outcome can be compared. It includes an interactive part, so that you can play with the board sizes and the positioning of the two pieces and check the results:
function knightDistance(rowCount, colCount, whiteX, whiteY, blackX, blackY) {
// Convert the state so to ensure that black is at the right & upper side of white, and below the diagonal
if (blackX < whiteX) return knightDistance(rowCount, colCount, blackX, blackY, whiteX, whiteY); // Swap pieces
if (blackY < whiteY) return knightDistance(rowCount, colCount, whiteX, rowCount - 1 - whiteY, blackX, rowCount - 1 - blackY); // Mirror against X axis
let diffX = blackX - whiteX;
let diffY = blackY - whiteY;
if (diffX < diffY) return knightDistance(colCount, rowCount, whiteY, whiteX, blackY, blackX); // mirror along diagonal
if (diffX == 2 && diffY == 2) return 4;
if (diffX <= 2 * diffY && diffX != 1) {
if ((diffX + diffY) % 2) return Math.floor((diffX + diffY + 1) / 6) * 2 + 1;
return Math.floor((diffX + diffY + 4) / 6) * 2;
}
if (rowCount == 1 || colCount == 2) return -1;
if (rowCount == 2 && diffX % 4 != 2 * diffY) return -1;
if (diffX + diffY > 3) {
if ((diffX + diffY) % 2) return Math.floor((diffX + 1) / 4) * 2 + 1;
return Math.floor((diffX + 3) / 4) * 2;
}
// Now rowCount > 2 and colCount > 2
// Other cases where lack of space plays a role
if (diffY == 1) {
// Now diffX == 1
if (rowCount == 3 && colCount == 3 && whiteX == whiteY) return -1;
if (whiteX == 0 && whiteY == 0 || blackX == colCount - 1 && blackY == rowCount - 1) return 4;
return 2;
}
// Now diffY == 0
if (diffX == 1) {
if (whiteY == 1 && rowCount == 3 && colCount == 3) return -1;
if (whiteY == 1 && rowCount == 3 && colCount == 4 && whiteX == 1) return 5;
return 3;
}
if (diffX == 2) {
if (whiteY == 1 && rowCount == 3) return 4;
return 2;
}
// Now diffY == 3
if (colCount == 4 && (whiteY == 0 || whiteY == rowCount - 1)) return 5;
return 3;
}
// The BFS algorithm for verification of the above function
function knightDistanceBfs(rowCount, colCount, whiteX, whiteY, blackX, blackY) {
let visited = new Set;
let frontier = [[whiteX, whiteY]];
visited.add(whiteX + whiteY * colCount);
let steps = 0;
while (frontier.length) {
let newFrontier = [];
for (let [whiteX, whiteY] of frontier) {
if (whiteX == blackX && whiteY == blackY) return steps;
for (let [dx, dy] of [[-2, -1], [2, -1], [2, 1], [-2, 1], [-1, -2], [1, -2], [1, 2], [-1, 2]]) {
let newX = whiteX + dx;
let newY = whiteY + dy;
if (newX < 0 || newY < 0 || newX >= colCount || newY >= rowCount) continue;
let key = newX + newY * colCount;
if (visited.has(key)) continue;
visited.add(key);
newFrontier.push([newX, newY]);
}
}
steps++;
frontier = newFrontier;
}
return -1;
}
// Quick test of all possibilities on boards with at most 5 rows and 5 columns:
for (let rowCount = 1; rowCount <= 5; rowCount++) {
for (let colCount = 1; colCount <= 5; colCount++) {
for (let whiteX = 0; whiteX < colCount; whiteX++) {
for (let whiteY = 0; whiteY < rowCount; whiteY++) {
for (let blackX = 0; blackX < colCount; blackX++) {
for (let blackY = 0; blackY < rowCount; blackY++) {
let answer = knightDistanceBfs(rowCount, colCount, whiteX, whiteY, blackX, blackY);
let answer2 = knightDistance(rowCount, colCount, whiteX, whiteY, blackX, blackY);
if (answer !== answer2) {
console.log({rowCount, colCount, whiteX, whiteY, blackX, blackY});
throw "Test case failed";
}
}
}
}
}
}
}
// I/O handling
let [rowInput, colInput] = document.querySelectorAll("input");
let table = document.querySelector("table");
let outputs = document.querySelectorAll("span");
let whiteX, whiteY, blackX, blackY;
rowInput.oninput = colInput.oninput = function () {
// Create table
table.innerHTML = "";
for (let i = +rowInput.value; i > 0; i--) {
let row = table.insertRow();
for (let j = +colInput.value; j > 0; j--) {
row.insertCell();
}
}
whiteX = -1;
blackX = -1;
};
table.onclick = function (e) {
if (e.target.tagName != "TD") return;
let x = e.target.cellIndex;
let y = e.target.parentNode.rowIndex;
if (x == whiteX && y == whiteY) {
e.target.textContent = "";
whiteX = -1;
whiteY = -1;
} else if (x == blackX && y == blackY) {
e.target.textContent = "";
blackX = -1;
blackY = -1;
} else if (whiteX == -1) {
e.target.textContent = "♘";
whiteX = x;
whiteY = y;
} else {
if (blackX != -1) { // Remove black piece first
table.rows[blackY].cells[blackX].textContent = "";
}
e.target.textContent = "♞";
blackX = x;
blackY = y;
}
if (blackX != -1 && whiteX != -1) {
outputs[0].textContent = knightDistanceBfs(+rowInput.value, +colInput.value, whiteX, whiteY, blackX, blackY);
outputs[1].textContent = knightDistance(+rowInput.value, +colInput.value, whiteX, whiteY, blackX, blackY);
} else {
outputs[0].textContent = outputs[1].textContent = "--";
}
}
rowInput.oninput();
table { border-collapse: collapse; cursor: pointer; margin: 2px }
td { border: 1px solid; width: 22px; height: 22px; padding: 0 }
input { width: 3em }
<div>Rows: <input id="rows" type="number" value="3"> Columns: <input id="cols" type="number" value="3"></div>
<table></table>
Number of moves: <span>--</span> (with BFS: <span>--</span>)
<div>Click on the board to place/remove pieces</div>
This would seem to be the basic logic you want, where ?_locs is a set of the locations a particular knight can be in (initialized to its initial location) and one_move yields a set of the locations that can be reached in 1 move from one of the locations in the argument:
while bk_locs intersect wh_locs is empty:
bk_locs = one_move(bk_locs)
wh_locs = one_move(wh_locs)
What this doesn't handle is counting moves (trivial) or identifying when to give up (harder).

How to decode a barcode into ISBN?

For this question with illustrative purpose I will write Javascript code, but that's just an illustration, the question is language-agnostic.
I need to write a function which takes a barcode text (not the image) as an input and returns the ISBN as output. ISBN can be of 10 digits (older books) or 13 digits (newer books). We also know that the last digit of an ISBN is a checksum, which is computed differently if the ISBN is 10 digits long and differently if the ISBN is 13 digits long.
Assuming that input is a string, we can validate whether it is a valid ISBN, like:
function isValidISBN10(input) {
if (input.length !== 10) return false;
var sum = 0;
var p = 10;
for (var index = 0; index < 10; index++) {
sum += ((input[index] === 'X') ? 10 : input[index]) * (p--);
}
return sum % 11 === 0;
}
and ISBN13 can be validated like:
function isValidISBN13(input) {
if (input.length !== 13) return false;
var sum = 0;
var p = 3;
for (var index = 0; index < 13; index++) {
sum += input[index] * (p = (p + 2) % 4);
}
return sum % 10 === 0;
}
Checking a valid ISBN is:
function isValidISBN(input) {
return isValidISBN10(input) || isValidISBN13(input);
}
As we can see, the last digit of an ISBN is the number we should add in order to make sure the result is divisible by 11 (in the case of ISBN10) and 10 (in the case of ISBN13). The 'X' in the case of ISBN10 represents a number of 10 in 11-base.
As far as I understand these articles:
https://www.barcodefaq.com/1d/isbn/
https://isbn-information.com/isbn-barcode.html
barcodes will contain the digits of ISBNs, except its last digit, the example the first article gives is
ISBN = 09767736X
Barcode = 9780976773665
What confuses me is the number of 51050 on this picture
I wonder whether it is part of the barcode or not. If we consider it not to be a barcode, then converting a barcode to an ISBN would be trivial:
function convertBarcodeIntoISBN(input) {
var isbn = {isbn13: input};
if (input.startsWith("978")) {
var isbn10 = input.substring(3);
var checksum = 0;
var p = 10;
for (var index = 0; index < 9; index++) {
checksum += isbn10[index] * (p--);
}
checksum = 11 - (checksum % 11);
if (checksum === 10) checksum = 'X';
isbn10 += checksum;
isbn.isbn10 = isbn10;
}
return isbn;
}
But if we consider 51050 to be part of the barcode, then we will need to mine the ISBN from the barcode, however, in this case I am not sure how should I operate. The best I can pull from the top of my mind is:
function getLastISBNDigit(input) {
if ((input.length != 10) && (input.length != 13)) return;
var is10 = (input.length === 10);
var sum = 0;
var p = (is10 ? 11 : 3);
for (var index = 0; index < input.length - 1; index++) {
sum += ((input[index] === 'X') ? 10 : input[index]) * (p = (is10 ? (p - 1) : ((p + 2) % 4)));
}
var moduloClass = (is10 ? 11 : 10);
var result = (moduloClass - (sum % moduloClass)) % moduloClass;
return ((result === 10) ? 'X' : result);
}
function getISBN(input) {
var isbn = {};
if (input.length > 13) return getISBN(input.substring(0, 13));
if (input.length === 10) {
if (isValidISBN(input)) {
isbn.isbn10 = input;
isbn.isbn13 = "978" + input;
isbn.isbn13 = isbn.isbn13.substring(0, 12) + getLastISBNDigit(isbn.isbn13);
}
} else if (input.length === 13) {
if (isValidISBN(input)) {
isbn.isbn13 = input;
if (input.startsWith("978")) {
isbn.isbn10 = input.substring(3);
isbn.isbn10 = isbn.isbn10.substring(0, 9) + getLastISBNDigit(isbn.isbn10);
}
} else if (input.startsWith("978")) {
return getISBN(input.substring(3));
}
}
return isbn;
}
This is how I think barcodes should be converted into ISBN and ISBN13 values. Am I right with my reasoning?
The second part is the human-readable price (from this slide):
Hence, the first part of your consideration makes sense and 51050 is not part of the barcode!
The price of the product is 10.50$.

JavaScript: Calculate the nth root of a number

I'm trying to get the nth root of a number using JavaScript, but I don't see a way to do it using the built in Math object. Am I overlooking something?
If not...
Is there a math library I can use that has this functionality?
If not...
What's the best algorithm to do this myself?
Can you use something like this?
Math.pow(n, 1/root);
eg.
Math.pow(25, 1/2) == 5
The nth root of x is the same as x to the power of 1/n. You can simply use Math.pow:
var original = 1000;
var fourthRoot = Math.pow(original, 1/4);
original == Math.pow(fourthRoot, 4); // (ignoring floating-point error)
Use Math.pow()
Note that it does not handle negative nicely - here is a discussion and some code that does
http://cwestblog.com/2011/05/06/cube-root-an-beyond/
function nthroot(x, n) {
try {
var negate = n % 2 == 1 && x < 0;
if(negate)
x = -x;
var possible = Math.pow(x, 1 / n);
n = Math.pow(possible, n);
if(Math.abs(x - n) < 1 && (x > 0 == n > 0))
return negate ? -possible : possible;
} catch(e){}
}
You could use
Math.nthroot = function(x,n) {
//if x is negative function returns NaN
return this.exp((1/n)*this.log(x));
}
//call using Math.nthroot();
For the special cases of square and cubic root, it's best to use the native functions Math.sqrt and Math.cbrt respectively.
As of ES7, the exponentiation operator ** can be used to calculate the nth root as the 1/nth power of a non-negative base:
let root1 = Math.PI ** (1 / 3); // cube root of π
let root2 = 81 ** 0.25; // 4th root of 81
This doesn't work with negative bases, though.
let root3 = (-32) ** 5; // NaN
The n-th root of x is a number r such that r to the power of 1/n is x.
In real numbers, there are some subcases:
There are two solutions (same value with opposite sign) when x is positive and r is even.
There is one positive solution when x is positive and r is odd.
There is one negative solution when x is negative and r is odd.
There is no solution when x is negative and r is even.
Since Math.pow doesn't like a negative base with a non-integer exponent, you can use
function nthRoot(x, n) {
if(x < 0 && n%2 != 1) return NaN; // Not well defined
return (x < 0 ? -1 : 1) * Math.pow(Math.abs(x), 1/n);
}
Examples:
nthRoot(+4, 2); // 2 (the positive is chosen, but -2 is a solution too)
nthRoot(+8, 3); // 2 (this is the only solution)
nthRoot(-8, 3); // -2 (this is the only solution)
nthRoot(-4, 2); // NaN (there is no solution)
Well, I know this is an old question. But, based on SwiftNinjaPro's answer, I simplified the function and fixed some NaN issues. Note: This function used ES6 feature, arrow function and template strings, and exponentation. So, it might not work in older browsers:
Math.numberRoot = (x, n) => {
return (((x > 1 || x < -1) && n == 0) ? Infinity : ((x > 0 || x < 0) && n == 0) ? 1 : (x < 0 && n % 2 == 0) ? `${((x < 0 ? -x : x) ** (1 / n))}${"i"}` : (n == 3 && x < 0) ? -Math.cbrt(-x) : (x < 0) ? -((x < 0 ? -x : x) ** (1 / n)) : (n == 3 && x > 0 ? Math.cbrt(x) : (x < 0 ? -x : x) ** (1 / n)));
};
Example:
Math.numberRoot(-64, 3); // Returns -4
Example (Imaginary number result):
Math.numberRoot(-729, 6); // Returns a string containing "3i".
Here's a function that tries to return the imaginary number. It also checks for a few common things first, ex: if getting square root of 0 or 1, or getting 0th root of number x
function root(x, n){
if(x == 1){
return 1;
}else if(x == 0 && n > 0){
return 0;
}else if(x == 0 && n < 0){
return Infinity;
}else if(n == 1){
return x;
}else if(n == 0 && x > 1){
return Infinity;
}else if(n == 0 && x == 1){
return 1;
}else if(n == 0 && x < 1 && x > -1){
return 0;
}else if(n == 0){
return NaN;
}
var result = false;
var num = x;
var neg = false;
if(num < 0){
//not using Math.abs because I need the function to remember if the number was positive or negative
num = num*-1;
neg = true;
}
if(n == 2){
//better to use square root if we can
result = Math.sqrt(num);
}else if(n == 3){
//better to use cube root if we can
result = Math.cbrt(num);
}else if(n > 3){
//the method Digital Plane suggested
result = Math.pow(num, 1/n);
}else if(n < 0){
//the method Digital Plane suggested
result = Math.pow(num, 1/n);
}
if(neg && n == 2){
//if square root, you can just add the imaginary number "i=√-1" to a string answer
//you should check if the functions return value contains i, before continuing any calculations
result += 'i';
}else if(neg && n % 2 !== 0 && n > 0){
//if the nth root is an odd number, you don't get an imaginary number
//neg*neg=pos, but neg*neg*neg=neg
//so you can simply make an odd nth root of a negative number, a negative number
result = result*-1;
}else if(neg){
//if the nth root is an even number that is not 2, things get more complex
//if someone wants to calculate this further, they can
//i'm just going to stop at *n√-1 (times the nth root of -1)
//you should also check if the functions return value contains * or √, before continuing any calculations
result += '*'+n+√+'-1';
}
return result;
}
I have written an algorithm but it is slow when you need many numbers after the point:
https://github.com/am-trouzine/Arithmetic-algorithms-in-different-numeral-systems
NRoot(orginal, nthRoot, base, numbersAfterPoint);
The function returns a string.
E.g.
var original = 1000;
var fourthRoot = NRoot(original, 4, 10, 32);
console.log(fourthRoot);
//5.62341325190349080394951039776481

How to increment and decrement between two values

This is embarrassing, but:
Let say I want to add 1 to x until it reaches 100. At that point I then want to subtract 1 from x until it reaches 1. Then I want to add 1 to x until it reaches 100, and so on.
Could someone provide some simple pseudocode to this question that is making me feel especially dumb.
Thanks :)
EDIT 1
Apologies! I made my example too simple. I actually will be incrementing using a random number at each iteration, so responses that require (x == 100) would not work as x will surely go above 100 and below 1.
Here is math way:
for(int i=0;i<10000000;i++)
print(abs(i%200-100))
Algo's way:
int i = 1;
while(1)
{
while(i<100)print(i++);
while(i>1)print(--i);
}
Random updated:
int i = 1;
while(1)
{
while(i<100)print(i=min(100,i+random()));
while(i>1)print(i=max(1,i-random()));
}
int ceiling = 100;
int floor = 1;
int x = 1;
int step = GetRandomNumber(); //assume this isn't 0
while(someArbitraryCuttoffOrAlwaysTrueIDK) {
while(x + step <= ceiling) {
x += step;
}
while(x - step >= floor) {
x -= step;
}
}
Or, being more concise (at the risk of being less clear):
while(someArbitraryCuttoffOrAlwaysTrueIDK) {
while((step > 0 && x + step <= ceiling) || (step < 0 && x + step >= floor))
{
x += step;
}
step = step * -1;
}
Alternatively:
while(someArbitraryCuttoffOrAlwaysTrueIDK) {
if((step > 0 && x + step > ceiling) || (step < 0 && x + step < floor))
{
step = step * -1;
}
x += step;
}
C#:
Random rnd = new Random();
int someVarToIncreaseDecrease = 0;
bool increasing = true;
while(true) {
int addSubtractInt = rnd.Next(someUpperBound);
if (increasing && (someVarToIncreaseDecrease + addSubtractInt >= 100))
increasing = false;
else if (!increasing && (someVarToIncreaseDecrease - addSubtractInt < 0))
increasing = true;
if (increasing) {
someVarToIncreaseDecrease += addSubtractInt;
}
else {
someVarToIncreaseDecrease -= addSubtractInt;
}
}

Resources