Validating Israeli ID number - luhn

I'm looking for a clean and efficient way to validate an Israeli ID number.
It's basically an implementation of the Luhn algorithm on a 9 digits number.
Note:
This question is here for the community because it wasn't on stack overflow yet.
You can add answers in different coding languages.

Here's an efficient way to implement it in C# (link):
public static bool IsValidIsraeliID(string israeliID)
{
if (israeliID.Length != 9)
return false;
long sum = 0;
for (int i = 0; i < israeliID.Length; i++)
{
var digit = israeliID[israeliID.Length - 1 - i] - '0';
sum += (i % 2 != 0) ? GetDouble(digit) : digit;
}
return sum % 10 == 0;
int GetDouble(long i)
{
switch (i)
{
case 0: return 0;
case 1: return 2;
case 2: return 4;
case 3: return 6;
case 4: return 8;
case 5: return 1;
case 6: return 3;
case 7: return 5;
case 8: return 7;
case 9: return 9;
default: return 0;
}
}
}

JS example code like it appears in Wikipedia:
https://he.wikipedia.org/wiki/ספרת_ביקורת
function IDValidator(id)
{
if (id.length !== 9 || isNaN(id)) { // Make sure ID is formatted properly
return false;
}
let sum = 0, incNum;
for (let i = 0; i < id.length; i++) {
incNum = Number(id[i]) * ((i % 2) + 1); // Multiply number by 1 or 2
sum += (incNum > 9) ? incNum - 9 : incNum; // Sum the digits up and add to total
}
return (sum % 10 === 0);
}

Related

How to format a number into thousands, millions and billions with dart/flutter?

How to get a number converted into something like this: 12K, 1.5M, 4.2B from a normal number like: 134900.
This is a minimalist function, of course you'll have to add validation code to verify if the number is valid before executing the function. Otherwise Enjoy ...
void main() {
double num = 1250;
var myNumber = k_m_b_generator(num);
print(myNumber);
}
String k_m_b_generator(num) {
if (num > 999 && num < 99999) {
return "${(num / 1000).toStringAsFixed(1)} K";
} else if (num > 99999 && num < 999999) {
return "${(num / 1000).toStringAsFixed(0)} K";
} else if (num > 999999 && num < 999999999) {
return "${(num / 1000000).toStringAsFixed(1)} M";
} else if (num > 999999999) {
return "${(num / 1000000000).toStringAsFixed(1)} B";
} else {
return num.toString();
}
}
You can use flutter's NumberFormat class with the compact function.
formatNumber(dynamic myNumber) {
// Convert number into a string if it was not a string previously
String stringNumber = myNumber.toString();
// Convert number into double to be formatted.
// Default to zero if unable to do so
double doubleNumber = double.tryParse(stringNumber) ?? 0;
// Set number format to use
NumberFormat numberFormat = new NumberFormat.compact();
return numberFormat.format(doubleNumber);
}
The answer is not entirely correct. If you test it, you will see what i meant. Base on the answer above, I created this solution:
String numberFormat(int n) {
String num = n.toString();
int len = num.length;
if (n >= 1000 && n < 1000000) {
return num.substring(0, len - 3) + '.' + num.substring(len - 3, 1 + (len - 3)) + 'k';
} else if (n >= 1000000 && n < 1000000000) {
return num.substring(0, len - 6) + '.' + num.substring(len - 6, 1 + (len - 6)) + 'm';
} else if (n > 1000000000) {
return num.substring(0, len - 9) + '.' + num.substring(len - 9, 1 + (len - 9)) + 'b';
} else {
return num.toString();
}
}

How to write a non-C-like for-loop in Swift 2.2+?

I have updated Xcode (7.3) and there are a lot of changes; C-like for expressions will be deprecated. For a simple example,
for var i = 0; i <= array.count - 1; i++
{
//something with array[i]
}
How do I write this clear and simple C-like for-loop to be compliant with the new changes?
for var i = 0, j = 1; i <= array.count - 2 && j <= array.count - 1; i++, j++
{
//something with array[i] and array[j]
}
Update.
One more variant
for var i = 0; i <= <array.count - 1; i++
{
for var j = i + 1; j <= array.count - 1; j++
{
//something with array[i] and array[j]
}
}
And more ...
for var i = 0, j = 1, g = 2; i <= array.count - 3 && j <= array.count - 2 && g <= array.count - 1; i++, j++, g++
{
//something with array[i] and array[j] and array[g]
}
Update2 After several suggestions for me while loop is preferable universal substitution for all cases more complicated than the simple example of C-like for-loop (suitable for for in expression). No need every time to search for new approach.
For instance: Instead of
for var i = 0; i <= <array.count - 1; i++
{
for var j = i + 1; j <= array.count - 1; j++
{
//something with array[i] and array[j]
}
}
I can use
var i = 0
while i < array.count
{
var j = i + 1
while j < array.count
{
//something with array[i] and array[j]
j += 1
}
i += 1
}
charl's (old) answer will crash. You want 0..<array.count:
for index in 0..<array.count {
// ...
}
If you want something like your i/j loop you can use stride and get i's successor:
for i in 0.stride(through: array.count, by: 1) {
let j = i.successor()
// ...
}
Just make sure to check i.successor() in case you go out of bounds.
for var i = 0; i <= array.count - 1; i++ {
//something with array[i]
}
Here you don't need the element index at all, so you can simply
enumerate the array elements:
for elem in array {
// Do something with elem ...
}
for var i = 0, j = 1; i <= array.count - 2 && j <= array.count - 1; i++, j++ {
//something with array[i] and array[j]
}
To iterate over pairs of adjacent elements, use zip()
and dropFirst():
for (x, y) in zip(array, array.dropFirst()) {
// Do something with x and y ...
print(x, y)
}
Output:
1 2
2 3
3 4
4 5
For other distances, use dropFirst(n):
for (x, y) in zip(array, array.dropFirst(3)) {
// Do something with x and y ...
print(x, y)
}
Output:
1 4
2 5
There are probably many solutions to do
for var i = 0; i <= <array.count - 1; i++ {
for var j = i + 1; j <= array.count - 1; j++ {
//something with array[i] and array[j]
}
}
without a C-style for-loop, here is one:
for (index, x) in array.enumerate() {
for y in array.dropFirst(index + 1) {
print(x, y)
}
}
If you want to do something with subsequent pairs there are many other ways to do it.
Something like this would work...
var previousItem = array.first
for index in 1..<array.count {
let currentItem = array[index]
// do something with current and previous items
previousItem = currentItem
}
for (i, j) in zip(array.dropLast(), array.dropFirst())
{
// something
}
What you're really doing here is enumerating two parallel sequences. So, create those sequences and use zip to turn them into a single sequence.
Do enumeration
let suits = ["♠︎", "♥︎", "♣︎", "♦︎"]
for (i, suite) in suits.enumerate() {
// ...
}
or to compare neighbors
import Foundation
let suits = ["♠︎", "♥︎", "♣︎", "♦︎"]
for (i, suite1) in suits.enumerate() {
let j = i.successor()
if j < suits.count {
let suite2 = suits[j]
// ...
}
}
or zipping and enumerating
let suits = ["♠︎", "♥︎", "♣︎", "♦︎"]
let combination = zip(suits, suits.dropFirst())
for (i, (s1,s2)) in combination.enumerate() {
print("\(i): \(s1) \(s2)")
}
result
0: ♠︎ ♥︎
1: ♥︎ ♣︎
2: ♣︎ ♦︎
Worst case, you can convert it to a while loop.
var i = 0
var j = 1
while i <= array.count -2 && j <= array.count - 1 {
// something
i += 1
j += 1
}
-- EDIT --
Because you said, "while loop is preferable universal substitution for all cases more complicated than the simple example of C-like for-loop"... I feel the need to expand on my answer. I don't want to be responsible for a bunch of bad code...
In most cases, there is a simple for-in loop that can handle the situation:
for item in array {
// do something with item
}
for (item1, item2) in zip(array, array[1 ..< array.count]) {
// do something with item1 and item2
}
for (index, item1) in array.enumerate() {
for item2 in array[index + 1 ..< array.count] {
// do soemthing with item1 and item2
}
}
For your last case, you might be justified using a for look, but that is an extremely rare edge case.
Don't litter your code with for loops.
to compare neighbouring elements from the same array you can use
let arr = [1,2,2,5,2,2,3,3]
arr.reduce(nil) { (i, j)->Int? in
if let i = i {
print(i,"==",j,"is",i == j)
}
return j
}
it prints
1 == 2 is false
2 == 2 is true
2 == 5 is false
5 == 2 is false
2 == 2 is true
2 == 3 is false
3 == 3 is true
more 'generic' approach without using subscript but separate generators
let arr1 = [1,2,3,4,5,6,7,8,9,0]
var g1 = arr1.generate()
var g2 = (arr1.dropFirst(5) as AnySequence).generate()
var g3 = (arr1.dropFirst(6) as AnySequence).generate()
while true {
if let a1 = g1.next(),
let a2 = g2.next(),
let a3 = g3.next() {
print(a1,a2,a3)
} else {
break
}
}
/* prints
1 6 7
2 7 8
3 8 9
4 9 0
*/

Solving Twitter Puddle with Zipper

This is a follow-up to my previous question. Consider the following puzzle
I would like to generate a waterLevel array, so that the i-th item is the water level at the i-th point and then sum them up to solve the puzzle.
waterLevel[i] =
max(0, min(max of left neighbors, max of right neighbors) - height[i])
I would probably try to code it with Zipper
waterLevels = heights.toZipper.cobind {z =>
max(0, min(max(z.left), max(z.right)) - z.focus
}.toList
Does it make sense ?
My solution with java, it comes with tests with expected solution:
package com.company;
import java.util.*;
enum Orientation {DOWN, UP};
class Walls{
public static void main(String []args){
HashMap<String, Integer> tests = new HashMap<String,Integer>();
tests.put("2 5 1 2 3 4 7 7 6", 10);
tests.put("2 2 5 1 3 1 2 1 7 7 6", 17);
tests.put("2 7 2 7 4 7 1 7 3 7", 18);
tests.put("4 6 7 7 4 3 2 1 5 2", 10);
tests.put("5 2 5 1 2 3 4 7 7 6 2 7 1 2 3 4 5 5 4", 26);
Iterator it = tests.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pairs = (Map.Entry)it.next();
it.remove();
String[] strings = ((String)pairs.getKey()).split(" ");
int[] walls = new int[strings.length];
for (int i = 0; i < walls.length; i++){
walls[i] = Integer.parseInt(strings[i].trim());
}
System.out.println(pairs.getKey()+" result="+accumulatedWater(walls)+" expected= " +pairs.getValue());
}
}
static int accumulatedWater(int []wall){
int MAX = 0;
int start = 0;
for(int i=0;i < wall.length;i++){ //let's go to the first peak
if(wall[i] >= MAX){
MAX = wall[i];
start = i;
}else{
break;
}
}
int []accumulate_max = new int[MAX+1]; // sums up to certain height
int []accumulate_max_step = new int[MAX+1]; // steps up to certain height
Orientation going = Orientation.DOWN;
int prev = MAX;
int local_sum=0;
int total_sum=0;
int PREVPEAK = MAX;
for(int i=start+1; i< wall.length; i++){
if( i == wall.length -1 ||
wall[i] < prev && going == Orientation.UP ){
going = Orientation.DOWN;
if(wall[i-1] >= MAX){
total_sum += accumulate_max_step[MAX-1] * MAX - accumulate_max[MAX-1];
MAX = wall[i-1];
PREVPEAK = MAX;
accumulate_max = new int[MAX+1];
accumulate_max_step = new int[MAX+1];
local_sum = 0;
}else{
int indexNewPeak = (i == wall.length -1 && wall[i]> wall[i-1]) ? i : i-1;
int water = accumulate_max_step[wall[indexNewPeak]-1] * wall[indexNewPeak] - accumulate_max[wall[indexNewPeak]-1];
if(wall[indexNewPeak] > PREVPEAK){
local_sum = water;
PREVPEAK = wall[indexNewPeak];
}else{
local_sum += water;
}
}
}else if(wall[i]>prev){
going = Orientation.UP;
}
for(int j=wall[i];j <= MAX;j++){
accumulate_max[j] += wall[i];
accumulate_max_step[j] += 1;
}
prev = wall[i];
}
return total_sum + local_sum;
}
}

Split a integer into its separate digits

Say I have an integer, 9802, is there a way I can split that value in the four individual digits : 9, 8, 0 & 2 ?
Keep doing modulo-10 and divide-by-10:
int n; // from somewhere
while (n) { digit = n % 10; n /= 10; }
This spits out the digits from least-significant to most-significant. You can clearly generalise this to any number base.
You probably want to use mod and divide to get these digits.
Something like:
Grab first digit:
Parse digit: 9802 mod 10 = 2
Remove digit: (int)(9802 / 10) = 980
Grab second digit:
Parse digit: 980 mod 10 = 0
Remove digit: (int)(980 / 10) = 98
Something like that.
if you need to display the digits in the same order you will need to do the module twice visa verse this is the code doing that:
#import <Foundation/Foundation.h>
int main (int argc, char * argv[])
{
#autoreleasepool {
int number1, number2=0 , right_digit , count=0;
NSLog (#"Enter your number.");
scanf ("%i", &number);
do {
right_digit = number1 % 10;
number1 /= 10;
For(int i=0 ;i<count; i++)
{
right_digit = right_digit*10;
}
Number2+= right_digit;
Count++;
}
while ( number != 0 );
do {
right_digit = number2 % 10;
number2 /= 10;
Nslog(#”digit = %i”, number2);
}
while ( number != 0 );
}
}
return 0;
}
i hope that it is useful :)

finding the left substring is equal to right substring

Write a function which given a string S returns the index (counting from 0) of character such that the substring on its left is a reversed susbstring on its right (or -1 if such an index does not exist).
For example, given a string
racecar
Function should return 3, because the substring on the left of the character e at index 3 is rac, and the one on the right is car.
get the length/2 and verify lengths first and then if the lengths are same then reverse the first half and compare with the second.
Example function:
private int TestMethod1(string str)
{
if (str.Length > 0)
{
if (str.Length % 2 != 0)
{
string strFront = string.Empty;
for (int i = (str.Length / 2) - 1; i >= 0; i--)
{
strFront += str.Substring(i, 1);
}
if (strFront.Equals(str.Substring((str.Length / 2) + 1)))
{
return str.Length / 2;
}
}
}
return -1;
}