kapusta 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +10 -2
- data/bin/check-all +17 -0
- data/bin/compile-examples +70 -0
- data/bin/fennel-parity +4 -38
- data/examples/account-lockout.kap +11 -0
- data/examples/accumulator.kap +2 -0
- data/examples/bank-account.kap +2 -0
- data/examples/bst-iterator.kap +52 -0
- data/examples/circle.kap +18 -0
- data/examples/convert-temperature.kap +14 -0
- data/examples/count-effects.kap +13 -0
- data/examples/counter.kap +2 -0
- data/examples/falling-drops.kap +12 -0
- data/examples/fennel-parity-examples.txt +40 -0
- data/examples/hit-counter.kap +2 -0
- data/examples/max-achievable.kap +8 -0
- data/examples/module-header.kap +4 -2
- data/examples/mruby-runtime-examples.txt +92 -0
- data/examples/number-of-1-bits.kap +13 -0
- data/examples/number-of-steps.kap +15 -0
- data/examples/parking-system.kap +2 -0
- data/examples/recent-counter.kap +17 -0
- data/examples/scopes.kap +2 -0
- data/examples/signal-harvest.kap +16 -0
- data/examples/stack.kap +2 -0
- data/examples/two-sum-hash.kap +11 -14
- data/examples/underscore-patterns.kap +1 -1
- data/examples/valid-parentheses-1.kap +2 -0
- data/lib/kapusta/cli.rb +11 -6
- data/lib/kapusta/compiler/emitter/bindings.rb +27 -2
- data/lib/kapusta/compiler/emitter/control_flow.rb +97 -14
- data/lib/kapusta/compiler/emitter/expressions.rb +1 -0
- data/lib/kapusta/compiler/emitter/interop.rb +4 -2
- data/lib/kapusta/compiler/emitter/patterns.rb +125 -0
- data/lib/kapusta/compiler/emitter/support.rb +63 -24
- data/lib/kapusta/compiler/emitter.rb +2 -1
- data/lib/kapusta/compiler/normalizer.rb +6 -0
- data/lib/kapusta/compiler.rb +15 -6
- data/lib/kapusta/errors.rb +6 -0
- data/lib/kapusta/formatter.rb +1 -2
- data/lib/kapusta/lsp/definition.rb +17 -0
- data/lib/kapusta/lsp/rename.rb +3 -1
- data/lib/kapusta/lsp/scope_walker.rb +40 -11
- data/lib/kapusta/lsp.rb +2 -1
- data/lib/kapusta/version.rb +1 -1
- data/lib/kapusta.rb +2 -2
- data/spec/cli_spec.rb +35 -0
- data/spec/examples_errors_spec.rb +20 -0
- data/spec/examples_spec.rb +136 -0
- data/spec/lsp_spec.rb +71 -3
- data/spec/spec_helper.rb +9 -0
- metadata +14 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 326afa9f8872d9d92bf4c3ca32fa5c15f78559691aa447a23472a4042a4f3a4c
|
|
4
|
+
data.tar.gz: 625c013cad69a7e2229ea99a64796c2de90f9fd9665152c74cbd6753c67319f0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2768ae288a6011b651f7e084af68717a3cf6486a45483985fe8eeb7ed9fa9ea3f2ce18c6db77b94e74b130cc10c84c486970569eee760fb82ae858070486049b
|
|
7
|
+
data.tar.gz: 04245b8c5e76773abe1f6c9efde7c64242eaec147e8f07c3d91239a893c25cf2477e4e2b7cec518aa2e82ee948238088d37f68731f41f807aebb6c911c2d03e8
|
data/README.md
CHANGED
|
@@ -4,7 +4,7 @@ Kapusta is a Lisp for the Ruby runtime.
|
|
|
4
4
|
|
|
5
5
|
It is inspired by [Fennel](https://fennel-lang.org). It is not intended to be production-ready like Clojure: that would be a lot of work, and Ruby is already a rich, elegant language.
|
|
6
6
|
|
|
7
|
-
Instead, Kapusta aims to bring some of the simplicity and joy of Lisp to Ruby. Where
|
|
7
|
+
Instead, Kapusta aims to bring some of the simplicity and joy of Lisp to Ruby. Where Fennel uses Lua's stdlib and runtime, Kapusta uses Ruby's. You can use it for small apps, LeetCode, DragonRuby, or maybe even Rails.
|
|
8
8
|
|
|
9
9
|
For more information about Kapusta, see the official Fennel documentation and tutorials.
|
|
10
10
|
|
|
@@ -45,6 +45,12 @@ exe/kapusta --compile examples/fizzbuzz.kap > examples/fizzbuzz.rb
|
|
|
45
45
|
ruby examples/fizzbuzz.rb
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
+
For mruby-compatible output, such as DragonRuby, use:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
exe/kapusta --compile --target=mruby examples/match.kap > examples/match-mruby.rb
|
|
52
|
+
```
|
|
53
|
+
|
|
48
54
|
## Use from Ruby
|
|
49
55
|
|
|
50
56
|
Ruby can require a `.kap` file and use it directly.
|
|
@@ -104,7 +110,9 @@ Kapusta keeps most core Fennel forms. The main differences come from Ruby's runt
|
|
|
104
110
|
Kapusta-specific additions:
|
|
105
111
|
|
|
106
112
|
- `module` and `class` for Ruby host structure, including file-header forms
|
|
107
|
-
- `
|
|
113
|
+
- `(end)` closes a bodyless file-header
|
|
114
|
+
- `(defn name ...)` or `(fn class.name ..)`
|
|
115
|
+
- `ivar` or `@var` / `cvar` or `@@var` / `gvar` or `$var`
|
|
108
116
|
- `try` / `catch` / `finally` plus `raise` for exceptions
|
|
109
117
|
- `(ruby "...")` raw host escape hatch
|
|
110
118
|
- a trailing symbol-keyed hash is emitted as Ruby keyword arguments
|
data/bin/check-all
CHANGED
|
@@ -16,4 +16,21 @@ bin/fennel-parity
|
|
|
16
16
|
echo "== compile examples =="
|
|
17
17
|
bin/compile-examples
|
|
18
18
|
|
|
19
|
+
echo "== run mruby-compatible examples on mruby =="
|
|
20
|
+
MRUBY_RUNTIME_EXAMPLES=()
|
|
21
|
+
while IFS= read -r example || [[ -n "$example" ]]; do
|
|
22
|
+
[[ -n "$example" ]] && MRUBY_RUNTIME_EXAMPLES+=("$example")
|
|
23
|
+
done < examples/mruby-runtime-examples.txt
|
|
24
|
+
|
|
25
|
+
for example in "${MRUBY_RUNTIME_EXAMPLES[@]}"; do
|
|
26
|
+
ruby_file="examples-compiled/$example.rb"
|
|
27
|
+
file="examples-compiled/$example-mruby.rb"
|
|
28
|
+
if [[ ! -f "$file" ]]; then
|
|
29
|
+
file="$ruby_file"
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
ruby "$ruby_file" >/dev/null
|
|
33
|
+
mruby "$file" >/dev/null
|
|
34
|
+
done
|
|
35
|
+
|
|
19
36
|
echo "== Success! =="
|
data/bin/compile-examples
CHANGED
|
@@ -4,6 +4,61 @@ set -euo pipefail
|
|
|
4
4
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
5
5
|
SOURCE_DIR="$ROOT_DIR/examples"
|
|
6
6
|
TARGET_DIR="$ROOT_DIR/examples-compiled"
|
|
7
|
+
tmp_files=()
|
|
8
|
+
MRUBY_RUNTIME_EXAMPLES=()
|
|
9
|
+
|
|
10
|
+
while IFS= read -r example || [[ -n "$example" ]]; do
|
|
11
|
+
[[ -n "$example" ]] && MRUBY_RUNTIME_EXAMPLES+=("$example")
|
|
12
|
+
done < "$SOURCE_DIR/mruby-runtime-examples.txt"
|
|
13
|
+
|
|
14
|
+
cleanup() {
|
|
15
|
+
rm -f "${tmp_files[@]}"
|
|
16
|
+
}
|
|
17
|
+
trap cleanup EXIT
|
|
18
|
+
|
|
19
|
+
is_mruby_runtime_example() {
|
|
20
|
+
local name="$1"
|
|
21
|
+
|
|
22
|
+
for example in "${MRUBY_RUNTIME_EXAMPLES[@]}"; do
|
|
23
|
+
[[ "$name" == "$example" ]] && return 0
|
|
24
|
+
done
|
|
25
|
+
|
|
26
|
+
return 1
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
needs_mruby_artifact() {
|
|
30
|
+
local name="$1"
|
|
31
|
+
local ruby_file="$2"
|
|
32
|
+
local ruby_stdout
|
|
33
|
+
local ruby_stderr
|
|
34
|
+
local mruby_stdout
|
|
35
|
+
local mruby_stderr
|
|
36
|
+
|
|
37
|
+
is_mruby_runtime_example "$name" || return 1
|
|
38
|
+
|
|
39
|
+
ruby_stdout="$(mktemp)"
|
|
40
|
+
ruby_stderr="$(mktemp)"
|
|
41
|
+
mruby_stdout="$(mktemp)"
|
|
42
|
+
mruby_stderr="$(mktemp)"
|
|
43
|
+
tmp_files+=("$ruby_stdout" "$ruby_stderr" "$mruby_stdout" "$mruby_stderr")
|
|
44
|
+
|
|
45
|
+
if ! ruby "$ruby_file" > "$ruby_stdout" 2> "$ruby_stderr"; then
|
|
46
|
+
printf 'Compiled example failed under ruby: %s\n' "$ruby_file" >&2
|
|
47
|
+
cat "$ruby_stderr" >&2
|
|
48
|
+
exit 1
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
if ! mruby "$ruby_file" > "$mruby_stdout" 2> "$mruby_stderr"; then
|
|
52
|
+
return 0
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
! cmp -s "$ruby_stdout" "$mruby_stdout"
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (($# > 0)); then
|
|
59
|
+
printf 'usage: bin/compile-examples\n' >&2
|
|
60
|
+
exit 1
|
|
61
|
+
fi
|
|
7
62
|
|
|
8
63
|
mkdir -p "$TARGET_DIR"
|
|
9
64
|
|
|
@@ -18,7 +73,22 @@ fi
|
|
|
18
73
|
for kap_file in "${kap_files[@]}"; do
|
|
19
74
|
name="$(basename "$kap_file" .kap)"
|
|
20
75
|
ruby_file="$TARGET_DIR/$name.rb"
|
|
76
|
+
mruby_file="$TARGET_DIR/$name-mruby.rb"
|
|
21
77
|
|
|
22
78
|
"$ROOT_DIR/exe/kapusta" --compile "$kap_file" > "$ruby_file"
|
|
23
79
|
printf 'Compiled %s -> %s\n' "$kap_file" "$ruby_file"
|
|
80
|
+
|
|
81
|
+
if needs_mruby_artifact "$name" "$ruby_file"; then
|
|
82
|
+
tmp_mruby="$(mktemp)"
|
|
83
|
+
tmp_files+=("$tmp_mruby")
|
|
84
|
+
"$ROOT_DIR/exe/kapusta" --compile --target=mruby "$kap_file" > "$tmp_mruby"
|
|
85
|
+
if cmp -s "$ruby_file" "$tmp_mruby"; then
|
|
86
|
+
rm -f "$mruby_file"
|
|
87
|
+
else
|
|
88
|
+
mv "$tmp_mruby" "$mruby_file"
|
|
89
|
+
printf 'Compiled %s -> %s\n' "$kap_file" "$mruby_file"
|
|
90
|
+
fi
|
|
91
|
+
else
|
|
92
|
+
rm -f "$mruby_file"
|
|
93
|
+
fi
|
|
24
94
|
done
|
data/bin/fennel-parity
CHANGED
|
@@ -9,44 +9,10 @@ EXAMPLES_ERRORS = File.join(ROOT, 'examples-errors')
|
|
|
9
9
|
KAPUSTA = File.join(ROOT, 'exe', 'kapusta')
|
|
10
10
|
KAPFMT = File.join(ROOT, 'exe', 'kapfmt')
|
|
11
11
|
|
|
12
|
-
COMPATIBLE =
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
climbing-stairs.kap
|
|
17
|
-
describe.kap
|
|
18
|
-
destructure.kap
|
|
19
|
-
even-squares.kap
|
|
20
|
-
factorial.kap
|
|
21
|
-
fib.kap
|
|
22
|
-
fizzbuzz.kap
|
|
23
|
-
gcd.kap
|
|
24
|
-
hashfn.kap
|
|
25
|
-
leap-year.kap
|
|
26
|
-
macros-dbg.kap
|
|
27
|
-
macros-import-helpers.kap
|
|
28
|
-
macros-import-whole.kap
|
|
29
|
-
macros-import.kap
|
|
30
|
-
macros-multi.kap
|
|
31
|
-
macros-swap.kap
|
|
32
|
-
macros-thrice-if.kap
|
|
33
|
-
macros-unless.kap
|
|
34
|
-
macros-when-let.kap
|
|
35
|
-
match.kap
|
|
36
|
-
min-max.kap
|
|
37
|
-
or-patterns.kap
|
|
38
|
-
power-of-three.kap
|
|
39
|
-
packet-router.kap
|
|
40
|
-
points.kap
|
|
41
|
-
primes.kap
|
|
42
|
-
safe-lookup.kap
|
|
43
|
-
shapes.kap
|
|
44
|
-
squares.kap
|
|
45
|
-
sum.kap
|
|
46
|
-
thread-styles.kap
|
|
47
|
-
tic-tac-toe.kap
|
|
48
|
-
underscore-patterns.kap
|
|
49
|
-
].freeze
|
|
12
|
+
COMPATIBLE = File.readlines(File.join(EXAMPLES, 'fennel-parity-examples.txt'), chomp: true)
|
|
13
|
+
.reject(&:empty?)
|
|
14
|
+
.map { |name| "#{name}.kap" }
|
|
15
|
+
.freeze
|
|
50
16
|
|
|
51
17
|
def run(cmd, file, chdir: EXAMPLES, env: {})
|
|
52
18
|
out, err, status = Open3.capture3(env, cmd, file, chdir:)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
(local max-missed 3)
|
|
2
|
+
|
|
3
|
+
(fn classify [guesses]
|
|
4
|
+
(var missed 0)
|
|
5
|
+
(each [_ g (ipairs guesses)]
|
|
6
|
+
(when (= g 1) (set missed (+ missed 1))))
|
|
7
|
+
(if (< missed max-missed) :ok :locked))
|
|
8
|
+
|
|
9
|
+
(print (classify [0 1 0 1]))
|
|
10
|
+
(print (classify [1 1 1]))
|
|
11
|
+
(print (classify [1 1 1 0]))
|
data/examples/accumulator.kap
CHANGED
data/examples/bank-account.kap
CHANGED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
(class TreeNode)
|
|
2
|
+
|
|
3
|
+
(fn initialize [val left right]
|
|
4
|
+
(set @val val)
|
|
5
|
+
(set @left left)
|
|
6
|
+
(set @right right))
|
|
7
|
+
|
|
8
|
+
(fn val [] @val)
|
|
9
|
+
(fn left [] @left)
|
|
10
|
+
(fn right [] @right)
|
|
11
|
+
|
|
12
|
+
(end)
|
|
13
|
+
|
|
14
|
+
(class BSTIterator)
|
|
15
|
+
|
|
16
|
+
(fn initialize [root]
|
|
17
|
+
(set @stack [])
|
|
18
|
+
(self.push-left root))
|
|
19
|
+
|
|
20
|
+
(fn push-left [node]
|
|
21
|
+
(var n node)
|
|
22
|
+
(while n
|
|
23
|
+
(let [stack @stack]
|
|
24
|
+
(stack.push n))
|
|
25
|
+
(set n (n.left))))
|
|
26
|
+
|
|
27
|
+
(fn next []
|
|
28
|
+
(let [stack @stack
|
|
29
|
+
node (stack.pop)]
|
|
30
|
+
(self.push-left (node.right))
|
|
31
|
+
(node.val)))
|
|
32
|
+
|
|
33
|
+
(fn has-next? []
|
|
34
|
+
(let [stack @stack]
|
|
35
|
+
(not (stack.empty?))))
|
|
36
|
+
|
|
37
|
+
(end)
|
|
38
|
+
|
|
39
|
+
(let [root (TreeNode.new 7
|
|
40
|
+
(TreeNode.new 3 nil nil)
|
|
41
|
+
(TreeNode.new 15
|
|
42
|
+
(TreeNode.new 9 nil nil)
|
|
43
|
+
(TreeNode.new 20 nil nil)))
|
|
44
|
+
it (BSTIterator.new root)]
|
|
45
|
+
(print (it.next))
|
|
46
|
+
(print (it.next))
|
|
47
|
+
(print (it.has-next?))
|
|
48
|
+
(print (it.next))
|
|
49
|
+
(print (it.has-next?))
|
|
50
|
+
(print (it.next))
|
|
51
|
+
(print (it.next))
|
|
52
|
+
(print (it.has-next?)))
|
data/examples/circle.kap
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
(class Circle)
|
|
2
|
+
|
|
3
|
+
(local pi 3.14159)
|
|
4
|
+
|
|
5
|
+
(fn initialize [radius]
|
|
6
|
+
(set @radius radius))
|
|
7
|
+
|
|
8
|
+
(fn area []
|
|
9
|
+
(* pi @radius @radius))
|
|
10
|
+
|
|
11
|
+
(fn circumference []
|
|
12
|
+
(* 2 pi @radius))
|
|
13
|
+
|
|
14
|
+
(end)
|
|
15
|
+
|
|
16
|
+
(let [c (Circle.new 5)]
|
|
17
|
+
(print (c.area))
|
|
18
|
+
(print (c.circumference)))
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
(local KELVIN-OFFSET 273.15)
|
|
2
|
+
(local FAHRENHEIT-SCALE 1.8)
|
|
3
|
+
(local FAHRENHEIT-OFFSET 32.0)
|
|
4
|
+
|
|
5
|
+
(fn convert-temperature [celsius]
|
|
6
|
+
(let [k (+ celsius KELVIN-OFFSET)
|
|
7
|
+
f (+ (* celsius FAHRENHEIT-SCALE) FAHRENHEIT-OFFSET)]
|
|
8
|
+
[k f]))
|
|
9
|
+
|
|
10
|
+
(let [[k f] (convert-temperature 36.5)]
|
|
11
|
+
(print k f))
|
|
12
|
+
|
|
13
|
+
(let [[k f] (convert-temperature 122.11)]
|
|
14
|
+
(print k f))
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
(fn count-by-kind [effects]
|
|
2
|
+
(var quits 0)
|
|
3
|
+
(var moves 0)
|
|
4
|
+
(each [_ effect (ipairs effects)]
|
|
5
|
+
(case (. effect :kind)
|
|
6
|
+
:quit (set quits (+ quits 1))
|
|
7
|
+
:move (set moves (+ moves 1))
|
|
8
|
+
_ nil))
|
|
9
|
+
[quits moves])
|
|
10
|
+
|
|
11
|
+
(let [effects [{:kind :move} {:kind :quit} {:kind :move} {:kind :other}]
|
|
12
|
+
[q m] (count-by-kind effects)]
|
|
13
|
+
(print q m))
|
data/examples/counter.kap
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
(fn step [drops]
|
|
2
|
+
(each [_ drop (ipairs drops)]
|
|
3
|
+
(let [falling {:kind (. drop :kind)
|
|
4
|
+
:x (. drop :x)
|
|
5
|
+
:y (+ (. drop :y) (. drop :speed))
|
|
6
|
+
:w (. drop :w)
|
|
7
|
+
:h (. drop :h)
|
|
8
|
+
:speed (. drop :speed)}]
|
|
9
|
+
(print (. falling :kind) (. falling :x) (. falling :y)))))
|
|
10
|
+
|
|
11
|
+
(step [{:kind "rain" :x 0 :y 0 :w 1 :h 1 :speed 2}
|
|
12
|
+
{:kind "snow" :x 5 :y 1 :w 1 :h 1 :speed 1}])
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
ackermann
|
|
2
|
+
anonymous-greeter
|
|
3
|
+
classify-wallet
|
|
4
|
+
climbing-stairs
|
|
5
|
+
convert-temperature
|
|
6
|
+
count-effects
|
|
7
|
+
describe
|
|
8
|
+
destructure
|
|
9
|
+
even-squares
|
|
10
|
+
factorial
|
|
11
|
+
falling-drops
|
|
12
|
+
fib
|
|
13
|
+
fizzbuzz
|
|
14
|
+
gcd
|
|
15
|
+
hashfn
|
|
16
|
+
leap-year
|
|
17
|
+
macros-dbg
|
|
18
|
+
macros-import-helpers
|
|
19
|
+
macros-import-whole
|
|
20
|
+
macros-import
|
|
21
|
+
macros-multi
|
|
22
|
+
macros-swap
|
|
23
|
+
macros-thrice-if
|
|
24
|
+
macros-unless
|
|
25
|
+
macros-when-let
|
|
26
|
+
match
|
|
27
|
+
max-achievable
|
|
28
|
+
min-max
|
|
29
|
+
or-patterns
|
|
30
|
+
power-of-three
|
|
31
|
+
packet-router
|
|
32
|
+
points
|
|
33
|
+
primes
|
|
34
|
+
safe-lookup
|
|
35
|
+
shapes
|
|
36
|
+
squares
|
|
37
|
+
sum
|
|
38
|
+
thread-styles
|
|
39
|
+
tic-tac-toe
|
|
40
|
+
underscore-patterns
|
data/examples/hit-counter.kap
CHANGED
data/examples/module-header.kap
CHANGED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
account-lockout
|
|
2
|
+
accumulator
|
|
3
|
+
ackermann
|
|
4
|
+
anagram
|
|
5
|
+
anonymous-greeter
|
|
6
|
+
bank-account
|
|
7
|
+
baseball-game
|
|
8
|
+
best-time-to-buy-sell-stock
|
|
9
|
+
binary-search
|
|
10
|
+
binary-to-decimal
|
|
11
|
+
block-sort
|
|
12
|
+
bst-iterator
|
|
13
|
+
calc
|
|
14
|
+
circle
|
|
15
|
+
classify-wallet
|
|
16
|
+
climbing-stairs
|
|
17
|
+
contains-duplicate
|
|
18
|
+
convert-temperature
|
|
19
|
+
count-effects
|
|
20
|
+
counter
|
|
21
|
+
describe
|
|
22
|
+
destructure
|
|
23
|
+
doto-hygiene
|
|
24
|
+
doto
|
|
25
|
+
egg-count
|
|
26
|
+
even-squares
|
|
27
|
+
exceptions
|
|
28
|
+
factorial
|
|
29
|
+
falling-drops
|
|
30
|
+
fib
|
|
31
|
+
fizzbuzz
|
|
32
|
+
gcd
|
|
33
|
+
greet
|
|
34
|
+
happy-number
|
|
35
|
+
hashfn
|
|
36
|
+
hit-counter
|
|
37
|
+
kwargs
|
|
38
|
+
leap-year
|
|
39
|
+
length-of-last-word
|
|
40
|
+
macros-dbg
|
|
41
|
+
macros-import-helpers
|
|
42
|
+
macros-import-whole
|
|
43
|
+
macros-import
|
|
44
|
+
macros-multi
|
|
45
|
+
macros-swap
|
|
46
|
+
macros-thrice-if
|
|
47
|
+
macros-unless
|
|
48
|
+
macros-when-let
|
|
49
|
+
majority-element
|
|
50
|
+
manhattan-distance
|
|
51
|
+
match
|
|
52
|
+
max-achievable
|
|
53
|
+
maximum-subarray
|
|
54
|
+
min-max
|
|
55
|
+
module-header
|
|
56
|
+
move-zeroes
|
|
57
|
+
number-of-1-bits
|
|
58
|
+
number-of-steps
|
|
59
|
+
or-patterns
|
|
60
|
+
packet-router
|
|
61
|
+
parking-system
|
|
62
|
+
pipeline
|
|
63
|
+
pivot-index
|
|
64
|
+
plus-one
|
|
65
|
+
points
|
|
66
|
+
power-of-three
|
|
67
|
+
primes
|
|
68
|
+
raindrops
|
|
69
|
+
recent-counter
|
|
70
|
+
record
|
|
71
|
+
reverse-integer
|
|
72
|
+
roman-to-integer
|
|
73
|
+
ruby-eval
|
|
74
|
+
safe-lookup
|
|
75
|
+
scopes
|
|
76
|
+
shapes
|
|
77
|
+
signal-harvest
|
|
78
|
+
single-number
|
|
79
|
+
squares
|
|
80
|
+
stack
|
|
81
|
+
subtract-product-sum
|
|
82
|
+
sum
|
|
83
|
+
thread-styles
|
|
84
|
+
threading
|
|
85
|
+
tic-tac-toe
|
|
86
|
+
tset
|
|
87
|
+
two-sum-hash
|
|
88
|
+
two-sum
|
|
89
|
+
ugly-number
|
|
90
|
+
underscore-patterns
|
|
91
|
+
valid-parentheses-1
|
|
92
|
+
zoo-animal-1
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
(local BIT-WIDTH 32)
|
|
2
|
+
|
|
3
|
+
(fn hamming-weight [n]
|
|
4
|
+
(var x n)
|
|
5
|
+
(var count 0)
|
|
6
|
+
(for [_ 1 BIT-WIDTH]
|
|
7
|
+
(set count (+ count (% x 2)))
|
|
8
|
+
(set x (: (/ x 2) :floor)))
|
|
9
|
+
count)
|
|
10
|
+
|
|
11
|
+
(print (hamming-weight 11))
|
|
12
|
+
(print (hamming-weight 128))
|
|
13
|
+
(print (hamming-weight 4294967293))
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
(local target 0)
|
|
2
|
+
|
|
3
|
+
(fn steps-to-zero [n]
|
|
4
|
+
(var x n)
|
|
5
|
+
(var steps 0)
|
|
6
|
+
(while (not= x target)
|
|
7
|
+
(if (= 0 (% x 2))
|
|
8
|
+
(set x (: (/ x 2) :floor))
|
|
9
|
+
(set x (- x 1)))
|
|
10
|
+
(set steps (+ steps 1)))
|
|
11
|
+
steps)
|
|
12
|
+
|
|
13
|
+
(print (steps-to-zero 14))
|
|
14
|
+
(print (steps-to-zero 8))
|
|
15
|
+
(print (steps-to-zero 123))
|
data/examples/parking-system.kap
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
(class RecentCounter)
|
|
2
|
+
(fn initialize [] (set @pings []))
|
|
3
|
+
(fn ping [t]
|
|
4
|
+
(let [pings @pings]
|
|
5
|
+
(pings.push t)
|
|
6
|
+
(while (< (. pings 0) (- t 3000))
|
|
7
|
+
(pings.shift))
|
|
8
|
+
(length pings)))
|
|
9
|
+
(defn warm [history]
|
|
10
|
+
(let [c (RecentCounter.new)]
|
|
11
|
+
(each [_ t (ipairs history)] (c.ping t))
|
|
12
|
+
c))
|
|
13
|
+
(end)
|
|
14
|
+
|
|
15
|
+
(let [c (RecentCounter.warm [100 200 300])]
|
|
16
|
+
(print (c.ping 3001))
|
|
17
|
+
(print (c.ping 3002)))
|
data/examples/scopes.kap
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
(module SignalHarvest)
|
|
2
|
+
|
|
3
|
+
(local SCREEN-W 1280)
|
|
4
|
+
(local TARGET-SCORE 36)
|
|
5
|
+
|
|
6
|
+
(defn cell-width [columns]
|
|
7
|
+
(/ SCREEN-W columns))
|
|
8
|
+
|
|
9
|
+
(defn win? [score]
|
|
10
|
+
(>= score TARGET-SCORE))
|
|
11
|
+
|
|
12
|
+
(end)
|
|
13
|
+
|
|
14
|
+
(print (SignalHarvest.cell-width 32))
|
|
15
|
+
(print (SignalHarvest.win? 40))
|
|
16
|
+
(print (SignalHarvest.win? 12))
|
data/examples/stack.kap
CHANGED
data/examples/two-sum-hash.kap
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
(let [
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
(set i (+ i 1)))
|
|
13
|
-
answer)
|
|
14
|
-
]
|
|
1
|
+
(let [two-sum-hash (fn [nums target seen]
|
|
2
|
+
(var i 0)
|
|
3
|
+
(var answer nil)
|
|
4
|
+
(while (and (< i (length nums)) (= answer nil))
|
|
5
|
+
(let [n (. nums i)
|
|
6
|
+
complement (- target n)]
|
|
7
|
+
(if (seen.key? complement)
|
|
8
|
+
(set answer [(. seen complement) i])
|
|
9
|
+
(tset seen n i)))
|
|
10
|
+
(set i (+ i 1)))
|
|
11
|
+
answer)]
|
|
15
12
|
(print (two-sum-hash [2 7 11 15] 9 {}))
|
|
16
13
|
(print (two-sum-hash [3 2 4] 6 {}))
|
|
17
14
|
(print (two-sum-hash [1 2 3] 10 {})))
|