exercism / lfe

Exercism exercises in Lisp Flavoured Erlang (LFE).
https://exercism.org/tracks/lfe
MIT License
25 stars 30 forks source link

Building a training set of tags for lfe #176

Closed iHiD closed 10 months ago

iHiD commented 11 months ago

Hello lovely maintainers :wave:

We've recently added "tags" to student's solutions. These express the constructs, paradigms and techniques that a solution uses. We are going to be using these tags for lots of things including filtering, pointing a student to alternative approaches, and much more.

In order to do this, we've built out a full AST-based tagger in C#, which has allowed us to do things like detect recursion or bit shifting. We've set things up so other tracks can do the same for their languages, but its a lot of work, and we've determined that actually it may be unnecessary. Instead we think that we can use machine learning to achieve tagging with good enough results. We've fine-tuned a model that can determine the correct tags for C# from the examples with a high success rate. It's also doing reasonably well in an untrained state for other languages. We think that with only a few examples per language, we can potentially get some quite good results, and that we can then refine things further as we go.

I released a new video on the Insiders page that talks through this in more detail.

We're going to be adding a fully-fledged UI in the coming weeks that allow maintainers and mentors to tag solutions and create training sets for the neural networks, but to start with, we're hoping you would be willing to manually tag 20 solutions for this track. In this post we'll add 20 comments, each with a student's solution, and the tags our model has generated. Your mission (should you choose to accept it) is to edit the tags on each issue, removing any incorrect ones, and add any that are missing. In order to build one model that performs well across languages, it's best if you stick as closely as possible to the C# tags as you can. Those are listed here. If you want to add extra tags, that's totally fine, but please don't arbitrarily reword existing tags, even if you don't like what Erik's chosen, as it'll just make it less likely that your language gets the correct tags assigned by the neural network.


To summarise - there are two paths forward for this issue:

  1. You're up for helping: Add a comment saying you're up for helping. Update the tags some time in the next few days. Add a comment when you're done. We'll then add them to our training set and move forward.
  2. You not up for helping: No problem! Just please add a comment letting us know :)

If you tell us you're not able/wanting to help or there's no comment added, we'll automatically crowd-source this in a week or so.

Finally, if you have questions or want to discuss things, it would be best done on the forum, so the knowledge can be shared across all maintainers in all tracks.

Thanks for your help! :blue_heart:


Note: Meta discussion on the forum

iHiD commented 11 months ago

Exercise: leap

Code

(defmodule leap
  (export (leap-year 1)))

(defun leap-year
  ((year) (when (== (rem year 400) 0))
   'true)
  ((year) (when (== (rem year 100) 0))
   'false)
  ((year) (when (== (rem year 4) 0))
   'true)
  ((_)
   'false))

Tags:

construct:boolean
construct:integer
construct:module
construct:parameter
construct:quote
construct:function
construct:when
construct:rem
construct:export
construct:tuple
construct:equals
construct:invocation
construct:pattern-matching
construct:year
paradigm:functional
technique:bit-manipulation
technique:boolean-logic
technique:logical-operators
technique:recursion
iHiD commented 11 months ago

Exercise: rna-transcription

Code

(defmodule rna-transcription
  (export (to-rna 1)))

(defun to-rna (nucleotides)
  (lists:map #'map-nucleotide/1 nucleotides))

(defun map-nucleotide
  ((#\G) #\C)
  ((#\C) #\G)
  ((#\T) #\A)
  ((#\A) #\U)
  ((_) '("")))

Tags:

construct:char
construct:function
construct:invocation
construct:list
construct:module
construct:parameter
construct:quote
construct:single-quoted-string
construct:tuple
construct:underscore
paradigm:functional
paradigm:reflective
technique:higher-order-functions
iHiD commented 11 months ago

Exercise: bob

Code

(defmodule bob
  (export (response-for 1)))

(defun question? [phrase]
  (=:= (lists:last phrase) #\?))

(defun whitespace? [phrase]
  (=/= (re:run phrase "^(\\h|\\v)*$") 'nomatch))

(defun yelling? [phrase]
  (andalso (lists:any (lambda [c] (andalso (>= c #\A) (=< c #\Z))) phrase)
           (=:= (string:to_upper phrase) phrase)))

(defun response-for [phrase]
  (cond
    ((whitespace? phrase) "Fine. Be that way!")
    ((yelling? phrase) "Whoa, chill out!")
    ((question? phrase) "Sure.")
    ('true "Whatever.")))

Tags:

construct:andalso
construct:=:=/2
construct:char
construct:cond
construct:constructor-invocation
construct:define-function
construct:export
construct:lambda
construct:list
construct:module
construct:parameter
construct:string
construct:tuple
construct:unicode-char
construct:whitespace
construct:word
paradigm:functional
paradigm:logical
paradigm:object-oriented
technique:boolean-logic
technique:higher-order-functions
iHiD commented 11 months ago

Exercise: bob

Code

(defmodule bob
  (export (response-for 1)))

(defun response-for (in-str)
  (let ((trimmed-in-str (string:trim in-str))
        (yell-answer "Whoa, chill out!")
        (question-answer "Sure.")
        (silence-answer "Fine. Be that way!")
        (else-answer "Whatever."))
    (cond
     ((silence trimmed-in-str) silence-answer)
     ((yell trimmed-in-str) yell-answer)
     ((question trimmed-in-str) question-answer)
     ('true else-answer))))

(defun question
  (("")
   'false)
  ((str)
   (== (lists:last str) #\?)))

(defun yell
  (("")
   'false)
  ((str)
   (and (== (string:uppercase str) str)
        (not (== (string:lowercase str) str)))))

(defun silence (str)
  (== str ""))

Tags:

construct:and
construct:boolean
construct:char
construct:cond
construct:define-function
construct:export
construct:implicit-boolean-conversion
construct:invocation
construct:let
construct:list
construct:module
construct:not
construct:parameter
construct:string
construct:tuple
construct:variable-shadowing
construct:visibility-modifiers
paradigm:functional
paradigm:logical
paradigm:object-oriented
technique:boolean-logic
technique:higher-order-functions
uses:string:trim
iHiD commented 11 months ago

Exercise: sum-of-multiples

Code

(defmodule sum-of-multiples
  (export (sum-of-multiples 2)))

(defun sum-of-multiples (multiples upto)
  (let ((range (lists:seq 1 upto))
         (multiple-of (lambda (mult) (lambda (x) (cond ((== upto x) 'false)
                                             ((== mult x) 'true)
                                             ((== 0 (rem x mult)) 'true)
                                             ('true 'false))) )))
    (lists:sum (lists:umerge
      (lists:map
        (lambda (mult) (lists:filter (funcall multiple-of mult) range))
        multiples)
    ))
  )
)

Tags:

construct:boolean
construct:char
construct:cond
construct:define
construct:export
construct:funcall
construct:function
construct:implicit-visibility
construct:lambda
construct:let
construct:list
construct:map
construct:module
construct:number
construct:parameter
construct:quote
construct:string
construct:sum
construct:tuple
construct:visibility-modifiers
paradigm:functional
paradigm:higher-order-functions
iHiD commented 11 months ago

Exercise: strain

Code

(defmodule strain
  (export (keep 2) (discard 2)))

(defun keep (f elements)
  (lists:filter (lambda (x) (funcall f x)) elements))

(defun discard (f elements)
  (lists:filter (lambda (x) (not (funcall f x))) elements))

Tags:

construct:boolean
construct:defmodule
construct:export
construct:funcall
construct:function
construct:lambda
construct:list
construct:module
construct:parameter
construct:tuple
construct:variable
paradigm:functional
technique:higher-order-functions
iHiD commented 11 months ago

Exercise: strain

Code

(defmodule strain
  (export (keep 2) (discard 2)))

(defun keep
  ((pred ()) ())
  ((pred (cons x more))
   (if (funcall pred x)
     (cons x (keep pred more))
     (keep pred more))))

(defun discard (pred coll)
  (keep (lambda (x) (not (funcall pred x))) coll))

Tags:

construct:boolean
construct:cons
construct:define-function
construct:export
construct:funcall
construct:function
construct:if
construct:lambda
construct:list
construct:module
construct:parameter
construct:recursive-call
construct:tuple
paradigm:functional
technique:higher-order-functions
technique:recursion
iHiD commented 11 months ago

Exercise: hamming

Code

(defmodule hamming
  (export (distance 2)))

(defun distance (a b)
  (lists:sum (lists:zipwith (lambda (x y) (if (== x y) 0 1)) a b)))

Tags:

construct:boolean
construct:define
construct:defmodule
construct:export
construct:expression
construct:if
construct:import
construct:invocation
construct:lambda
construct:list
construct:module
construct:number
construct:parameter
construct:tuple
construct:variable
construct:visibility-modifiers
paradigm:functional
paradigm:object-oriented
technique:higher-order-functions
iHiD commented 11 months ago

Exercise: space-age

Code

(defmodule space-age
  (export (age-on 2)))

(defun age-on (planet seconds)
  (/ seconds (seconds-per-year planet)))

(defun seconds-per-year
  (('earth) 31557600)
  ((planet) (* (ratio-to-earth-year planet)
               (seconds-per-year 'earth))))

(defun ratio-to-earth-year
  (('mercury) 0.2408467)
  (('venus) 0.615197267)
  (('mars) 1.8808158)
  (('jupiter) 11.862615)
  (('saturn) 29.447498)
  (('uranus) 84.016846)
  (('neptune) 164.79132))

Tags:

construct:double
construct:export
construct:floating-point-number
construct:function
construct:invocation
construct:lambda
construct:module
construct:number
construct:parameter
construct:quotient
construct:ratio
construct:tuple
construct:variable
paradigm:functional
iHiD commented 11 months ago

Exercise: grains

Code

(defmodule grains 
  (export all))

(defun square (n)
  (round (math:pow 2 (- n 1))))

(defun total ()
  (- (square 65) 1))

;; recursive

;(defun square (n) 
;  (round (r-square (- n 1) 0)))
;
;(defun r-square 
;  ((0 a) (+ 1 a))
;  ((n a) (let ((m (- n 1))) (r-square m (+ a (math:pow 2 m))))))

Tags:

No tags generated

iHiD commented 11 months ago

Exercise: grains

Code

(defmodule grains
  (export (square 1)
      (total 0)))

(defun square (num)
  (trunc (math:pow 2 (- num 1))))

(defun total ()
  (lists:sum
   (lists:map #'square/1 (lists:seq 1 64))))

Tags:

construct:application
construct:divide
construct:export
construct:float
construct:import
construct:invocation
construct:lambda
construct:list
construct:map
construct:module
construct:number
construct:parameter
construct:subtract
construct:truncation
construct:tuple
construct:zero
paradigm:functional
paradigm:object-oriented
technique:higher-order-functions
iHiD commented 11 months ago

Exercise: anagram

Code

(defmodule anagram
  (export (find 2)))

(defun find (subj candidates)
  "finds candidates that are anagrams of the subject"
  (let* ((lowered (string:lowercase subj))
         (hashed (lists:sort lowered)))
    (lists:filter
      (lambda (word)
        (and
          (!= lowered (string:lowercase word))
          (== hashed (lists:sort (string:lowercase word)))))
      candidates))
)

Tags:

construct:boolean
construct:define
construct:defmodule
construct:export
construct:lambda
construct:let
construct:let*
construct:list
construct:string
construct:underscore
construct:variable
paradigm:functional
technique:higher-order-functions
iHiD commented 11 months ago

Exercise: nucleotide-count

Code

;; For God so loved the world, that He gave His only begotten Son, 
;; that all who believe in Him should not perish but have everlasting life.
(defmodule dna
  (export 
    (count 2)
    (nucleotide-counts 1)))

(defun valid-n-aleluya (nuc_aleluya)
  (if 
    (lists:member (car nuc_aleluya) "ACGT")
    'true
    (erlang:error "ALELUYA")))

(defun count 
  (str_aleluya nuc_aleluya)
  (if
    (valid-n-aleluya nuc_aleluya)
    (lists:flatlength
      (lists:filter
        (lambda 
          (l_aleluya) 
          (and
            (valid-n-aleluya `(,l_aleluya))
            (== `(,l_aleluya) nuc_aleluya)))
        str_aleluya))))

(defun nucleotide-counts (str_aleluya) 
  (lists:map 
    (lambda 
      (c_aleluya)
      `#((,c_aleluya) ,(count str_aleluya `(,c_aleluya) )))
    "ACGT"))

; Matthew 4:17 
; From that time Jesus began to preach, and to say, 
; Repent: for the kingdom of heaven is at hand. -kjv

Tags:

construct:assignment
construct:backquote
construct:boolean
construct:car
construct:comment
construct:constructor
construct:define-function
construct:export
construct:if
construct:implicit-boolean-conversion
construct:invocation
construct:lambda
construct:list
construct:module
construct:number
construct:parameter
construct:quote
construct:string
construct:tuple
construct:undocumented
construct:variable
paradigm:functional
paradigm:reflective
technique:higher-order-functions
iHiD commented 11 months ago

Exercise: nucleotide-count

Code

(defmodule dna
  (export (count 2) (nucleotide-counts 1)))

(defun count (seq nucleotide)
  (if (valid (string:concat seq nucleotide))
    (length
      (lists:filter (lambda (c) (== (list c) nucleotide)) seq))
    (error "Invalid nucleotide")))

(defun nucleotide-counts (seq)
  (lists:map
    (lambda (n) (tuple (list n) (count seq (list n))))
    (nucleotides)))

(defun valid (seq)
  (sets:is_subset
    (sets:from_list seq)
    (sets:from_list (nucleotides))))

(defun nucleotides () "ACGT")

Tags:

construct:boolean
construct:concatenation
construct:define
construct:export
construct:function
construct:if
construct:import
construct:invocation
construct:lambda
construct:length
construct:list
construct:module
construct:number
construct:parameter
construct:set
construct:string
construct:tuple
construct:variable
construct:visibility-modifiers
paradigm:functional
paradigm:imperative
paradigm:declarative
technique:higher-order-functions
uses:Sets
uses:Strings
uses:Tuple
iHiD commented 11 months ago

Exercise: atbash-cipher

Code

;; -*- mode: lisp -*-

(defmodule atbash-cipher
  (export (decode 1)
          (encode 1)))

(defmacro is_lower (c)
  (quote (and (>= c #\a)
              (=< c #\z))))

(defmacro is_upper (c)
  (quote (and (>= c #\A)
              (=< c #\Z))))

(defmacro is_digit (c)
  (quote (and (>= c #\0)
              (=< c #\9))))

(defmacro is_alpha (c)
  (quote (or (is_upper c) (is_lower c))))

(defmacro is_alnum (c)
  (quote (or (is_alpha c) (is_digit c))))

(defun encode (text)
  (encode-and-group text "" 0))

(defun decode (text)
  (decode-and-ungroup text ""))

(defun encode-and-group
  (((cons c cs) acc 0) (when (is_alnum c)) (encode-and-group cs (cons (codec c) (cons #\  acc)) 1))
  (((cons c cs) acc p) (when (is_alnum c)) (encode-and-group cs (cons (codec c) acc) (rem (+ 1 p) 5)))
  (((cons c cs) acc p)                     (encode-and-group cs acc p))
  (('()         acc p)                     (lists:nthtail 1 (lists:reverse acc))))

(defun decode-and-ungroup
  (((cons c cs) acc) (when (is_alnum c)) (decode-and-ungroup cs (cons (codec c) acc)))
  (((cons c cs) acc)                     (decode-and-ungroup cs acc))
  (('()         acc)                     (lists:reverse acc)))

(defun codec
  ((c) (when (is_lower c))   (- (+ #\a #\z) c))
  ((c) (when (is_upper c))   (- (+ #\A #\z) c))
  ((c) (when (is_integer c)) c))

Tags:

construct:add
construct:and
construct:char
construct:cons
construct:define-function
construct:define-macro
construct:export
construct:function
construct:invocation
construct:lambda
construct:list
construct:macro
construct:number
construct:or
construct:parameter
construct:pattern
construct:quote
construct:string
construct:subtract
construct:tuple
construct:underscore
construct:when
construct:zero
paradigm:functional
paradigm:imperative
paradigm:macro-oriented
paradigm:object-oriented
technique:boolean-logic
uses:cons
uses:list
iHiD commented 11 months ago

Exercise: robot-simulator

Code

;; -*- mode: lisp -*-

(defmodule robot-simulator
  (export (create 0)
          (place 3)
          (direction 1)
          (position 1)
          (left 1)
          (right 1)
          (advance 1)
          (control 2)

          ;; gen_server stuff
          (init 1)
          (handle_cast 2)
          (handle_call 3))
  (behaviour gen_server))

(defrecord robot
  pid)

(defrecord robot_info
  (position (tuple 'undefined 'undefined))
  direction)

;; public API
;; ==========

(defun create ()
  (let [((tuple 'ok pid) (gen_server:start_link 'robot-simulator '() '()))]
       (make-robot pid pid)))

(defun place (robot dir pos)
  (let [(pid (robot-pid robot))]
       (begin
        (gen_server:cast pid (tuple 'position  pos))
        (gen_server:cast pid (tuple 'direction dir)))))

(defun direction (rob)
  (gen_server:call (robot-pid rob) 'direction))

(defun position (rob)
  (gen_server:call (robot-pid rob) 'position))

(defun left (rob)
  (gen_server:cast (robot-pid rob) (tuple 'turn 'left)))

(defun right (rob)
  (gen_server:cast (robot-pid rob) (tuple 'turn 'right)))

(defun advance (rob)
  (gen_server:cast (robot-pid rob) 'advance))

(defun control (rob commands)
  (lists:foldl (match-lambda [(#\R _) (right rob)]
                             [(#\L _) (left  rob)]
                             [(#\A _) (advance rob)]
                             [(_   _) 'ok])
               '()
               commands))

;; gen_server API
;; ==============

(defun init (_)
  (tuple 'ok (make-robot_info)))

(defun handle_cast
    [((tuple 'position  pos) ri) (tuple 'noreply (set-robot_info-position  ri pos))]
    [((tuple 'direction dir) ri) (tuple 'noreply (set-robot_info-direction ri dir))]
    [((tuple 'turn 'left)  ri) (handle_cast (tuple 'direction (turn_left  (robot_info-direction ri))) ri)]
    [((tuple 'turn 'right) ri) (handle_cast (tuple 'direction (turn_right (robot_info-direction ri))) ri)]
    [('advance ri) (handle_cast (tuple 'position (advance (robot_info-position ri)
                                                          (robot_info-direction ri)))
                                ri)])

(defun handle_call
    [('direction _ ri) (tuple 'reply (robot_info-direction ri) ri)]
    [('position  _ ri) (tuple 'reply (robot_info-position  ri) ri)])

;; Private helper functions
;; ========================

(defun turn_left
    [('north) 'west]
    [('west)  'south]
    [('south) 'east]
    [('east)  'north])

(defun turn_right
    [('north) 'east]
    [('east)  'south]
    [('south) 'west]
    [('west)  'north])

(defun advance
    [((tuple x y) 'east)  (tuple (+ x 1) y)]
    [((tuple x y) 'west)  (tuple (- x 1) y)]
    [((tuple x y) 'north) (tuple x (+ y 1))]
    [((tuple x y) 'south) (tuple x (- y 1))])

Tags:

construct:add
construct:assignment
construct:begin
construct:behaviour
construct:call
construct:char
construct:comment
construct:constructor
construct:defmodule
construct:defrecord
construct:divide
construct:export
construct:field
construct:foldl
construct:fun
construct:function
construct:implicit-visibility
construct:import
construct:int
construct:invocation
construct:lambda
construct:let
construct:list
construct:module-attribute
construct:multiply
construct:number
construct:parameter
construct:pattern-matching
construct:record
construct:set
construct:subtract
construct:tuple
construct:underscore
construct:variable
paradigm:functional
paradigm:imperative
paradigm:object-oriented
technique:higher-order-functions
uses:RobotSimulator
uses:lists
uses:records
uses:tuples
iHiD commented 11 months ago

Exercise: binary

Code

;; -*- mode: lisp -*-

(defmodule binary-string
  (export (to-decimal 1)))

(defun to-decimal (str)
  (case (lists:foldl #'to-decimal/2 (tuple 'ok 0) str)
    [(tuple 'ok val) val]
    ['error            0]))

(defun to-decimal
    [(#\0 (tuple 'ok acc)) (tuple 'ok (bsl acc 1))]
    [(#\1 (tuple 'ok acc)) (tuple 'ok (+ (bsl acc 1) 1))]
    [(_   _)               'error])

Tags:

construct:binary
construct:bit-shift
construct:case
construct:char
construct:define-function
construct:integer
construct:list
construct:module
construct:number
construct:parameter
construct:pattern-matching
construct:tuple
construct:underscore
paradigm:functional
paradigm:object-oriented
technique:bit-manipulation
technique:bit-shifting
technique:higher-order-functions
iHiD commented 11 months ago

Exercise: accumulate

Code

(defmodule accumulate
    (export (accumulate 2)))

(defun accumulate
  ([f (cons head tail)] (cons (funcall f head) (accumulate f tail)))
  ([f '()] '()))

Tags:

construct:cons
construct:function
construct:module
construct:parameter
construct:quote
construct:tuple
construct:variadic-function
paradigm:functional
paradigm:metaprogramming
technique:higher-order-functions
uses:Cons
iHiD commented 11 months ago

Exercise: accumulate

Code

(defmodule accumulate
  (export (accumulate 2)))

(defun accumulate (function list)
  "lists:map re-implemented"
  (do-accumulate function list []))

(defun do-accumulate
 ((_ [] accumulator)
  (lists:reverse accumulator))
 ((function (cons head tail) accumulator)
  (do-accumulate function tail (cons (funcall function head) accumulator))))

Tags:

construct:cons
construct:do
construct:export
construct:funcall
construct:function
construct:module
construct:parameter
construct:pattern-matching
construct:tail-call
construct:string
construct:underscore
construct:visibility
paradigm:functional
technique:higher-order-functions
technique:recursion
iHiD commented 11 months ago

Exercise: hello-world

Code

(defmodule hello-world
  (export (hello-world 0)))

(defun hello-world ()
  "Hello, world!")

Tags:

construct:module
construct:string
construct:export
construct:function
construct:invocation
construct:method
construct:parameter
construct:quoted-string
construct:visibility
paradigm:functional
ErikSchierboom commented 10 months ago

This is an automated comment

Hello :wave: Next week we're going to start using the tagging work people are doing on these. If you've already completed the work, thank you! If you've not, but intend to this week, that's great! If you're not going to get round to doing it, and you've not yet posted a comment letting us know, could you please do so, so that we can find other people to do it. Thanks!