Skip to content

Commit

Permalink
Refactorings based on Steffan153's work
Browse files Browse the repository at this point in the history
  • Loading branch information
ingydotnet committed Oct 28, 2024
1 parent 4374e99 commit a9edbba
Show file tree
Hide file tree
Showing 34 changed files with 145 additions and 314 deletions.
3 changes: 1 addition & 2 deletions exercises/practice/acronym/.meta/acronym.ys
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
!yamlscript/v0

defn abbreviate(phrase):
uc(phrase):
.re-seq(/[A-Z']+/)
uc(phrase).re-seq(/[A-Z']+/)
.map(first):join
19 changes: 4 additions & 15 deletions exercises/practice/allergies/.meta/allergies.ys
Original file line number Diff line number Diff line change
@@ -1,20 +1,9 @@
!yamlscript/v0

allergen-map =:
zipmap _ range()::
- eggs
- peanuts
- shellfish
- strawberries
- tomatoes
- chocolate
- pollen
- cats

defn allergic-to(item score):
bit-test score: allergen-map.$item
list-allergens(score).has?(item)

defn list-allergens(score):
keep _ allergen-map:
fn([allergen num]):
bit-test(score num) &&& allergen
(0 .. 7).filter(P(bit-test score))
.map(qw(eggs peanuts shellfish strawberries
tomatoes chocolate pollen cats))
2 changes: 1 addition & 1 deletion exercises/practice/anagram/.meta/anagram.ys
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

defn find-anagrams(subject candidates):
filter _ candidates:
partial _ subject:
P _ subject:
fn(*words):
word1 word2 =: words.map(lc)
word1 != word2 &&:
Expand Down
66 changes: 22 additions & 44 deletions exercises/practice/bank-account/.meta/bank-account.ys
Original file line number Diff line number Diff line change
@@ -1,50 +1,28 @@
!yamlscript/v0

account =: atom(nil)
closed =: 'closed'
closed? =: P(== closed)

defn reset-test-state():
reset! account: nil

defn bank-account(operations):
last:
for operation operations:
operation
.operation
.str('do-' _)
.call(operation)

defn- do-open(op):
when deref(account):
die: 'account already open'
reset! account: 0

defn- do-close(op):
when-not deref(account):
die: 'account not open'
reset! account: nil

defn- do-balance(op):
balance =: deref(account)
if-not balance:
die: 'account not open'
else: balance

defn- do-deposit(op):
when-not deref(account):
die: 'account not open'
swap! account +: op:get-amount

defn- do-withdraw(op):
balance =: deref(account)
when-not balance:
die: 'account not open'
amount =: op:get-amount
when amount > balance:
die: 'amount must be less than balance'
swap! account -: amount

defn- get-amount(op):
amount =: op.amount
if amount < 0:
die: 'amount must be greater than 0'
else: amount
reduce _ closed operations:
fn(bal op):
case op.operation:
-'open':
if closed?(bal): 0, die('account already open')
-'close':
if closed?(bal): die('account not open'), closed
-'balance':
if closed?(bal): die('account not open'), bal
-'deposit':
cond:
closed?(bal): die('account not open')
op.amount <= 0: die('amount must be greater than 0')
else: bal + op.amount
-'withdraw':
cond:
closed?(bal): die('account not open')
op.amount <= 0: die('amount must be greater than 0')
op.amount > bal: die('amount must be less than balance')
else: bal - op.amount
16 changes: 6 additions & 10 deletions exercises/practice/binary-search/.meta/binary-search.ys
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
!yamlscript/v0

defn find(array value):
loop low 0, high array.--:
when low > high:
die: 'value not in array'
mid =: (high + low).quot(2)
item =: array.$mid

cond:
value == item : mid
value < item : recur(low mid.--)
else : recur(mid.++ high)
when array.#.!: die('value not in array')
mid =: array.#.--.quot(2)
case compare(array.$mid value):
0: mid
1: find(take(mid array) value)
-1: find(drop(mid.++ array) value) + mid.++
15 changes: 8 additions & 7 deletions exercises/practice/circular-buffer/.meta/circular-buffer.ys
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
!yamlscript/v0

defn run(capacity operations):
buffer =: M(:B V(capacity * [nil]), :P 0)
buffer =: -{:B V(capacity * [nil]), :P 0}
reduce _ buffer operations:
fn(buffer op):
op item pass want =:
Expand All @@ -10,14 +10,14 @@ defn run(capacity operations):
args =:
condp eq op:
-'clear' : -[buffer]
-'read' : L(buffer pass want)
-'write' : L(buffer pass item)
-'overwrite' : L(buffer pass item)
-'read' : -[buffer pass want]
-'write' : -[buffer pass item]
-'overwrite' : -[buffer pass item]
value("op-$op"): args*
=>: -{}

defn op-clear(buffer):
M: :B V(buffer.B.# * [nil]) :P 0
hash-map: :B V(buffer.B.# * [nil]) :P 0

defn op-read(buffer pass want):
cell =: buffer.B.nth(buffer.P)
Expand All @@ -26,8 +26,9 @@ defn op-read(buffer pass want):
die: S("Can't read:\ " buffer)
when cell != want:
die: "Bad read:\ $cell != $want ($buffer)"
M: :B update-in(buffer.B [buffer.P] constantly(nil))
:P (buffer.P.++ % buffer.B.#)
hash-map:
:B update-in(buffer.B [buffer.P] constantly(nil))
:P (buffer.P.++ % buffer.B.#)

defn op-write(buffer pass item):
B P =: buffer.slice(q(B P))
Expand Down
5 changes: 1 addition & 4 deletions exercises/practice/eliuds-eggs/.meta/eliuds-eggs.ys
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
!yamlscript/v0

defn egg-count(number):
loop num number, eggs 0:
if num > 0:
recur: quot(num 2), eggs.add(num % 2)
else: eggs
len: P(bit-test number).filter(0 .. 31)
2 changes: 1 addition & 1 deletion exercises/practice/etl/.meta/etl.ys
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
defn transform(legacy):
into {}:
for [score letters] legacy, letter letters:
V: lc(letter) score:N
-[lc(letter) score:N]
3 changes: 1 addition & 2 deletions exercises/practice/grains/.meta/grains.ys
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@
defn square(square):
(1 <= square <= 64) |||:
die: 'square must be between 1 and 64'

pow 2: square - 1
2 **: square.--
3 changes: 1 addition & 2 deletions exercises/practice/hamming/.meta/hamming.ys
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@
defn distance(strand1 strand2):
strand1.# == strand2.# ||:
die: 'strands must be of equal length'

len: map(ne strand1 strand2).filter(a)
sum: map(ne strand1 strand2).map(N)
7 changes: 2 additions & 5 deletions exercises/practice/isogram/.meta/isogram.ys
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
!yamlscript/v0

defn isogram(string):
empty?(string) ||:
lc(string):split \"Want to be case insensitive"
.filter(/^[a-z]$/) \"Keep letters only"
.distinct?(*) \"Check if distinct letters"
defn isogram(phrase):
phrase !~ /(?i)(\w).*\1/
8 changes: 1 addition & 7 deletions exercises/practice/list-ops/.meta/list-ops.ys
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,4 @@ defn foldl(list initial function):
list.reduce(function initial)

defn foldr(list initial function):
if len(list) > 0:
function _ list:first:
foldr: rest(list) initial function
else: initial

defn reverse(list):
core/reverse: list
list:reverse.reduce(function initial)
18 changes: 3 additions & 15 deletions exercises/practice/luhn/.meta/luhn.ys
Original file line number Diff line number Diff line change
@@ -1,18 +1,6 @@
!yamlscript/v0

defn valid(value):
digits =: value.replace(' ')

and:
digits.# >=: 2
digits !~: /[^\d]/
digits:split:
.map(to-num):reverse:V
.conj(0).partition(2)
.map(munge):flat:sum
.mod(10).eq(0)

defn munge([a b]):
b *=: 2
vector a:
if b > 9: (b - 9) b
digits =: value.replace(' ').map(\(_ - \\0)):reverse
digits.#.gt(1) &&: digits.every?(\(0 <= _ <= 9)) &&
map(int.comp(mul) digits [1 2.2]:cycle):sum.mod(10).!
19 changes: 5 additions & 14 deletions exercises/practice/matching-brackets/.meta/matching-brackets.ys
Original file line number Diff line number Diff line change
@@ -1,17 +1,8 @@
!yamlscript/v0

pairs =: reverse('()[]{}'):M
opening =: vals(pairs):set
closing =: keys(pairs):set

defn is-paired(value):
loop stack [], [char *chars] value:
cond:
char:nil?: stack:count:zero?
opening(char):
recur: conj(stack char) chars
closing(char):
if peek(stack) == pairs(char):
recur: pop(stack) chars
else: false
else: recur(stack chars)
x =: value.replace(/\[\]|\(\)|\{\}|[^(){}\[\]]/)
cond:
x == '': true
x == value: false
else: is-paired(x)
18 changes: 6 additions & 12 deletions exercises/practice/nth-prime/.meta/nth-prime.ys
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
!yamlscript/v0

defn prime(number):
lazy-primes().nth(number.--)

defn- lazy-primes(d=2 table={}):
if-let factors table.$d:
recur d.++:
reduce _ table.dissoc(d) factors:
\(update-in(%1 [(%2 + d)] conj %2))

lazy-seq:
cons d:
lazy-primes d.++:
assoc table: sqr(d) [d]
loop n 2, u 0:
cond:
u == number: n.--
range(2 sqrt(n):I.++).every?(\((n % _).?)):
recur(n.++ u.++)
else: recur(n.++ u)
8 changes: 3 additions & 5 deletions exercises/practice/nucleotide-count/.meta/nucleotide-count.ys
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
!yamlscript/v0

nucleotides =: zipmap(qw(A C G T) repeat(0))

defn nucleotide-counts(strand):
when strand !~ /^[ACGT]*$/:
when strand =~ /[^ACGT]/:
die: 'Invalid nucleotide in strand'

reduce-kv _ nucleotides frequencies(strand):
fn(map key val): map.assoc(str(key) val)
into zipmap(qw(A C G T) repeat(0)):
frequencies(strand.map(str))
4 changes: 1 addition & 3 deletions exercises/practice/pangram/.meta/pangram.ys
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
!yamlscript/v0

defn is-pangram(sentence):
26 ==: lc(sentence)
.replace(/[^a-z]/)
.distinct():len
B: sentence =~ /(?i)(?>.*?(\pL)(?!.*\1)){26}/
10 changes: 2 additions & 8 deletions exercises/practice/pascals-triangle/.meta/pascals-triangle.ys
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
!yamlscript/v0

defn rows(count):
reduce _ [] range(1 count.++):
fn(tri row):
conj tri:
or _ [1]:
when row > 1:
mapv _ (-1 .. row.sub(2)):
\(last(tri).get(_):N.or(0) +
last(tri).get(_.++):N.or(0))
\(mapv + _.cons(0) _.conj(0))
.iterate([1]).take(count)
9 changes: 4 additions & 5 deletions exercises/practice/perfect-numbers/.meta/perfect-numbers.ys
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
!yamlscript/v0

defn classify(number):
when number <= 0:
when number < 1:
die: 'Classification is only possible for positive integers.'

sum-of-divisors =:
sum:
for n range(1 quot(number 2).++) :when (number % n).!: n
nums =:
for n range(1 quot(number 2).++) :when (number % n).!: n

case compare(sum-of-divisors, number):
case compare(nums:sum number):
0 :: perfect
1 :: abundant
-1 :: deficient
20 changes: 6 additions & 14 deletions exercises/practice/pig-latin/.meta/pig-latin.ys
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
!yamlscript/v0

rules =::
^(?:[aeiou]|yt|xr).*::
\(_ + 'ay')
^(s?qu|thr|sch|[crst]h|[^aeiou])(.*)::
\("$(_.2)$(_.1)ay")

defn translate(phrase):
join ' ':
map _ words(phrase):
fn(word):
reduce-kv _ nil rules:
fn(translated regex function):
match =: word =~ qr(regex)
translated ||:
match && function(match)
replace phrase:
/(?x)
([^aeioquxy\s]*
(?:qu|q|x|y)?)
([aeiouxy]\w*)/
"$2$1ay"
2 changes: 1 addition & 1 deletion exercises/practice/prime-factors/.meta/prime-factors.ys
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ defn factors(value):
or _ []:
when value >= 2:
divisor =: range(2 (value / 2).++)
.filter(\((value % _) == 0)):first || value
.filter(\((value % _).!)).0 || value
into [divisor]: factors(quot(value divisor))
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@

defn proteins(strand):
proteins =:
strand.str('XX').partition(3)
.map(join).map(translate-codon)
strand.re-seq(/.{1,3}/).map(translate)
.take-while(ne('STOP'))

if proteins.has?('INVALID'):
die: 'Invalid codon'
else: proteins

defn translate-codon(codon):
defn translate(codon):
case codon:
('AUG' ) :: Methionine
('UUU' 'UUC' ) :: Phenylalanine
Expand Down
Loading

0 comments on commit a9edbba

Please sign in to comment.