Something wrong with
(def b [08])
java.lang.NullPointerException: null
but
(def b [8])
is OK
why?
I know nothing about clojure, but in many languages, an integer literal that starts with a zero is interpreted as octal (base 8). And 8 is an invalid octal digit.
From a quick experiment at Try Clojure:
> (def b [08])
java.lang.NumberFormatException: Invalid number: 08
> (def b [07])
#'sandbox155/b
It appears that this is indeed your problem.
Don't start integers with a leading zero (e.g. 08), unless you actually intend octal notation.
#Jonathon Reinhart is right, according to the LispReader.java :(https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.java#L65) :
static Pattern intPat =
Pattern.compile(
"([-+]?)(?:(0)|([1-9][0-9]*)|0[xX]([0-9A-Fa-f]+)|0([0-7]+)|([1-9][0-9]?)[rR]([0-9A-Za-z]+)|0[0-9]+)(N)?");
The part 0([0-7]+) in the pattern prove this.
Related
(def conversions {"G" "C"
"C" "G"
"T" "A"
"A" "U"})
(defn to-rna [dna]
(map conversions dna)
)
(conversions "G") ;; Gives "C"
(to-rna "GC") ;; Gives (nil nil)
I'm attempting to do an exercise where I convert letters. I have a working solution, but I don't like it. I feel like the above ought to work, but evidently I'm wrong, because it doesn't.
Could someone explain to me why this is, and how I might properly achieve this?
When mapping over a string, it will treat the string as a sequence of characters. So, your code ends up looking for a \G and a \C entry in the map, which both return nil.
As dpassen says, you need to put a java.lang.Character in the map, not a length-1 string. Try this:
(def conversions { \G \C
\C \G
\T \A
\A \U })
I'm just starting learning Clojure myself so please take this answer with caution.
In addition to what's been already suggested, I would put the conversions map into a let form to keep your function "isolated". (As is, your function relies on a conversions being defined outside of its scope).
I also read (can't remember where exactly) that a common naming convention when writing functions that "convert" X to Y should be named as follow: x->y.
Finally I'd use a threading macro for improved readability.
(defn dna->rna [dna]
(let [conversions {\G \C
\C \G
\T \A
\A \U}]
(->> dna
(map conversions)
(string/join ""))))
(dna->rna "GC")
;; "CG"
FYI, Clojure has clojure.string/escape and clojure.string/replace that you might want to look at. escape is probably most similar to what you are doing.
Please, how can I write this in clojure? I have an # character and I want to compare it to "#".
eg (= # "#")
gives error (ClassCastException java.lang.String cannot be cast to java.util.concurrent.Future clojure.core/deref-future (core.clj:2206))
There's an inherent conflict in this comparison, in that "#" is a string sequence of characters and \# is an individual character. If you wanted to confirm that the string consisted of a single character which matched the \# symbol, something like the following would be work:
(let [s "#"]
(and (= \# (first s)) (= (count s) 1)))
However, if you want to detect if the string contains any \# characters or if it just started with an \# character, that requires different code. This is the problem with comparing strings and characters -- it's not inherently obvious what you need from the comparison.
Why do you get the error? The reader translates your example into ...
(= (deref "#"))
The deref function tests whether the argument is deref-able (implementing IDeref). If not, it treats the argument as a future. It isn't, so it throws the confusing exception. This behaviour is a defect, albeit a minor one.
By the way, (= x) returns true for any x, if it returns at all.
Tim Clemons' answer shows what you can do about this.
Yoy can quote your # using \# for Clojure to interpret it as a character literal. By default # is a reader macro for a deref form to make many other things in clojure less verbose. Anyway:
(= \# \#)
true
If you want to check that the first character of a string is a # then:
(= \# (first "#"))
true
The following only works in Clojurescript as it doesn't have a character type and just uses strings of length one.
(= \# "#")
true ;; in cljs only
So I did a problem earlier that said:
L(r) = {w in {a,b}* : w contains at least 2 a's}
For that one I said {a^2n , b} because that guarantees a string like aab or aabaab etc. Not sure how to approach the one I posted about in the title. Possibly a solution might be a^2n, b^2m so its always even, but also 2 odd numbers like a^n b^3m is also always even. Am i allowed to set boundaries like n>=m?
Thank you!
You correctly observe that n and m must either be both even or both odd. It only needs to be added that an odd number is one more than an even number.
A simple regular expression for "an even number of as" ( {a2n : n ≥ 0}) is (aa)*, while "an odd number of as" is (aa)*a.
Building on that, we can two cases for the original question: (aa)*(bb)* and (aa)*a(bb)*b, which can be combined into (aa)*(ab+ε)(bb)*. (Assuming you are using + for alternation and ε for the empty string.)
r=((a+b)^2)* ,i think this regular expression is also giving the right answer
I'm using clojure.core.match and seeing the following error:
Can't let qualified name
My code resembles:
(match [msg-type]
[MsgType/TYPE_1] (do-type-1-thing)
[MsgType/TYPE_2] (do-type-2-thing))
Where MsgType/TYPE_1 comes from a Java class:
public class MsgType {
public static final String TYPE_1 = "1";
public static final String TYPE_2 = "2";
}
What does this error mean, and how can I work around it?
The problem seems related to macro name binding, though I don't understand it deeply as I'm quite new to macros.
Originally I hoped using case rather than match would prove a viable workaround:
(case msg-type
MsgType/TYPE_1 (do-type-1-thing)
MsgType/TYPE_2 (do-type-2-thing))
However the above doesn't work. case matches on the symbol MsgType/TYPE_n, not the evaluation of that symbol.
The best I've found so far is to convert the value coming in to a keyword and match that way:
(def type->keyword
{MsgType/TYPE_1 :type-1
MsgType/TYPE_2 :type-2})
(case (type->keyword msg-type)
:type-1 (do-type-1-thing)
:type-2 (do-type-2-thing))
In general, pattern matching is not the right tool for comparing one variable with another. Patterns are supposed to be either literals such as 1 or :a, destructuring expressions or variables to be bound. So, for example, take this expression:
(let [a 1
b 2]
(match [2]
[a] "It matched A"
[b] "It matched B"))
You might expect it to yield "It matched B" since the variable b is equal to 2, but in fact it will bind the value 2 to a new variable named a and yield "It matched A".
I think you're looking for condp =. It's basically what you wish case would be.
(condp = msg-type
MsgType/TYPE_1 (do-type-1-thing)
MsgType/TYPE_2 (do-type-2-thing))
a) Start and end with a number
b) Hyphen should start and end with a number
c) Comma should start and end with a number
d) Range of number should be from 1-31
[Edit: Need this rule in the regex, thanks Ed-Heal!]
e) If a number starts with a hyphen (-), it cannot end with any other character other than a comma AND follow all rules listed above.
E.g. 2-2,1 OR 2,2-1 is valid while 1-1-1-1 is not valid
E.g.
a) 1-5,5,15-29
b) 1,28,1-31,15
c) 15,25,3 [Edit: Replaced 56 with 3, thanks for pointing it out Brian!]
d) 1-24,5-6,2-9
Tried this but it passes even if the string starts with a comma:
/^[0-9]*(?:-[0-9]+)*(?:,[0-9]+)*$/
How about this? This will check rules a, b and c, at least, but does not check rule d.
/^[0-9]+(-[0-9]+)?(,[0-9]+(-[0-9]+)?)*$/
If you need to ensure that all the numbers are in the range 1-31, then the expression will get a whole lot uglier:
/^([1-9]|[12][0-9]|3[01])(-([1-9]|[12][0-9]|3[01]))?(,([1-9]|[12][0-9]|3[01])(-([1-9]|[12][0-9]|3[01]))?)*$/
Note that your example c contains a number, 56, that does not fall within the range 1-31, so it will not pass the second expression.
try this
^\d+(-\d+)?(,\d+(-\d+)?)*$
DEMO
Here is my workings
Numbers:
0|([1-9][0-9]*) call this expression A Note this expression treats zero as a special case and prevents numbers starting with a zero eg 0000001234
Number or a range:
A|(A-A) call this expression B (i.e (0|([1-9][0-9]*))|((0|([1-9][0-9]*))-(0|([1-9][0-9]*)))
Comma operator
B(,B)*
Putting this togher should do the trick and we get
((0|([1-9][0-9]*))|((0|([1-9][0-9]*))-(0|([1-9][0-9]*))))(,((0|([1-9][0-9]*))|((0|([1-9][0-9]*))-(0|([1-9][0-9]*)))))*
You can abbreviatge this with \d for [0-9]
The other approaches have not restricted the allowed range of numbers. This allows 1 through 31 only, and seems simpler than some of the monstrosities people have come up with ...
^([12][0-9]?|3[01]?|[4-9])([-,]([12][0-9]?|3[01]?|[4-9]))*$
There is no check for sensible ranges; adding that would make the expression significantly more complex. In the end you might be better off with a simpler regex and implementing sanity checks in code.
I propose the following regex:
(?<number>[1-9]|[12]\d|3[01]){0}(?<thing>\g<number>-\g<number>|\g<number>){0}^(\g<thing>,)*\g<thing>$
It looks awful but it isn't :) In fact the construction (?<name>...){0} allows us to define a named regex and to say that it doesn't match where it is defined. Thus I defined a pattern for numbers called number and a pattern for what I called a thing i.e. a range or number called thing. Next I know that your expression is a sequence of those things, so I use the named regex thing to build it with the construct \g<thing>. It gives (\g<thing>,)*\g<thing>. That's easy to read and understand. If you allow whitespaces to be non significant in your regex, you could even indent it like this:
(?<number>[1-9]|[12]\d|3[01]){0}
(?<thing>\g<number>-\g<number>|\g<number>){0}
^(\g<thing>,)*\g<thing>$/
I tested it with Ruby 1.9.2. Your regex engine should support named groups to allow that kind of clarity.
irb(main):001:0> s1 = '1-5,5,15-29'
=> "1-5,5,15-29"
irb(main):002:0> s2 = '1,28,1-31,15'
=> "1,28,1-31,15"
irb(main):003:0> s3 = '15,25,3'
=> "15,25,3"
irb(main):004:0> s4 = '1-24,5-6,2-9'
=> "1-24,5-6,2-9"
irb(main):005:0> r = /(?<number>[1-9]|[12]\d|3[01]){0}(?<thing>\g<number>-\g<number>|\g<number>){0}^(\g<thing>,)*\g<thing>$/
=> /(?<number>[1-9]|[12]\d|3[01]){0}(?<thing>\g<number>-\g<number>|\g<number>){0}^(\g<thing>,)*\g<thing>$/
irb(main):006:0> s1.match(r)
=> #<MatchData "1-5,5,15-29" number:"29" thing:"15-29">
irb(main):007:0> s2.match(r)
=> #<MatchData "1,28,1-31,15" number:"15" thing:"15">
irb(main):008:0> s3.match(r)
=> #<MatchData "15,25,3" number:"3" thing:"3">
irb(main):009:0> s4.match(r)
=> #<MatchData "1-24,5-6,2-9" number:"9" thing:"2-9">
irb(main):010:0> '1-1-1-1'.match(r)
=> nil
Using the same logic in my previous answer but limiting the range
A becomes [1-9]\d|3[01]
B becomes ([1-9]\d|3[01])|(([1-9]\d|3[01])-([1-9]\d|3[01]))
Overall expression
(([12]\d|3[01])|(([12]\d|3[01])-([12]\d|3[01])))(,(([12]\d|3[01])|(([12]\d|3[01])-([12]\d|3[01]))))*
An optimal Regex for this topic could be:
^(?'int'[1-2]?[1-9]|3[01])((,\g'int')|(-\g'int'(?=$|,)))*$
demo