Skip to content

Commit cfb8574

Browse files
author
Jaroslaw Zabiello
committed
add crystal example
1 parent 4cf79b9 commit cfb8574

File tree

9 files changed

+187
-0
lines changed

9 files changed

+187
-0
lines changed

example-crystal/.editorconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
root = true
2+
3+
[*.cr]
4+
charset = utf-8
5+
end_of_line = lf
6+
insert_final_newline = true
7+
indent_style = space
8+
indent_size = 2
9+
trim_trailing_whitespace = true

example-crystal/LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2022 Jaroslaw Zabiello <[email protected]>
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

example-crystal/README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# example-crystal
2+
3+
TODO: Write a description here
4+
5+
## Installation
6+
7+
TODO: Write installation instructions here
8+
9+
## Usage
10+
11+
crystal build --release -Dpreview_mt src/example-crystal.cr -o main
12+
CRYSTAL_WORKES=10 ./main
13+
14+
MacOS 12.2
15+
Crystal 1.3.2
16+
MBP 16" M1Max 10 cores
17+
Total files: 123
18+
Total size: 504 MB
19+
Total time: 6.0035 s
20+
21+
## Development
22+
23+
TODO: Write development instructions here
24+
25+
## Contributing
26+
27+
1. Fork it (<https://github.com/your-github-user/example-crystal/fork>)
28+
2. Create your feature branch (`git checkout -b my-new-feature`)
29+
3. Commit your changes (`git commit -am 'Add some feature'`)
30+
4. Push to the branch (`git push origin my-new-feature`)
31+
5. Create a new Pull Request
32+
33+
## Contributors
34+
35+
- [Jaroslaw Zabiello](https://github.com/your-github-user) - creator and maintainer

example-crystal/main

337 KB
Binary file not shown.

example-crystal/shard.lock

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
version: 2.0
2+
shards: {}

example-crystal/shard.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
name: example-crystal
2+
version: 0.1.0
3+
4+
authors:
5+
- Jaroslaw Zabiello <[email protected]>
6+
7+
targets:
8+
example-crystal:
9+
main: src/example-crystal.cr
10+
11+
crystal: 1.3.2
12+
13+
license: MIT
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
require "./spec_helper"
2+
3+
describe Example::Crystal do
4+
it "should be understand PL collations" do
5+
words = %w(ala ąla ćma ciemno ęle element łódź lody śmierć serial źdźbło żółw zawias)
6+
expected = %w(ala ąla ciemno ćma element ęle lody łódź serial śmierć zawias źdźbło żółw)
7+
words.sort { |x, y| Example::Crystal.word_cmp(x, y) }.should eq(expected)
8+
end
9+
10+
it "should be understand PL collations for q" do
11+
words = %w(ala ąla ćma ciemno ęle element łódź lody śmierć serial źdźbło żółw zawias querty)
12+
expected = %w(ala ąla ciemno ćma element ęle lody łódź querty serial śmierć zawias źdźbło żółw)
13+
words.sort { |x, y| Example::Crystal.word_cmp(x, y) }.should eq(expected)
14+
end
15+
16+
it "should understand PL collations for upper chars" do
17+
words = %w(ala ąla Ćma ciemno Ęle Element łódź lody śmierć serial źdźbło żółw zawias querty)
18+
expected = %w(ala ąla ciemno Ćma Element Ęle lody łódź querty serial śmierć zawias źdźbło żółw)
19+
words.sort { |x, y| Example::Crystal.word_cmp(x.downcase, y.downcase) }.should eq(expected)
20+
end
21+
end
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
require "spec"
2+
require "../src/example-crystal"
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
require "json"
2+
require "yaml"
3+
4+
# TODO: Write documentation for `FastWordsCr`
5+
6+
module Example::Crystal
7+
VERSION = "0.2.0"
8+
CHARSET = "aąbcćdeęfghijklłmnńoópqrsśtuvwxyzźż"
9+
10+
def self.main(outpath = "words")
11+
with_sorting = false
12+
concurrent = true
13+
14+
prepare_folder(outpath, "*.txt")
15+
16+
file_count = 0
17+
total_size = 0
18+
19+
channel = Channel(Tuple(String, Int64)).new
20+
srcPath = "../data/??/**/*.yml"
21+
# srcPath = "./bibles/??/**/*.yml"
22+
Dir.glob(srcPath, follow_symlinks: true).each do |path|
23+
if concurrent
24+
spawn do
25+
channel.send worker(path, outpath, with_sorting)
26+
end
27+
file_count += 1
28+
else
29+
worker(path, outpath, with_sorting)
30+
end
31+
end
32+
if concurrent
33+
file_count.times do |i|
34+
path, size = channel.receive
35+
total_size += size
36+
# puts("[#{i + 1}/#{file_count}] #{path}")
37+
end
38+
end
39+
total_size = total_size / 1024 / 1024
40+
puts("Total size: #{total_size} MB")
41+
end
42+
43+
def self.worker(path, outpath, with_sorting)
44+
filepath = path.gsub(".yml", ".txt")
45+
text = File.read(filepath).gsub("\n", " ").downcase
46+
47+
words = text.split(/[^\p{L}]+/).to_set
48+
49+
if with_sorting
50+
words = words.to_a.sort { |x, y| self.word_cmp(x, y) }
51+
end
52+
53+
meta = File.open(path) { |file| YAML.parse(file) }
54+
filepath = %Q(#{outpath}/#{meta["lang"]}-#{meta["code"]}.txt)
55+
File.write(filepath, words.join("\n"))
56+
filesize = File.size(filepath)
57+
puts([filepath, filesize])
58+
{filepath, filesize}
59+
end
60+
61+
def self.prepare_folder(folder : String, pattern : String)
62+
Dir.mkdir_p(folder) unless File.exists?(folder)
63+
Dir.glob("#{folder}/#{pattern}").each do |path|
64+
File.delete path
65+
end
66+
end
67+
68+
def self.word_cmp(str1 : String, str2 : String)
69+
tokens2 = str2.chars
70+
str1.chars.each_with_index do |s1, i|
71+
return 1 unless tokens2[i]?
72+
idx1 = CHARSET.index(s1) || -1
73+
idx2 = CHARSET.index(tokens2[i]) || -1
74+
return 1 if idx1 > idx2
75+
return -1 if idx1 < idx2
76+
end
77+
0
78+
end
79+
end
80+
81+
elapsed_time = Time.measure do
82+
Example::Crystal.main
83+
end
84+
puts elapsed_time

0 commit comments

Comments
 (0)