Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
2
Task/ISBN13-check-digit/00-META.yaml
Normal file
2
Task/ISBN13-check-digit/00-META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
from: http://rosettacode.org/wiki/ISBN13_check_digit
|
||||
22
Task/ISBN13-check-digit/00-TASK.txt
Normal file
22
Task/ISBN13-check-digit/00-TASK.txt
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
;Task:
|
||||
Validate the check digit of an ISBN-13 code:
|
||||
::* Multiply every other digit by '''3'''.
|
||||
::* Add these numbers and the other digits.
|
||||
::* Take the remainder of this number after division by '''10'''.
|
||||
::* If it is '''0''', the ISBN-13 check digit is correct.
|
||||
|
||||
|
||||
You might use the following codes for testing:
|
||||
::::* 978-0596528126 (good)
|
||||
::::* 978-0596528120 (bad)
|
||||
::::* 978-1788399081 (good)
|
||||
::::* 978-1788399083 (bad)
|
||||
|
||||
|
||||
Show output here, on this page
|
||||
|
||||
|
||||
;See also:
|
||||
:* for details: [https://isbn-information.com/the-13-digit-isbn.html 13-digit ISBN method of validation]. (installs cookies.)
|
||||
<br><br>
|
||||
|
||||
15
Task/ISBN13-check-digit/11l/isbn13-check-digit.11l
Normal file
15
Task/ISBN13-check-digit/11l/isbn13-check-digit.11l
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
F is_isbn13(=n)
|
||||
n = n.replace(‘-’, ‘’).replace(‘ ’, ‘’)
|
||||
I n.len != 13
|
||||
R 0B
|
||||
V product = sum(n[(0..).step(2)].map(ch -> Int(ch)))
|
||||
+ sum(n[(1..).step(2)].map(ch -> Int(ch) * 3))
|
||||
R product % 10 == 0
|
||||
|
||||
V tests = |‘978-1734314502
|
||||
978-1734314509
|
||||
978-1788399081
|
||||
978-1788399083’.split("\n")
|
||||
|
||||
L(t) tests
|
||||
print(‘ISBN13 ’t‘ validates ’is_isbn13(t))
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
org 100h
|
||||
jmp demo
|
||||
;;; ---------------------------------------------------------------
|
||||
;;; Check if the string at BC is a valid ISBN-13 code.
|
||||
;;; Carry set if true, clear if not.
|
||||
isbn13: lxi h,0 ; HL = accumulator
|
||||
mov d,h ; D = 0 (such that if E=A, DE=A).
|
||||
call isbngc ; Get first character
|
||||
rnc ; Carry clear = invalid
|
||||
dad d ; Add to running total once
|
||||
call isbngc ; Get second character
|
||||
rnc ; Carry clear = invalid
|
||||
dad d ; Add to running total thrice
|
||||
dad d
|
||||
dad d
|
||||
call isbngc ; Get third character
|
||||
rnc ; Carry clear = invalid
|
||||
dad d ; Add to running total once
|
||||
ldax b ; Fourth character should be a dash '-'
|
||||
inx b
|
||||
cpi '-'
|
||||
stc ; Clear carry w/o touching other flags
|
||||
cmc
|
||||
rnz ; If not equal, invalid.
|
||||
push h ; Keep loop counter on stack
|
||||
mvi l,5 ; 5 times 2 characters
|
||||
isbnlp: xthl ; Accumulator in HL
|
||||
call isbngc ; Get even character
|
||||
jnc isbnex ; If invalid, stop
|
||||
dad d ; Add to running total thrice
|
||||
dad d
|
||||
dad d
|
||||
call isbngc ; Get odd character
|
||||
jnc isbnex ; If invalid, stop
|
||||
dad d ; Add to running total once
|
||||
xthl ; Loop counter in (H)L
|
||||
dcr l ; Done yet?
|
||||
jnz isbnlp ; If not, do next two characters
|
||||
pop h ; Get accumulator
|
||||
lxi d,-10 ; Trial division by ten
|
||||
isbndv: dad d ; Subtract 10
|
||||
jc isbndv ; Until zero passed
|
||||
mov a,l ; Move low byte to A
|
||||
adi 10 ; Add ten back (the mod loop went one step too far)
|
||||
rz ; If zero, return (carry will have been set)
|
||||
ana a ; Otherwise, make sure carry is clear
|
||||
ret ; And then return
|
||||
isbnex: pop h ; Test failed - throw away accumulator and return
|
||||
ret
|
||||
isbngc: ldax b ; Get character from [BC]
|
||||
inx b ; Increment BC
|
||||
sui '0' ; Subtract ASCII '0' to get digit value
|
||||
cpi 10 ; If 10 or higher (unsigned), invalid digit.
|
||||
mov e,a ; Set (D)E = value
|
||||
ret
|
||||
;;; ---------------------------------------------------------------
|
||||
;;; Demo: see if the CP/M command line contains a valid ISBN13
|
||||
;;; code.
|
||||
demo: lxi b,82h ; Start of command line argument, skipping first space
|
||||
call isbn13 ; Is it valid?
|
||||
mvi c,9 ; CP/M print string
|
||||
lxi d,good ; If carry is set, then yes
|
||||
jc 5
|
||||
lxi d,bad ; Otherwise, no.
|
||||
jmp 5
|
||||
good: db 'good$'
|
||||
bad: db 'bad$'
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
cpu 8086
|
||||
bits 16
|
||||
org 100h
|
||||
section .text
|
||||
jmp demo
|
||||
isbn13: ;;; ---------------------------------------------------------------
|
||||
;;; Check if the string at DS:SI is a valid ISBN-13 code.
|
||||
;;; Carry set if true, clear if false.
|
||||
xor dx,dx ; DX = running total
|
||||
xor ah,ah ; Set AH=0 so that AX=AL
|
||||
call .digit ; Get first digit and add to DX
|
||||
call .digit ; Get second digit and add to DX
|
||||
add dx,ax ; Add to DX twice more
|
||||
add dx,ax
|
||||
call .digit ; Get third digit and add to DX
|
||||
lodsb ; Fourth character should be a '-'
|
||||
cmp al,'-'
|
||||
jne .fail ; If not equal, fail
|
||||
mov cx,5 ; Then loop 5 times for the next 10 digits
|
||||
.loop: call .digit ; Get even digit and add to DX
|
||||
add dx,ax ; Add to running total twice more
|
||||
add dx,ax
|
||||
call .digit ; Get odd digit and add to DX
|
||||
loop .loop ; Do this 5 times
|
||||
mov ax,dx ; Divide running total by 10
|
||||
mov dl,10
|
||||
div dl
|
||||
test ah,ah ; Is the remainder zero?
|
||||
jnz .out ; If not, stop (TEST clears carry)
|
||||
stc ; Otherwise, set carry and return
|
||||
ret
|
||||
.digit: lodsb ; Get first character
|
||||
sub al,'0' ; Subtract ASCII 0 to get digit value
|
||||
cmp al,9
|
||||
ja .dfail
|
||||
add dx,ax ; Add to ASCII
|
||||
ret
|
||||
.dfail: pop dx ; Remove return pointer for .digit from stack
|
||||
.fail: clc ; Failure - clear carry
|
||||
.out: ret
|
||||
;;; ---------------------------------------------------------------
|
||||
;;; Demo: see if the MS-DOS command line contains a valid ISBN13
|
||||
;;; code.
|
||||
demo: mov si,82h ; Start of command line argument skipping space
|
||||
call isbn13 ; Is it valid?
|
||||
mov ah,9 ; MS-DOS print string
|
||||
mov dx,good ; If carry is set, it is good
|
||||
jc .print
|
||||
mov dx,bad ; Otherwise, it is bad
|
||||
.print: int 21h
|
||||
ret
|
||||
section .data
|
||||
good: db 'good$'
|
||||
bad: db 'bad$'
|
||||
35
Task/ISBN13-check-digit/ALGOL-68/isbn13-check-digit.alg
Normal file
35
Task/ISBN13-check-digit/ALGOL-68/isbn13-check-digit.alg
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
BEGIN # Check some IsBN13 check digits #
|
||||
# returns TRUE if the alledged isbn13 has the correct check sum, #
|
||||
# FALSE otherwise #
|
||||
# non-digit characters are ignored and there must be 13 digits #
|
||||
PROC check isbn13 = ( STRING isbn13 )BOOL:
|
||||
BEGIN
|
||||
INT sum := 0;
|
||||
INT digits := 0;
|
||||
BOOL other digit := FALSE;
|
||||
FOR pos FROM LWB isbn13 TO UPB isbn13 DO
|
||||
IF CHAR c = isbn13[ pos ];
|
||||
c >= "0" AND c <= "9"
|
||||
THEN
|
||||
# have another digit #
|
||||
digits +:= 1;
|
||||
sum +:= ( ABS c - ABS "0" ) * IF other digit THEN 3 ELSE 1 FI;
|
||||
other digit := NOT other digit
|
||||
FI
|
||||
OD;
|
||||
digits = 13 AND sum MOD 10 = 0
|
||||
END; # check isbn13 #
|
||||
# task test cases #
|
||||
[]STRING tests = ( "978-1734314502", "978-1734314509", "978-1788399081", "978-1788399083" );
|
||||
[]BOOL expected = ( TRUE, FALSE, TRUE, FALSE );
|
||||
FOR pos FROM LWB tests TO UPB tests DO
|
||||
BOOL result = check isbn13( tests[ pos ] );
|
||||
print( ( tests[ pos ]
|
||||
, ": "
|
||||
, IF result THEN "good" ELSE "bad" FI
|
||||
, IF result = expected[ pos ] THEN "" ELSE " NOT AS EXPECTED" FI
|
||||
, newline
|
||||
)
|
||||
)
|
||||
OD
|
||||
END
|
||||
4
Task/ISBN13-check-digit/APL/isbn13-check-digit.apl
Normal file
4
Task/ISBN13-check-digit/APL/isbn13-check-digit.apl
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
check_isbn13←{
|
||||
13≠⍴n←(⍵∊⎕D)/⍵:0
|
||||
0=10|(⍎¨n)+.×13⍴1 3
|
||||
}
|
||||
22
Task/ISBN13-check-digit/AWK/isbn13-check-digit.awk
Normal file
22
Task/ISBN13-check-digit/AWK/isbn13-check-digit.awk
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# syntax: GAWK -f ISBN13_CHECK_DIGIT.AWK
|
||||
BEGIN {
|
||||
arr[++n] = "978-1734314502"
|
||||
arr[++n] = "978-1734314509"
|
||||
arr[++n] = "978-1788399081"
|
||||
arr[++n] = "978-1788399083"
|
||||
arr[++n] = "9780820424521"
|
||||
arr[++n] = "0820424528"
|
||||
for (i=1; i<=n; i++) {
|
||||
printf("%s %s\n",arr[i],isbn13(arr[i]))
|
||||
}
|
||||
exit(0)
|
||||
}
|
||||
function isbn13(isbn, check_digit,i,sum) {
|
||||
gsub(/[ -]/,"",isbn)
|
||||
if (length(isbn) != 13) { return("NG length") }
|
||||
for (i=1; i<=12; i++) {
|
||||
sum += substr(isbn,i,1) * (i % 2 == 1 ? 1 : 3)
|
||||
}
|
||||
check_digit = 10 - (sum % 10)
|
||||
return(substr(isbn,13,1) == check_digit ? "OK" : sprintf("NG check digit S/B %d",check_digit))
|
||||
}
|
||||
45
Task/ISBN13-check-digit/Action-/isbn13-check-digit.action
Normal file
45
Task/ISBN13-check-digit/Action-/isbn13-check-digit.action
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
INCLUDE "D2:CHARTEST.ACT" ;from the Action! Tool Kit
|
||||
|
||||
BYTE FUNC CheckISBN13(CHAR ARRAY t)
|
||||
BYTE i,index,sum,v
|
||||
|
||||
sum=0 index=0
|
||||
FOR i=1 TO t(0)
|
||||
DO
|
||||
v=t(i)
|
||||
IF IsDigit(v) THEN
|
||||
v==-'0
|
||||
IF index MOD 2=1 THEN
|
||||
v==*3
|
||||
FI
|
||||
sum==+v
|
||||
index==+1
|
||||
ELSEIF v#' AND v#'- THEN
|
||||
RETURN (0)
|
||||
FI
|
||||
OD
|
||||
IF index#13 OR sum MOD 10#0 THEN
|
||||
RETURN (0)
|
||||
FI
|
||||
RETURN (1)
|
||||
|
||||
PROC Test(CHAR ARRAY t)
|
||||
BYTE correct
|
||||
|
||||
correct=CheckISBN13(t)
|
||||
Print(t) Print(" is ")
|
||||
IF correct THEN
|
||||
PrintE("correct")
|
||||
ELSE
|
||||
PrintE("incorrect")
|
||||
FI
|
||||
RETURN
|
||||
|
||||
PROC Main()
|
||||
Put(125) PutE() ;clear screen
|
||||
|
||||
Test("978-1734314502")
|
||||
Test("978-1734314509")
|
||||
Test("978-1788399081")
|
||||
Test("978-1788399083")
|
||||
RETURN
|
||||
37
Task/ISBN13-check-digit/Ada/isbn13-check-digit.ada
Normal file
37
Task/ISBN13-check-digit/Ada/isbn13-check-digit.ada
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
with Ada.Text_IO;
|
||||
|
||||
procedure ISBN_Check is
|
||||
|
||||
function Is_Valid (ISBN : String) return Boolean is
|
||||
Odd : Boolean := True;
|
||||
Sum : Integer := 0;
|
||||
Value : Integer;
|
||||
begin
|
||||
for I in ISBN'Range loop
|
||||
if ISBN (I) in '0' .. '9' then
|
||||
Value := Character'Pos (ISBN (I)) - Character'Pos ('0');
|
||||
if Odd then
|
||||
Sum := Sum + Value;
|
||||
else
|
||||
Sum := Sum + 3 * Value;
|
||||
end if;
|
||||
Odd := not Odd;
|
||||
end if;
|
||||
end loop;
|
||||
return Sum mod 10 = 0;
|
||||
end Is_Valid;
|
||||
|
||||
procedure Show (ISBN : String) is
|
||||
use Ada.Text_IO;
|
||||
Valid : constant Boolean := Is_Valid (ISBN);
|
||||
begin
|
||||
Put (ISBN); Put (" ");
|
||||
Put ((if Valid then "Good" else "Bad"));
|
||||
New_Line;
|
||||
end Show;
|
||||
begin
|
||||
Show ("978-1734314502");
|
||||
Show ("978-1734314509");
|
||||
Show ("978-1788399081");
|
||||
Show ("978-1788399083");
|
||||
end ISBN_Check;
|
||||
|
|
@ -0,0 +1,205 @@
|
|||
-------------------- ISBN13 CHECK DIGIT --------------------
|
||||
|
||||
-- isISBN13 :: String -> Bool
|
||||
on isISBN13(s)
|
||||
script digitValue
|
||||
on |λ|(c)
|
||||
if isDigit(c) then
|
||||
{c as integer}
|
||||
else
|
||||
{}
|
||||
end if
|
||||
end |λ|
|
||||
end script
|
||||
|
||||
set digits to concatMap(digitValue, characters of s)
|
||||
|
||||
13 = length of digits ¬
|
||||
and 0 = sum(zipWith(my mul, digits, cycle({1, 3}))) mod 10
|
||||
end isISBN13
|
||||
|
||||
|
||||
--------------------------- TEST ---------------------------
|
||||
on run
|
||||
script test
|
||||
on |λ|(s)
|
||||
{s, isISBN13(s)}
|
||||
end |λ|
|
||||
end script
|
||||
|
||||
map(test, {"978-1734314502", "978-1734314509", ¬
|
||||
"978-1788399081", "978-1788399083"})
|
||||
end run
|
||||
|
||||
|
||||
-------------------- GENERIC FUNCTIONS ---------------------
|
||||
|
||||
-- concatMap :: (a -> [b]) -> [a] -> [b]
|
||||
on concatMap(f, xs)
|
||||
set lng to length of xs
|
||||
set acc to {}
|
||||
tell mReturn(f)
|
||||
repeat with i from 1 to lng
|
||||
set acc to acc & (|λ|(item i of xs, i, xs))
|
||||
end repeat
|
||||
end tell
|
||||
return acc
|
||||
end concatMap
|
||||
|
||||
|
||||
-- cycle :: [a] -> Generator [a]
|
||||
on cycle(xs)
|
||||
script
|
||||
property lng : 1 + (length of xs)
|
||||
property i : missing value
|
||||
on |λ|()
|
||||
if missing value is i then
|
||||
set i to 1
|
||||
else
|
||||
set nxt to (1 + i) mod lng
|
||||
if 0 = ((1 + i) mod lng) then
|
||||
set i to 1
|
||||
else
|
||||
set i to nxt
|
||||
end if
|
||||
end if
|
||||
return item i of xs
|
||||
end |λ|
|
||||
end script
|
||||
end cycle
|
||||
|
||||
|
||||
-- foldl :: (a -> b -> a) -> a -> [b] -> a
|
||||
on foldl(f, startValue, xs)
|
||||
tell mReturn(f)
|
||||
set v to startValue
|
||||
set lng to length of xs
|
||||
repeat with i from 1 to lng
|
||||
set v to |λ|(v, item i of xs, i, xs)
|
||||
end repeat
|
||||
return v
|
||||
end tell
|
||||
end foldl
|
||||
|
||||
|
||||
-- isDigit :: Char -> Bool
|
||||
on isDigit(c)
|
||||
set n to (id of c)
|
||||
48 ≤ n and 57 ≥ n
|
||||
end isDigit
|
||||
|
||||
|
||||
-- length :: [a] -> Int
|
||||
on |length|(xs)
|
||||
set c to class of xs
|
||||
if list is c or string is c then
|
||||
length of xs
|
||||
else
|
||||
(2 ^ 29 - 1) -- (maxInt - simple proxy for non-finite)
|
||||
end if
|
||||
end |length|
|
||||
|
||||
|
||||
-- map :: (a -> b) -> [a] -> [b]
|
||||
on map(f, xs)
|
||||
-- The list obtained by applying f
|
||||
-- to each element of xs.
|
||||
tell mReturn(f)
|
||||
set lng to length of xs
|
||||
set lst to {}
|
||||
repeat with i from 1 to lng
|
||||
set end of lst to |λ|(item i of xs, i, xs)
|
||||
end repeat
|
||||
return lst
|
||||
end tell
|
||||
end map
|
||||
|
||||
|
||||
-- min :: Ord a => a -> a -> a
|
||||
on min(x, y)
|
||||
if y < x then
|
||||
y
|
||||
else
|
||||
x
|
||||
end if
|
||||
end min
|
||||
|
||||
|
||||
-- mReturn :: First-class m => (a -> b) -> m (a -> b)
|
||||
on mReturn(f)
|
||||
-- 2nd class handler function lifted into 1st class script wrapper.
|
||||
if script is class of f then
|
||||
f
|
||||
else
|
||||
script
|
||||
property |λ| : f
|
||||
end script
|
||||
end if
|
||||
end mReturn
|
||||
|
||||
|
||||
-- mul (*) :: Num a => a -> a -> a
|
||||
on mul(a, b)
|
||||
a * b
|
||||
end mul
|
||||
|
||||
|
||||
-- sum :: [Num] -> Num
|
||||
on sum(xs)
|
||||
script add
|
||||
on |λ|(a, b)
|
||||
a + b
|
||||
end |λ|
|
||||
end script
|
||||
|
||||
foldl(add, 0, xs)
|
||||
end sum
|
||||
|
||||
|
||||
-- take :: Int -> [a] -> [a]
|
||||
-- take :: Int -> String -> String
|
||||
on take(n, xs)
|
||||
set c to class of xs
|
||||
if list is c then
|
||||
if 0 < n then
|
||||
items 1 thru min(n, length of xs) of xs
|
||||
else
|
||||
{}
|
||||
end if
|
||||
else if string is c then
|
||||
if 0 < n then
|
||||
text 1 thru min(n, length of xs) of xs
|
||||
else
|
||||
""
|
||||
end if
|
||||
else if script is c then
|
||||
set ys to {}
|
||||
repeat with i from 1 to n
|
||||
set v to |λ|() of xs
|
||||
if missing value is v then
|
||||
return ys
|
||||
else
|
||||
set end of ys to v
|
||||
end if
|
||||
end repeat
|
||||
return ys
|
||||
else
|
||||
missing value
|
||||
end if
|
||||
end take
|
||||
|
||||
|
||||
-- zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
|
||||
on zipWith(f, xs, ys)
|
||||
set lng to min(|length|(xs), |length|(ys))
|
||||
if 1 > lng then return {}
|
||||
set xs_ to take(lng, xs) -- Allow for non-finite
|
||||
set ys_ to take(lng, ys) -- generators like cycle etc
|
||||
set lst to {}
|
||||
tell mReturn(f)
|
||||
repeat with i from 1 to lng
|
||||
set end of lst to |λ|(item i of xs_, item i of ys_)
|
||||
end repeat
|
||||
return lst
|
||||
end tell
|
||||
end zipWith
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
on validateISBN13(ISBN13)
|
||||
if (ISBN13's class is not text) then return false
|
||||
|
||||
set astid to AppleScript's text item delimiters
|
||||
set AppleScript's text item delimiters to {"-", space}
|
||||
set ISBN13 to ISBN13's text items
|
||||
set AppleScript's text item delimiters to ""
|
||||
set ISBN13 to ISBN13 as text
|
||||
set AppleScript's text item delimiters to astid
|
||||
|
||||
if (((count ISBN13) is not 13) or (ISBN13 contains ".") or (ISBN13 contains ",")) then return false
|
||||
try
|
||||
ISBN13 as number
|
||||
on error
|
||||
return false
|
||||
end try
|
||||
|
||||
set sum to 0
|
||||
repeat with i from 1 to 12 by 2
|
||||
set sum to sum + (character i of ISBN13) + (character (i + 1) of ISBN13) * 3 -- Automatic text-to-number coercions.
|
||||
end repeat
|
||||
|
||||
return ((sum + (character 13 of ISBN13)) mod 10 = 0)
|
||||
end validateISBN13
|
||||
|
||||
-- Test:
|
||||
set output to {}
|
||||
set verdicts to {"bad", "good"}
|
||||
repeat with thisISBN13 in {"978-1734314502", "978-1734314509", "978-1788399081", "978-1788399083"}
|
||||
set isValid to validateISBN13(thisISBN13)
|
||||
set end of output to thisISBN13 & ": " & item ((isValid as integer) + 1) of verdicts
|
||||
end repeat
|
||||
|
||||
set astid to AppleScript's text item delimiters
|
||||
set AppleScript's text item delimiters to linefeed
|
||||
set output to output as text
|
||||
set AppleScript's text item delimiters to astid
|
||||
return output
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
on validateISBN13(ISBN13)
|
||||
if (ISBN13's class is not text) then return false
|
||||
|
||||
set astid to AppleScript's text item delimiters
|
||||
set AppleScript's text item delimiters to {"-", space}
|
||||
set ISBN13 to ISBN13's text items
|
||||
set AppleScript's text item delimiters to ""
|
||||
set ISBN13 to ISBN13 as text
|
||||
set AppleScript's text item delimiters to astid
|
||||
|
||||
if (((count ISBN13) is not 13) or (ISBN13 contains ".") or (ISBN13 contains ",")) then return false
|
||||
try
|
||||
set ISBN13 to ISBN13 as number
|
||||
on error
|
||||
return false
|
||||
end try
|
||||
|
||||
set sum to 0
|
||||
repeat 6 times
|
||||
set sum to sum + ISBN13 mod 10 + ISBN13 mod 100 div 10 * 3
|
||||
set ISBN13 to ISBN13 div 100
|
||||
end repeat
|
||||
|
||||
return ((sum + ISBN13) mod 10 = 0)
|
||||
end validateISBN13
|
||||
21
Task/ISBN13-check-digit/Arturo/isbn13-check-digit.arturo
Normal file
21
Task/ISBN13-check-digit/Arturo/isbn13-check-digit.arturo
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
validISBN?: function [isbn][
|
||||
currentCheck: to :integer to :string last isbn
|
||||
isbn: map split chop replace isbn "-" "" 'd -> to :integer d
|
||||
|
||||
s: 0
|
||||
loop.with:'i isbn 'n [
|
||||
if? even? i -> s: s + n
|
||||
else -> s: s + 3*n
|
||||
]
|
||||
checkDigit: 10 - s % 10
|
||||
return currentCheck = checkDigit
|
||||
]
|
||||
|
||||
tests: [
|
||||
"978-1734314502" "978-1734314509"
|
||||
"978-1788399081" "978-1788399083"
|
||||
]
|
||||
|
||||
loop tests 'test [
|
||||
print [test "=>" validISBN? test]
|
||||
]
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
ISBN13_check_digit(n){
|
||||
for i, v in StrSplit(RegExReplace(n, "[^0-9]"))
|
||||
sum += !Mod(i, 2) ? v*3 : v
|
||||
return n "`t" (Mod(sum, 10) ? "(bad)" : "(good)")
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
output := ""
|
||||
nums := ["978-1734314502","978-1734314509","978-1788399081","978-1788399083"]
|
||||
for i, n in nums
|
||||
output .= ISBN13_check_digit(n) "`n"
|
||||
MsgBox % output
|
||||
return
|
||||
22
Task/ISBN13-check-digit/BASIC256/isbn13-check-digit.basic
Normal file
22
Task/ISBN13-check-digit/BASIC256/isbn13-check-digit.basic
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
arraybase 1
|
||||
dim isbn = {"978-1734314502", "978-1734314509", "978-1788399081", "978-1788399083", "978-2-74839-908-0", "978-2-74839-908-5", "978 1 86197 876 9"}
|
||||
|
||||
for n = 1 to isbn[?]
|
||||
sum = 0
|
||||
isbnStr = isbn[n]
|
||||
isbnStr = replace(isbnStr, "-", "")
|
||||
isbnStr = replace(isbnStr, " ", "")
|
||||
for m = 1 to length(isbnStr)
|
||||
if m mod 2 = 0 then
|
||||
num = 3 * int(mid(isbnStr, m, 1))
|
||||
else
|
||||
num = int(mid(isbnStr, m, 1))
|
||||
end if
|
||||
sum += num
|
||||
next m
|
||||
if sum mod 10 = 0 then
|
||||
print isbn[n]; ": good"
|
||||
else
|
||||
print isbn[n]; ": bad"
|
||||
end if
|
||||
next n
|
||||
33
Task/ISBN13-check-digit/BCPL/isbn13-check-digit.bcpl
Normal file
33
Task/ISBN13-check-digit/BCPL/isbn13-check-digit.bcpl
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
get "libhdr"
|
||||
|
||||
let checkISBN(s) = valof
|
||||
$( let tally = 0
|
||||
unless s%0 = 14 resultis false
|
||||
unless s%4 = '-' resultis false
|
||||
|
||||
for i=1 to 3
|
||||
$( let digit = s%i-'0'
|
||||
test i rem 2 = 0
|
||||
do tally := tally + 3 * digit
|
||||
or tally := tally + digit
|
||||
$)
|
||||
|
||||
for i=5 to 14
|
||||
$( let digit = s%i-'0'
|
||||
test i rem 2 = 0
|
||||
do tally := tally + digit
|
||||
or tally := tally + 3 * digit
|
||||
$)
|
||||
|
||||
resultis tally rem 10 = 0
|
||||
$)
|
||||
|
||||
let show(s) be
|
||||
writef("%S: %S*N", s, checkISBN(s) -> "good", "bad")
|
||||
|
||||
let start() be
|
||||
$( show("978-1734314502")
|
||||
show("978-1734314509")
|
||||
show("978-1788399081")
|
||||
show("978-1788399083")
|
||||
$)
|
||||
36
Task/ISBN13-check-digit/C++/isbn13-check-digit.cpp
Normal file
36
Task/ISBN13-check-digit/C++/isbn13-check-digit.cpp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#include <iostream>
|
||||
|
||||
bool check_isbn13(std::string isbn) {
|
||||
int count = 0;
|
||||
int sum = 0;
|
||||
|
||||
for (auto ch : isbn) {
|
||||
/* skip hyphens or spaces */
|
||||
if (ch == ' ' || ch == '-') {
|
||||
continue;
|
||||
}
|
||||
if (ch < '0' || ch > '9') {
|
||||
return false;
|
||||
}
|
||||
if (count & 1) {
|
||||
sum += 3 * (ch - '0');
|
||||
} else {
|
||||
sum += ch - '0';
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count != 13) {
|
||||
return false;
|
||||
}
|
||||
return sum % 10 == 0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
auto isbns = { "978-1734314502", "978-1734314509", "978-1788399081", "978-1788399083" };
|
||||
for (auto isbn : isbns) {
|
||||
std::cout << isbn << ": " << (check_isbn13(isbn) ? "good" : "bad") << '\n';
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
23
Task/ISBN13-check-digit/C-sharp/isbn13-check-digit.cs
Normal file
23
Task/ISBN13-check-digit/C-sharp/isbn13-check-digit.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
|
||||
public class Program
|
||||
{
|
||||
public static void Main() {
|
||||
Console.WriteLine(CheckISBN13("978-1734314502"));
|
||||
Console.WriteLine(CheckISBN13("978-1734314509"));
|
||||
Console.WriteLine(CheckISBN13("978-1788399081"));
|
||||
Console.WriteLine(CheckISBN13("978-1788399083"));
|
||||
|
||||
static bool CheckISBN13(string code) {
|
||||
code = code.Replace("-", "").Replace(" ", "");
|
||||
if (code.Length != 13) return false;
|
||||
int sum = 0;
|
||||
foreach (var (index, digit) in code.Select((digit, index) => (index, digit))) {
|
||||
if (char.IsDigit(digit)) sum += (digit - '0') * (index % 2 == 0 ? 1 : 3);
|
||||
else return false;
|
||||
}
|
||||
return sum % 10 == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
32
Task/ISBN13-check-digit/C/isbn13-check-digit.c
Normal file
32
Task/ISBN13-check-digit/C/isbn13-check-digit.c
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int check_isbn13(const char *isbn) {
|
||||
int ch = *isbn, count = 0, sum = 0;
|
||||
/* check isbn contains 13 digits and calculate weighted sum */
|
||||
for ( ; ch != 0; ch = *++isbn, ++count) {
|
||||
/* skip hyphens or spaces */
|
||||
if (ch == ' ' || ch == '-') {
|
||||
--count;
|
||||
continue;
|
||||
}
|
||||
if (ch < '0' || ch > '9') {
|
||||
return 0;
|
||||
}
|
||||
if (count & 1) {
|
||||
sum += 3 * (ch - '0');
|
||||
} else {
|
||||
sum += ch - '0';
|
||||
}
|
||||
}
|
||||
if (count != 13) return 0;
|
||||
return !(sum%10);
|
||||
}
|
||||
|
||||
int main() {
|
||||
int i;
|
||||
const char* isbns[] = {"978-1734314502", "978-1734314509", "978-1788399081", "978-1788399083"};
|
||||
for (i = 0; i < 4; ++i) {
|
||||
printf("%s: %s\n", isbns[i], check_isbn13(isbns[i]) ? "good" : "bad");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
34
Task/ISBN13-check-digit/CLU/isbn13-check-digit.clu
Normal file
34
Task/ISBN13-check-digit/CLU/isbn13-check-digit.clu
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
isbn13_check = proc (s: string) returns (bool)
|
||||
if string$size(s) ~= 14 then return(false) end
|
||||
if s[4] ~= '-' then return(false) end
|
||||
begin
|
||||
check: int := 0
|
||||
for i: int in int$from_to(1, 14) do
|
||||
if i=4 then continue end
|
||||
d: int := int$parse(string$c2s(s[i]))
|
||||
if i=2 cor (i>4 cand i//2=1) then d := d*3 end
|
||||
check := check + d
|
||||
end
|
||||
return(check//10 = 0)
|
||||
end except when bad_format:
|
||||
return(false)
|
||||
end
|
||||
end isbn13_check
|
||||
|
||||
start_up = proc ()
|
||||
po: stream := stream$primary_output()
|
||||
tests: array[string] := array[string]$
|
||||
["978-1734314502",
|
||||
"978-1734314509",
|
||||
"978-1788399081",
|
||||
"978-1788399083"]
|
||||
|
||||
for test: string in array[string]$elements(tests) do
|
||||
stream$puts(po, test)
|
||||
stream$puts(po, ": ")
|
||||
if isbn13_check(test)
|
||||
then stream$putl(po, "good")
|
||||
else stream$putl(po, "bad")
|
||||
end
|
||||
end
|
||||
end start_up
|
||||
139
Task/ISBN13-check-digit/COBOL/isbn13-check-digit.cobol
Normal file
139
Task/ISBN13-check-digit/COBOL/isbn13-check-digit.cobol
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
******************************************************************
|
||||
* Author: Jay Moseley
|
||||
* Date: November 10, 2019
|
||||
* Purpose: Testing various subprograms/ functions.
|
||||
* Tectonics: cobc -xj testSubs.cbl
|
||||
******************************************************************
|
||||
IDENTIFICATION DIVISION.
|
||||
|
||||
PROGRAM-ID. testSubs.
|
||||
ENVIRONMENT DIVISION.
|
||||
|
||||
CONFIGURATION SECTION.
|
||||
REPOSITORY.
|
||||
FUNCTION ALL INTRINSIC
|
||||
FUNCTION validISBN13.
|
||||
|
||||
INPUT-OUTPUT SECTION.
|
||||
FILE-CONTROL.
|
||||
|
||||
DATA DIVISION.
|
||||
|
||||
FILE SECTION.
|
||||
|
||||
WORKING-STORAGE SECTION.
|
||||
|
||||
01 IX PIC S9(4) COMP.
|
||||
01 TEST-ISBNS.
|
||||
02 FILLER PIC X(14) VALUE '978-1734314502'.
|
||||
02 FILLER PIC X(14) VALUE '978-1734314509'.
|
||||
02 FILLER PIC X(14) VALUE '978-1788399081'.
|
||||
02 FILLER PIC X(14) VALUE '978-1788399083'.
|
||||
01 TEST-ISBN REDEFINES TEST-ISBNS
|
||||
OCCURS 4 TIMES
|
||||
PIC X(14).
|
||||
|
||||
PROCEDURE DIVISION.
|
||||
|
||||
MAIN-PROCEDURE.
|
||||
|
||||
PERFORM
|
||||
VARYING IX
|
||||
FROM 1
|
||||
BY 1
|
||||
UNTIL IX > 4
|
||||
|
||||
DISPLAY TEST-ISBN (IX) ' ' WITH NO ADVANCING
|
||||
END-DISPLAY
|
||||
IF validISBN13(TEST-ISBN (IX)) = -1
|
||||
DISPLAY '(bad)'
|
||||
ELSE
|
||||
DISPLAY '(good)'
|
||||
END-IF
|
||||
|
||||
END-PERFORM.
|
||||
|
||||
GOBACK.
|
||||
|
||||
END PROGRAM testSubs.
|
||||
|
||||
******************************************************************
|
||||
* Author: Jay Moseley
|
||||
* Date: May 19, 2016
|
||||
* Purpose: validate ISBN-13 (International Standard
|
||||
* Book Number).
|
||||
******************************************************************
|
||||
IDENTIFICATION DIVISION.
|
||||
|
||||
FUNCTION-ID. validISBN13.
|
||||
ENVIRONMENT DIVISION.
|
||||
|
||||
CONFIGURATION SECTION.
|
||||
REPOSITORY.
|
||||
FUNCTION ALL INTRINSIC.
|
||||
|
||||
INPUT-OUTPUT SECTION.
|
||||
FILE-CONTROL.
|
||||
|
||||
DATA DIVISION.
|
||||
|
||||
FILE SECTION.
|
||||
|
||||
WORKING-STORAGE SECTION.
|
||||
|
||||
01 PASSED-SIZE PIC S9(6) COMP-5.
|
||||
01 IX PIC S9(4) COMP.
|
||||
|
||||
01 WORK-FIELDS.
|
||||
02 WF-DIGIT PIC X.
|
||||
02 WF-COUNT PIC 9(2).
|
||||
88 WEIGHT-1 VALUE 1, 3, 5, 7, 9, 11, 13.
|
||||
88 WEIGHT-3 VALUE 2, 4, 6, 8, 10, 12.
|
||||
02 WF-SUM PIC S9(8) COMP.
|
||||
|
||||
LINKAGE SECTION.
|
||||
|
||||
01 PASSED-ISBN PIC X ANY LENGTH.
|
||||
01 RETURN-VALUE PIC S9.
|
||||
|
||||
PROCEDURE DIVISION USING PASSED-ISBN
|
||||
RETURNING RETURN-VALUE.
|
||||
|
||||
CALL 'C$PARAMSIZE'
|
||||
USING 1
|
||||
GIVING PASSED-SIZE
|
||||
END-CALL.
|
||||
|
||||
COMPUTE-CKDIGIT.
|
||||
|
||||
INITIALIZE WORK-FIELDS.
|
||||
PERFORM
|
||||
VARYING IX
|
||||
FROM 1
|
||||
BY 1
|
||||
UNTIL IX GREATER THAN PASSED-SIZE
|
||||
|
||||
MOVE PASSED-ISBN (IX:1) TO WF-DIGIT
|
||||
IF WF-DIGIT IS NUMERIC
|
||||
ADD 1 TO WF-COUNT
|
||||
IF WEIGHT-1
|
||||
ADD NUMVAL(WF-DIGIT) TO WF-SUM
|
||||
ELSE
|
||||
COMPUTE WF-SUM = WF-SUM +
|
||||
(NUMVAL(WF-DIGIT) * 3)
|
||||
END-COMPUTE
|
||||
END-IF
|
||||
END-IF
|
||||
|
||||
END-PERFORM.
|
||||
|
||||
IF MOD(WF-SUM, 10) = 0
|
||||
MOVE +0 TO RETURN-VALUE
|
||||
ELSE
|
||||
MOVE -1 TO RETURN-VALUE
|
||||
END-IF.
|
||||
|
||||
GOBACK.
|
||||
* - - - - - - - - - - - - - - - - - - - - - - PROGRAM EXIT POINT
|
||||
|
||||
END FUNCTION validISBN13.
|
||||
37
Task/ISBN13-check-digit/Cowgol/isbn13-check-digit.cowgol
Normal file
37
Task/ISBN13-check-digit/Cowgol/isbn13-check-digit.cowgol
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
include "cowgol.coh";
|
||||
|
||||
sub check_isbn13(isbn: [uint8]): (r: uint8) is
|
||||
var n: uint8 := 0;
|
||||
r := 0;
|
||||
loop
|
||||
var c := [isbn];
|
||||
isbn := @next isbn;
|
||||
if c == 0 then break; end if;
|
||||
c := c - '0';
|
||||
if c <= 9 then
|
||||
r := r + c;
|
||||
n := n + 1;
|
||||
if (n & 1) == 0 then
|
||||
r := r + c * 2;
|
||||
end if;
|
||||
end if;
|
||||
end loop;
|
||||
if n == 13 and r%10 == 0 then
|
||||
r := 1;
|
||||
else
|
||||
r := 0;
|
||||
end if;
|
||||
end sub;
|
||||
|
||||
var isbns: [uint8][] := {
|
||||
"978-1734314502", "978-1734314509", "978-1788399081", "978-1788399083"
|
||||
};
|
||||
|
||||
var result: [uint8][] := {": bad\n", ": good\n"};
|
||||
|
||||
var n: uint8 := 0;
|
||||
while n < @sizeof isbns loop
|
||||
print(isbns[n]);
|
||||
print(result[check_isbn13(isbns[n])]);
|
||||
n := n + 1;
|
||||
end loop;
|
||||
25
Task/ISBN13-check-digit/D/isbn13-check-digit.d
Normal file
25
Task/ISBN13-check-digit/D/isbn13-check-digit.d
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import std.stdio;
|
||||
|
||||
bool isValidISBN13(string text) {
|
||||
int sum, i;
|
||||
foreach (c; text) {
|
||||
if ('0' <= c && c <= '9') {
|
||||
int value = c - '0';
|
||||
if (i % 2 == 0) {
|
||||
sum += value;
|
||||
} else {
|
||||
sum += 3 * value;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return i == 13 && 0 == sum % 10;
|
||||
}
|
||||
|
||||
unittest {
|
||||
assert(isValidISBN13("978-1734314502"));
|
||||
assert(!isValidISBN13("978-1734314509"));
|
||||
assert(isValidISBN13("978-1788399081"));
|
||||
assert(!isValidISBN13("978-1788399083"));
|
||||
}
|
||||
37
Task/ISBN13-check-digit/Delphi/isbn13-check-digit.delphi
Normal file
37
Task/ISBN13-check-digit/Delphi/isbn13-check-digit.delphi
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
function ValidateISBN(ISBN: string): boolean;
|
||||
{Validate an ISBN number}
|
||||
var I,N,Sum: integer;
|
||||
begin
|
||||
Sum:=0;
|
||||
{Go througha chars, ignoring non-digits}
|
||||
for I:=1 to Length(ISBN) do
|
||||
if ISBN[I] in ['0'..'9'] then
|
||||
begin
|
||||
N:=StrToInt(ISBN[I]);
|
||||
{Every other digit multiplied by 3}
|
||||
if (I and 1)=1 then N:=N*3;
|
||||
{Sum digits}
|
||||
Sum:=Sum+N;
|
||||
end;
|
||||
{The sum must be an even multiple of 10}
|
||||
Result:=(Sum mod 10)=0;
|
||||
end;
|
||||
|
||||
procedure ValidateAndShow(Memo: TMemo; ISBN: string);
|
||||
{Validate ISBN number and show the result}
|
||||
var S: string;
|
||||
begin
|
||||
S:=ISBN;
|
||||
if ValidateISBN(ISBN) then S:=S+' (Good)'
|
||||
else S:=S+' (Bad)';
|
||||
Memo.Lines.Add(S);
|
||||
end;
|
||||
|
||||
procedure TestISBNSet(Memo: TMemo);
|
||||
{Test supplied set of ISBN numbers}
|
||||
begin
|
||||
ValidateAndShow(Memo,'978-0596528126'); //(good)
|
||||
ValidateAndShow(Memo,'978-0596528120'); //(bad)
|
||||
ValidateAndShow(Memo,'978-1788399081'); //(good)
|
||||
ValidateAndShow(Memo,'978-1788399083'); //(bad)
|
||||
end;
|
||||
39
Task/ISBN13-check-digit/Draco/isbn13-check-digit.draco
Normal file
39
Task/ISBN13-check-digit/Draco/isbn13-check-digit.draco
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
proc nonrec isbn13_check(*char isbn) bool:
|
||||
byte n, check, d;
|
||||
char cur;
|
||||
bool ok;
|
||||
n := 0;
|
||||
check := 0;
|
||||
ok := true;
|
||||
while
|
||||
cur := isbn*;
|
||||
isbn := isbn + 1;
|
||||
ok and cur ~= '\e'
|
||||
do
|
||||
if n=3 then
|
||||
if cur ~= '-' then ok := false fi
|
||||
elif cur<'0' or cur>'9' then
|
||||
ok := false
|
||||
else
|
||||
d := cur - '0';
|
||||
if n=1 or (n>3 and n&1 = 0) then
|
||||
d := d * 3;
|
||||
fi;
|
||||
check := check + d
|
||||
fi;
|
||||
n := n + 1
|
||||
od;
|
||||
ok and n = 14 and check%10 = 0
|
||||
corp
|
||||
|
||||
proc nonrec test(*char isbn) void:
|
||||
writeln(isbn, ": ",
|
||||
if isbn13_check(isbn) then "good" else "bad" fi)
|
||||
corp
|
||||
|
||||
proc nonrec main() void:
|
||||
test("978-1734314502");
|
||||
test("978-1734314509");
|
||||
test("978-1788399081");
|
||||
test("978-1788399083")
|
||||
corp
|
||||
27
Task/ISBN13-check-digit/EasyLang/isbn13-check-digit.easy
Normal file
27
Task/ISBN13-check-digit/EasyLang/isbn13-check-digit.easy
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
proc ISBN13check ISBN$ . valid .
|
||||
for i = 1 to len ISBN$
|
||||
currentChar$ = substr ISBN$ i 1
|
||||
if currentChar$ <> "-"
|
||||
digitCounter += 1
|
||||
.
|
||||
currentDigit = number currentChar$
|
||||
if digitCounter mod 2 = 0
|
||||
currentDigit *= 3
|
||||
.
|
||||
sum += currentDigit
|
||||
.
|
||||
if sum mod 10 = 0
|
||||
valid = 1
|
||||
else
|
||||
valid = 0
|
||||
.
|
||||
.
|
||||
ISBNcodes$[] = [ "978-0596528126" "978-0596528120" "978-1788399081" "978-1788399083" ]
|
||||
for ISBN$ in ISBNcodes$[]
|
||||
call ISBN13check ISBN$ valid
|
||||
if valid = 1
|
||||
print ISBN$ & " is a valid ISBN"
|
||||
else
|
||||
print ISBN$ & " is not a valid ISBN"
|
||||
.
|
||||
.
|
||||
26
Task/ISBN13-check-digit/Excel/isbn13-check-digit-1.excel
Normal file
26
Task/ISBN13-check-digit/Excel/isbn13-check-digit-1.excel
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
ISBN13Check
|
||||
=LAMBDA(s,
|
||||
LET(
|
||||
ns, FILTERP(
|
||||
LAMBDA(v,
|
||||
NOT(ISERROR(v))
|
||||
)
|
||||
)(
|
||||
VALUE(CHARSROW(s))
|
||||
),
|
||||
ixs, SEQUENCE(
|
||||
1, COLUMNS(ns),
|
||||
1, 1
|
||||
),
|
||||
|
||||
0 = MOD(
|
||||
SUM(
|
||||
IF(0 <> MOD(ixs, 2),
|
||||
INDEX(ns, ixs),
|
||||
3 * INDEX(ns, ixs)
|
||||
)
|
||||
),
|
||||
10
|
||||
)
|
||||
)
|
||||
)
|
||||
25
Task/ISBN13-check-digit/Excel/isbn13-check-digit-2.excel
Normal file
25
Task/ISBN13-check-digit/Excel/isbn13-check-digit-2.excel
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
CHARSROW
|
||||
=LAMBDA(s,
|
||||
MID(s,
|
||||
SEQUENCE(1, LEN(s), 1, 1),
|
||||
1
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
FILTERP
|
||||
=LAMBDA(p,
|
||||
LAMBDA(xs,
|
||||
FILTER(xs, p(xs))
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
ISDIGIT
|
||||
=LAMBDA(c,
|
||||
LET(
|
||||
ic, CODE(c),
|
||||
|
||||
AND(47 < ic, 58 > ic)
|
||||
)
|
||||
)
|
||||
19
Task/ISBN13-check-digit/F-Sharp/isbn13-check-digit.fs
Normal file
19
Task/ISBN13-check-digit/F-Sharp/isbn13-check-digit.fs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// ISBN13 Check Digit
|
||||
open System
|
||||
|
||||
let parseInput (input: string) =
|
||||
Seq.map(fun c -> c |> string) input |> Seq.toList |> List.map(fun x -> Int32.Parse x)
|
||||
|
||||
[<EntryPoint>]
|
||||
let main argv =
|
||||
let isbnnum = parseInput (String.filter (fun x -> x <> '-') argv.[0])
|
||||
// Multiply every other digit by 3
|
||||
let everyOther = List.mapi (fun i x -> if i % 2 = 0 then x * 3 else x) isbnnum
|
||||
// Sum the *3 list with the original list
|
||||
let sum = List.sum everyOther + List.sum isbnnum
|
||||
// If the remainder of sum / 10 is 0 then it's a valid ISBN13
|
||||
if sum % 10 = 0 then
|
||||
printfn "%s Valid ISBN13" argv.[0]
|
||||
else
|
||||
printfn "%s Invalid ISBN13" argv.[0]
|
||||
0
|
||||
14
Task/ISBN13-check-digit/Factor/isbn13-check-digit.factor
Normal file
14
Task/ISBN13-check-digit/Factor/isbn13-check-digit.factor
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
USING: combinators.short-circuit formatting kernel math
|
||||
math.functions math.parser math.vectors qw sequences
|
||||
sequences.extras sets unicode ;
|
||||
|
||||
: (isbn13?) ( str -- ? )
|
||||
string>digits
|
||||
[ <evens> sum ] [ <odds> 3 v*n sum + ] bi 10 divisor? ;
|
||||
|
||||
: isbn13? ( str -- ? )
|
||||
"- " without
|
||||
{ [ length 13 = ] [ [ digit? ] all? ] [ (isbn13?) ] } 1&& ;
|
||||
|
||||
qw{ 978-1734314502 978-1734314509 978-1788399081 978-1788399083 }
|
||||
[ dup isbn13? "good" "bad" ? "%s: %s\n" printf ] each
|
||||
8
Task/ISBN13-check-digit/Forth/isbn13-check-digit.fth
Normal file
8
Task/ISBN13-check-digit/Forth/isbn13-check-digit.fth
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
: is-digit [char] 0 - 10 u< ;
|
||||
|
||||
: isbn? ( a n -- f)
|
||||
1- chars over + 2>r 0 1 2r> ?do
|
||||
dup i c@ dup is-digit \ get length and factor, setup loop
|
||||
if [char] 0 - * rot + swap 3 * 8 mod else drop drop then
|
||||
-1 chars +loop drop 10 mod 0= \ now calculate checksum
|
||||
;
|
||||
36
Task/ISBN13-check-digit/Fortran/isbn13-check-digit.f
Normal file
36
Task/ISBN13-check-digit/Fortran/isbn13-check-digit.f
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
program isbn13
|
||||
implicit none
|
||||
|
||||
character(len=14), dimension(4), parameter :: isbns=["978-1734314502", "978-1734314509", "978-1788399081", "978-1788399083"]
|
||||
integer :: i
|
||||
|
||||
do i = 1, ubound(isbns, 1)
|
||||
if (check_isbn13(isbns(i))) then
|
||||
print*, isbns(i), " : ", "good"
|
||||
else
|
||||
print*, isbns(i), " : ", "bad"
|
||||
end if
|
||||
end do
|
||||
contains
|
||||
pure function check_isbn13(isbn)
|
||||
character(len=*), intent(in) :: isbn
|
||||
logical :: check_isbn13
|
||||
integer :: summ, counter, i, digit
|
||||
|
||||
check_isbn13 = .false.
|
||||
counter = 0
|
||||
summ = 0
|
||||
|
||||
do i = 1, len(isbn)
|
||||
if (isbn(i:i) == ' ' .or. isbn(i:i) == '-') cycle
|
||||
counter = counter + 1
|
||||
read(isbn(i:i), '(I1)') digit
|
||||
if (modulo(counter, 2) == 0) then
|
||||
summ = summ + 3*digit
|
||||
else
|
||||
summ = summ + digit
|
||||
end if
|
||||
end do
|
||||
if (counter == 13 .and. modulo(summ, 10) == 0) check_isbn13 = .true.
|
||||
end function check_isbn13
|
||||
end program isbn13
|
||||
37
Task/ISBN13-check-digit/FreeBASIC/isbn13-check-digit.basic
Normal file
37
Task/ISBN13-check-digit/FreeBASIC/isbn13-check-digit.basic
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#define ZEROC asc("0")
|
||||
|
||||
function is_num( byval c as string ) as boolean
|
||||
if asc(c) >= ZEROC andalso asc(c)<ZEROC+10 then return true
|
||||
return false
|
||||
end function
|
||||
|
||||
function is_good_isbn( isbn as string ) as boolean
|
||||
dim as uinteger charno = 0, digitno = 0, sum = 0
|
||||
dim as string*1 currchar
|
||||
while charno <= len(isbn)
|
||||
currchar = mid(isbn,charno,1)
|
||||
if is_num(currchar) then
|
||||
if digitno mod 2 = 1 then
|
||||
sum += 2*(asc(currchar)-ZEROC)
|
||||
end if
|
||||
sum += asc(currchar)-ZEROC
|
||||
digitno += 1
|
||||
end if
|
||||
charno += 1
|
||||
wend
|
||||
if sum mod 10 = 0 then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end if
|
||||
end function
|
||||
|
||||
dim as string isbns(0 to 3) = { "978-1734314502", "978-1734314509", "978-1788399081", "978-1788399083" }
|
||||
dim as uinteger i
|
||||
for i = 0 to 3
|
||||
if is_good_isbn( isbns(i) ) then
|
||||
print isbns(i)+": good"
|
||||
else
|
||||
print isbns(i)+": bad"
|
||||
end if
|
||||
next i
|
||||
25
Task/ISBN13-check-digit/Gambas/isbn13-check-digit.gambas
Normal file
25
Task/ISBN13-check-digit/Gambas/isbn13-check-digit.gambas
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
Public Sub Main()
|
||||
|
||||
Dim isbn As String[] = ["978-1734314502", "978-1734314509", "978-1788399081", "978-1788399083", "978-2-74839-908-0", "978-2-74839-908-5", "978 1 86197 876 9"]
|
||||
|
||||
For n As Integer = 1 To isbn.Count
|
||||
Dim sum As Integer = 0, num As Integer
|
||||
Dim isbnStr As String = isbn[n]
|
||||
isbnStr = Replace(isbnStr, "-", "")
|
||||
isbnStr = Replace(isbnStr, " ", "")
|
||||
For m As Integer = 1 To Len(isbnStr)
|
||||
If m Mod 2 = 0 Then
|
||||
num = 3 * CInt(Mid(isbnStr, m, 1))
|
||||
Else
|
||||
num = CInt(Mid(isbnStr, m, 1))
|
||||
End If
|
||||
sum += num
|
||||
Next
|
||||
If sum Mod 10 = 0 Then
|
||||
Print isbn[n]; ": good"
|
||||
Else
|
||||
Print isbn[n]; ": bad"
|
||||
End If
|
||||
Next
|
||||
|
||||
End
|
||||
41
Task/ISBN13-check-digit/Go/isbn13-check-digit.go
Normal file
41
Task/ISBN13-check-digit/Go/isbn13-check-digit.go
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
func checkIsbn13(isbn string) bool {
|
||||
// remove any hyphens or spaces
|
||||
isbn = strings.ReplaceAll(strings.ReplaceAll(isbn, "-", ""), " ", "")
|
||||
// check length == 13
|
||||
le := utf8.RuneCountInString(isbn)
|
||||
if le != 13 {
|
||||
return false
|
||||
}
|
||||
// check only contains digits and calculate weighted sum
|
||||
sum := int32(0)
|
||||
for i, c := range isbn {
|
||||
if c < '0' || c > '9' {
|
||||
return false
|
||||
}
|
||||
if i%2 == 0 {
|
||||
sum += c - '0'
|
||||
} else {
|
||||
sum += 3 * (c - '0')
|
||||
}
|
||||
}
|
||||
return sum%10 == 0
|
||||
}
|
||||
|
||||
func main() {
|
||||
isbns := []string{"978-1734314502", "978-1734314509", "978-1788399081", "978-1788399083"}
|
||||
for _, isbn := range isbns {
|
||||
res := "bad"
|
||||
if checkIsbn13(isbn) {
|
||||
res = "good"
|
||||
}
|
||||
fmt.Printf("%s: %s\n", isbn, res)
|
||||
}
|
||||
}
|
||||
28
Task/ISBN13-check-digit/Haskell/isbn13-check-digit-1.hs
Normal file
28
Task/ISBN13-check-digit/Haskell/isbn13-check-digit-1.hs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import Data.Char (digitToInt, isDigit)
|
||||
import Text.Printf (printf)
|
||||
|
||||
pair :: Num a => [a] -> [(a, a)]
|
||||
pair [] = []
|
||||
pair xs = p (take 2 xs) : pair (drop 2 xs)
|
||||
where
|
||||
p ps = case ps of
|
||||
(x : y : zs) -> (x, y)
|
||||
(x : zs) -> (x, 0)
|
||||
|
||||
validIsbn13 :: String -> Bool
|
||||
validIsbn13 isbn
|
||||
| length (digits isbn) /= 13 = False
|
||||
| otherwise = calc isbn `rem` 10 == 0
|
||||
where
|
||||
digits = map digitToInt . filter isDigit
|
||||
calc = sum . map (\(x, y) -> x + y * 3) . pair . digits
|
||||
|
||||
main :: IO ()
|
||||
main =
|
||||
mapM_
|
||||
(printf "%s: Valid: %s\n" <*> (show . validIsbn13))
|
||||
[ "978-1734314502",
|
||||
"978-1734314509",
|
||||
"978-1788399081",
|
||||
"978-1788399083"
|
||||
]
|
||||
20
Task/ISBN13-check-digit/Haskell/isbn13-check-digit-2.hs
Normal file
20
Task/ISBN13-check-digit/Haskell/isbn13-check-digit-2.hs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import Data.Char (digitToInt, isDigit)
|
||||
|
||||
isISBN13 :: String -> Bool
|
||||
isISBN13 =
|
||||
(0 ==)
|
||||
. flip rem 10
|
||||
. sum
|
||||
. flip
|
||||
(zipWith ((*) . digitToInt) . filter isDigit)
|
||||
(cycle [1, 3])
|
||||
|
||||
main :: IO ()
|
||||
main =
|
||||
mapM_
|
||||
(print . ((,) <*> isISBN13))
|
||||
[ "978-1734314502",
|
||||
"978-1734314509",
|
||||
"978-1788399081",
|
||||
"978-1788399083"
|
||||
]
|
||||
26
Task/ISBN13-check-digit/IS-BASIC/isbn13-check-digit.basic
Normal file
26
Task/ISBN13-check-digit/IS-BASIC/isbn13-check-digit.basic
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
100 PROGRAM "ISBN13.bas"
|
||||
110 DO
|
||||
120 PRINT :INPUT PROMPT "ISBN-13 code: ":IS$
|
||||
130 IF IS$="" THEN EXIT DO
|
||||
140 IF ISBN(IS$) THEN
|
||||
150 PRINT "Ok."
|
||||
160 ELSE
|
||||
170 PRINT "CRC error."
|
||||
180 END IF
|
||||
190 LOOP
|
||||
200 DEF TRIM$(S$)
|
||||
210 LET T$=""
|
||||
220 FOR I=1 TO LEN(S$)
|
||||
230 IF S$(I)>CHR$(47) AND S$(I)<CHR$(58) THEN LET T$=T$&S$(I)
|
||||
240 NEXT
|
||||
250 LET TRIM$=T$
|
||||
260 END DEF
|
||||
270 DEF ISBN(S$)
|
||||
280 LET SUM,ISBN=0:LET ISBN$=TRIM$(IS$)
|
||||
290 IF LEN(ISBN$)<>13 THEN PRINT "Invalid length.":EXIT DEF
|
||||
300 FOR I=1 TO 11 STEP 2
|
||||
310 LET SUM=SUM+VAL(ISBN$(I))+VAL(ISBN$(I+1))*3
|
||||
320 NEXT
|
||||
330 LET SUM=SUM+VAL(ISBN$(13))
|
||||
340 IF MOD(SUM,10)=0 THEN LET ISBN=-1
|
||||
350 END DEF
|
||||
7
Task/ISBN13-check-digit/J/isbn13-check-digit-1.j
Normal file
7
Task/ISBN13-check-digit/J/isbn13-check-digit-1.j
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
D =: '0123456789'
|
||||
|
||||
isbn13c =: D&([ check@:i. clean)
|
||||
check =: 0 = 10 | lc
|
||||
lc =: [ +/@:* weight
|
||||
weight =: 1 3 $~ #
|
||||
clean =: ] -. a. -. [
|
||||
2
Task/ISBN13-check-digit/J/isbn13-check-digit-2.j
Normal file
2
Task/ISBN13-check-digit/J/isbn13-check-digit-2.j
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
isbn13c;._1 ' 978-1734314502 978-1734314509 978-1788399081 978-1788399083'
|
||||
1 0 1 0
|
||||
38
Task/ISBN13-check-digit/Java/isbn13-check-digit-1.java
Normal file
38
Task/ISBN13-check-digit/Java/isbn13-check-digit-1.java
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
public static void main(String[] args) {
|
||||
String[] isbn13s = {
|
||||
"978-0596528126",
|
||||
"978-0596528120",
|
||||
"978-1788399081",
|
||||
"978-1788399083"
|
||||
};
|
||||
for (String isbn13 : isbn13s)
|
||||
System.out.printf("%s %b%n", isbn13, validateISBN13(isbn13));
|
||||
}
|
||||
|
||||
static boolean validateISBN13(String string) {
|
||||
int[] digits = digits(string.strip().replace("-", ""));
|
||||
return digits[12] == checksum(digits);
|
||||
}
|
||||
|
||||
static int[] digits(String string) {
|
||||
int[] digits = new int[13];
|
||||
int index = 0;
|
||||
for (char character : string.toCharArray()) {
|
||||
if (character < '0' || character > '9')
|
||||
throw new IllegalArgumentException("Invalid ISBN-13");
|
||||
/* convert ascii to integer */
|
||||
digits[index++] = Character.digit(character, 10);
|
||||
}
|
||||
return digits;
|
||||
}
|
||||
|
||||
static int checksum(int[] digits) {
|
||||
int total = 0;
|
||||
int index = 0;
|
||||
for (int digit : digits) {
|
||||
if (index == 12) break;
|
||||
if (index++ % 2 == 1) digit *= 3;
|
||||
total += digit;
|
||||
}
|
||||
return 10 - (total % 10);
|
||||
}
|
||||
18
Task/ISBN13-check-digit/Java/isbn13-check-digit-2.java
Normal file
18
Task/ISBN13-check-digit/Java/isbn13-check-digit-2.java
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
public static void main(){
|
||||
System.out.println(isISBN13("978-1734314502"));
|
||||
System.out.println(isISBN13("978-1734314509"));
|
||||
System.out.println(isISBN13("978-1788399081"));
|
||||
System.out.println(isISBN13("978-1788399083"));
|
||||
}
|
||||
public static boolean isISBN13(String in){
|
||||
int pre = Integer.parseInt(in.substring(0,3));
|
||||
if (pre!=978)return false;
|
||||
String postStr = in.substring(4);
|
||||
if (postStr.length()!=10)return false;
|
||||
int post = Integer.parseInt(postStr);
|
||||
int sum = 38;
|
||||
for(int x = 0; x<10;x+=2)
|
||||
sum += (postStr.charAt(x)-48)*3 + ((postStr.charAt(x+1)-48));
|
||||
if(sum%10==0) return true;
|
||||
return false;
|
||||
}
|
||||
15
Task/ISBN13-check-digit/Jq/isbn13-check-digit.jq
Normal file
15
Task/ISBN13-check-digit/Jq/isbn13-check-digit.jq
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
def isbn_check:
|
||||
def digits: tostring | explode | map( select(. >= 48 and . <= 57) | [.] | implode | tonumber);
|
||||
def sum(s): reduce s as $x (null; . + $x);
|
||||
digits
|
||||
| . as $digits
|
||||
| sum(range(0;length;2) | $digits[.]) as $one
|
||||
| (3 * sum(range(1;length;2) | $digits[.])) as $two
|
||||
| (($one+$two) % 10) == 0;
|
||||
|
||||
def testingcodes:
|
||||
["978-1734314502", "978-1734314509",
|
||||
"978-1788399081", "978-1788399083"];
|
||||
|
||||
testingcodes[]
|
||||
| "\(.): \(if isbn_check then "good" else "bad" end)"
|
||||
11
Task/ISBN13-check-digit/Julia/isbn13-check-digit.julia
Normal file
11
Task/ISBN13-check-digit/Julia/isbn13-check-digit.julia
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
function isbncheck(str)
|
||||
return sum(iseven(i) ? 3 * parse(Int, ch) : parse(Int, ch)
|
||||
for (i, ch) in enumerate(replace(str, r"\D" => ""))) % 10 == 0
|
||||
end
|
||||
|
||||
const testingcodes = ["978-1734314502", "978-1734314509",
|
||||
"978-1788399081", "978-1788399083"]
|
||||
|
||||
for code in testingcodes
|
||||
println(code, ": ", isbncheck(code) ? "good" : "bad")
|
||||
end
|
||||
11
Task/ISBN13-check-digit/K/isbn13-check-digit.k
Normal file
11
Task/ISBN13-check-digit/K/isbn13-check-digit.k
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
digits: {x[&(x>"/")&x<":"]-"0"}
|
||||
isbn13c: 0=10!+/{x*(#x)#1 3} digits@
|
||||
|
||||
isbn13c "978-0596528126"
|
||||
1
|
||||
isbn13c "978-0596528120"
|
||||
0
|
||||
isbn13c " 978-1788399081"
|
||||
1
|
||||
isbn13c "978-1788399083"
|
||||
0
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
fun isValidISBN13(text: String): Boolean {
|
||||
val isbn = text.replace(Regex("[- ]"), "")
|
||||
return isbn.length == 13 && isbn.map { it - '0' }
|
||||
.mapIndexed { index, value -> when (index % 2) { 0 -> value else -> 3 * value } }
|
||||
.sum() % 10 == 0
|
||||
}
|
||||
16
Task/ISBN13-check-digit/Kotlin/isbn13-check-digit-2.kotlin
Normal file
16
Task/ISBN13-check-digit/Kotlin/isbn13-check-digit-2.kotlin
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
describe("ISBN Utilities") {
|
||||
mapOf(
|
||||
"978-1734314502" to true,
|
||||
"978-1734314509" to false,
|
||||
"978-1788399081" to true,
|
||||
"978-1788399083" to false
|
||||
).forEach { (input, expected) ->
|
||||
it("returns $expected for $input") {
|
||||
println("$input: ${when(isValidISBN13(input)) {
|
||||
true -> "good"
|
||||
else -> "bad"
|
||||
}}")
|
||||
assert(isValidISBN13(input) == expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
18
Task/ISBN13-check-digit/Langur/isbn13-check-digit-1.langur
Normal file
18
Task/ISBN13-check-digit/Langur/isbn13-check-digit-1.langur
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
val .isbn13checkdigit = f(var .s) {
|
||||
.s = replace(.s, RE/[\- ]/)
|
||||
matching(re/^[0-9]{13}$/, .s) and
|
||||
fold(f{+}, map [_, f{x 3}], s2n .s) div 10
|
||||
}
|
||||
|
||||
val .tests = h{
|
||||
"978-0596528126": true,
|
||||
"978-0596528120": false,
|
||||
"978-1788399081": true,
|
||||
"978-1788399083": false,
|
||||
}
|
||||
|
||||
for .key of .tests {
|
||||
val .pass = .isbn13checkdigit(.key)
|
||||
write .key, ": ", if(.pass: "good"; "bad")
|
||||
writeln if(.pass == .tests[.key]: ""; " (ISBN-13 CHECK DIGIT TEST FAILED)")
|
||||
}
|
||||
19
Task/ISBN13-check-digit/Langur/isbn13-check-digit-2.langur
Normal file
19
Task/ISBN13-check-digit/Langur/isbn13-check-digit-2.langur
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
val .isbn13checkdigit = f(var .s) {
|
||||
.s = replace(.s, RE/[\- ]/)
|
||||
var .alt = true
|
||||
matching(re/^[0-9]{13}$/, .s) and
|
||||
for[=0] .d in s2n(.s) { _for += if(not= .alt: .d x 3; .d) } div 10
|
||||
}
|
||||
|
||||
val .tests = h{
|
||||
"978-0596528126": true,
|
||||
"978-0596528120": false,
|
||||
"978-1788399081": true,
|
||||
"978-1788399083": false,
|
||||
}
|
||||
|
||||
for .key of .tests {
|
||||
val .pass = .isbn13checkdigit(.key)
|
||||
write .key, ": ", if(.pass: "good"; "bad")
|
||||
writeln if(.pass == .tests[.key]: ""; " (ISBN-13 CHECK DIGIT TEST FAILED)")
|
||||
}
|
||||
41
Task/ISBN13-check-digit/Lua/isbn13-check-digit.lua
Normal file
41
Task/ISBN13-check-digit/Lua/isbn13-check-digit.lua
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
function checkIsbn13(isbn)
|
||||
local count = 0
|
||||
local sum = 0
|
||||
for c in isbn:gmatch"." do
|
||||
if c == ' ' or c == '-' then
|
||||
-- skip
|
||||
elseif c < '0' or '9' < c then
|
||||
return false
|
||||
else
|
||||
local digit = c - '0'
|
||||
if (count % 2) > 0 then
|
||||
sum = sum + 3 * digit
|
||||
else
|
||||
sum = sum + digit
|
||||
end
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
|
||||
if count ~= 13 then
|
||||
return false
|
||||
end
|
||||
return (sum % 10) == 0
|
||||
end
|
||||
|
||||
function test(isbn)
|
||||
if checkIsbn13(isbn) then
|
||||
print(isbn .. ": good")
|
||||
else
|
||||
print(isbn .. ": bad")
|
||||
end
|
||||
end
|
||||
|
||||
function main()
|
||||
test("978-1734314502")
|
||||
test("978-1734314509")
|
||||
test("978-1788399081")
|
||||
test("978-1788399083")
|
||||
end
|
||||
|
||||
main()
|
||||
15
Task/ISBN13-check-digit/Mathematica/isbn13-check-digit.math
Normal file
15
Task/ISBN13-check-digit/Mathematica/isbn13-check-digit.math
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
ClearAll[ValidISBNQ]
|
||||
ValidISBNQ[iban_String] := Module[{i},
|
||||
i = StringReplace[iban, {" " -> "", "-" -> ""}];
|
||||
If[StringMatchQ[i, Repeated[DigitCharacter]],
|
||||
i = ToExpression /@ Characters[i];
|
||||
i[[2 ;; ;; 2]] *= 3;
|
||||
Mod[Total[i], 10] == 0
|
||||
,
|
||||
False
|
||||
]
|
||||
]
|
||||
ValidISBNQ["978-1734314502"]
|
||||
ValidISBNQ["978-1734314509"]
|
||||
ValidISBNQ["978-1788399081"]
|
||||
ValidISBNQ["978-1788399083"]
|
||||
44
Task/ISBN13-check-digit/Modula-2/isbn13-check-digit.mod2
Normal file
44
Task/ISBN13-check-digit/Modula-2/isbn13-check-digit.mod2
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
MODULE ISBN;
|
||||
FROM InOut IMPORT WriteString, WriteLn;
|
||||
FROM Strings IMPORT Length;
|
||||
|
||||
PROCEDURE validISBN(s: ARRAY OF CHAR): BOOLEAN;
|
||||
VAR total, i, length: CARDINAL;
|
||||
BEGIN
|
||||
total := 0;
|
||||
length := Length(s);
|
||||
IF (length # 14) OR (s[3] # '-') THEN
|
||||
RETURN FALSE;
|
||||
END;
|
||||
FOR i := 0 TO length-1 DO
|
||||
IF i # 3 THEN
|
||||
IF (s[i] < '0') OR (s[i] > '9') THEN
|
||||
RETURN FALSE;
|
||||
ELSIF (i < 3) AND (i MOD 2 = 1) OR (i > 3) AND (i MOD 2 = 0) THEN
|
||||
total := total + 3 * (ORD(s[i]) - ORD('0'));
|
||||
ELSE
|
||||
total := total + ORD(s[i]) - ORD('0');
|
||||
END;
|
||||
END;
|
||||
END;
|
||||
RETURN total MOD 10 = 0;
|
||||
END validISBN;
|
||||
|
||||
PROCEDURE check(s: ARRAY OF CHAR);
|
||||
BEGIN
|
||||
WriteString(s);
|
||||
WriteString(': ');
|
||||
IF validISBN(s) THEN
|
||||
WriteString('good');
|
||||
ELSE
|
||||
WriteString('bad');
|
||||
END;
|
||||
WriteLn;
|
||||
END check;
|
||||
|
||||
BEGIN
|
||||
check('978-1734314502');
|
||||
check('978-1734314509');
|
||||
check('978-1788399081');
|
||||
check('978-1788399083');
|
||||
END ISBN.
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
def checkIsbn13(isbn)
|
||||
// remove any hyphens or spaces
|
||||
isbn = str(isbn).replace("-","").replace(" ","")
|
||||
|
||||
// check length = 13
|
||||
if len(isbn) != 13
|
||||
return false
|
||||
end
|
||||
|
||||
// check only contains digits and calculate weighted sum
|
||||
sum = 0
|
||||
for i in range(0, len(isbn) - 1)
|
||||
c = isbn[i]
|
||||
if (ord(c) < ord("0")) or (ord(c) > ord("9"))
|
||||
return false
|
||||
end
|
||||
|
||||
if (i % 2) = 0
|
||||
sum += ord(c) - ord("0")
|
||||
else
|
||||
sum += 3 * (ord(c) - ord("0"))
|
||||
end
|
||||
end
|
||||
|
||||
return (sum % 10) = 0
|
||||
end
|
||||
|
||||
isbns = {"978-1734314502", "978-1734314509", "978-1788399081", "978-1788399083"}
|
||||
for isbn in isbns
|
||||
res = "bad"
|
||||
if checkIsbn13(isbn)
|
||||
res = "good"
|
||||
end
|
||||
|
||||
print format("%s: %s\n", isbn, res)
|
||||
end
|
||||
18
Task/ISBN13-check-digit/Nim/isbn13-check-digit.nim
Normal file
18
Task/ISBN13-check-digit/Nim/isbn13-check-digit.nim
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import strutils, strformat
|
||||
|
||||
func is_isbn*(s: string): bool =
|
||||
var sum, len: int
|
||||
for c in s:
|
||||
if is_digit(c):
|
||||
sum += (ord(c) - ord('0')) * (if len mod 2 == 0: 1 else: 3)
|
||||
len += 1
|
||||
elif c != ' ' and c != '-':
|
||||
return false
|
||||
return (len == 13) and (sum mod 10 == 0)
|
||||
|
||||
when is_main_module:
|
||||
let isbns = [ "978-1734314502", "978-1734314509",
|
||||
"978-1788399081", "978-1788399083" ]
|
||||
for isbn in isbns:
|
||||
var quality: string = if is_isbn(isbn): "good" else: "bad"
|
||||
echo &"{isbn}: {quality}"
|
||||
53
Task/ISBN13-check-digit/PL-M/isbn13-check-digit.plm
Normal file
53
Task/ISBN13-check-digit/PL-M/isbn13-check-digit.plm
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
100H:
|
||||
|
||||
CHECK$ISBN13: PROCEDURE (PTR) BYTE;
|
||||
DECLARE PTR ADDRESS, ISBN BASED PTR BYTE;
|
||||
DECLARE (I, F, T) BYTE;
|
||||
F = 1;
|
||||
T = 0;
|
||||
DO I = 0 TO 13;
|
||||
IF I = 3 THEN DO;
|
||||
/* THIRD CHAR SHOULD BE '-' */
|
||||
IF ISBN(I) <> '-' THEN RETURN 0;
|
||||
END;
|
||||
ELSE DO;
|
||||
/* DIGITS MUST BE VALID */
|
||||
IF ISBN(I) < '0' OR ISBN(I) > '9' THEN RETURN 0;
|
||||
T = T + (ISBN(I) - '0') * F;
|
||||
F = 4 - F; /* MULTIPLY BY 1 AND 3 ALTERNATELY */
|
||||
END;
|
||||
END;
|
||||
RETURN (T MOD 10) = 0;
|
||||
END CHECK$ISBN13;
|
||||
|
||||
/* CP/M BDOS CALL */
|
||||
BDOS: PROCEDURE (FUNC, ARG);
|
||||
DECLARE FUNC BYTE, ARG ADDRESS;
|
||||
GO TO 5;
|
||||
END BDOS;
|
||||
|
||||
PRINT: PROCEDURE (STR);
|
||||
DECLARE STR ADDRESS;
|
||||
CALL BDOS(9, STR);
|
||||
END PRINT;
|
||||
|
||||
/* TESTS */
|
||||
DECLARE TEST (4) ADDRESS;
|
||||
TEST(0) = .'978-1734314502$';
|
||||
TEST(1) = .'978-1734314509$';
|
||||
TEST(2) = .'978-1788399081$';
|
||||
TEST(3) = .'978-1788399083$';
|
||||
|
||||
DECLARE I BYTE;
|
||||
DO I = 0 TO LAST(TEST);
|
||||
CALL PRINT(TEST(I));
|
||||
CALL PRINT(.': $');
|
||||
IF CHECK$ISBN13(TEST(I)) THEN
|
||||
CALL PRINT(.'GOOD$');
|
||||
ELSE
|
||||
CALL PRINT(.'BAD$');
|
||||
CALL PRINT(.(13,10,'$'));
|
||||
END;
|
||||
|
||||
CALL BDOS(0,0);
|
||||
EOF
|
||||
85
Task/ISBN13-check-digit/Pascal/isbn13-check-digit.pas
Normal file
85
Task/ISBN13-check-digit/Pascal/isbn13-check-digit.pas
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
program ISBNChecksum(output);
|
||||
|
||||
const
|
||||
codeIndexMaximum = 17;
|
||||
ISBNIndexMinimum = 1;
|
||||
ISBNIndexMaximum = 13;
|
||||
ISBNIndexRange = ISBNIndexMaximum - ISBNIndexMinimum + 1;
|
||||
|
||||
type
|
||||
code = string(codeIndexMaximum);
|
||||
codeIndex = 1..codeIndexMaximum value 1;
|
||||
decimalDigit = '0'..'9';
|
||||
decimalValue = 0..9;
|
||||
ISBNIndex = ISBNIndexMinimum..ISBNIndexMaximum;
|
||||
ISBN = array[ISBNIndex] of decimalDigit;
|
||||
|
||||
{ returns the integer value represented by a character }
|
||||
function numericValue(protected c: decimalDigit): decimalValue;
|
||||
begin
|
||||
{ in Pascal result variable bears the same name as the function }
|
||||
numericValue := ord(c) - ord('0')
|
||||
end;
|
||||
|
||||
{ determines whether an ISBN is technically valid (checksum correct) }
|
||||
function isValidISBN(protected n: ISBN): Boolean;
|
||||
var
|
||||
sum: 0..225 value 0;
|
||||
i: ISBNIndex;
|
||||
begin
|
||||
{ NB: in Pascal for-loop-limits are _inclusive_ }
|
||||
for i := ISBNIndexMinimum to ISBNIndexMaximum do
|
||||
begin
|
||||
{ alternating scale factor 3^0, 3^1 based on Boolean }
|
||||
sum := sum + numericValue(n[i]) * 3 pow ord(not odd(i))
|
||||
end;
|
||||
|
||||
isValidISBN := sum mod 10 = 0
|
||||
end;
|
||||
|
||||
{ transform '978-0-387-97649-5' into '9780387976495' }
|
||||
function digits(n: code): code;
|
||||
var
|
||||
sourceIndex, destinationIndex: codeIndex;
|
||||
begin
|
||||
for sourceIndex := 1 to length(n) do
|
||||
begin
|
||||
if n[sourceIndex] in ['0'..'9'] then
|
||||
begin
|
||||
n[destinationIndex] := n[sourceIndex];
|
||||
destinationIndex := destinationIndex + 1
|
||||
end
|
||||
end;
|
||||
|
||||
{ to alter a string’s length you need overwrite it completely }
|
||||
digits := subStr(n, 1, destinationIndex - 1)
|
||||
end;
|
||||
|
||||
{ data type coercion }
|
||||
function asISBN(protected n: code): ISBN;
|
||||
var
|
||||
result: ISBN;
|
||||
begin
|
||||
unpack(n[1..length(n)], result, 1);
|
||||
asISBN := result
|
||||
end;
|
||||
|
||||
{ tells whether a string value contains a proper ISBN representation }
|
||||
function isValidISBNString(protected hyphenatedForm: code): Boolean;
|
||||
var
|
||||
digitOnlyForm: code;
|
||||
begin
|
||||
digitOnlyForm := digits(hyphenatedForm);
|
||||
{ The Extended Pascal `and_then` Boolean operator allows us }
|
||||
{ to first check the length before invoking `isValidISBN`. }
|
||||
isValidISBNString := (length(digitOnlyForm) = ISBNIndexRange)
|
||||
and_then isValidISBN(asISBN(digitOnlyForm))
|
||||
end;
|
||||
|
||||
{ === MAIN ============================================================= }
|
||||
begin
|
||||
writeLn(isValidISBNString('978-1734314502'));
|
||||
writeLn(isValidISBNString('978-1734314509'));
|
||||
writeLn(isValidISBNString('978-1788399081'));
|
||||
writeLn(isValidISBNString('978-1788399083'))
|
||||
end.
|
||||
15
Task/ISBN13-check-digit/Perl/isbn13-check-digit.pl
Normal file
15
Task/ISBN13-check-digit/Perl/isbn13-check-digit.pl
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
use strict;
|
||||
use warnings;
|
||||
use feature 'say';
|
||||
|
||||
sub check_digit {
|
||||
my($isbn) = @_; my($sum);
|
||||
$sum += (1,3)[$_%2] * (split '', join '', split /\D/, $isbn)[$_] for 0..11;
|
||||
(10 - $sum % 10) % 10;
|
||||
}
|
||||
|
||||
for (<978-1734314502 978-1734314509 978-1788399081 978-1788399083 978-2-74839-908-0 978-2-74839-908-5>) {
|
||||
my($isbn,$check) = /(.*)(.)/;
|
||||
my $check_d = check_digit($isbn);
|
||||
say "$_ : " . ($check == $check_d ? 'Good' : "Bad check-digit $check; should be $check_d")
|
||||
}
|
||||
23
Task/ISBN13-check-digit/Phix/isbn13-check-digit.phix
Normal file
23
Task/ISBN13-check-digit/Phix/isbn13-check-digit.phix
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">check_isbn13</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">isbn</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">digits</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">checksum</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">w</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">isbn</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">isbn</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">!=</span><span style="color: #008000;">' '</span> <span style="color: #008080;">and</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">!=</span><span style="color: #008000;">'-'</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">ch</span> <span style="color: #0000FF;">-=</span> <span style="color: #008000;">'0'</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;"><</span><span style="color: #000000;">0</span> <span style="color: #008080;">or</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">></span><span style="color: #000000;">9</span> <span style="color: #008080;">then</span> <span style="color: #000000;">checksum</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">9</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #000000;">checksum</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">*</span><span style="color: #000000;">w</span>
|
||||
<span style="color: #000000;">digits</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #000000;">w</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">-</span><span style="color: #000000;">w</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #000000;">checksum</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">checksum</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">gb</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">digits</span><span style="color: #0000FF;">=</span><span style="color: #000000;">13</span> <span style="color: #008080;">and</span> <span style="color: #000000;">checksum</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #0000FF;">?</span> <span style="color: #008000;">"good"</span> <span style="color: #0000FF;">:</span> <span style="color: #008000;">"bad"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">isbn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">gb</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
|
||||
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">isbns</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"978-1734314502"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"978-1734314509"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"978-1788399081"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"978-1788399083"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #008000;">"978-2-74839-908-0"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"978-2-74839-908-5"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"978 1 86197 876 9"</span><span style="color: #0000FF;">}</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">isbns</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> <span style="color: #000000;">check_isbn13</span><span style="color: #0000FF;">(</span><span style="color: #000000;">isbns</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<!--
|
||||
20
Task/ISBN13-check-digit/PicoLisp/isbn13-check-digit.l
Normal file
20
Task/ISBN13-check-digit/PicoLisp/isbn13-check-digit.l
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
(de isbn13? (S)
|
||||
(let L
|
||||
(make
|
||||
(for N (chop S)
|
||||
(and (format N) (link @)) ) )
|
||||
(and
|
||||
(= 13 (length L))
|
||||
(=0 (% (sum * L (circ 1 3)) 10)) ) ) )
|
||||
(mapc
|
||||
'((A)
|
||||
(tab
|
||||
(-19 1)
|
||||
A
|
||||
(if (isbn13? A) 'ok 'fail) ) )
|
||||
(quote
|
||||
"978-1734314502"
|
||||
"978-1734314509"
|
||||
"978-1-86197-876-9"
|
||||
"978-2-74839-908-5"
|
||||
"978 1 86197 876 9" ) )
|
||||
38
Task/ISBN13-check-digit/PowerShell/isbn13-check-digit.psh
Normal file
38
Task/ISBN13-check-digit/PowerShell/isbn13-check-digit.psh
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
function Get-ISBN13 {
|
||||
$codes = (
|
||||
"978-1734314502",
|
||||
"978-1734314509",
|
||||
"978-1788399081",
|
||||
"978-1788399083"
|
||||
)
|
||||
|
||||
foreach ($line in $codes) {
|
||||
|
||||
$sum = $null
|
||||
$codeNoDash = $line.Replace("-","")
|
||||
|
||||
for ($i = 0; $i -lt $codeNoDash.length; $i++) {
|
||||
|
||||
if (($i % 2) -eq 1) {
|
||||
|
||||
$sum += [decimal]$codeNoDash[$i] * 3
|
||||
|
||||
}else {
|
||||
|
||||
$sum += [decimal]$codeNoDash[$i]
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (($sum % 10) -eq 0) {
|
||||
|
||||
Write-Host "$line Good"
|
||||
|
||||
}else {
|
||||
|
||||
Write-Host "$line Bad"
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Get-ISBN13
|
||||
21
Task/ISBN13-check-digit/PureBasic/isbn13-check-digit.basic
Normal file
21
Task/ISBN13-check-digit/PureBasic/isbn13-check-digit.basic
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
Macro TestISBN13(X)
|
||||
Print(X)
|
||||
If IsISBN13(X) : PrintN(" good") : Else : PrintN(" bad") : EndIf
|
||||
EndMacro
|
||||
|
||||
Procedure.b IsISBN13(ISBN13.s)
|
||||
ISBN13=Left(ISBN13,3)+Mid(ISBN13,5)
|
||||
If IsNAN(Val(ISBN13)) Or Len(ISBN13)<>13 : ProcedureReturn #False : EndIf
|
||||
Dim ISBN.s{1}(12) : PokeS(@ISBN(),ISBN13)
|
||||
For i=0 To 11 Step 2 : sum+Val(ISBN(i))+Val(ISBN(i+1))*3 : Next
|
||||
sum+Val(ISBN(12))
|
||||
ProcedureReturn Bool(sum%10=0)
|
||||
EndProcedure
|
||||
|
||||
If OpenConsole()
|
||||
TestISBN13("978-1734314502")
|
||||
TestISBN13("978-1734314509")
|
||||
TestISBN13("978-1788399081")
|
||||
TestISBN13("978-1788399083")
|
||||
Input()
|
||||
EndIf
|
||||
16
Task/ISBN13-check-digit/Python/isbn13-check-digit-1.py
Normal file
16
Task/ISBN13-check-digit/Python/isbn13-check-digit-1.py
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
def is_isbn13(n):
|
||||
n = n.replace('-','').replace(' ', '')
|
||||
if len(n) != 13:
|
||||
return False
|
||||
product = (sum(int(ch) for ch in n[::2])
|
||||
+ sum(int(ch) * 3 for ch in n[1::2]))
|
||||
return product % 10 == 0
|
||||
|
||||
if __name__ == '__main__':
|
||||
tests = '''
|
||||
978-1734314502
|
||||
978-1734314509
|
||||
978-1788399081
|
||||
978-1788399083'''.strip().split()
|
||||
for t in tests:
|
||||
print(f"ISBN13 {t} validates {is_isbn13(t)}")
|
||||
41
Task/ISBN13-check-digit/Python/isbn13-check-digit-2.py
Normal file
41
Task/ISBN13-check-digit/Python/isbn13-check-digit-2.py
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
'''ISBN13 check digit'''
|
||||
|
||||
|
||||
from itertools import cycle
|
||||
|
||||
|
||||
# isISBN13 :: String -> Bool
|
||||
def isISBN13(s):
|
||||
'''True if s is a valid ISBN13 string
|
||||
'''
|
||||
digits = [int(c) for c in s if c.isdigit()]
|
||||
return 13 == len(digits) and (
|
||||
0 == sum(map(
|
||||
lambda f, x: f(x),
|
||||
cycle([
|
||||
lambda x: x,
|
||||
lambda x: 3 * x
|
||||
]),
|
||||
digits
|
||||
)) % 10
|
||||
)
|
||||
|
||||
|
||||
# ------------------------- TEST -------------------------
|
||||
# main :: IO ()
|
||||
def main():
|
||||
'''Test strings for ISBN-13 validity.'''
|
||||
|
||||
print('\n'.join(
|
||||
repr((s, isISBN13(s))) for s
|
||||
in ["978-1734314502",
|
||||
"978-1734314509",
|
||||
"978-1788399081",
|
||||
"978-1788399083"
|
||||
]
|
||||
))
|
||||
|
||||
|
||||
# MAIN ---
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
32
Task/ISBN13-check-digit/Quackery/isbn13-check-digit.quackery
Normal file
32
Task/ISBN13-check-digit/Quackery/isbn13-check-digit.quackery
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
[ char 0 char 9 1+ within ] is digit? ( c --> b )
|
||||
|
||||
[ 1 & ] is odd? ( n --> b )
|
||||
|
||||
[ [] swap ]'[ swap
|
||||
witheach [
|
||||
dup nested
|
||||
unrot over do
|
||||
iff [ dip join ]
|
||||
else nip
|
||||
] drop ] is filter ( [ --> [ )
|
||||
|
||||
[ 0 swap
|
||||
witheach [
|
||||
char->n i^ odd?
|
||||
iff [ 3 * + ]
|
||||
else +
|
||||
] ] is checksum ( $ --> n )
|
||||
|
||||
[ filter digit?
|
||||
dup size 13 = not
|
||||
iff [ drop false ] done
|
||||
checksum 10 mod 0 = ] is isbn ( $ --> b )
|
||||
|
||||
[ dup echo$ say ": " isbn
|
||||
iff [ say "Good" ]
|
||||
else [ say "Bad" ] cr ] is isbn-test ( $ --> )
|
||||
|
||||
$ '978-1734314502' isbn-test
|
||||
$ '978-1734314509' isbn-test
|
||||
$ '978-1788399081' isbn-test
|
||||
$ '978-1788399083' isbn-test
|
||||
19
Task/ISBN13-check-digit/REXX/isbn13-check-digit.rexx
Normal file
19
Task/ISBN13-check-digit/REXX/isbn13-check-digit.rexx
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*REXX pgm validates the check digit of an ISBN─13 code (it may have embedded minuses).*/
|
||||
parse arg $ /*obtain optional arguments from the CL*/
|
||||
if $='' | if $="," then $= '978-1734314502 978-1734314509 978-1788399081 978-1788399083'
|
||||
@ISBN= "ISBN─13 code isn't" /*a literal used when displaying msgs. */
|
||||
/* [↓] remove all minuses from X code.*/
|
||||
do j=1 for words($); y= word($,j) /*obtain an ISBN─13 code from $ list.*/
|
||||
x= space( translate(y, , '-'), 0) /*remove all minus signs from the code.*/
|
||||
L= length(x) /*obtain the length of the ISBN-13 code*/
|
||||
if L \== 13 then do; say @ISBN '13 characters: ' x; exit 13; end
|
||||
if verify(x, 9876543210)\==0 then do; say @ISBN 'numeric: ' x; exit 10; end
|
||||
sum= 0
|
||||
do k=1 for L; #= substr(x, k, 1) /*get a decimal digit from the X code. */
|
||||
if \(k//2) then #= # * 3 /*multiply every other digit by three. */
|
||||
sum= sum + # /*add the digit (or product) to the SUM*/
|
||||
end /*k*/
|
||||
|
||||
if right(sum, 1)==0 then say ' ISBN-13 code ' x " is valid."
|
||||
else say ' ISBN-13 code ' x " isn't valid."
|
||||
end /*j*/ /*stick a fork in it, we're all done. */
|
||||
15
Task/ISBN13-check-digit/Racket/isbn13-check-digit.rkt
Normal file
15
Task/ISBN13-check-digit/Racket/isbn13-check-digit.rkt
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#lang racket/base
|
||||
|
||||
(define (isbn13-check-digit-valid? s)
|
||||
(zero? (modulo (for/sum ((i (in-naturals))
|
||||
(d (regexp-replace* #px"[^[:digit:]]" s "")))
|
||||
(* (- (char->integer d) (char->integer #\0))
|
||||
(if (even? i) 1 3)))
|
||||
10)))
|
||||
|
||||
(module+ test
|
||||
(require rackunit)
|
||||
(check-true (isbn13-check-digit-valid? "978-1734314502"))
|
||||
(check-false (isbn13-check-digit-valid? "978-1734314509"))
|
||||
(check-true (isbn13-check-digit-valid? "978-1788399081"))
|
||||
(check-false (isbn13-check-digit-valid? "978-1788399083")))
|
||||
18
Task/ISBN13-check-digit/Raku/isbn13-check-digit.raku
Normal file
18
Task/ISBN13-check-digit/Raku/isbn13-check-digit.raku
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
sub check-digit ($isbn) {
|
||||
(10 - (sum (|$isbn.comb(/<[0..9]>/)) »*» (1,3)) % 10).substr: *-1
|
||||
}
|
||||
|
||||
{
|
||||
my $check = .substr(*-1);
|
||||
my $check-digit = check-digit .chop;
|
||||
say "$_ : ", $check == $check-digit ??
|
||||
'Good' !!
|
||||
"Bad check-digit $check; should be $check-digit"
|
||||
} for words <
|
||||
978-1734314502
|
||||
978-1734314509
|
||||
978-1788399081
|
||||
978-1788399083
|
||||
978-2-74839-908-0
|
||||
978-2-74839-908-5
|
||||
>;
|
||||
23
Task/ISBN13-check-digit/Red/isbn13-check-digit.red
Normal file
23
Task/ISBN13-check-digit/Red/isbn13-check-digit.red
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
check_valid_isbn13: function [str] [
|
||||
is_digit: charset [#"0" - #"9"]
|
||||
remove-each i str [not pick is_digit i] ; remove non-digits
|
||||
|
||||
either 13 = length? str [ ; reject strings of incorrect length
|
||||
sum: 0
|
||||
repeat i 13 [
|
||||
mul: either even? i [3] [1] ; multiplier for odd/even digits
|
||||
sum: sum + (mul * to integer! to string! pick str i)
|
||||
]
|
||||
|
||||
zero? (sum % 10) ; check if remainder mod 10 is zero
|
||||
] [
|
||||
false
|
||||
]
|
||||
]
|
||||
|
||||
; check given examples
|
||||
foreach [str] ["978-1734314502" "978-1734314509" "978-1788399081" "978-1788399083"] [
|
||||
prin str
|
||||
prin " - "
|
||||
print check_valid_isbn13 str
|
||||
]
|
||||
24
Task/ISBN13-check-digit/Ring/isbn13-check-digit.ring
Normal file
24
Task/ISBN13-check-digit/Ring/isbn13-check-digit.ring
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
load "stdlib.ring"
|
||||
|
||||
isbn = ["978-1734314502","978-1734314509", "978-1788399081", "978-1788399083","978-2-74839-908-0","978-2-74839-908-5","978 1 86197 876 9"]
|
||||
|
||||
for n = 1 to len(isbn)
|
||||
sum = 0
|
||||
isbnStr = isbn[n]
|
||||
isbnStr = substr(isbnStr,"-","")
|
||||
isbnStr = substr(isbnStr," ","")
|
||||
for m = 1 to len(isbnStr)
|
||||
if m%2 = 0
|
||||
num = 3*number(substr(isbnStr,m,1))
|
||||
sum = sum + num
|
||||
else
|
||||
num = number(substr(isbnStr,m,1))
|
||||
sum = sum + num
|
||||
ok
|
||||
next
|
||||
if sum%10 = 0
|
||||
see "" + isbn[n] + ": true" + nl
|
||||
else
|
||||
see "" + isbn[n] + ": bad" + nl
|
||||
ok
|
||||
next
|
||||
8
Task/ISBN13-check-digit/Ruby/isbn13-check-digit.rb
Normal file
8
Task/ISBN13-check-digit/Ruby/isbn13-check-digit.rb
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
def validISBN13?(str)
|
||||
cleaned = str.delete("^0-9").chars
|
||||
return false unless cleaned.size == 13
|
||||
cleaned.each_slice(2).sum{|d1, d2| d1.to_i + 3*d2.to_i }.remainder(10) == 0
|
||||
end
|
||||
|
||||
isbns = ["978-1734314502", "978-1734314509", "978-1788399081", "978-1788399083"]
|
||||
isbns.each{|isbn| puts "#{isbn}: #{validISBN13?(isbn)}" }
|
||||
14
Task/ISBN13-check-digit/Rust/isbn13-check-digit.rust
Normal file
14
Task/ISBN13-check-digit/Rust/isbn13-check-digit.rust
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
fn main() {
|
||||
let isbns = ["978-1734314502", "978-1734314509", "978-1788399081", "978-1788399083"];
|
||||
isbns.iter().for_each(|isbn| println!("{}: {}", isbn, check_isbn(isbn)));
|
||||
}
|
||||
|
||||
fn check_isbn(isbn: &str) -> bool {
|
||||
if isbn.chars().filter(|c| c.is_digit(10)).count() != 13 {
|
||||
return false;
|
||||
}
|
||||
let checksum = isbn.chars().filter_map(|c| c.to_digit(10))
|
||||
.zip([1, 3].iter().cycle())
|
||||
.fold(0, |acc, (val, fac)| acc + val * fac);
|
||||
checksum % 10 == 0
|
||||
}
|
||||
34
Task/ISBN13-check-digit/Seed7/isbn13-check-digit.seed7
Normal file
34
Task/ISBN13-check-digit/Seed7/isbn13-check-digit.seed7
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
$ include "seed7_05.s7i";
|
||||
|
||||
const func boolean: isISBN13 (in var string: input) is func
|
||||
result
|
||||
var boolean: isbn is FALSE;
|
||||
local
|
||||
var char: c is ' ';
|
||||
var integer: digit is 0;
|
||||
var integer: i is 1;
|
||||
var integer: sum is 0;
|
||||
begin
|
||||
input := replace(input, " ", "");
|
||||
input := replace(input, "-", "");
|
||||
if length(input) = 13 then
|
||||
for c range input do
|
||||
digit := ord(c) - 48;
|
||||
if not odd(i) then
|
||||
digit *:= 3;
|
||||
end if;
|
||||
sum +:= digit;
|
||||
incr(i);
|
||||
end for;
|
||||
isbn := sum rem 10 = 0;
|
||||
end if;
|
||||
end func;
|
||||
|
||||
const proc: main is func
|
||||
local
|
||||
var string: str is "";
|
||||
begin
|
||||
for str range [] ("978-1734314502", "978-1734314509", "978-1788399081", "978-1788399083") do
|
||||
writeln(str <& ": " <& isISBN13(str));
|
||||
end for;
|
||||
end func;
|
||||
15
Task/ISBN13-check-digit/Standard-ML/isbn13-check-digit.ml
Normal file
15
Task/ISBN13-check-digit/Standard-ML/isbn13-check-digit.ml
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
local
|
||||
fun check (c, p as (m, n)) =
|
||||
if Char.isDigit c then
|
||||
(not m, (if m then 3 * (ord c - 48) else ord c - 48) + n)
|
||||
else
|
||||
p
|
||||
in
|
||||
fun checkISBN s =
|
||||
Int.rem (#2 (CharVector.foldl check (false, 0) s), 10) = 0
|
||||
end
|
||||
|
||||
val test = ["978-1734314502", "978-1734314509", "978-1788399081", "978-1788399083"]
|
||||
val () = (print
|
||||
o concat
|
||||
o map (fn s => s ^ (if checkISBN s then ": good\n" else ": bad\n"))) test
|
||||
24
Task/ISBN13-check-digit/Swift/isbn13-check-digit.swift
Normal file
24
Task/ISBN13-check-digit/Swift/isbn13-check-digit.swift
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
func checkISBN(isbn: String) -> Bool {
|
||||
guard !isbn.isEmpty else {
|
||||
return false
|
||||
}
|
||||
|
||||
let sum = isbn
|
||||
.compactMap({ $0.wholeNumberValue })
|
||||
.enumerated()
|
||||
.map({ $0.offset & 1 == 1 ? 3 * $0.element : $0.element })
|
||||
.reduce(0, +)
|
||||
|
||||
return sum % 10 == 0
|
||||
}
|
||||
|
||||
let cases = [
|
||||
"978-1734314502",
|
||||
"978-1734314509",
|
||||
"978-1788399081",
|
||||
"978-1788399083"
|
||||
]
|
||||
|
||||
for isbn in cases {
|
||||
print("\(isbn) => \(checkISBN(isbn: isbn) ? "good" : "bad")")
|
||||
}
|
||||
19
Task/ISBN13-check-digit/Tcl/isbn13-check-digit-1.tcl
Normal file
19
Task/ISBN13-check-digit/Tcl/isbn13-check-digit-1.tcl
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
proc validISBN13 code {
|
||||
regsub -all {\D} $code "" code ;# remove non-digits
|
||||
if {[string length $code] == 13} {
|
||||
set sum 0
|
||||
set fac 1
|
||||
foreach digit [split $code ""] {
|
||||
set sum [expr {$sum + $digit * $fac}]
|
||||
set fac [expr {$fac == 1? 3: 1}]
|
||||
}
|
||||
if {$sum % 10 == 0} {return true}
|
||||
}
|
||||
return false
|
||||
}
|
||||
foreach test {
|
||||
978-1734314502
|
||||
978-1734314509
|
||||
978-1788399081
|
||||
978-1788399083
|
||||
} {puts $test:[validISBN13 $test]}
|
||||
12
Task/ISBN13-check-digit/Tcl/isbn13-check-digit-2.tcl
Normal file
12
Task/ISBN13-check-digit/Tcl/isbn13-check-digit-2.tcl
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
proc validISBN13 code {
|
||||
regsub -all {\D} $code "" code ;# remove non-digits
|
||||
if {[string length $code] == 13} {
|
||||
set sum 0
|
||||
foreach {d1 d2} [split $code ""] {
|
||||
if {$d2 eq ""} {set d2 0} ;# last round
|
||||
set sum [expr {$sum + $d1 + $d2 * 3}]
|
||||
}
|
||||
if {$sum % 10 == 0} {return true}
|
||||
}
|
||||
return false
|
||||
}
|
||||
18
Task/ISBN13-check-digit/UNIX-Shell/isbn13-check-digit.sh
Normal file
18
Task/ISBN13-check-digit/UNIX-Shell/isbn13-check-digit.sh
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
check_isbn13 () {
|
||||
local i n t
|
||||
n=${1//[^0-9]/}
|
||||
t=0
|
||||
for ((i=0; i<${#n}; ++i )); do
|
||||
(( t += ${n:i:1}*(1 + ((i&1)<<1)) ))
|
||||
done
|
||||
(( 0 == t % 10 ))
|
||||
}
|
||||
|
||||
for isbn in 978-1734314502 978-1734314509 978-1788399081 978-1788399083; do
|
||||
printf '%s: ' "$isbn"
|
||||
if check_isbn13 "$isbn"; then
|
||||
printf '%s\n' OK
|
||||
else
|
||||
printf '%s\n' 'NOT OK'
|
||||
fi
|
||||
done
|
||||
33
Task/ISBN13-check-digit/V-(Vlang)/isbn13-check-digit.v
Normal file
33
Task/ISBN13-check-digit/V-(Vlang)/isbn13-check-digit.v
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
fn check_isbn13(isbn13 string) bool {
|
||||
// remove any hyphens or spaces
|
||||
isbn := isbn13.replace('-','').replace(' ','')
|
||||
// check length == 13
|
||||
le := isbn.len
|
||||
if le != 13 {
|
||||
return false
|
||||
}
|
||||
// check only contains digits and calculate weighted sum
|
||||
mut sum := 0
|
||||
for i, c in isbn.split('') {
|
||||
if c.int() < '0'.int() || c.int() > '9'.int() {
|
||||
return false
|
||||
}
|
||||
if i%2 == 0 {
|
||||
sum += c.int() - '0'.int()
|
||||
} else {
|
||||
sum += 3 * (c.int() - '0'.int())
|
||||
}
|
||||
}
|
||||
return sum%10 == 0
|
||||
}
|
||||
|
||||
fn main() {
|
||||
isbns := ["978-1734314502", "978-1734314509", "978-1788399081", "978-1788399083"]
|
||||
for isbn in isbns {
|
||||
mut res := "bad"
|
||||
if check_isbn13(isbn) {
|
||||
res = "good"
|
||||
}
|
||||
println("$isbn: $res")
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
Module Module1
|
||||
|
||||
Function CheckISBN13(code As String) As Boolean
|
||||
code = code.Replace("-", "").Replace(" ", "")
|
||||
If code.Length <> 13 Then
|
||||
Return False
|
||||
End If
|
||||
Dim sum = 0
|
||||
For Each i_d In code.Select(Function(digit, index) (index, digit))
|
||||
Dim index = i_d.index
|
||||
Dim digit = i_d.digit
|
||||
If Char.IsDigit(digit) Then
|
||||
sum += (Asc(digit) - Asc("0")) * If(index Mod 2 = 0, 1, 3)
|
||||
Else
|
||||
Return False
|
||||
End If
|
||||
Next
|
||||
Return sum Mod 10 = 0
|
||||
End Function
|
||||
|
||||
Sub Main()
|
||||
Console.WriteLine(CheckISBN13("978-1734314502"))
|
||||
Console.WriteLine(CheckISBN13("978-1734314509"))
|
||||
Console.WriteLine(CheckISBN13("978-1788399081"))
|
||||
Console.WriteLine(CheckISBN13("978-1788399083"))
|
||||
End Sub
|
||||
|
||||
End Module
|
||||
21
Task/ISBN13-check-digit/Wren/isbn13-check-digit.wren
Normal file
21
Task/ISBN13-check-digit/Wren/isbn13-check-digit.wren
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
var isbn13 = Fn.new { |s|
|
||||
var cps = s.codePoints
|
||||
var digits = []
|
||||
// extract digits
|
||||
for (i in 0...cps.count) {
|
||||
var c = cps[i]
|
||||
if (c >= 48 && c <= 57) digits.add(c)
|
||||
}
|
||||
// do calcs
|
||||
var sum = 0
|
||||
for (i in 0...digits.count) {
|
||||
var d = digits[i] - 48
|
||||
sum = sum + ((i%2 == 0) ? d : 3 * d)
|
||||
}
|
||||
return sum % 10 == 0
|
||||
}
|
||||
|
||||
var tests = ["978-1734314502", "978-1734314509", "978-1788399081", "978-1788399083"]
|
||||
for (test in tests) {
|
||||
System.print("%(test) -> %(isbn13.call(test) ? "good" : "bad")")
|
||||
}
|
||||
27
Task/ISBN13-check-digit/XPL0/isbn13-check-digit.xpl0
Normal file
27
Task/ISBN13-check-digit/XPL0/isbn13-check-digit.xpl0
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
include xpllib; \contains StrLen function
|
||||
|
||||
proc ISBN13(Str); \Show if International Standard Book Number is good
|
||||
char Str;
|
||||
int Sum, Cnt, Dig, I;
|
||||
[Sum:= 0; Cnt:= 0;
|
||||
for I:= 0 to StrLen(Str)-1 do
|
||||
[Dig:= Str(I) - ^0;
|
||||
if Dig>=0 & Dig<=9 then
|
||||
[Sum:= Sum + Dig;
|
||||
Cnt:= Cnt + 1;
|
||||
if (Cnt&1) = 0 then
|
||||
Sum:= Sum + Dig + Dig;
|
||||
];
|
||||
];
|
||||
Text(0, Str);
|
||||
Text(0, if rem(Sum/10)=0 & Cnt=13 then ": good" else ": bad");
|
||||
CrLf(0);
|
||||
];
|
||||
|
||||
[ISBN13("978-1734314502");
|
||||
ISBN13("978-1734314509");
|
||||
ISBN13("978-1788399081");
|
||||
ISBN13("978-1788399083");
|
||||
ISBN13("978-1-59327-220-3");
|
||||
ISBN13("978-178839918");
|
||||
]
|
||||
5
Task/ISBN13-check-digit/Zkl/isbn13-check-digit-1.zkl
Normal file
5
Task/ISBN13-check-digit/Zkl/isbn13-check-digit-1.zkl
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
fcn ISBN13_check(isbn){ // "978-1734314502", throws on invalid digits
|
||||
var [const] one3=("13"*6 + 1).split("").apply("toInt"); // examine 13 digits
|
||||
// one3=("13"*6) if you want to calculate what the check digit should be
|
||||
one3.zipWith('*,isbn - " -").sum(0) % 10 == 0
|
||||
}
|
||||
11
Task/ISBN13-check-digit/Zkl/isbn13-check-digit-2.zkl
Normal file
11
Task/ISBN13-check-digit/Zkl/isbn13-check-digit-2.zkl
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
isbns:=
|
||||
#<<<"
|
||||
978-1734314502
|
||||
978-1734314509
|
||||
978-1788399081
|
||||
978-1788399083
|
||||
978-2-74839-908-0
|
||||
978-2-74839-908-5".split("\n");
|
||||
#<<<
|
||||
foreach isbn in (isbns)
|
||||
{ println(isbn.strip()," ",ISBN13_check(isbn) and " Good" or " Bad") }
|
||||
Loading…
Add table
Add a link
Reference in a new issue