1. Requesting submissions for Exercism track

I've cooked up examples for the hamming, isogram, leap and raindrops tasks as defined in my copy of the Task descriptions. I don't expect you to write the full folder tree for a task, just the public function. Whatever you submit should pass all the tests. If it doesn't, I'll let you know. And if you are going to write the tests, they must follow those in each task's canonical-data.json file. Code can be left here or emailed to bruceax at gmail dot com.

As a for instance, Greg gave me the following for the isogram task:

include std/sequence.e  
include std/sort.e  
include std/text.e  
  
public function isogram( sequence str )  
    str = filter( str, STDFLTR_ALPHA )  
    str = sort( upper(str) )  
    for i = 2 to length( str ) do  
        if str[i] = str[i-1] then  
            return 0  
        end if  
    end for  
  
    return 1  
end function 

It made my first attempt look very pedestrian.

I need at least 20 working tasks before I can launch the track. After that there are documentation requirements and a CI workflow. But let's get the tasks going first.

At this point I'm not taking on Phix. I'll mention it in the documentation but that's as far as I'm prepared to take it at this point. Suitably motivated Phix users could create a Phix track. I'd be happy to help with that, just not lead it.

Finally, the code I've written thus far is on github. Bouquets and brickbats are appreciated.

-Bruce

new topic     » topic index » view message » categorize

2. Re: Requesting submissions for Exercism track

"This application will be able to read your private email addresses."

That's the first thing I see when I go to sign up for exercism. It's also the last thing. Not interested in them reading anything on my computer.

new topic     » goto parent     » topic index » view message » categorize

3. Re: Requesting submissions for Exercism track

irv said...

"This application will be able to read your private email addresses."

That's the first thing I see when I go to sign up for exercism. It's also the last thing. Not interested in them reading anything on my computer.

Fair call. It'd be nice if they'd explain that. In a world of bad actors you'd think they could write a better script.

-Bruce

new topic     » goto parent     » topic index » view message » categorize

4. Re: Requesting submissions for Exercism track

Okay, this link to the Problem Descriptions is on github and does not require any giving away of personal details to access. Choose one or two. I need at least 20 in all and I've already go solutions for hamming, hello-world, isogram, leap, raindrops and phone-number.

new topic     » goto parent     » topic index » view message » categorize

5. Re: Requesting submissions for Exercism track

irv said...

"This application will be able to read your private email addresses."

I did take up the case with the Exercism admins. This is their response:

iHID said...

This is how GitHub oauth works. If you sign up with GitHub, GitHub gives us your email address. I think they’ve entirely misunderstood what’s going on here. It’s not like we can then magically read things on their computer…

Regardless, that’s language on GitHub’s side, not ours, so I’m going to mark this as wontfix.

-Bruce

new topic     » goto parent     » topic index » view message » categorize

6. Re: Requesting submissions for Exercism track

axtens_bruce said...
irv said...

"This application will be able to read your private email addresses."

I did take up the case with the Exercism admins. This is their response:

iHID said...

This is how GitHub oauth works. If you sign up with GitHub, GitHub gives us your email address. I think they’ve entirely misunderstood what’s going on here. It’s not like we can then magically read things on their computer…

Regardless, that’s language on GitHub’s side, not ours, so I’m going to mark this as wontfix.

-Bruce

Hey, if irv doesn't want to share his github email with the iHID folks, that should be his choice.

Would be nice if they could let you sign up with a custom (read: throwaway) email address, instead of requiring Github (which would require creating a throwaway Github account with a throwaway email).

new topic     » goto parent     » topic index » view message » categorize

7. Re: Requesting submissions for Exercism track

jimcbrown said...

Hey, if irv doesn't want to share his github email with the iHID folks, that should be his choice.

And it is.

Anyway, irv doesn't need to create an Exercism or Github account to contribute code. All he needs to do is read the publicly accessible task description, write some code, and send it to me. I'll take care of folding it into the framework.

-Bruce

new topic     » goto parent     » topic index » view message » categorize

8. Re: Requesting submissions for Exercism track

Have just PR-ed Bob. I've also posted the code for it for comment and improvement. 12 more to go.

-Bruce

new topic     » goto parent     » topic index » view message » categorize

9. Re: Requesting submissions for Exercism track

The following have been done

acronym 
bob 
grains 
hamming 
hello-world 
isbn-verifier 
isogram 
leap 
pangram 
raindrops 
So don't do those. The remainder are still here. Halfway to launch-minimum.

-Bruce

new topic     » goto parent     » topic index » view message » categorize

10. Re: Requesting submissions for Exercism track

axtens_bruce said...

The following have been done

acronym 
bob 
grains 
hamming 
hello-world 
isbn-verifier 
isogram 
leap 
pangram 
raindrops 
So don't do those. The remainder are still here. Halfway to launch-minimum.

-Bruce

Also darts

new topic     » goto parent     » topic index » view message » categorize

11. Re: Requesting submissions for Exercism track

The following have been done

acronym 
bob 
grains 
hamming 
hello-world 
isbn-verifier 
isogram 
leap 
pangram 
raindrops 
darts 
two-fer 
collatz-conjecture 
anagram 
So don't do those. The remainder are still here. 6 left.

-Bruce

new topic     » goto parent     » topic index » view message » categorize

12. Re: Requesting submissions for Exercism track

triangle done.

5 left.

new topic     » goto parent     » topic index » view message » categorize

13. Re: Requesting submissions for Exercism track

yacht.

4 to go.

new topic     » goto parent     » topic index » view message » categorize

14. Re: Requesting submissions for Exercism track

Oh, you've done yacht, n'er mind, here's a few more that I quickly bashed out smile

function score_yacht(sequence hand, string category) 
    integer score = 0 
    if category[$]='s' then 
        score = find(category,{"ones","twos","threes","fours","fives","sixes"}) 
        score = sum(sq_eq(hand,score))*score 
    else 
        hand = sort(deep_copy(hand)) 
        integer {c1,c2,c3,c4,c5} = hand 
        if category="full house" then 
            if (c1=c3 and c4=c5 and c3!=c4) 
            or (c1=c2 and c3=c5 and c2!=c3) then 
                score = sum(hand) 
            end if 
        elsif category="four of a kind" then 
            if c2=c4 and (c1=c2 or c4=c5) then 
                score = c3*4 
            end if 
        elsif category="little straight" then 
            if hand={1,2,3,4,5} then 
                score = 30 
            end if 
        elsif category="big straight" then 
            if hand={2,3,4,5,6} then 
                score = 30 
            end if 
        elsif category="choice" then 
            score = sum(hand) 
        elsif category="yacht" then 
            if c1=c5 then 
                score = 50 
            end if 
        else 
            ?9/0 
        end if 
    end if 
    return score 
end function 
 
constant tests = {{"Yacht",{5, 5, 5, 5, 5},"yacht",50}, 
                  {"Not Yacht",{1, 3, 3, 2, 5},"yacht",0}, 
                  {"Ones",{1, 1, 1, 3, 5},"ones",3}, 
                  {"Ones, out of order",{3, 1, 1, 5, 1},"ones",3}, 
                  {"No ones",{4, 3, 6, 5, 5},"ones",0}, 
                  {"Twos",{2, 3, 4, 5, 6},"twos",2}, 
                  {"Fours",{1, 4, 1, 4, 1},"fours",8}, 
                  {"Yacht counted as threes",{3, 3, 3, 3, 3},"threes",15}, 
                  {"Yacht of 3s counted as fives",{3, 3, 3, 3, 3},"fives",0}, 
                  {"Fives",{1, 5, 3, 5, 3},"fives",10}, 
                  {"Sixes",{2, 3, 4, 5, 6},"sixes",6}, 
                  {"Full house two small, three big",{2, 2, 4, 4, 4},"full house",16}, 
                  {"Full house three small, two big",{5, 3, 3, 5, 3},"full house",19}, 
                  {"Two pair is not a full house",{2, 2, 4, 4, 5},"full house",0}, 
                  {"Four of a kind is not a full house",{1, 4, 4, 4, 4},"full house",0}, 
                  {"Yacht is not a full house",{2, 2, 2, 2, 2},"full house",0}, 
                  {"Four of a Kind",{6, 6, 4, 6, 6},"four of a kind",24}, 
                  {"Yacht can be scored as Four of a Kind",{3, 3, 3, 3, 3},"four of a kind",12}, 
                  {"Full house is not Four of a Kind",{3, 3, 3, 5, 5},"four of a kind",0}, 
                  {"Little Straight",{3, 5, 4, 1, 2},"little straight",30}, 
                  {"Little Straight as Big Straight",{1, 2, 3, 4, 5},"big straight",0}, 
                  {"Four in order but not a little straight",{1, 1, 2, 3, 4},"little straight",0}, 
                  {"No pairs but not a little straight",{1, 2, 3, 4, 6},"little straight",0}, 
                  {"Minimum is 1, maximum is 5, but not a little straight",{1, 1, 3, 4, 5},"little straight",0}, 
                  {"Big Straight",{4, 6, 2, 5, 3},"big straight",30}, 
                  {"Big Straight as little straight",{6, 5, 4, 3, 2},"little straight",0}, 
                  {"No pairs but not a big straight",{6, 5, 4, 3, 1},"big straight",0}, 
                  {"Choice",{3, 3, 5, 6, 6},"choice",23}, 
                  {"Yacht as choice",{2, 2, 2, 2, 2},"choice",10}} 
for t in tests do 
    {string desc, sequence hand, string category, integer expected} = t 
    assert(score_yacht(hand,category)=expected,desc) 
end for 
 
 
function encode(sequence data) 
    sequence bytes = {} 
    for d in reverse(data) do 
        bytes &= and_bits(d,#7F) 
        d = floor(d/#80) 
        while d do 
            bytes &= and_bits(d,#7F)+#80 
            d = floor(d/#80) 
        end while        
    end for 
    bytes = reverse(bytes) 
    return bytes 
end function 
 
function decode(sequence bytes) 
    sequence data = {} 
    if length(bytes) and and_bits(bytes[$],#80) then 
        return "incomplete sequence" 
    end if 
    atom d = 0 
    for b in bytes do 
        d = d*#80 + and_bits(b,#7F) 
        if not and_bits(b,#80) then 
            data &= d 
            d = 0 
        end if 
    end for 
    return data 
end function 
 
constant e = {{"zero",{#00},{#00}}, 
              {"arbitrary single byte",{#40},{#40}}, 
              {"largest single byte",{#7F},{#7F}}, 
              {"smallest double byte",{#80},{#81, #00}}, 
              {"arbitrary double byte",{#2000},{#C0, #00}}, 
              {"largest double byte",{#3FFF},{#FF, #7F}}, 
              {"smallest triple byte",{#4000},{#81, #80, #00}}, 
              {"arbitrary triple byte",{#100000},{#C0, #80, #00}}, 
              {"largest triple byte",{#1FFFFF},{#FF, #FF, #7F}}, 
              {"smallest quadruple byte",{#200000},{#81, #80, #80, #00}}, 
              {"arbitrary quadruple byte",{#8000000},{#C0, #80, #80, #00}}, 
              {"largest quadruple byte",{#FFFFFFF},{#FF, #FF, #FF, #7F}}, 
              {"smallest quintuple byte",{#10000000},{#81, #80, #80, #80, #00}}, 
              {"arbitrary quintuple byte",{#FF000000},{#8F, #F8, #80, #80, #00}}, 
              {"maximum 32-bit integer input",{#FFFFFFFF},{#8F, #FF, #FF, #FF, #7F}}, 
              {"two single-byte values",{#40, #7F},{#40, #7F}}, 
              {"two multi-byte values",{#4000, #123456},{#81, #80, #00, #C8, #E8, #56}}, 
              {"many multi-byte values",{#2000, #123456, #FFFFFFF, #00, #3FFF, #4000}, 
                                        {#C0, #0, #C8, #E8, #56, #FF, #FF, #FF, #7F, #00, #FF, #7F, #81, #80, #00}}}, 
         d = {{"one byte",{#7F},{#7F}}, 
              {"two bytes",{#C0, #00},{#2000}}, 
              {"three bytes",{#FF, #FF, #7F},{#1FFFFF}}, 
              {"four bytes",{#81, #80, #80, #0},{#200000}}, 
              {"maximum 32-bit integer",{#8F, #FF, #FF, #FF, #7F},{#FFFFFFFF}}, 
              {"incomplete sequence causes error",{#FF},"incomplete sequence"}, 
              {"incomplete sequence causes error, even if value is zero",{#80},"incomplete sequence"}, 
              {"multiple values",{#C0, #00, #C8, #E8, #56, #FF, #FF, #FF, #7F, #00, #FF, #7F, #81, #80, #00}, 
                                 {#2000, #123456, #FFFFFFF, #00, #3FFF, #4000}}} 
 
string desc; sequence data, expected 
for t in e do 
    {desc, data, expected} = t 
    assert(encode(data)=expected,desc) 
end for 
for t in d do 
    {desc, data, expected} = t 
    assert(decode(data)=expected,desc) 
end for 
 
function sum_of_multiples(sequence f, integer lim) 
    integer res = 0 
    for n = 1 to lim-1 do 
        for k in f do  
            if k!=0 and remainder(n,k)=0 then 
                res += n 
                exit 
            end if 
        end for 
    end for 
    return res 
end function 
 
constant tests = {{"no multiples within limit",{3, 5},1,0}, 
                  {"one factor has multiples within limit",{3, 5},4,3}, 
                  {"more than one multiple within limit",{3},7,9}, 
                  {"more than one factor with multiples within limit",{3, 5},10,23}, 
                  {"each multiple is only counted once",{3, 5},100,2318}, 
                  {"a much larger limit",{3, 5},1000,233168}, 
                  {"three factors",{7, 13, 17},20,51}, 
                  {"factors not relatively prime",{4, 6},15,30}, 
                  {"some pairs of factors relatively prime and some not",{5, 6, 8},150,4419}, 
                  {"one factor is a multiple of another",{5, 25},51,275}, 
                  {"much larger factors",{43, 47},10000,2203160}, 
                  {"all numbers are multiples of 1",{1},100,4950}, 
                  {"no factors means an empty sum",{},10000,0}, 
                  {"the only multiple of 0 is 0",{0},1,0}, 
                  {"the factor 0 does not affect the sum of multiples of other factors",{3, 0},4,3}, 
                  {"solutions using include-exclude must extend to cardinality greater than 3",{2, 3, 5, 7, 11},10000,39614537}} 
for t in tests do 
    {string desc, sequence f, integer lim, integer expected} = t 
    assert(sum_of_multiples(f,lim)=expected,desc) 
end for 
 
constant tests = {{"root of 1",1,1}, 
                  {"root of 4",4,2}, 
                  {"root of 25",25,5}, 
                  {"root of 81",81,9}, 
                  {"root of 196",196,14}, 
                  {"root of 65025",65025,255}} 
 
for t in tests do 
    {string desc, integer n, integer expected} = t 
    assert(sqrt(n)=expected,desc) 
end for 
 
function spiral(integer n) 
    integer x = 1, y = 0, counter = 1,  
          len = n, dx = 0, dy = 1 
    sequence m = repeat(repeat(0,n),n) 
    for i=1 to 2*n do                       -- 2n runs.. 
        for j=1 to len do                   -- of a length... 
            x += dx 
            y += dy 
            m[x][y] = counter 
            counter += 1 
        end for 
        len -= odd(i)                       -- ..-1 every other  
        {dx,dy} = {dy,-dx}                  -- in new direction 
    end for 
    return m 
end function 
 
constant tests = {{"empty spiral",0,{}}, 
                  {"trivial spiral",1,{{1}}}, 
                  {"spiral of size 2",2,{{1, 2}, 
                                         {4, 3}}}, 
                  {"spiral of size 3",3,{{1, 2, 3}, 
                                         {8, 9, 4}, 
                                         {7, 6, 5}}}, 
                  {"spiral of size 4",4,{{ 1,  2,  3, 4}, 
                                         {12, 13, 14, 5}, 
                                         {11, 16, 15, 6}, 
                                         {10,  9,  8, 7}}}, 
                  {"spiral of size 5",5,{{ 1,  2,  3,  4, 5}, 
                                         {16, 17, 18, 19, 6}, 
                                         {15, 24, 25, 20, 7}, 
                                         {14, 23, 22, 21, 8}, 
                                         {13, 12, 11, 10, 9}}}} 
for t in tests do 
    {string desc, integer n, sequence expected} = t 
    assert(spiral(n)=expected,desc) 
end for 
 
 
constant ROMAN  = {"M", "CM", "D","CD", "C","XC","L","XL","X","IX","V","IV","I"}, 
         DECML  = {1000, 900, 500, 400, 100, 90, 50,  40,  10,  9,  5,   4,  1 } 
 
function roman(integer val) 
    string res = "" 
    for i=1 to length(ROMAN) do 
        while val>=DECML[i] do 
            res &= ROMAN[i] 
            val -= DECML[i] 
        end while 
    end for 
    return res 
end function 
 
constant tests = {{"1 is I",1,"I"}, 
                  {"2 is II",2,"II"}, 
                  {"3 is III",3,"III"}, 
                  {"4 is IV",4,"IV"}, 
                  {"5 is V",5,"V"}, 
                  {"6 is VI",6,"VI"}, 
                  {"9 is IX",9,"IX"}, 
                  {"16 is XVI",16,"XVI"}, 
                  {"27 is XXVII",27,"XXVII"}, 
                  {"48 is XLVIII",48,"XLVIII"}, 
                  {"49 is XLIX",49,"XLIX"}, 
                  {"59 is LIX",59,"LIX"}, 
                  {"66 is LXVI",66,"LXVI"}, 
                  {"93 is XCIII",93,"XCIII"}, 
                  {"141 is CXLI",141,"CXLI"}, 
                  {"163 is CLXIII",163,"CLXIII"}, 
                  {"166 is CLXVI",166,"CLXVI"}, 
                  {"402 is CDII",402,"CDII"}, 
                  {"575 is DLXXV",575,"DLXXV"}, 
                  {"666 is DCLXVI",666,"DCLXVI"}, 
                  {"911 is CMXI",911,"CMXI"}, 
                  {"1024 is MXXIV",1024,"MXXIV"}, 
                  {"1666 is MDCLXVI",1666,"MDCLXVI"}, 
                  {"3000 is MMM",3000,"MMM"}, 
                  {"3001 is MMMI",3001,"MMMI"}, 
                  {"3999 is MMMCMXCIX",3999,"MMMCMXCIX"}} 
for t in tests do 
    {string desc, integer n, string expected} = t 
    assert(roman(n)=expected,desc) 
end for 
 
 
constant tests = { 
                  {"an empty string","",""}, 
                  {"a word","robot","tobor"}, 
                  {"a capitalized word","Ramen","nemaR"}, 
                  {"a sentence with punctuation","I'm hungry!","!yrgnuh m'I"}, 
                  {"a palindrome","racecar","racecar"}, 
                  {"an even-sized word","drawer","reward"}} 
for t in tests do 
    string {desc, s, expected} = t 
    assert(reverse(s)=expected,desc) 
end for 
 
 
function check(sequence p) 
    integer {r,c} = p 
    if r<0 then return "row not positive" end if 
    if r>7 then return "row not on board" end if 
    if c<0 then return "column not positive" end if 
    if c>7 then return "column not on board" end if 
    return 0 
end function 
 
function can_attack(sequence p) 
    integer {{r1,c1},{r2,c2}} = p 
    return r1=r2 or c1=c2 or r1-c1=r2-c2 or r1+c1=r2+c2 
end function 
 
constant places = {{"queen with a valid position",{2,2},0}, 
                   {"queen must have positive row",{-2,2},"row not positive"}, 
                   {"queen must have row on board",{8,4},"row not on board"}, 
                   {"queen must have positive column",{2,-2},"column not positive"}, 
                   {"queen must have column on board",{4,8},"column not on board"}}, 
        attacks = {{"cannot attack",{{2,4},{6,6}},false}, 
                   {"can attack on same row",{{2,4},{2,6}},true}, 
                   {"can attack on same column",{{4,5},{2,5}},true}, 
                   {"can attack on first diagonal",{{2,2},{0,4}},true}, 
                   {"can attack on second diagonal",{{2,2},{3,1}},true}, 
                   {"can attack on third diagonal",{{2,2},{1,1}},true}, 
                   {"can attack on fourth diagonal",{{1,7},{0,6}},true}, 
                   {"cannot attack if falling diagonals are only the same when reflected across the longest falling diagonal",{{4,1},{2,5}},false}} 
string desc; sequence p; object expected 
for p in places do 
    {desc,p,expected} = p 
    assert(check(p)=expected,desc) 
end for 
for a in attacks do 
    {desc,p,expected} = a 
    assert(can_attack(p)=expected,desc) 
end for 
 
 
function pythagorean_triplets(integer perim) 
    sequence res = {} 
    for a=1 to floor(perim/3) do 
        for b=a+1 to floor((perim-a)/2) do 
            integer c = perim-(a+b) 
            if a*a+b*b=c*c then 
                res = append(res,{a,b,c}) 
            end if 
        end for 
    end for 
    return res 
end function 
 
constant tests = {{"triplets whose sum is 12",12,{{3, 4, 5}}}, 
                  {"triplets whose sum is 108",108,{{27, 36, 45}}}, 
                  {"triplets whose sum is 1000",1000,{{200, 375, 425}}}, 
                  {"no matching triplets for 1001",1001,{}}, 
                  {"returns all matching triplets",90,{{9, 40, 41},{15, 36, 39}}}, 
                  {"several matching triplets",840,{{40, 399, 401},{56, 390, 394},{105, 360, 375},{120, 350, 370},{140, 336, 364},{168, 315, 357},{210, 280, 350},{240, 252, 348}}}, 
                  {"triplets for large number",30000,{{1200, 14375, 14425},{1875, 14000, 14125},{5000, 12000, 13000},{6000, 11250, 12750},{7500, 10000, 12500}}}} 
for t in tests do 
    {string desc, integer n, sequence expected} = t 
    assert(pythagorean_triplets(n)=expected,desc) 
end for 
 
 
function pascal(integer n) 
    sequence res = {}, row = repeat(1,n) 
    for r=1 to n do 
        for n=r-1 to 2 by -1 do 
            row[n] += row[n-1] 
        end for 
        res = append(res,row[1..r]) 
    end for 
    return res 
end function 
 
constant pt = {{1}, 
               {1, 1}, 
               {1, 2, 1}, 
               {1, 3, 3, 1}, 
               {1, 4, 6, 4, 1}, 
               {1, 5, 10, 10, 5, 1}, 
               {1, 6, 15, 20, 15, 6, 1}, 
               {1, 7, 21, 35, 35, 21, 7, 1}, 
               {1, 8, 28, 56, 70, 56, 28, 8, 1}, 
               {1, 9, 36, 84, 126, 126, 84, 36, 9, 1}} 
for n=0 to 10 do 
    assert(pascal(n)=pt[1..n]) 
end for 
 
 
function matrix(string s, rc, integer idx) 
    sequence m = split(s,"\n") 
    for i,r in m do 
        m[i] = apply(split(r,' '),to_integer) 
    end for 
    if rc="row" then return m[idx] end if 
    return vslice(m,idx) 
end function 
 
constant tests = {{"extract row from one number matrix","row","1",1,{1}}, 
                  {"can extract row","row","1 2\n3 4",2,{3,4}}, 
                  {"extract row where numbers have different widths","row","1 2\n10 20",2,{10, 20}}, 
                  {"can extract row from non-square matrix with no corresponding column","row","1 2 3\n4 5 6\n7 8 9\n8 7 6",4,{8, 7, 6}}, 
                  {"extract column from one number matrix","column","1",1,{1}}, 
                  {"can extract column","column","1 2 3\n4 5 6\n7 8 9",3,{3, 6, 9}}, 
                  {"can extract column from non-square matrix with no corresponding row","column","1 2 3 4\n5 6 7 8\n9 8 7 6",4,{4, 8, 6}}, 
                  {"extract column where numbers have different widths","column","89 1903 3\n18 3 1\n9 4 800",2,{1903, 3, 4}}} 
 
for t in tests do 
    string desc, rc, m; integer idx; sequence expected 
    {desc, rc, m, idx, expected} = t 
    printf(1,"%s : %s[%d] = %v (%t)\n",{m,rc,idx,matrix(m,rc,idx),matrix(m,rc,idx)=expected}) 
    assert(matrix(m,rc,idx)=expected,desc) 
end for 
 
function matching_brackets(string s) 
    sequence stack = {} 
    string openers = "[{(", 
           closers = "]})" 
    for ch in s do 
        integer k = find(ch,openers) 
        if k then 
            stack &= closers[k] 
        else 
            k = find(ch,closers) 
            if k then 
                if stack={} or ch!=stack[$] then 
                    return false 
                end if 
                stack = stack[1..$-1] 
            end if 
        end if 
    end for 
    return stack = {} 
end function 
     
constant tests = {{"paired square brackets","[]",true}, 
                  {"empty string","",true}, 
                  {"unpaired brackets","[[",false}, 
                  {"wrong ordered brackets","}{",false}, 
                  {"wrong closing bracket","{]",false}, 
                  {"paired with whitespace","{ }",true}, 
                  {"partially paired brackets","{[])",false}, 
                  {"simple nested brackets","{[]}",true}, 
                  {"several paired brackets","{}[]",true}, 
                  {"paired and nested brackets","([{}({}[])])",true}, 
                  {"unopened closing brackets","{[)][]}",false}, 
                  {"unpaired and nested brackets","([{])",false}, 
                  {"paired and wrong nested brackets","[({]})",false}, 
                  -- Ensures last opened bracket is not the only one being traced 
                  {"paired and wrong nested brackets but innermost are correct","[({}])",false}, 
                  {"paired and incomplete brackets","{}[",false}, 
                  {"too many closing brackets","[]]",false}, 
                  {"early unexpected brackets",")()",false}, 
                  {"early mismatched brackets","{)()",false}, 
                  {"math expression","(((185 + 223.85) * 15) - 543)/2",true}, 
                  {"complex latex expression","\\left(\\begin{array}{cc} \\frac{1}{3} & x\\\\ \\mathrm{e}^{x} &... x^2 \\end{array}\\right)",true}} 
 
for t in tests do 
    {string desc, string b, bool expected} = t 
    printf(1,"%s : %t\n",{b,matching_brackets(b)=expected}) 
    assert(matching_brackets(b)=expected,desc) 
end for 
 
function luhn(string s) 
    s = reverse(filter(s,"out"," ")) 
    if length(s)<=1 then return false end if 
    integer checksum = 0 
    for i,c in s do 
        c -= '0' 
        if c<0 or c>9 then return false end if 
        if even(i) then 
            c *= 2 
            if c>9 then c -= 9 end if 
        end if 
        checksum += c 
    end for 
    return remainder(checksum,10)=0 
end function 
 
constant tests = {{"single digit strings can not be valid","1",false}, 
                  {"a single zero is invalid","0",false}, 
                  {"a simple valid SIN that remains valid if reversed","059",true}, 
                  {"a simple valid SIN that becomes invalid if reversed","59",true}, 
                  {"a valid Canadian SIN","055 444 285",true}, 
                  {"invalid Canadian SIN","055 444 286",false}, 
                  {"invalid credit card","8273 1232 7352 0569",false}, 
                  {"invalid long number with an even remainder","1 2345 6789 1234 5678 9012",false}, 
                  {"invalid long number with a remainder divisible by 5","1 2345 6789 1234 5678 9013",false}, 
                  {"valid number with an even number of digits","095 245 88",true}, 
                  {"valid number with an odd number of spaces","234 567 891 234",true}, 
                  {"valid strings with a non-digit added at the end become invalid","059a",false}, 
                  {"valid strings with punctuation included become invalid","055-444-285",false}, 
                  {"valid strings with symbols included become invalid","055# 444$ 285",false}, 
                  {"single zero with space is invalid"," 0",false}, 
                  {"more than a single zero is valid","0000 0",true}, 
                  {"input digit 9 is correctly converted to output digit 9","091",true}, 
                  -- Designed to prevent converting input to a single number as this approach can risk an overflow 
                  {"very long input is valid","9999999999 9999999999 9999999999 9999999999",true}, 
                  {"valid luhn with an odd number of digits and non zero first digit","109",true}, 
                  -- Convert non-digits to their ascii values and then offset them by 48 sometimes accidentally  
                  -- declare an invalid string to be valid. Next two tests are designed to avoid that solution. 
                  {"using ascii value for non-doubled non-digit isn't allowed","055b 444 285",false}, 
                  {"using ascii value for doubled non-digit isn't allowed",":9",false}, 
                  {"non-numeric, non-space char in the middle with a sum that's divisible by 10 isn't allowed","59%59",false}} 
 
for t in tests do 
    {string desc, string n, bool expected} = t 
    printf(1,"%s : %t\n",{n,luhn(n)=expected}) 
    assert(luhn(n)=expected,desc) 
end for 
new topic     » goto parent     » topic index » view message » categorize

15. Re: Requesting submissions for Exercism track

Wow. I think that about does it. Thank you -Bruce

new topic     » goto parent     » topic index » view message » categorize

16. Re: Requesting submissions for Exercism track

By the way @petelomax , I did notice a certain phixation in some of your code, like "for i,c in" and "string". Even so, thanks.

-Bruce

new topic     » goto parent     » topic index » view message » categorize

17. Re: Requesting submissions for Exercism track

So I've completed 20 tasks, viz

acronym 
anagram 
bob 
collatz-conjecture 
darts 
grains 
hamming 
hello-world 
isbn-verifier 
isogram 
leap 
luhn 
pangram 
pythagorean-triplets 
raindrops 
roman-numerals 
sum-of-multiples 
triangle 
two-fer 
yacht 

That's the minimum. I will, eventually, add the rest of Pete's contributions. There are lots of others if anyone's interested. I'm now moving on to the CI and the documentation. I expect that'll be done in a few weeks time after which the launch of the learning track will occur.

Suitably motivated folk may wish to critique the postings. That'd be VERY helpful.

-Bruce

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu