# caveat

This programming challenge is found at

or

and it will be **presented as is**:

# the challenge

Cellulant has implemented a custom, card number verification system to ensure detection and blocking of fake cards. A scratch card consists of

4sets of5digits (20 digits in total) e.g. [10006-12342-00081-99993] which are printed separated by a space or a dash.Each set of 5 digits consists of two parts, the first 4 digits (the number) and a 5th digit (the checksum) The formula dictates that each of the sets must be validated as follows: The first 4 digits, e.g 1234, as decimal numbers be converted into an octal number (base 8) i.e. 23228. This octal number is then processed to generate the checksum, as follows:

- Add all digits to each other to get a new number
“X”- If
“X”is more than 1 digit, repeat step(1)until you have a single digit.“Y”- Append
“Y”to the end of the original decimal number e.g. 12342## For Example:

Given the set “10006”Convert 1000 to octal =>1750>

1+7+5+0=15

1+5=68

Valid number is 10006 so;

return(TRUE)

Given the set “99998”Convert 9999 to octal => 23417

2+3+4+1+7=21

2+1=3

Valid number is 99993 so;

return(FALSE)Create a

Java,Java-ScriptorPHPscript with thefunctionthat will receive astringvalue(scratch card number)and return boolean TRUE or FALSE, on whether the card number is valid, as shown belowYou should use as

many other functionsas you deem necessary within your code.

# really neat solution

This solution was contributed by Filipe Ramalho

- We get the modulo operation of first-four with 7
- Then we subtract the result from the checksum
- Next we get the modulo operation of the result above with 7
- Then we check if it is equal to 0

Better explained by Filipe Ramalho:

For 9999|8

- 9999 % 7 = 3 //First you modulo through 7
- 8 - 3 = 5 //Then you subtract the result from the checksum.
- 5 % 7 = 5 //Then you modulo that through 7.
The end result isn't 0, so the digit isn't valid

```
(defn is-valid?
[number]
(let [first-four (quot number 10)
check-sum (rem number 10)]
(-> first-four
(mod 7)
(- check-sum)
(mod 7)
(= 0))))
user> (is-valid-modified? 10006)
true
user> (is-valid-modified? 99993)
true
user> (is-valid-modified? 99998)
false
user> (is-valid-modified? 12342)
true
user> (is-valid-modified? 11697)
true
```

```
(defn validate-scratch-card [card-number]
(let [f (comp is-valid? #(Integer/parseInt %))]
(->> (string/split card-number #"(-|\s)")
(map f)
(every? true?))))
user> (validate-scratch-card "10006 12342 00081 99998")
false
user> (validate-scratch-card "10006 12342 00081 99993")
true
```

It is an elegant solution.

# the old solution

Instead of using any of the proposed languages above, I shall use **Clojure**.

`validate-scratch-card`

is a function which takes a **string** which may look like:

- "
`10006-12342-00081-99993`

" - "
`10006 12342 00081 99993`

"

It would be nice to split the argument based on the presence of a space or a hyphen so that I could work on each substring:

```
;; has hyphen
user> (clojure.string/split "10006-12342-00081-99993" #("-|\s)")
;; ["10006" "12342" "00081" "99993"]
;; has spaces
user> (clojure.string/split "10006 12342 00081 99993" #"(-|\s)")
;; ["10006" "12342" "00081" "99993"]
```

Next item on the agenda is to parse each individual substring to `Integer`

via the Java method `Integer/parseInt`

.

```
user> (Integer/parseInt "10006")
;; 10006
```

`map`

can be used to parse each individual substring

```
user> (map #(Integer/parseInt %) "10006 12342 00081 99993")
;; 10006
```

Each Integer can be **checked for validity** based on the rules above.

Each Integer has 2 parts:

- first four digits (the number)
- the fifth digit (the checksum)

```
user> (quot 10006 10)
;; 1000 first four digits (the number)
user> (rem 10006 10)
;; 6 fifth digit (checksum)
```

Next is to convert the first four digits to octal.

This will be achieved by creating a base converter

```
(defn- to-digits [number base]
(loop [n number
digits '()]
(if (pos? n)
(recur (quot n base)
(conj digits (mod n base)))
digits)))
(defn to-octal [number]
"returns a list of octal numbers"
(to-digits number 8))
```

```
user> (to-octal 1000)
;; (1 7 5 0)
```

Subsequent step is to sum up each of the generated numbers.

But before that, a function that takes two octal numbers and sums them up is needed.

```
(defn add-two-octal [x y]
"add two octal numbers"
(let [a (Integer/parseInt (str x) 8)
b (Integer/parseInt (str y) 8)]
(-> (+ a b)
Integer/toOctalString
Integer/parseInt)))
```

```
user> (add-two-octal 3 6)
;; 11
```

This `add-two-octal`

function can then be used to sum up a list of octal numbers together as follows:

```
user> (reduce #(add-two-octal %1 %2)
(to-octal 1000))
;; 15
user> (reduce #(add-two-octal %1 %2)
'(1 7 5 0))
;; 15
```

Although the addition works fine it doesn't satisfy the requirement that the result of the sum should be a single digit.

If a single digit is the result of the sum then the single digit should be returned else the summation should be done again.

Also there is need for a function to separate the new summation if it happens to be two digits.

```
(defn separate [number]
"a utility function to separate digits"
(loop [n number
digits '()]
(if (zero? n)
digits
(recur (quot n 10)
(conj digits (rem n 10))))))
(defn sum-octal [number]
(let [sum (reduce #(add-two-octal %1 %2)
(to-octal number))]
(if (zero? (quot sum 10))
sum
(apply add-two-octal (separate sum)))))
```

```
user> (sum-octal 1000)
;; 6
```

Next a function that takes a number and checks for validity can be written as follows:

```
(defn is-valid? [number]
(let [first-four (quot number 10)
check-sum (rem number 10)
verify (sum-octal first-four)]
(= verify check-sum)))
```

```
user> (is-valid? 10006)
;; true
user> (is-valid? 99998)
;; false
```

The `is-valid?`

function and the `#(Integer/parseInt %)`

can be composed together

```
(comp is-valid? #(Integer/parseInt %))
user> ((comp is-valid? #(Integer/parseInt %)) "10006")
;; true
```

Finally, the `validate-scratch-card`

function will shape up as follows

```
(defn validate-scratch-card [card-number]
(let [f (comp is-valid? #(Integer/parseInt %))]
(->> (string/split card-number #"(-|\s)")
(map f)
(every? true?))))
```

```
user> (validate-scratch-card "10006 12342 00081 99993")
;; true
user> (validate-scratch-card "10006 12342 00081 99998")
;; false
```

## Top comments (4)

You can also use modulo. You calculate the iterative digit sum with number % 9. If 0 comes out the sum is 9.

sjsu.edu/faculty/watkins/Digitsum0...

I'm not familiar with Clojure so I can't give you a code example of Clojure. But here in pseudocode

You can also consider 0 and 9 equal and spare the conversion from 0 to 9:

Or you could modulo the difference through 9. If it's 0 the result is 0, if it's 9 the result is also 0.

So in one line it would look like this

Thank you for contribution.

I have really tried my best to understand, but have failed.

Could you use examples?

Actually I had an error. You shouldn't convert the digit. And instead modulo through 7.

For 9999|8

The end result isn't 0, so the digit isn't valid

For 1234|2

The end result is 0, so the digit is valid

For 1169|7

1.1169 % 7 = 0 //If you modulo through 7, when the digit sum is 7 instead 0 comes out, so you can consider 0=7.

The end result is 0, so the digit is valid

Updated code

You can also consider 0 and 7 equal and spare the conversion from 0 to 7:

Or you could modulo the difference through 7. The difference must be either 7 or 0 and both have the same result for modulo 7.

So in one line it would look like this

Thank you for clarifying. I have now understood.

It is actually a really neat solution it basically reduces the code to just two functions.

I have learnt something, thank you.