diff --git a/.travis.yml b/.travis.yml index 2a28131..c23a3ea 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,9 @@ language: crystal before_install: - sudo apt-get -qq update - sudo apt-get install -y ruby default-jdk haskell-platform python3 + - wget http://www.lua.org/ftp/lua-5.3.4.tar.gz + - tar -zxv -f lua-5.3.4.tar.gz + - pushd lua-5.3.4 && make CFLAGS="-O2 -fPIC -DLUA_COMPAT_5_2 -DLUA_COMPAT_5_1" linux && sudo make INSTALL_TOP=/usr install && popd install: make clean build diff --git a/Makefile b/Makefile index 0ba9231..6d15051 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,7 @@ build: g++ -O2 main.cpp -o $(BIN_DIR)/cpp javac -d $(BIN_DIR) Main.java ghc -O2 main.hs -outputdir=$(BUILD_DIR) -o $(BIN_DIR)/haskell + luac -o $(BIN_DIR)/lua main.lua test: mkdir $(TMP_DIR) @@ -32,4 +33,6 @@ test: @cmp $(TMP_DIR)/crystal.out $(TMP_DIR)/haskell.out || (echo "Failed: Haskell" && exit 1) python3 main.py < $(TMP_DIR)/test_data.in > $(TMP_DIR)/python3.out @cmp $(TMP_DIR)/crystal.out $(TMP_DIR)/python3.out || (echo "Failed: Python3" && exit 1) + lua $(BIN_DIR)/lua < $(TMP_DIR)/test_data.in > $(TMP_DIR)/lua.out + @cmp $(TMP_DIR)/crystal.out $(TMP_DIR)/lua.out || (echo "Failed: Lua" && exit 1) @echo "Passed" diff --git a/README.md b/README.md index 6d2d23f..3d8f88a 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ Solve 2D Rank Finding Problem in Several Languages - Java - Haskell - Python 3 +- Lua ## Problem @@ -80,3 +81,4 @@ Your output should consist of a single line for each test case containing n numb - [scps940707](https://github.com/scps940707) YyWang - Java - [sifmelcara](https://github.com/sifmelcara) mingchuan - Haskell - [chuanchan1116](https://github.com/chuanchan1116) William Tsai - Python 3 +- [firejox](https://github.com/firejox) Firejox - Lua diff --git a/main.lua b/main.lua new file mode 100644 index 0000000..5570a34 --- /dev/null +++ b/main.lua @@ -0,0 +1,72 @@ +local Point = {} +Point.__index = Point +Point.__lt = function(a, b) + if a.x == b.x then + return a.y < b.y + end + return a.x < b.x +end + +function Point:new(x, y, idx) + return setmetatable({ x = x, y = y, idx = idx }, Point) +end + +while true do + local ranks = {} + + function find_ranks(pts) + local sz = #pts + local l_sz = math.floor(sz / 2) + local r_sz = sz - l_sz + + if sz == 1 then + return pts + end + + local pts_l = find_ranks(table.pack(table.unpack(pts, 1, l_sz))) + local pts_r = find_ranks(table.pack(table.unpack(pts, l_sz + 1))) + local res = {} + local i, j = 1, 1 + + while true do + if pts_l[i].y <= pts_r[j].y then + table.insert(res, pts_l[i]) + i = i + 1 + if i > l_sz then + while j <= r_sz do + ranks[pts_r[j].idx] = ranks[pts_r[j].idx] + i - 1 + table.insert(res, pts_r[j]) + j = j + 1 + end + break + end + else + table.insert(res, pts_r[j]) + ranks[pts_r[j].idx] = ranks[pts_r[j].idx] + i - 1 + j = j + 1 + if j > r_sz then + table.move(pts_l, i, l_sz, #res + 1, res) + break + end + end + end + + return res + end + + local pts = {} + local n = io.read("*n") + if n == 0 then + break + end + + for i = 1, n do + x, y = io.read("*n", "*n") + pts[i] = Point:new(x, y, i) + ranks[i] = 0 + end + + table.sort(pts, cmp) + find_ranks(pts) + print(table.concat(ranks, ' ')) +end