(SCHEME) convert words-> Numbers - parsing

I have most of this program down, but I am trying to figure out how to get the grammar done for this program. The program uses a lexer and a parser to turn words into numbers (IE. "million" -> 100000)
I have everything working up to the thousands.
Here is the grammar for the parser
#lang scheme
(S [(zero) $1]
[(L) $1])
(zero [(ZERO) 0])
**(L [(T) $1]
[(T D) (expt (thousands-number $1) 10)]
[(T D L) $1])**
(T [(H) $1]
[(A HUNDRED H) (+ (* $1 100) $3)]
[(A HUNDRED) (* $1 100)])
(H [(B) $1]
[(C) $1]
[(C B) (+ $1 $2)])
(A [(UNDERTEN) (undertwenty-number $1)])
(B [(UNDERTWENTY) (undertwenty-number $1)]
[(A) $1])
(C [(TENS) (tens-number $1)])
(D [(THOUSANDS) (thousands-number $1)])
)
)
)
I'm trying to use exponents to the power of 10 to get the number.
Everything else works below 1000. "eight thousand" just returns 8.

Here is the updated code and Fixed
(S [(zero) $1]
[(L) $1])
(zero [(ZERO) 0])
**(L [(T) $1]
[(T D) (* (expt 10 $2) $1)]
[(T D L) (+ (* (expt 10 $2) $1) $3) ])**
(T [(H) $1]
[(A HUNDRED H) (+ (* $1 100) $3)]
[(A HUNDRED) (* $1 100)])
(H [(B) $1]
[(C) $1]
[(C B) (+ $1 $2)])
(A [(UNDERTEN) (undertwenty-number $1)])
(B [(UNDERTWENTY) (undertwenty-number $1)]
[(A) $1])
(C [(TENS) (tens-number $1)])
(D [(THOUSANDS) (thousands-number $1)])
)
)
)
Will now work for numbers up to a billion.

Related

SICP 3.52 delayed cdr

Exercise 3.52,
(define sum 0)
(define (accum x)
(set! sum (+ x sum))
sum)
;1: (define seq (stream-map accum (stream-enumerate-interval 1 20)))
;2: (define y (stream-filter even? seq))
;3: (define z (stream-filter (lambda (x) (= (remainder x 5) 0))
; seq))
;4: (stream-ref y 7)
;5: (display-stream z)
Step 1:
;1: ==> (cons-stream 1 (stream-map proc (stream-cdr s)) (Assume stream-cdr is evaluated only when we force the cdr of this stream)
sum is now 1
Step 2:
1 is not even, hence (also memoized so not added again), it calls (stream-filter pred (stream-cdr stream)).
This leads to
evaluation of cdr hence materializing 2 which is even, hence it should call: (cons-stream 2 (stream-cdr stream)).
According to this answer should be 1+2 = 3 , but it is 6
Can someone help with why the cdr's car is materialized before the current cdr is called?
Using Daniel P. Friedman's memoizing tail
#lang r5rs
(define-syntax cons-stream
(syntax-rules ()
((_ h t) (cons h (lambda () t)))))
(define (stream-cdr s)
(if (and (not (pair? (cdr s)))
(not (null? (cdr s))))
(set-cdr! s ((cdr s))))
(cdr s))
we observe:
> sum
0
> (define seq (stream-map accum (stream-enumerate-interval 1 20)))
> sum
1
> seq
(mcons 1 #<procedure:friedmans-tail.rkt:21:26>)
> (define y (stream-filter even? seq))
> sum
6
> seq
(mcons
1
(mcons
3
(mcons 6 #<procedure:friedmans-tail.rkt:21:26>)))
> y
(mcons 6 #<procedure:friedmans-tail.rkt:21:26>)
>
stream-filter? needs to get to the first element of the stream it is constructing in order to construct it. A stream has its head element already forced, calculated, so it must be already present.
In the list of accumulated sums of the enumerated interval from 1 to 20, the first even number is 6:
1 = 1
1+2 = 3
1+2+3 = 6
...

Make script work both in DrRacket and (x)repl

I am trying to make a script work from both DrRacket and the repl, having this as my starting point: Racket calculator
Here is my current code:
#lang racket
(provide (all-defined-out))
(require parser-tools/lex
(prefix-in re: parser-tools/lex-sre)
parser-tools/yacc)
(define-tokens value-tokens (INT ANY))
(define-empty-tokens empty-tokens
(PLUS MINUS MULTIPLY DIVIDE NEWLINE EOF))
(define basic-lexer
(lexer
((re:+ numeric) (token-INT lexeme))
(#\+ (token-PLUS))
(#\- (token-MINUS))
(#\* (token-MULTIPLY))
(#\/ (token-DIVIDE))
((re:or #\tab #\space) (basic-lexer input-port))
(#\newline (token-NEWLINE))
((eof) (token-EOF))
(any-char (token-ANY lexeme))))
(define (display-plus expr)
(display "Result: ")
(let ((left (string->number (first expr)))
(right (string->number (last expr))))
(display (+ left right)))
(newline))
(define (display-minus expr)
(display "Result: ")
(let ((left (string->number (first expr)))
(right (string->number (last expr))))
(display (- left right)))
(newline))
(define (display-multiply expr)
(display "Result: ")
(let ((left (string->number (first expr)))
(right (string->number (last expr))))
(display (* left right)))
(newline))
(define (display-divide expr)
(display "Result: ")
(let ((left (string->number (first expr)))
(right (string->number (last expr))))
(display (/ left right)))
(newline))
(define basic-parser
(parser
(start start)
(end NEWLINE EOF)
(tokens value-tokens empty-tokens)
(error (lambda (ok? name value)
(printf "Couldn't parse: ~a\n" name)))
(grammar
(start ((expr) $1)
((expr start) $2))
(expr ((INT PLUS INT) (display-plus (list $1 $3)))
((INT MINUS INT) (display-minus (list $1 $3)))
((INT MULTIPLY INT) (display-multiply (list $1 $3)))
((INT DIVIDE INT) (display-divide (list $1 $3)))
((ANY) (displayln $1))))))
(define input1 (open-input-string "123 + 456"))
(define input2 (open-input-string "123 *456"))
(basic-parser (lambda() (basic-lexer input1)))
(basic-parser (lambda() (basic-lexer input2)))
;(define (my-repl)
; (display ">>> ")
; (let* ((input (read-line))
; (input-port (open-input-string
; (list->string
; (drop-right
; (string->list input) 1)))))
; (cond
; ((not (equal? "\r" input)
; (print (basic-parser
; (lambda () (basic-lexer input-port))))))))
; (my-repl))
(define (calc str)
(let* ([port (open-input-string str)]
[result (basic-parser (lambda() (basic-lexer port)))])
(displayln result)))
(define (repl)
(display ">>> ")
(let ((input (read-line)))
(print input)
(cond
((eof-object? input) (displayln "eof"))
((eq? input #\newline) (displayln "new line"))
(else (calc (read-line))))
(newline))
(repl))
A test from DrRacket is shown here:
Welcome to DrRacket, version 7.1 [3m].
Language: racket, with debugging; memory limit: 512 MB.
Result: 579
Result: 56088
> (repl)
>>> 1+1
"1+1"2+2
Result: 4
#<void>
>>> 3+3
"3+3"4+4
Result: 8
#<void>
And from the repl:
Welcome to Racket v7.1.
> (require "untitled7.rkt")
Result: 579
Result: 56088
> (repl)
>>> "\r"
#<void>
>>> 1+1
"1+1\r"2+2
Result: 4
#<void>
>>> 3+3
"3+3\r"4+4
Result: 8
#<void>
>>> #<eof>eof
>>> ; user break [,bt for context]
It only displays every second calculation. It appears that read-line returns a new line before waiting for user input, which I tried to check with (eof-object? input) and (eq? input #\newline) but now I get only every second result.
There are two problems:
First, you're reading a line, (let ((input (read-line))), but you're not sending that input to the calculator, you'r sending another one – (calc (read-line)).
You should pass input to calc for evaluation instead.
Second, you have a lot of #<void>s in your output.
This is because calc assumes that your parser produces a value that it can print:
(displayln result)
but the parser does not produce any value, it only prints one.
Either remove the output of result, or rewrite the parser to return the value to its caller.
Replace (calc (read-line)) with (calc input).

Write a stream of sexy prime pairs in SCHEME

I have a SCHEME function is-sexy? which takes one parameter, n, and returns true if n is part of a pair of sexy primes and false otherwise, and a SCHEME function, sexy-primes, which takes an integer, n, as a parameter and returns a list of pairs of prime numbers whose difference is 6 and whose smaller number is less than or equal to n.
How do I define a stream of sexy prime pairs?
(define (is-sexy? n)
(define (is-prime? x)
(define (is-prime?-aux x k)
(cond ((< x 1) #f)
((= x k) #t)
(else
(if (= (remainder x k) 0) #f
(is-prime?-aux x (+ k 1))))))
(cond ((= x 1) #t)
((= x 2) #t)
(else (is-prime?-aux x 2))))
(if (and (is-prime? n)
(or (is-prime? (- n 6)) (is-prime? (+ n 6)))) #t
#f))
(define (sexy-primes n)
(if (= n 0) '()
(if (is-sexy? n) (cons n (sexy-primes (- n 1)))
(sexy-primes (- n 1)))))
This works:
(define (sexyprimes-from k)
(if (is-sexy? k) (cons (cons k (+ k 6)) (delay (sexyprimes-from (+ k 1))))
(sexyprimes-from (+ k 1))))
(define sexy-primes (sexyprimes-from 5))

How can i change working of forall in agda?

I am working with pair of Stream of rationals, Lets say (L,R) Where L and R are Stream of rationals. There are 3 conditions which L and R both have to satisfy to say it is valid. I have written the code as..
isCut_ : cut → Set
isCut x = (p q : pair ) →
if((((p mem (getLC x)) ∨ (p mem (getRC x)))) ∧
((not (p mem getLC x)) ∨ (not (p mem getRC x))) ∧
(not (p <pair q) ∨ ((p mem getLC x) ∨ (q mem getRC x))))then ⊤
else ⊥
I really wanted to change the return type of this function to Bool. Here cut means (L, R) and mem is membership.
The problem coming from forall p q which expect return type to be Set.
How should i handle to get desired result.
You can write something like this:
isCut : cut → (p q : pair) → Bool
isCut x p q = (((p mem (getLC x)) ∨ (p mem (getRC x))))
∧ ((not (p mem getLC x)) ∨ (not (p mem getRC x)))
∧ (not (p <pair q) ∨ ((p mem getLC x) ∨ (q mem getRC x))))

Print first N prime numbers in Common Lisp

I am making a Common Lisp function to print the first N prime numbers. So far I've managed to write this code:
;globals
(setf isprime 1) ;if 1 then its a prime, 0 if not.
(setf from 1) ;start from 1
(setf count 0) ;should act as counter to check if we have already
; N primes printed
;function so far.
(defun prime-numbers (to)
(if (> count to) nil(progn
(is-prime from from)
(if (= isprime 1) (print from)(setf count (+ count 1)))
(setf isprime 1)
(setf from (+ from 1))
(prime-numbers to)))
(if (>= count to)(setf count 0) (setf from 1)))
;code to check if a number is prime
(defun is-prime(num val)
(if (< num 3) nil
(progn
(if (= (mod val (- num 1)) 0) (setf isprime 0))
(is-prime (- num 1) val))))
My problem is, it does not print N primes correctly.
If I call >(prime-numbers 10),
results are:
1
2
3
5
7
11
13
17
19
1,
i.e. it printed only 9 primes correctly.
but then if i call >(prime-numbers 2)
the results are: 1
2
3
5
7
1
what am I doing wrong here?? this is my first time to code in LISP.
UPDATE:
(defparameter from 1)
(defparameter count 0)
(defun prime-numbers (to)
(if (> count to)nil
(progn
(when (is-prime from)
(print from)
(setf count (+ count 1)))
(setf from (+ from 1))
(prime-numbers to)))
(when (>= count to)
(setf count 0)
(setf from 1)))
(defun is-prime (n)
(cond ((= 2 n) t)
((= 3 n) t)
((evenp n) nil)
(t
(loop for i from 3 to (isqrt n) by 2
never (zerop (mod n i))))))
works fine. but outputs a NIL at the end.
First, there's no need to use globals here, at all.
Use true/false return values. That would allow your is-prime function to be something like:
(defun is-prime (n)
(cond ((= 2 n) t) ;; Hard-code "2 is a prime"
((= 3 n) t) ;; Hard-code "3 is a prime"
((evenp n) nil) ;; If we're looking at an even now, it's not a prime
(t ;; If it is divisible by an odd number below its square root, it's not prime
(loop for i from 3 to (isqrt n) by 2
never (zerop (mod n i))))))
That way, the function is not relying on any external state and there's nothing that can confuse anything.
Second, the last 1 you see is (probably) the return value from the function.
To check that, try:
(progn (prime-numbers 10) nil)
Third, re-write your prime-numbers function to not use global variables.
Fourth, never create global variables with setf or setq, use either defvar or defparameter. It's also (mostly, but some disagree) good style to use *earmuffs* on your global (really, "special") variables.
To expand on Vatines answer:
A possible rewrite of the prime-numbers function, using the same algoritm but avoiding globals is
(defun prime-numbers (num &optional (from 2))
(cond ((<= num 0) nil)
((is-prime from) (cons from (prime-numbers (1- num) (1+ from))))
(t (prime-numbers num (1+ from)))))
This function also returns the primes instead of printing them.
The problem with this recursive solution is it consumes stack for each prime found/tested. Thus stack space may be exhausted for large values of num.
A non-recursive variant is
(defun prime-numbers (num &optional (start 2))
(loop for n upfrom start
when (is-prime n)
sum 1 into count
and collect n
until (>= count num)))

Resources