Skip to content

Instantly share code, notes, and snippets.

@holyshared
Last active August 17, 2017 02:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save holyshared/cf375f3cc0e83223560e705cd5f768b4 to your computer and use it in GitHub Desktop.
Save holyshared/cf375f3cc0e83223560e705cd5f768b4 to your computer and use it in GitHub Desktop.
Check digit of numbers

Check digit of numbers

This program is a program to calculate the check digit of many numbers.

Basic usage

First prepare a file in which numbers are written.
After that, we will load the file into the program.

10001
10002
10003
.....
.....

When loading it, the number with the check digit should be displayed.

cat numbers.txt | check_digit

Verify the number with check digit, use the -c, --check option.

cat numbers.txt | check_digit -c

Build

To execute the build, execute the following command.

make build

To execute the build for the release, execute the following command.

make release

Test

The test can be executed with the following command.

make test

Licence

The MIT Licence

#[
checkdigit.nim
Noritaka Horio <holy.shared.design@gmail.com>
Copyright (c) 2017 Noritaka Horio
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]#
import strutils, sequtils
# Odd/Even number list
type NumberSet = tuple[odd: seq[int], even: seq[int]]
# Check Digit result
type CheckDigitResult = tuple[input: string, checkDigit: int]
proc isOdd(n: int): bool =
n mod 2 == 0
#
# Collect odd/event number of original number
#
proc collectNumbers(number: string): NumberSet =
var odd_numbers, even_numbers: seq[int] = @[]
for pos in 0..(len(number) - 1):
let next = pos + 1
let v = parseInt(number[pos..pos])
if isOdd(next):
odd_numbers.add(v)
else:
even_numbers.add(v)
(odd: odd_numbers, even: even_numbers)
#
# Calculate check digit
#
proc ofNumber*(number: string): CheckDigitResult =
let numbers = collectNumbers(number)
let odd_sum = foldl(numbers.odd, a + b)
let even_sum = foldl(numbers.even, a + b)
let odd_even_sum = odd_sum + (even_sum * 3)
let str_num = intToStr(odd_even_sum)
let last_index = len(str_num) - 1
let last_num = parseInt(str_num[last_index..last_index])
var check_digit = 0
if last_num == 0:
check_digit = 0
else:
check_digit = 10 - last_num
(input: number, checkDigit: checkDigit)
proc isValid*(number: string): bool =
let last_index = len(number) - 1
let last_check_digit = parseInt(number[last_index..last_index])
let check_digit = ofNumber(number[0..(last_index - 1)])
check_digit.checkDigit == last_check_digit
import unittest, checkdigit
suite "checkdigit module":
test "calucate check digit":
let result = ofNumber("10000")
check(result.input == "10000")
check(result.checkDigit == 7)
test "check valid digit":
check(isValid("100007"))
check(isValid("435451"))
check(isValid("567787"))
check(isValid("567671"))
#[
main.nim
Noritaka Horio <holy.shared.design@gmail.com>
Copyright (c) 2017 Noritaka Horio
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]#
import parseopt, checkdigit
const PROGRAM_NAME = "checkdigit"
const PROGRAM_VERSION = "1.0.0"
const PROGRAM_AUTHOR = "Noritaka Horio <holy.shared.design@gmail.com>"
const PROGRAM_LICENCE = "The MIT Licence"
type CheckDigitAction = proc(number: string): void
proc writeHelp(): void =
echo "Usage ", PROGRAM_NAME, "\n"
echo " checkdigit [OPTIONS]\n"
echo "EXAMPLE:\n"
echo " cat number.txt | ", PROGRAM_NAME, " [OPTIONS]\n"
echo """OPTIONS:
-c, --check Validate the check digit
-v, --version Displays the version of the program
-h, --help Display program help
"""
quit(QuitSuccess)
proc writeVersion(): void =
echo PROGRAM_NAME, " ", PROGRAM_VERSION
echo "Author: ", PROGRAM_AUTHOR
echo "Licence: ", PROGRAM_LICENCE
quit(QuitSuccess)
proc printCheckDigit(number: string): void =
let result = checkdigit.ofNumber(number)
echo result.input, result.checkDigit
proc printInvalidCheckDigit(number: string): void =
if checkdigit.isValid(number): return
echo number
var check: CheckDigitAction = printCheckDigit
for kind, key, val in getopt():
case kind
of cmdArgument:
continue
of cmdLongOption, cmdShortOption:
case key
of "check", "c": check = printInvalidCheckDigit
of "help", "h": writeHelp()
of "version", "v": writeVersion()
of cmdEnd: assert(false)
while endOfFile(stdin) == false:
let number = readLine(stdin)
check(number)
build:
nim compile main.nim
mv main checkdigit
release:
nim compile -d:release main.nim
mv main checkdigit
test:
nim compile checkdigit_test.nim
./checkdigit_test
clean:
rm nimcache/*
rm checkdigit
rm checkdigit_test
435451
567787
567671
778893
345460
43545
56778
56767
77889
34546
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment