kapusta 0.13.2 → 0.14.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 +50 -11
- data/bin/check-all +6 -1
- data/bin/compile-examples +7 -2
- data/examples/anagram.kap +3 -3
- data/examples/app/args.kap +9 -0
- data/examples/arrange-coins.kap +3 -3
- data/examples/baseball-game.kap +5 -5
- data/examples/best-time-to-buy-sell-stock.kap +2 -2
- data/examples/binary-search.kap +2 -2
- data/examples/binary-to-decimal.kap +1 -1
- data/examples/blocks-and-kwargs.kap +2 -2
- data/examples/count-effects.kap +1 -1
- data/examples/count-items-matching-rule.kap +18 -0
- data/examples/doto-hygiene.kap +2 -2
- data/examples/doto.kap +2 -2
- data/examples/egg-count.kap +1 -1
- data/examples/exceptions.kap +1 -1
- data/examples/falling-drops.kap +7 -7
- data/examples/fennel-parity-examples.txt +3 -6
- data/examples/good-pairs.kap +18 -0
- data/examples/greet.kap +1 -1
- data/examples/happy-number.kap +2 -2
- data/examples/left-right-difference.kap +60 -0
- data/examples/length-of-last-word.kap +4 -4
- data/examples/manhattan-distance.kap +1 -1
- data/examples/maximum-subarray.kap +23 -7
- data/examples/minimum-start-value.kap +19 -0
- data/examples/move-zeroes.kap +2 -2
- data/examples/mruby-runtime-examples.txt +8 -2
- data/examples/non-constant-local.kap +1 -1
- data/examples/number-of-1-bits.kap +1 -1
- data/examples/number-of-steps.kap +1 -1
- data/examples/palindrome.kap +2 -2
- data/examples/pangram.kap +4 -4
- data/examples/pcall.kap +3 -3
- data/examples/pipeline.kap +4 -4
- data/examples/plus-one.kap +3 -3
- data/examples/raindrops.kap +1 -1
- data/examples/range-width.kap +14 -0
- data/examples/recent-counter.kap +6 -6
- data/examples/require-local-args.kap +9 -0
- data/examples/require-local.kap +7 -0
- data/examples/require-module-local.kap +4 -0
- data/examples/require-module.kap +4 -0
- data/examples/reverse-integer.kap +1 -1
- data/examples/roman-to-integer.kap +3 -3
- data/examples/running-sum.kap +20 -0
- data/examples/safe-lookup.kap +2 -2
- data/examples/single-number.kap +1 -1
- data/examples/stack.kap +14 -14
- data/examples/subtract-product-sum.kap +1 -1
- data/examples/summary-ranges.kap +45 -0
- data/examples/threading.kap +5 -5
- data/examples/tset.kap +1 -1
- data/examples/two-sum-hash.kap +3 -3
- data/examples/two-sum.kap +1 -1
- data/examples/ugly-number.kap +1 -1
- data/examples/underground-system.kap +39 -0
- data/examples/valid-parentheses-1.kap +6 -6
- data/exe/kapusta-ls +49 -2
- data/lib/kapusta/ast.rb +8 -0
- data/lib/kapusta/compiler/emitter/bindings.rb +111 -89
- data/lib/kapusta/compiler/emitter/collections.rb +32 -40
- data/lib/kapusta/compiler/emitter/control_flow.rb +33 -31
- data/lib/kapusta/compiler/emitter/expressions.rb +21 -5
- data/lib/kapusta/compiler/emitter/interop.rb +168 -48
- data/lib/kapusta/compiler/emitter/patterns.rb +12 -14
- data/lib/kapusta/compiler/emitter/support.rb +63 -81
- data/lib/kapusta/compiler/language.rb +522 -0
- data/lib/kapusta/compiler/lua_compat.rb +23 -28
- data/lib/kapusta/compiler/macro_expander.rb +30 -30
- data/lib/kapusta/compiler/macro_lowerer.rb +12 -24
- data/lib/kapusta/compiler/normalizer.rb +25 -17
- data/lib/kapusta/compiler.rb +3 -24
- data/lib/kapusta/env.rb +2 -2
- data/lib/kapusta/errors.rb +2 -1
- data/lib/kapusta/formatter/ast_helpers.rb +78 -0
- data/lib/kapusta/formatter/cli.rb +125 -0
- data/lib/kapusta/formatter/line_helpers.rb +44 -0
- data/lib/kapusta/formatter/validator.rb +32 -0
- data/lib/kapusta/formatter.rb +354 -325
- data/lib/kapusta/lsp/identifier.rb +1 -1
- data/lib/kapusta/lsp/rename.rb +21 -11
- data/lib/kapusta/lsp/scope_walker.rb +122 -212
- data/lib/kapusta/lsp/workspace_index.rb +17 -5
- data/lib/kapusta/reader.rb +4 -2
- data/lib/kapusta/version.rb +1 -1
- data/lib/kapusta.rb +39 -6
- data/spec/cli_spec.rb +13 -0
- data/spec/examples_errors_spec.rb +3 -1
- data/spec/examples_spec.rb +67 -15
- data/spec/formatter_spec.rb +246 -0
- data/spec/lsp_spec.rb +69 -0
- data/spec/require_spec.rb +294 -0
- metadata +20 -2
- data/examples/describe.kap +0 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e247dd5e305dcac681bcdb9decbf30d8e0628232626f751c2f39fe8d79796e02
|
|
4
|
+
data.tar.gz: 6d1e24c986c1301045e469b03a76295e03276cee031939ac87dea34187931251
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 919382905342cffcbf1b6986a232f9050dcacfeb196fab8131d9d72a462d8c741e560fe1b72922998bb980a8fb3eeecbda9c348acd694b3299d890b44022132c
|
|
7
|
+
data.tar.gz: 50e77ee9da2df8b1a2f6e694b205dde09e2631d6b49cbc9ddd9cc022e2f86122055abd721d5a82f76af1a2004e78e0f14f2a1b4d02c16cbfb8ee09fb1397a900
|
data/README.md
CHANGED
|
@@ -92,20 +92,59 @@ p ack(2, 3)
|
|
|
92
92
|
p ack(3, 3)
|
|
93
93
|
```
|
|
94
94
|
|
|
95
|
+
## Calls and lookup
|
|
96
|
+
|
|
97
|
+
Hash lookup uses `:`.
|
|
98
|
+
|
|
99
|
+
```fennel
|
|
100
|
+
user:name
|
|
101
|
+
(: user :name)
|
|
102
|
+
(?: user :profile :name) ; safe lookup
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Method calls use `.`.
|
|
106
|
+
|
|
107
|
+
```fennel
|
|
108
|
+
user.name
|
|
109
|
+
(. user :name)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Kapusta source always uses `require`.
|
|
113
|
+
|
|
114
|
+
```fennel
|
|
115
|
+
(require :app.args)
|
|
116
|
+
(local messages (require :app.messages))
|
|
117
|
+
(require "./config")
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Compiled Ruby uses the Ruby form that fits:
|
|
121
|
+
|
|
122
|
+
```ruby
|
|
123
|
+
require "app/args"
|
|
124
|
+
require "app/messages"
|
|
125
|
+
messages = App::Messages
|
|
126
|
+
require_relative "config"
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
For larger programs, organize code with Kapusta's Ruby host forms:
|
|
130
|
+
|
|
131
|
+
1. Use `module` + `defn` for stateless functions.
|
|
132
|
+
2. Use `class` + `fn` for state or dependencies.
|
|
133
|
+
3. Avoid returning hashes of functions as the main app structure.
|
|
134
|
+
|
|
95
135
|
## Comparison with Fennel
|
|
96
136
|
|
|
97
137
|
Kapusta keeps most core Fennel forms. The main differences come from Ruby's runtime and object model.
|
|
98
138
|
|
|
99
|
-
| Fennel | Kapusta
|
|
100
|
-
|
|
101
|
-
| Lua stdlib | Ruby stdlib
|
|
102
|
-
| `:foo` is a Lua string | `:foo` is a Ruby symbol
|
|
103
|
-
| `(. xs 1)` is the first element | `(
|
|
104
|
-
| `string.format`, `table.insert`, etc. | use Ruby methods and stdlib instead
|
|
105
|
-
| `
|
|
106
|
-
| `(
|
|
107
|
-
| `
|
|
108
|
-
| `with-open`, `tail!` | not provided |
|
|
139
|
+
| Fennel | Kapusta |
|
|
140
|
+
|---------------------------------------|-----------------------------------------------------|
|
|
141
|
+
| Lua stdlib | Ruby stdlib |
|
|
142
|
+
| `:foo` is a Lua string | `:foo` is a Ruby symbol |
|
|
143
|
+
| `(. xs 1)` is the first element | `(: xs 0)` is the first element |
|
|
144
|
+
| `string.format`, `table.insert`, etc. | use Ruby methods and stdlib instead |
|
|
145
|
+
| `(print x)` is Lua's `print` (bare) | `(print x)` is Ruby's `p` (inspect-style) |
|
|
146
|
+
| `(.. "x: " nil)` errors at runtime | `(.. "x: " nil)` produces `"x: "` (Ruby `nil.to_s`) |
|
|
147
|
+
| `with-open`, `tail!` | not provided |
|
|
109
148
|
|
|
110
149
|
Kapusta-specific additions:
|
|
111
150
|
|
|
@@ -116,7 +155,7 @@ Kapusta-specific additions:
|
|
|
116
155
|
- `try` / `catch` / `finally` plus `raise` for exceptions
|
|
117
156
|
- `(ruby "...")` raw host escape hatch
|
|
118
157
|
- pass Ruby keyword arguments by ending a call with a symbol-keyed hash: `(File.open path "r" {:encoding "UTF-8"})`
|
|
119
|
-
- pass a Ruby block by ending a call with a `(fn ...)` or `#(...)` literal: `(File.open path "r" (fn [io]
|
|
158
|
+
- pass a Ruby block by ending a call with a `(fn ...)` or `#(...)` literal: `(File.open path "r" (fn [io] io.read))`
|
|
120
159
|
|
|
121
160
|
## Format
|
|
122
161
|
|
data/bin/check-all
CHANGED
|
@@ -8,7 +8,12 @@ echo "== rubocop -A =="
|
|
|
8
8
|
bundle exec rubocop -A
|
|
9
9
|
|
|
10
10
|
echo "== kapfmt =="
|
|
11
|
-
|
|
11
|
+
while IFS= read -r file; do
|
|
12
|
+
./exe/kapfmt --fix "$file"
|
|
13
|
+
done < <(find examples -type f -name '*.kap' | sort)
|
|
14
|
+
|
|
15
|
+
echo "== kapusta-ls =="
|
|
16
|
+
./exe/kapusta-ls --lint examples
|
|
12
17
|
|
|
13
18
|
echo "== fennel parity =="
|
|
14
19
|
bin/fennel-parity
|
data/bin/compile-examples
CHANGED
|
@@ -63,7 +63,10 @@ fi
|
|
|
63
63
|
mkdir -p "$TARGET_DIR"
|
|
64
64
|
|
|
65
65
|
shopt -s nullglob
|
|
66
|
-
kap_files=(
|
|
66
|
+
kap_files=()
|
|
67
|
+
while IFS= read -r kap_file; do
|
|
68
|
+
kap_files+=("$kap_file")
|
|
69
|
+
done < <(find "$SOURCE_DIR" -type f -name '*.kap' | sort)
|
|
67
70
|
|
|
68
71
|
if ((${#kap_files[@]} == 0)); then
|
|
69
72
|
printf 'No .kap files found in %s\n' "$SOURCE_DIR" >&2
|
|
@@ -71,9 +74,11 @@ if ((${#kap_files[@]} == 0)); then
|
|
|
71
74
|
fi
|
|
72
75
|
|
|
73
76
|
for kap_file in "${kap_files[@]}"; do
|
|
74
|
-
|
|
77
|
+
relative_name="${kap_file#"$SOURCE_DIR"/}"
|
|
78
|
+
name="${relative_name%.kap}"
|
|
75
79
|
ruby_file="$TARGET_DIR/$name.rb"
|
|
76
80
|
mruby_file="$TARGET_DIR/$name-mruby.rb"
|
|
81
|
+
mkdir -p "$(dirname "$ruby_file")"
|
|
77
82
|
|
|
78
83
|
"$ROOT_DIR/exe/kapusta" --compile "$kap_file" > "$ruby_file"
|
|
79
84
|
printf 'Compiled %s -> %s\n' "$kap_file" "$ruby_file"
|
data/examples/anagram.kap
CHANGED
data/examples/arrange-coins.kap
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
(fn arrange-coins [n]
|
|
2
2
|
(let [rows (faccumulate [acc {:sum 0 :rows 0} i 1 n]
|
|
3
|
-
(let [new-sum (+
|
|
3
|
+
(let [new-sum (+ acc:sum i)]
|
|
4
4
|
(if (<= new-sum n)
|
|
5
5
|
{:sum new-sum :rows i}
|
|
6
6
|
acc)))
|
|
7
7
|
used (faccumulate [acc {:sum 0 :rows 0} i 1 n]
|
|
8
|
-
(let [new-sum (+
|
|
8
|
+
(let [new-sum (+ acc:sum i)]
|
|
9
9
|
(if (<= new-sum n)
|
|
10
10
|
{:sum new-sum :rows i}
|
|
11
11
|
acc)))]
|
|
12
|
-
[
|
|
12
|
+
[rows:rows used:sum]))
|
|
13
13
|
|
|
14
14
|
(let [[r u] (arrange-coins 0)]
|
|
15
15
|
(print r)
|
data/examples/baseball-game.kap
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
(fn cal-points [ops]
|
|
2
2
|
(let [scores []]
|
|
3
3
|
(each [op ops]
|
|
4
|
-
(if (= op "C") (do (
|
|
5
|
-
(= op "D") (scores
|
|
6
|
-
(= op "+") (scores
|
|
7
|
-
(scores
|
|
8
|
-
scores
|
|
4
|
+
(if (= op "C") (do (. (. scores :pop) :abs) nil)
|
|
5
|
+
(= op "D") (. scores :push (* 2 (: scores -1)))
|
|
6
|
+
(= op "+") (. scores :push (+ (: scores -1) (: scores -2)))
|
|
7
|
+
(. scores :push (. op :to-i))))
|
|
8
|
+
(. scores :sum)))
|
|
9
9
|
|
|
10
10
|
(print (cal-points ["5" "2" "C" "D" "+"]))
|
|
11
11
|
(print (cal-points ["5" "-2" "4" "C" "D" "9" "+" "+"]))
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
(fn max-profit [prices]
|
|
2
|
-
(var min-price (
|
|
2
|
+
(var min-price (: prices 0))
|
|
3
3
|
(var best 0)
|
|
4
4
|
(for [i 1 (- (length prices) 1)]
|
|
5
|
-
(let [p (
|
|
5
|
+
(let [p (: prices i)]
|
|
6
6
|
(when (< p min-price) (set min-price p))
|
|
7
7
|
(when (> (- p min-price) best) (set best (- p min-price)))))
|
|
8
8
|
best)
|
data/examples/binary-search.kap
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
(var hi (- (length xs) 1))
|
|
4
4
|
(var answer nil)
|
|
5
5
|
(while (and (<= lo hi) (= answer nil))
|
|
6
|
-
(let [mid (
|
|
7
|
-
guess (
|
|
6
|
+
(let [mid (. (/ (+ lo hi) 2) :floor)
|
|
7
|
+
guess (: xs mid)]
|
|
8
8
|
(if (= guess target) (set answer mid)
|
|
9
9
|
(< guess target) (set lo (+ mid 1))
|
|
10
10
|
(set hi (- mid 1)))))
|
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
(File.open path
|
|
9
9
|
"w"
|
|
10
10
|
{:encoding "UTF-8"}
|
|
11
|
-
(fn [io] (
|
|
11
|
+
(fn [io] (io.write "Ada\nLin\n")))
|
|
12
12
|
(File.open path
|
|
13
13
|
"r"
|
|
14
14
|
{:encoding "UTF-8"}
|
|
15
15
|
(fn [io]
|
|
16
|
-
(let [content (
|
|
16
|
+
(let [content (io.read)]
|
|
17
17
|
(print (content.strip))
|
|
18
18
|
(print (length (content.lines)))))))
|
|
19
19
|
(finally
|
data/examples/count-effects.kap
CHANGED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
(local rule-keys {"type" :type
|
|
2
|
+
"color" :color
|
|
3
|
+
"name" :name
|
|
4
|
+
"rating" :rating
|
|
5
|
+
"category" :category
|
|
6
|
+
"owner" :owner})
|
|
7
|
+
|
|
8
|
+
(fn count-matches [items rule-key rule-value]
|
|
9
|
+
(let [key (: rule-keys rule-key)]
|
|
10
|
+
(accumulate [count 0 _ item (ipairs items)]
|
|
11
|
+
(if (= (: item key) rule-value) (+ count 1) count))))
|
|
12
|
+
|
|
13
|
+
(let [items [{:type "phone" :color "blue" :name "pixel"}
|
|
14
|
+
{:type "computer" :color "silver" :name "lenovo"}
|
|
15
|
+
{:type "phone" :color "gold" :name "iphone"}]]
|
|
16
|
+
(print (count-matches items "type" "phone"))
|
|
17
|
+
(print (count-matches items "color" "silver"))
|
|
18
|
+
(print (count-matches items "name" "pixel")))
|
data/examples/doto-hygiene.kap
CHANGED
data/examples/doto.kap
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(let [xs (doto [] (
|
|
2
|
-
(print (xs
|
|
1
|
+
(let [xs (doto [] (. :push 1) (. :push 2) (. :push 3))]
|
|
2
|
+
(print (. xs :join ", ")))
|
data/examples/egg-count.kap
CHANGED
data/examples/exceptions.kap
CHANGED
data/examples/falling-drops.kap
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
(fn step [drops]
|
|
2
2
|
(each [_ drop (ipairs drops)]
|
|
3
|
-
(let [falling {:kind
|
|
4
|
-
:x
|
|
5
|
-
:y (+
|
|
6
|
-
:w
|
|
7
|
-
:h
|
|
8
|
-
:speed
|
|
9
|
-
(print
|
|
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
10
|
|
|
11
11
|
(step [{:kind "rain" :x 0 :y 0 :w 1 :h 1 :speed 2}
|
|
12
12
|
{:kind "snow" :x 5 :y 1 :w 1 :h 1 :speed 1}])
|
|
@@ -1,19 +1,15 @@
|
|
|
1
1
|
ackermann
|
|
2
2
|
anonymous-greeter
|
|
3
3
|
array-sign
|
|
4
|
-
arrange-coins
|
|
5
4
|
case-vs-match
|
|
6
5
|
classify-wallet
|
|
7
6
|
climbing-stairs
|
|
8
7
|
convert-temperature
|
|
9
|
-
count-effects
|
|
10
|
-
describe
|
|
11
8
|
destructure
|
|
12
9
|
divisibility-stats
|
|
13
10
|
equal-sums
|
|
14
11
|
even-squares
|
|
15
12
|
factorial
|
|
16
|
-
falling-drops
|
|
17
13
|
fib
|
|
18
14
|
fizzbuzz
|
|
19
15
|
gcd
|
|
@@ -30,18 +26,19 @@ macros-unless
|
|
|
30
26
|
macros-when-let
|
|
31
27
|
match
|
|
32
28
|
max-achievable
|
|
29
|
+
maximum-subarray
|
|
33
30
|
min-max
|
|
34
31
|
nested-nil-pattern
|
|
35
|
-
non-constant-local
|
|
36
32
|
or-patterns
|
|
37
33
|
packet-router
|
|
38
34
|
points
|
|
39
35
|
power-of-three
|
|
40
36
|
primes
|
|
41
|
-
|
|
37
|
+
range-width
|
|
42
38
|
shapes
|
|
43
39
|
squares
|
|
44
40
|
sum
|
|
41
|
+
summary-ranges
|
|
45
42
|
thread-styles
|
|
46
43
|
tic-tac-toe
|
|
47
44
|
underscore-patterns
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
(fn add-good-pairs [pairs counts n]
|
|
2
|
+
(let [prev (or (: counts n) 0)
|
|
3
|
+
next-pairs (+ pairs prev)]
|
|
4
|
+
(tset counts n (+ prev 1))
|
|
5
|
+
(values next-pairs counts)))
|
|
6
|
+
|
|
7
|
+
(fn num-identical-pairs [nums]
|
|
8
|
+
(var pairs 0)
|
|
9
|
+
(var counts {})
|
|
10
|
+
(each [_ n (ipairs nums)]
|
|
11
|
+
(let [(next-pairs next-counts) (add-good-pairs pairs counts n)]
|
|
12
|
+
(set pairs next-pairs)
|
|
13
|
+
(set counts next-counts)))
|
|
14
|
+
pairs)
|
|
15
|
+
|
|
16
|
+
(print (num-identical-pairs [1 2 3 1 1 3]))
|
|
17
|
+
(print (num-identical-pairs [1 1 1 1]))
|
|
18
|
+
(print (num-identical-pairs [1 2 3]))
|
data/examples/greet.kap
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(let [name (or (
|
|
1
|
+
(let [name (or (: ARGV 0) "world")]
|
|
2
2
|
(print (.. "Hello, " name "!")))
|
data/examples/happy-number.kap
CHANGED
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
(while (> x 0)
|
|
5
5
|
(let [d (% x 10)]
|
|
6
6
|
(set total (+ total (* d d)))
|
|
7
|
-
(set x (
|
|
7
|
+
(set x (. (/ x 10) :floor))))
|
|
8
8
|
total)
|
|
9
9
|
|
|
10
10
|
(fn happy? [n]
|
|
11
11
|
(let [seen {}]
|
|
12
12
|
(var x n)
|
|
13
|
-
(while (and (not= x 1) (not (seen
|
|
13
|
+
(while (and (not= x 1) (not (. seen :key? x)))
|
|
14
14
|
(tset seen x true)
|
|
15
15
|
(set x (sum-of-squares x)))
|
|
16
16
|
(= x 1)))
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
(fn same-list? [a b]
|
|
2
|
+
(var ok (= (length a) (length b)))
|
|
3
|
+
(each [i value (ipairs a)]
|
|
4
|
+
(when (not (= value (: b i)))
|
|
5
|
+
(set ok false)))
|
|
6
|
+
ok)
|
|
7
|
+
|
|
8
|
+
(fn abs [n]
|
|
9
|
+
(if (< n 0) (- n) n))
|
|
10
|
+
|
|
11
|
+
(fn left-right-difference [nums]
|
|
12
|
+
(let [total (accumulate [sum 0 _ n (ipairs nums)] (+ sum n))]
|
|
13
|
+
(var left 0)
|
|
14
|
+
(icollect [_ n (ipairs nums)]
|
|
15
|
+
(do
|
|
16
|
+
(let [right (- total left n)
|
|
17
|
+
diff (abs (- left right))]
|
|
18
|
+
(set left (+ left n))
|
|
19
|
+
diff)))))
|
|
20
|
+
|
|
21
|
+
(print (same-list? [209
|
|
22
|
+
206
|
|
23
|
+
201
|
|
24
|
+
194
|
|
25
|
+
185
|
|
26
|
+
174
|
|
27
|
+
161
|
|
28
|
+
146
|
|
29
|
+
129
|
|
30
|
+
110
|
|
31
|
+
89
|
|
32
|
+
66
|
|
33
|
+
41
|
|
34
|
+
14
|
|
35
|
+
15
|
|
36
|
+
46
|
|
37
|
+
79
|
|
38
|
+
114
|
|
39
|
+
151
|
|
40
|
+
190]
|
|
41
|
+
(left-right-difference [1
|
|
42
|
+
2
|
|
43
|
+
3
|
|
44
|
+
4
|
|
45
|
+
5
|
|
46
|
+
6
|
|
47
|
+
7
|
|
48
|
+
8
|
|
49
|
+
9
|
|
50
|
+
10
|
|
51
|
+
11
|
|
52
|
+
12
|
|
53
|
+
13
|
|
54
|
+
14
|
|
55
|
+
15
|
|
56
|
+
16
|
|
57
|
+
17
|
|
58
|
+
18
|
|
59
|
+
19
|
|
60
|
+
20])))
|
|
@@ -1,11 +1,27 @@
|
|
|
1
|
+
(fn max-subarray-step [current best n]
|
|
2
|
+
(let [extended (+ current n)
|
|
3
|
+
next-current (if (> extended n) extended n)
|
|
4
|
+
next-best (if (> next-current best) next-current best)]
|
|
5
|
+
(values next-current next-best)))
|
|
6
|
+
|
|
7
|
+
(fn max-subarray-state [nums]
|
|
8
|
+
(var current 0)
|
|
9
|
+
(var best 0)
|
|
10
|
+
(var initialized? false)
|
|
11
|
+
(each [_ n (ipairs nums)]
|
|
12
|
+
(if initialized?
|
|
13
|
+
(let [(next-current next-best) (max-subarray-step current best n)]
|
|
14
|
+
(set current next-current)
|
|
15
|
+
(set best next-best))
|
|
16
|
+
(do
|
|
17
|
+
(set current n)
|
|
18
|
+
(set best n)
|
|
19
|
+
(set initialized? true))))
|
|
20
|
+
(values current best))
|
|
21
|
+
|
|
1
22
|
(fn max-subarray [nums]
|
|
2
|
-
(
|
|
3
|
-
|
|
4
|
-
(for [i 1 (- (length nums) 1)]
|
|
5
|
-
(let [n (. nums i)]
|
|
6
|
-
(set curr (if (> (+ curr n) n) (+ curr n) n))
|
|
7
|
-
(when (> curr best) (set best curr))))
|
|
8
|
-
best)
|
|
23
|
+
(let [(_current best) (max-subarray-state nums)]
|
|
24
|
+
best))
|
|
9
25
|
|
|
10
26
|
(print (max-subarray [-2 1 -3 4 -1 2 1 -5 4]))
|
|
11
27
|
(print (max-subarray [1]))
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
(fn minimum-start-value [nums]
|
|
2
|
+
(var prefix 0)
|
|
3
|
+
(var lowest 0)
|
|
4
|
+
(each [_ n (ipairs nums)]
|
|
5
|
+
(set prefix (+ prefix n))
|
|
6
|
+
(when (< prefix lowest) (set lowest prefix)))
|
|
7
|
+
(values (+ 1 (- lowest)) prefix))
|
|
8
|
+
|
|
9
|
+
(let [[start total] (minimum-start-value [-3 2 -3 4 2])]
|
|
10
|
+
(print start)
|
|
11
|
+
(print total))
|
|
12
|
+
|
|
13
|
+
(let [[start total] (minimum-start-value [1 2])]
|
|
14
|
+
(print start)
|
|
15
|
+
(print total))
|
|
16
|
+
|
|
17
|
+
(let [[start total] (minimum-start-value [1 -2 -3])]
|
|
18
|
+
(print start)
|
|
19
|
+
(print total))
|
data/examples/move-zeroes.kap
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
(fn move-zeroes [nums]
|
|
2
2
|
(var write 0)
|
|
3
3
|
(for [read 0 (- (length nums) 1)]
|
|
4
|
-
(when (not= (
|
|
5
|
-
(tset nums write (
|
|
4
|
+
(when (not= (: nums read) 0)
|
|
5
|
+
(tset nums write (: nums read))
|
|
6
6
|
(set write (+ write 1))))
|
|
7
7
|
(for [i write (- (length nums) 1)]
|
|
8
8
|
(tset nums i 0))
|
|
@@ -19,8 +19,8 @@ climbing-stairs
|
|
|
19
19
|
contains-duplicate
|
|
20
20
|
convert-temperature
|
|
21
21
|
count-effects
|
|
22
|
+
count-items-matching-rule
|
|
22
23
|
counter
|
|
23
|
-
describe
|
|
24
24
|
destructure
|
|
25
25
|
divisibility-stats
|
|
26
26
|
doto
|
|
@@ -33,12 +33,14 @@ falling-drops
|
|
|
33
33
|
fib
|
|
34
34
|
fizzbuzz
|
|
35
35
|
gcd
|
|
36
|
+
good-pairs
|
|
36
37
|
greet
|
|
37
38
|
happy-number
|
|
38
39
|
hashfn
|
|
39
40
|
hit-counter
|
|
40
41
|
kwargs
|
|
41
42
|
leap-year
|
|
43
|
+
left-right-difference
|
|
42
44
|
length-of-last-word
|
|
43
45
|
macros-dbg
|
|
44
46
|
macros-import
|
|
@@ -55,9 +57,10 @@ match
|
|
|
55
57
|
max-achievable
|
|
56
58
|
maximum-subarray
|
|
57
59
|
min-max
|
|
60
|
+
minimum-start-value
|
|
58
61
|
module-header
|
|
59
|
-
nested-nil-pattern
|
|
60
62
|
move-zeroes
|
|
63
|
+
nested-nil-pattern
|
|
61
64
|
number-of-1-bits
|
|
62
65
|
number-of-steps
|
|
63
66
|
or-patterns
|
|
@@ -70,11 +73,13 @@ points
|
|
|
70
73
|
power-of-three
|
|
71
74
|
primes
|
|
72
75
|
raindrops
|
|
76
|
+
range-width
|
|
73
77
|
recent-counter
|
|
74
78
|
record
|
|
75
79
|
reverse-integer
|
|
76
80
|
roman-to-integer
|
|
77
81
|
ruby-eval
|
|
82
|
+
running-sum
|
|
78
83
|
safe-lookup
|
|
79
84
|
scopes
|
|
80
85
|
shapes
|
|
@@ -84,6 +89,7 @@ squares
|
|
|
84
89
|
stack
|
|
85
90
|
subtract-product-sum
|
|
86
91
|
sum
|
|
92
|
+
summary-ranges
|
|
87
93
|
thread-styles
|
|
88
94
|
threading
|
|
89
95
|
tic-tac-toe
|
data/examples/palindrome.kap
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
(fn palindrome? [s]
|
|
2
|
-
(let [normalized (-> s (
|
|
3
|
-
(= normalized (
|
|
2
|
+
(let [normalized (-> s (. :downcase) (. :gsub (ruby "/[^a-z]/") ""))]
|
|
3
|
+
(= normalized (. normalized :reverse))))
|
|
4
4
|
|
|
5
5
|
(print (palindrome? "racecar"))
|
|
6
6
|
(print (palindrome? "A man, a plan, a canal: Panama"))
|