Making a sudoku solver - clojure

I'm trying to make a sudoku solver program which gets a vector of vectors as an input where each vector inside the vector is a row of the sudoku, where each '0' is an empty cell in the sudoku.
Until now, I've found every possible number a cell with '0' can get.
So the problem is this, after finding which cell has only one possible solution, how will i put that unique solution onto its position despite the immutability of Clojure?
The program needs to return that same vector of vectors where each '0' is replaced by a number which meets the requirements.

If you have a vector of vectors, you can set a cell value using assoc-in e.g.
(def cells [[1 3 0]
[4 2 1]
[6 3 0]])
(defn set-cell-value [board row col value]
(assoc-in board [row col] value))
(set-cell-value cells 0 2 2)

If you need to have state, put it into atom https://clojuredocs.org/clojure.core/atom It is a mutable reference type which holds immutable values.

Related

Clojure Lazy Sequences: Equivalents in Kotlin

Clojure provides means for lazy evaluation of values in (infinite) sequences. With this, values will only be computed when they get actually consumed.
An example of an infinite sequence of one repeated element:
(take 3 (repeat "Hello StackOverflow"))
//=> ("Hello StackOverflow" "Hello StackOverflow" "Hello StackOverflow")
Using take helps to only consume as many elements from the sequence as we want. Without it, an OutOfMemoryError would kill the process quickly.
Another example of an infinite sequence is the following:
(take 5 (iterate inc 1))
//(1 2 3 4 5)
Or a more advanced sequence providing the factorial function:
((defn factorial [n]
(apply * (take n (iterate inc 1)))) 5)
Does Kotlin provide similar sequences? How do they look like?
I answered the question myself in order to document the knowledge here. This is fine according to Can I answer my own question?
In Kotlin, we can also make use of lazy evaluation using Sequences, too. In order to create a sequence, we may use generateSequence (with or without providing a seed.
fun <T : Any> generateSequence(
seed: T?,
nextFunction: (T) -> T?
): Sequence<T> (source)
Returns a sequence defined by the starting value seed and the function nextFunction, which is invoked to calculate the next value based on the previous one on each iteration.
The following will show some examples comparing Clojure with Kotlin sequences.
1. A simple take from an infinite sequence of one static value
Clojure
(take 3 (repeat "Hello StackOverflow"))
Kotlin
generateSequence { "Hello StackOverflow" }.take(3).toList()
These are pretty similar. In Clojure we can use repeat and in Kotlin it's simply generateSequence with a static value that will be yielded for ever. In both cases, take is being used in order to define the number of elements we want to compute.
Note: In Kotlin, we transform the resulting sequence into a list with toList()
2. A simple take from an infinite sequence of an dynamic value
Clojure
(take 5 (iterate inc 1))
Kotlin
generateSequence(1) { it.inc() }.take(5).toList()
This example is a bit different because the sequences yield the increment of the previous value infinitely. The Kotlin generateSequence can be invoked with a seed (here: 1) and a nextFunction (incrementing the previous value).
3. A cyclic repetition of values from a list
Clojure
(take 5 (drop 2 (cycle [:first :second :third ])))
// (:third :first :second :third :first)
Kotlin
listOf("first", "second", "third").let { elements ->
generateSequence(0) {
(it + 1) % elements.size
}.map(elements::get)
}.drop(2).take(5).toList()
In this example, we repeat the values of a list cyclically, drop the first two elements and then take 5. It happens to be quite verbose in Kotlin because repeating elements from the list isn't straightforward. In order to fix it, a simple extension function makes the relevant code more readable:
fun <T> List<T>.cyclicSequence() = generateSequence(0) {
(it + 1) % this.size
}.map(::get)
listOf("first", "second", "third").cyclicSequence().drop(2).take(5).toList()
4. Factorial
Last but not least, let's see how the factorial problem can be solved with a Kotlin sequence. First, let's review the Clojure version:
Clojure
(defn factorial [n]
(apply * (take n (iterate inc 1))))
We take n values from a sequence that yields an incrementing number starting with 1 and accumulate them with the help of apply.
Kotlin
fun factorial(n: Int) = generateSequence(1) { it.inc() }.take(n).fold(1) { v1, v2 ->
v1 * v2
}
Kotlin offers fold which let's us accumulate the values easily.

Clojure loop through a vector starting from the nth element not 0

I would like to loop through a vector starting from the nth element not 0;
How it looks like in Java:
for(int i = firstIndex; i <= lastIndex; i++) {
newText += contents[i] + " ";
}
If you are always dealing with a vector, then subvec is a good choice. For example:
(subvec contents firstIndex)
If you want to be compatible with sequences in general, you'll want to use drop. drop is O(n) w.r.t. the number of elements dropped, which subvec is always O(1). If you're only ever dropping a few elements, the difference is negligible. But for dropping a large number of elements (i.e., large firstIndex), subvec will be a clear winner. But subvec is only available on vectors.
You can use the drop function to skip first n elements and then loop over the result. For example, if you want to skip two first elements:
user=> (drop 2 [1 2 3 4])
(3 4)
The following can possibly do the same that the Java form you provided:
(require '[clojure.string :as str])
(str/join " " (drop first-index contents))

aget returns a java object when applied to a `make-array` array

I expect the following code to return the (0,0) value. Yet I get a java object
(let [axs (make-array Long 5 5 0)]
(aget axs 0 0))
Also I got a type mismatch when trying to mutate index (0,0)
(let [axs (make-array Long 5 5 0)]
(aset axs 0 0 1))
I expect to have initialized a Long[5][5] java array to zero. What am I missing here?
Thanks
Third argument to make-array doesn't initialize your array with zeros, but adds third array dimension, which size is equal to zero. As a result, the size of your array is zero as well. To fix the issue, create your array as follows:
(make-array Long/TYPE 5 5)
This will create array of primitive longs and will initialize it with zeros.

How can I define x as a list of integers to evaluate a polynomial for all elements in x?

The polynomial:
(modulo (+ (expt x 2) 2) 5)
I want to do something like
(define x <list of integers like 0, ..., 10>)
It should then output the result(s) like:
3
1
1
3
...
Do I have to write a separate method to get this working or does Scheme have something built-in?
The way you have it written won't work. In you're polynoimial your taking expt of x directly, which if you define it to be a list, will result in a run-time error.
(map (lambda (x) (modulo (+ (expt x 2) 2) 5)) (iota 11 1 1))
;Value 2: (3 1 1 3 2 3 1 1 3 2 3)
What I did was wrap up your polynomial as an anonymous function, and used it as an argument to map. The second argument (iota count start step) generates a list of length count starting at start and proceeding by and addition of step. start and step are optional argument defaulting to 0 and 1 respectively.
Map is a higher order function which accepts a function as it's first argument and one or more lists afterwards. To simplify thing's I'll ignore cases where more than one list is use. The new list meets the condition that any given element is the result of applying the function to the corresponting element of the original list.
(map f (x y z ...)) -> ((f x) (f y) (f z) ...)
I am not sure what you are asking, but if you want to construct a list of incrementing integers, to each element of which you can apply your polynomial function, SRFI-1 has the iota procedure. So
(iota 10)
will construct a list of 10 integers in the range 0 to 9. iota optionally takes additional start and step arguments. To apply the polynomial function to each integer and construct a new list of the results, you can use map.

Clojure - map function

As we know, (map f [a b c]) is equivalent to [(f a) (f b) (f c)].
My question is: The evaluation result of (map #(- (int %) (int \0)) "1234") is (1 2 3 4), why does it return the results of applying #(- (int %) (int \0)) to every digits of "1234", rather than the string "1234" as a whole? How should I understand this code example?
map calls seq on all arguments after the first. seq turns a string into a sequence of characters.
Clojure can treat a string as a sequence - of characters. This is useful because you can:
map things over the string
partition the string
get locations by index
do everything else sequences do.
It's perhaps a bit annoying having to remember to put the resulting sequence back into a string by wrapping the sequence manipulating expression in a call to str.