1. Exercism task - ISBN verifier

Is there a better/faster way of doing this?

include std/sequence.e 
include std/math.e 
 
public function is_valid(sequence isbn) 
    isbn = filter(isbn, "out", "-") 
    if length(isbn) != 10 then 
        return 0 
    end if 
     
    for i = 1 to 9 do 
        if not find(isbn[i],"0123456789") then 
            return 0 
        end if 
    end for 
     
    if not find(isbn[10],"0123456789X") then 
        return 0 
    end if 
     
    for i = 1 to 9 do 
        isbn[i] = isbn[i] - '0' 
    end for 
    if isbn[10] = 'X' then 
        isbn[10] = 10 
    else 
        isbn[10] = isbn[10] - '0' 
    end if 
     
    integer answer = 0 
    for i = 0 to 9 do 
        answer = answer + (10 - i) * isbn[i + 1] 
    end for 
    return mod(answer,11) = 0 
end function 

-Bruce

new topic     » topic index » view message » categorize

2. Re: Exercism task - ISBN verifier

This works for me, though you would have to replace the "for .. in" constructs

function is_valid(string isbn)  
    integer m = 10, res = 0 
    for c in isbn do 
        if c>='0' and c<='9' then 
            res += m*(c-'0') 
            m -= 1 
        elsif c='X' and m=1 then 
            res += 10 
            m -= 1 
        elsif c!='-' then 
            return false 
        end if 
    end for 
    return m=0 and mod(res,11)=0  
end function  
 
constant tests = {{"3-598-21508-8",  true, "valid isbn"}, 
                  {"3-598-21508-9", false, "invalid isbn check digit"}, 
                  {"3-598-21507-X",  true, "valid isbn with a check digit of 10"}, 
                  {"3-598-21507-A", false, "check digit is a character other than X"}, 
                  {"4-598-21507-B", false, "invalid check digit in isbn is not treated as zero"}, 
                  {"3-598-P1581-X", false, "invalid character in isbn is not treated as zero"}, 
                  {"3-598-2X507-9", false, "X is only valid as a check digit"}, 
                  {"3598215088",     true, "valid isbn without separating dashes"}, 
                  {"359821507X",     true, "isbn without separating dashes and X as check digit"}, 
                  {"359821507",     false, "isbn without check digit and dashes"}, 
                  {"3598215078X",   false, "too long isbn and no dashes"}, 
                  {"00",            false, "too short isbn"}, 
                  {"3-598-21507",   false, "isbn without check digit"}, 
                  {"3-598-21515-X", false, "check digit of X should not be used for 0"}, 
                  {"",              false, "empty isbn"}, 
                  {"134456729",     false, "input is 9 characters"}, 
                  {"3132P34035",    false, "invalid characters are not ignored after checking length"}, 
                  -- Catch invalid characters in an otherwise valid isbn: 
                  {"3598P215088",   false, "invalid characters are not ignored before checking length"}, 
                  {"98245726788",   false, "input is too long but contains a valid isbn"}} 
 
for t in tests do 
    assert(is_valid(t[1])=t[2],t[3]) 
end for 
new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu