Aaro Saila преди 8 месеца
ревизия
2d9b2318a9

+ 14 - 0
exercises/ch01/ex01/main.lua

@@ -0,0 +1,14 @@
+-- Negative n resulted in a stackoverflow (infinite recursion)
+function fact(n)
+    if n == 0 then
+        return 1
+    elseif n < 0 then
+        return nil
+    else
+        return n * fact(n - 1)
+    end
+end
+
+print("enter a number:")
+a = io.read("*n")
+print(fact(a))

+ 1 - 0
exercises/ch01/ex08/main.lua

@@ -0,0 +1 @@
+print(arg[0])

+ 8 - 0
exercises/ch02/correct_board.txt

@@ -0,0 +1,8 @@
+X - - - - - - -
+- - - - X - - -
+- - - - - - - X
+- - - - - X - -
+- - X - - - - -
+- - - - - - X -
+- X - - - - - -
+- - - X - - - -

+ 43 - 0
exercises/ch02/ex1.lua

@@ -0,0 +1,43 @@
+N = 8 -- board size
+
+-- check whether position (n,c) is free from attacks
+function isplaceok(a, n, c)
+    for i = 1, n - 1 do   -- for each queen already placed
+        if (a[i] == c) or -- same column?
+            (a[i] - i == c - n) or -- same diagonal?
+            (a[i] + i == c + n) then -- same diagonal?
+            return false  -- place can be attacked
+        end
+    end
+    return true -- no attacks; place is OK
+end
+
+-- print a board
+function printsolution(a)
+    for i = 1, N do -- for each row
+        for j = 1, N do -- and for each column
+            -- write "X" or "-" plus a space
+            io.write(a[i] == j and "X" or "-", " ")
+        end
+        io.write("\n")
+    end
+    io.write("\n")
+end
+
+-- add to board 'a' all queens from 'n' to 'N'
+function addqueen(a, n)
+    if n > N then -- all queens have been placed?
+        printsolution(a)
+        os.exit(0)
+    else       -- try to place n-th queen
+        for c = 1, N do
+            if isplaceok(a, n, c) then
+                a[n] = c -- place n-th queen at column 'c'
+                addqueen(a, n + 1)
+            end
+        end
+    end
+end
+
+-- run the program
+addqueen({}, 1)

+ 94 - 0
exercises/ch02/ex2.lua

@@ -0,0 +1,94 @@
+N = 8 -- board size
+
+-- check whether position (n,c) is free from attacks
+local function isplaceok(a, n, c)
+    for i = 1, n - 1 do   -- for each queen already placed
+        if (a[i] == c) or -- same column?
+            (a[i] - i == c - n) or -- same diagonal?
+            (a[i] + i == c + n) then -- same diagonal?
+            return false  -- place can be attacked
+        end
+    end
+    return true -- no attacks; place is OK
+end
+
+-- print a board
+local function printsolution(a)
+    for i = 1, N do -- for each row
+        for j = 1, N do -- and for each column
+            -- write "X" or "-" plus a space
+            io.write(a[i] == j and "X" or "-", " ")
+        end
+        io.write("\n")
+    end
+    io.write("\n")
+end
+
+local function reverse(a, s, e)
+    for i = s, e / 2 do
+        local counter_i = e - (i - 1)
+        local tmp = a[i]
+        a[i] = a[counter_i]
+        a[counter_i] = tmp
+    end
+end
+
+local function generatePermutations()
+    local p1 = { 1, 2, 3, 4, 5, 6, 7, 8}
+    local ps = {p1}
+
+    while true do
+        local newP = {}
+        local last_p = ps[#ps]
+        for i = 1, #last_p do
+            newP[i] = last_p[i]
+        end
+
+        local k = nil
+        for i = #newP, 1, -1 do
+            if newP[i + 1] == nil then
+                goto continue
+            end
+            if newP[i] < newP[i + 1] then
+                k = i
+                break
+            end
+            ::continue::
+        end
+        if k == nil then
+            break
+        end
+
+        local l = nil
+        for i = #newP, 1, -1 do
+            if newP[k] < newP[i] then
+                l = i
+                break
+            end
+        end
+
+        if l == nil then
+            print("ERROR: l was nil")
+            os.exit(1)
+        end
+
+        local tmp = newP[k]
+        newP[k] = newP[l]
+        newP[l] = tmp
+
+        reverse(newP, k + 1, #newP)
+
+        print(k, l)
+
+        table.insert(ps, newP)
+    end
+
+    return ps
+end
+
+local perms = generatePermutations()
+for i = 1, #perms do
+    print(table.unpack(perms[i]))
+end
+
+print(#perms)

+ 42 - 0
exercises/ch02/orig.lua

@@ -0,0 +1,42 @@
+N = 8 -- board size
+
+-- check whether position (n,c) is free from attacks
+function isplaceok(a, n, c)
+    for i = 1, n - 1 do   -- for each queen already placed
+        if (a[i] == c) or -- same column?
+            (a[i] - i == c - n) or -- same diagonal?
+            (a[i] + i == c + n) then -- same diagonal?
+            return false  -- place can be attacked
+        end
+    end
+    return true -- no attacks; place is OK
+end
+
+-- print a board
+function printsolution(a)
+    for i = 1, N do -- for each row
+        for j = 1, N do -- and for each column
+            -- write "X" or "-" plus a space
+            io.write(a[i] == j and "X" or "-", " ")
+        end
+        io.write("\n")
+    end
+    io.write("\n")
+end
+
+-- add to board 'a' all queens from 'n' to 'N'
+function addqueen(a, n)
+    if n > N then -- all queens have been placed?
+        printsolution(a)
+    else       -- try to place n-th queen
+        for c = 1, N do
+            if isplaceok(a, n, c) then
+                a[n] = c -- place n-th queen at column 'c'
+                addqueen(a, n + 1)
+            end
+        end
+    end
+end
+
+-- run the program
+addqueen({}, 1)

+ 12 - 0
exercises/ch02/reverse.lua

@@ -0,0 +1,12 @@
+local function reverse(a, s, e)
+    for i = s, e / 2 do
+        local counter_i = e - (i - 1)
+        local tmp = a[i]
+        a[i] = a[counter_i]
+        a[counter_i] = tmp
+    end
+end
+
+local a = {5, 3, 8, 1}
+reverse(a, 1, #a)
+print(table.unpack(a))

+ 25 - 0
exercises/ch03/ex3_6.lua

@@ -0,0 +1,25 @@
+function Calculate_volume(height, angle)
+    local r = math.tan(angle) * height
+    return 1/3 * math.pi * r^2 * height
+end
+
+function Tests()
+    -- height, angle
+    local cases = {
+        { 4.03, 3.55 },
+        { 308, 380 },
+        { 0.394, 0.826 }
+    }
+
+    for i = 1, #cases do
+        local case = cases[i]
+        local height = case[1]
+        local angle = case[2]
+
+        local volume = Calculate_volume(height, angle)
+
+        print(string.format("height: %f, angle: %f, volume: %f", height, angle, volume))
+    end
+end
+
+Tests()

+ 14 - 0
exercises/ch03/ex3_7.lua

@@ -0,0 +1,14 @@
+local function random_normal()
+    local u = math.random()
+    local v = math.random()
+    return math.sqrt(-2 * math.log(u, math.exp(1))) * math.cos(2 * math.pi * v)
+end
+
+local function generate()
+    for _ = 0, 10 do
+        local value = random_normal()
+        print(value)
+    end
+end
+
+generate()

+ 12 - 0
exercises/ch04/ex4_1.lua

@@ -0,0 +1,12 @@
+local str1 = "<![CDATA[\n  Hello World\n]]>"
+
+print(str1)
+
+print("\n------------------------------\n")
+
+local str2 = [=[
+<![CDATA[
+  Hello World
+]]>]=]
+
+print(str2)

+ 18 - 0
exercises/ch04/ex4_3.lua

@@ -0,0 +1,18 @@
+local function insert(str, i, o)
+    local first_half = str:sub(1, i - 1)
+    local latter_half = str:sub(i, -1)
+    return first_half .. o .. latter_half
+end
+
+local function tests()
+    local res = insert("hello world", 1, "start: ")
+    print(('insert("hello world", 1, "start: ") --> %s'):format(res))
+
+    res = insert("hello world", 7, "small ")
+    print(('insert("hello world", 7, "small ")  --> %s'):format(res))
+
+    res = insert("hello world", 12, "!")
+    print(('insert("hello world", 12, "!")      --> %s'):format(res))
+end
+
+tests()

+ 13 - 0
exercises/ch04/ex4_4.lua

@@ -0,0 +1,13 @@
+local function insert(str, i, o)
+    i = utf8.offset(str, i)
+    local first_half = str:sub(1, i - 1)
+    local latter_half = str:sub(i, -1)
+    return first_half .. o .. latter_half
+end
+
+local function tests()
+    local res = insert("ação", 5, "!")
+    print(('insert("ação", 5, "!") --> %s'):format(res))
+end
+
+tests()

+ 7 - 0
exercises/ch04/ex4_5.lua

@@ -0,0 +1,7 @@
+local function remove(str, start, length)
+    local start_part = str:sub(1, start - 1)
+    local end_part = str:sub(start + length, -1)
+    return start_part .. end_part
+end
+
+print(remove("hello world", 7, 4))

+ 9 - 0
exercises/ch04/ex4_6.lua

@@ -0,0 +1,9 @@
+local function remove(str, start, length)
+    local slice_start = utf8.offset(str, start - 1)
+    local slice_end = utf8.offset(str, start + length)
+    local start_part = str:sub(1, slice_start)
+    local end_part = str:sub(slice_end)
+    return start_part .. end_part
+end
+
+print(remove("ação", 2, 2))

+ 7 - 0
exercises/ch04/ex4_7.lua

@@ -0,0 +1,7 @@
+local function ispali(str)
+    str = str:lower()
+    return str == str:reverse()
+end
+
+print(ispali("step on no pets"))
+print(ispali("banana"))

+ 39 - 0
exercises/ch04/ex4_8.lua

@@ -0,0 +1,39 @@
+local function remove(str, start, _end)
+    local start_part = str:sub(1, start - 1)
+    local end_part = str:sub(_end + 1, -1)
+    return start_part .. end_part
+end
+
+local function remove_patterns(str, pattern)
+    while true do
+        local rem_start, rem_end, _ = str:find(pattern)
+        if rem_start == nil then
+            break
+        end
+        str = remove(str, rem_start, rem_end)
+    end
+
+    return str
+end
+
+local function ispali(str)
+    str = str:lower()
+
+    -- format
+    str = remove_patterns(str, "%s")
+    str = remove_patterns(str, "%p")
+
+    return str == str:reverse()
+end
+
+local function test(str)
+    print(("%s: %q"):format(str, ispali(str)))
+end
+
+test("step on no pets")
+test("banana")
+
+print()
+
+test("Step. On no   pets!")
+test("Banana??")