I am writing a sudoku solver. It has been a long time since I have touched prolog, thus I don't remember everything regarding unification, backtracking, etc. I think that I cause the system to backtrack forever (but I don't get any stack exceptions - at least not immediately). This is what I have so far (the puzzle can be found at http://en.wikipedia.org/wiki/File:Sudoku-by-L2G-20050714.svg):
% representation of the example puzzle
puzzle([5, 3, _, _, 7, _, _, _, _],
[6, _, _, 1, 9, 5, _, _, _],
[_, 9, 8, _, _, _, _, 6, _],
[8, _, _, _, 6, _, _, _, 3],
[4, _, _, 8, _, 3, _, _, 1],
[7, _, _, _, 2, _, _, _, 6],
[_, 6, _, _, _, _, 2, 8, _],
[_, _, _, 4, 1, 9, _, _, 5],
[_, _, _, _, 8, _, _, 7, 9]).
% solve(S)
% the starting point of the program
% saves the solution in the variable S
solve(R1, R2, C1) :-
% save the rows into variables
puzzle(R1, R2, R3, R4, R5, R6, R7, R8, R9),
% solve for each row
allunique(R1), allunique(R2), allunique(R3),
allunique(R4), allunique(R5), allunique(R6),
allunique(R7), allunique(R8), allunique(R9),
% the columns must be created first
nelement(R1, 1, C11), nelement(R2, 1, C21), nelement(R3, 1, C31),
nelement(R4, 1, C41), nelement(R5, 1, C51), nelement(R6, 1, C61),
nelement(R7, 1, C71), nelement(R8, 1, C81), nelement(R9, 1, C91),
C1 = [C11, C21, C31, C41, C51, C61, C71, C81, C91],
allunique(C1).
% allunique(List)
% Succeeds if all the numbers of List are between 1-9
% and each number exists only once
allunique([]). % Recursion stops when the list is empty
% A member should be between 1-9 and not a member of the tail
allunique([H|T]) :-
allunique(T),
member(H, [1, 2, 3, 4, 5, 6, 7, 8, 9]),
not(member(H, T)).
% nelement(List, N-th, X)
% Saves the nth element of a list in variable X
nelement([H|_], 1, H). % The first element is the head
% All other elements will be found in the tail
nelement([_|T], N, X) :-
N > 1,
N1 is N-1,
nelement(T, N1, X).
The line allunique(C1) causes the problem. It seems that the system puts a 7 in the first empty box of the 1st column and never changes it (or at least not in the near future). An example C1 list is [5, 6, 7, 8, 4, 7, 9, 8, 6]. I am curious to find out why this is happening.
Your example list [5, 6, 7, 8, 4, 7, 9, 8, 6] doesn't satisfy allunique since it contains 8 twice.
solve/3 is incorrect since it checks all rows, but only one column and no "region" (the 3x3 squares).
The solve/1 predicate promised in the comments doesn't appear, so I can't test your code; allunique/1 and nelement/3 seem fine.
Even if you complete this program, I doubt it's ever going to return an answer. I've seen similar Prolog programs run for hours without finding the solution. Check out CLP(fd) if you want to do this fast (link is for SWI, but SICStus, GNU, and ECLiPSe have similar libraries.)
Related
Let's say I have a vector a = [1, 0, 1, 2, 3, 4, 5, 0, 5, 6, 7, 8, 0, 9, 0] and I want to split it to smaller vectors based on a condition depending on value in that array. E.g. value being zero.
Thus I want to obtain vector of following vectors
[1, 0]
[1, 2, 3, 4, 5, 0]
[5, 6, 7, 8, 0]
[9, 0]
So far this was working for me as a naive solution, but it loses the type.
function split_by_λ(a::Vector, λ)
b = []
temp = []
for i in a
push!(temp, i)
if λ(i)
push!(b, temp)
temp = []
end
end
b
end
split_by_λ(a, isequal(0))
Then I tried to play with ranges, which feels a bit more idiomatic, and does not lose the type.
function split_by_λ(a::Vector, λ)
idx = findall(λ, a)
ranges = [(:)(i==1 ? 1 : idx[i-1]+1, idx[i]) for i in eachindex(idx)]
map(x->a[x], ranges)
end
split_by_λ(a, isequal(0))
but it still feels very cumbersome regarding it's a rather simple task.
Is there something I'm missing, some easier way?
Maybe someone has a shorter idea but here is mine:
julia> inds = vcat(0,findall(==(0),a),length(a))
julia> getindex.(Ref(a), (:).(inds[1:end-1].+1,inds[2:end]))
5-element Array{Array{Int64,1},1}:
[1, 0]
[1, 2, 3, 4, 5, 0]
[5, 6, 7, 8, 0]
[9, 0]
[]
Or if you want to avoid copying a
julia> view.(Ref(a), (:).(inds[1:end-1].+1,inds[2:end]))
5-element Array{SubArray{Int64,1,Array{Int64,1},Tuple{UnitRange{Int64}},true},1}:
[1, 0]
[1, 2, 3, 4, 5, 0]
[5, 6, 7, 8, 0]
[9, 0]
0-element view(::Array{Int64,1}, 16:15) with eltype Int64
Pretty much the same as Przemyslaw's answer, but maybe less cryptic dense:
function split_by(λ, a::Vector)
first, last = firstindex(a), lastindex(a)
splits = [first-1; findall(λ, a); last]
s1, s2 = #view(splits[1:end-1]), #view(splits[2:end])
return [view(a, i1+1:i2) for (i1, i2) in zip(s1, s2)]
end
Also, I changed the signature to the conventional one of "functions first", which allows you to use do-blocks. Additionally, this should work with offset indexing.
One could surely get rid of the intermediate allocations, but I think that gets ugly without yield:
function split_by(λ, a::Vector)
result = Vector{typeof(view(a, 1:0))}()
l = firstindex(a)
r = firstindex(a)
while r <= lastindex(a)
if λ(a[r])
push!(result, #view(a[l:r]))
l = r + 1
end
r += 1
end
push!(result, #view(a[l:end]))
return result
end
how can I find the next number in this sequence ,
1, 4, 7, 8, 13, 12, 9 , ?
How to check , given any sequence of numbers , feasible or not. Any general theory or approach is very much welcomed .
One method is to go to the Online Encyclopedia of Integer Sequences and enter your list of at least six or eight numbers into the box and see if that happens to be a known sequence. For your example this doesn't find a known sequence.
If that doesn't work then you can try Mathematica's FindFormula
p=FindFormula[{1, 4, 7, 8, 13, 12, 9}];
and then
p[1] returns 1, p[2] returns 4, p[3] returns 7... and p[8] returns 106, etc.
You can read the documentation on FindFormula and you can look at the formula p by using InputForm[p] where #1 represents a variable in the function p.
In general I think this is rarely going to produce the result that you are looking for.
seq = FindSequenceFunction[{1, 4, 7, 8, 13, 12, 9}, n]
(48 - 74 n - 14 n^2 + 11 n^3 - n^4)/(3 (-13 + 3 n))
Checking the 7th number
n = 7;
seq
9
The next number is a fraction, apparently
n = 8;
seq
32/11
Show[Plot[seq, {n, 1, 10}],
ListPlot[Table[seq, {n, 1, 10}]],
PlotRange -> {{0, 10}, {-20, 30}}, AxesOrigin -> {0, 0}]
What is julian way to do yield (and yield from) as python do?
Edit: I will try to add small example in python.
Think 4x4 chess board. Find every N moves long path chess king could do. Don't waste memory -> make generator of every path.
if we sign every position with numbers:
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 16
point 0 has 3 neighbors (1, 4, 5). We could find table for every neighbors for every point:
NEIG = [[1, 4, 5], [0, 2, 4, 5, 6], [1, 3, 5, 6, 7], [2, 6, 7], [0, 1, 5, 8, 9], [0, 1, 2, 4, 6, 8, 9, 10], [1, 2, 3, 5, 7, 9, 10, 11], [2, 3, 6, 10, 11], [4, 5, 9, 12, 13], [4, 5, 6, 8, 10, 12, 13, 14], [5, 6, 7, 9, 11, 13, 14, 15], [6, 7, 10, 14, 15], [8, 9, 13], [8, 9, 10, 12, 14], [9, 10, 11, 13, 15], [10, 11, 14]]
Recursive function (generator) which enlarge given path from list of points or from generator of (generator of ...) points:
def enlarge(path):
if isinstance(path, list):
for i in NEIG[path[-1]]:
if i not in path:
yield path[:] + [i]
else:
for i in path:
yield from enlarge(i)
Function (generator) which give every path with given length
def paths(length):
steps = ([i] for i in range(16)) # first steps on every point on board
for _ in range(length-1):
nsteps = enlarge(steps)
steps = nsteps
yield from steps
We could see that there is 905776 paths with length 10:
sum(1 for i in paths(10))
Out[89]: 905776
In ipython we could timeit:
%timeit sum(1 for i in paths(10))
1.21 s ± 15.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
My julia implementation is ugly and much more complicated. And it seems to be slower.
Check out ResumableFunctions.jl
from the README
using ResumableFunctions
#resumable function fibonnaci(n::Int) :: Int
a = 0
b = 1
for i in 1:n-1
#yield a
a, b = b, a+b
end
a
end
for fib in fibonnaci(10)
println(fib)
end
You can use Julia Iterators.
struct Fibonacci
last::Int64
end
function Base.iterate(fibo::Fibonacci)
return 1, (1, 1, 2) # the first output, and the next iteration state
end
function Base.iterate(fibo::Fibonacci, state)
i, a, b = state
if i ≤ fibo.last
return a, (i + 1, b, a + b) # the output, and the next iteration state
end
end
You can then use it like this:
for i in Fibonacci(10)
print(i, " ")
end
Which outputs:
1 1 2 3 5 8 13 21 34 55 89
This can result in excellent performance, but it is often a bit verbose, and it's also tricky to decide on what iteration state to use, and how to find the next element given that state. In your chess example, I would avoid this approach, but in other cases it can come in really handy.
You can use Channels:
function fibo(n)
Channel() do ch
a, b = 0, 1
for _ in 1:n
a, b = b, a + b
put!(ch, a)
end
end
end
Use it like this:
for val in fibo(10)
print(val, " ")
end
Which outputs:
1 1 2 3 5 8 13 21 34 55
To get the yield from behavior, you can just use a for loop. For example, to get the Fibonacci sequence r times:
function repeat_fibo(r, n)
Channel() do ch
for _ in 1:r
for val in fibo(n)
put!(ch, val)
end
end
end
end
For more details, see the docs.
Note that the ResumableFunctions.jl library has some benchmarks showing that their solution is significantly faster than using Channels (see #gggg's answer). Perhaps Channel performance will improve in future Julia versions.
To get better Channel performance, you should set the channel's element type and the channel's size: for example, use Channel{Int64}(100) instead of Channel().
Here's a Julia implementation of your chess problem using Channels:
NEIG = [[1, 4, 5], [0, 2, 4, 5, 6], [1, 3, 5, 6, 7], [2, 6, 7], [0, 1, 5, 8, 9],
[0, 1, 2, 4, 6, 8, 9, 10], [1, 2, 3, 5, 7, 9, 10, 11], [2, 3, 6, 10, 11],
[4, 5, 9, 12, 13], [4, 5, 6, 8, 10, 12, 13, 14],
[5, 6, 7, 9, 11, 13, 14, 15], [6, 7, 10, 14, 15], [8, 9, 13],
[8, 9, 10, 12, 14], [9, 10, 11, 13, 15], [10, 11, 14]]
function paths(start, length)
Channel{Vector{Int64}}(100) do ch
if length == 1
put!(ch, [start])
else
for path in paths(start, length - 1)
for next_step in NEIG[path[end] + 1]
next_step in path || put!(ch, [path; next_step])
end
end
end
end
end
function paths(length)
Channel{Vector{Int64}}(100) do ch
for start in 0:15
for path in paths(start, length)
put!(ch, path)
end
end
end
end
You can count all the paths of length 10 much like in Python:
sum(1 for _ in paths(10))
You can also time it:
#time sum(1 for _ in paths(10))
On my machine this takes about 4 seconds. There are probably ways to optimize this further, but this does show that Channel performance still has some room for improvement.
I've got this case statement which is giving an error 'variable constant1 is unused'. It seems to be ignoring the variables and returning the top line, so the variables obviously haven't got scope. If I replace the constant with a number 1 then it works. What is the best way of doing this in Elixir?
defmodule Main
do
def constant1, do: 1
def constant2, do: 1
def constant3, do: 1
x = 1
y = 0
z = 0
{a, b, c, d} =
case {x, y, z} do
{constant1, constant2, constant3} -> {1, 2, 3, 4}
{constant1, constant2, _} -> {5, 6, 7, 8}
{constant1, _, _} -> {9, 10, 11, 12}
{_, _, _} -> {13, 14, 15, 16}
end
IO.inspect {a, b, c, d}
end
Here is the output:
warning: variable constant1 is unused
Untitled 9:15
{1, 2, 3, 4}
Changing the constants to variables also doesn't work.
You have defined constant1 being a function. When you try to use it in pattern matching, Elixir expects the variable to be there and you’ve got an error. One can’t pattern match to functions.
What you’ve wanted is likely:
defmodule Main do
constant1 = 1
constant2 = 1
constant3 = 1
x = 1
y = 0
z = 0
{a, b, c, d} =
case {x, y, z} do
{^constant1, ^constant2, ^constant3} -> {1, 2, 3, 4}
{^constant1, ^constant2, _} -> {5, 6, 7, 8}
{^constant1, _, _} -> {9, 10, 11, 12}
{_, _, _} -> {13, 14, 15, 16}
end
IO.inspect {a, b, c, d}
end
#⇒ { 9, 10, 11, 12 }
Also, please remember that to pattern match to already defined value, one should use the pin operator ^ in front of matcher, otherwise the code
a = 42
case x do
a -> ...
end
will overwrite the value of a, setting it to the value of x (in the scope of case block, outside of case a will remain 42.) With ^, the code below will match if and only x == 42:
a = 42
case x do
^a -> ...
end
Answering the subsequent questions about “how to,” “can I use globals,” etc.
Elixir (as all known functional languages) has no notion of “global,” since everything is immutable from the outside point of view. True constants are being implemented as macros. Macros are compiled during the compilation stage to AST and therefore might be used as constants inside match:
defmodule Constants do
defmacro constant1 do
quote do: 1
end
defmacro constant2 do
quote do: 1
end
defmacro constant3 do
quote do: 1
end
end
defmodule Main do
require Constants
x = 1
y = 0
z = 0
{a, b, c, d} =·
case {x, y, z} do
{Constants.constant1, Constants.constant2, Constants.constant3} -> {1, 2, 3, 4}
{Constants.constant1, Constants.constant2, _} -> {5, 6, 7, 8}
{Constants.constant1, _, _} -> {9, 10, 11, 12}
{_, _, _} -> {13, 14, 15, 16}
end
IO.inspect {a, b, c, d}
end
The above works, because after compilation there is no Constants.constant1 anymore in Main code: there are real values: 1s and the code being run is:
case {x, y, z} do
{1, 1, 1} -> {1, 2, 3, 4}
{1, 1, _} -> {5, 6, 7, 8}
{1, _, _} -> {9, 10, 11, 12}
{_, _, _} -> {13, 14, 15, 16}
end
Hope it helps.
I'm almost a complete programming beginner and I've started to go through a Swift ebook from Apple.
The things I read are pretty clear, but once you start to experiment things get tricky :).
I'm stuck with the experiment in the Control Flow section. Here is the initial code:
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]
var largest = 0
for (kind, numbers) in interestingNumbers {
for number in numbers {
if number > largest {
largest = number
}
}
}
largest
And here is the task:
Add another variable to keep track of which kind of number was the
largest, as well as what that largest number was.
As I understand, they want me to add up all the values in each number kind (get a total sum for Prime, Fibonacci and Square) and then compare the result to show the largest result.
But I can't figure out the syntax.
Can someone share any advice on how to tackle this experiment?
Maybe I'm not understanding the problem?
They're just asking you to keep track of which number category the largest number belongs to:
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]
var largest = 0
var largestkind = ""
for (kind, numbers) in interestingNumbers {
for number in numbers {
if number > largest {
largest = number
largestkind = kind
}
}
}
largest
largestkind
Alternately you can use closure to make the tasks simpler.
The for loop calculate the sum of each series.
The final reduce finds the series tuple that contains maximum number.
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]
var sums = Array<(String, Int)>()
for (kind, numbers) in interestingNumbers {
sums = sums + [(kind, numbers.reduce(0, +))]
}
let maxSeries = sums.reduce(("", Int.min), { $0.1 > $1.1 ? $0 : $1 })
println(sums)
println(maxSeries)
Here it from playground using Xcode 8.3 and Swift 3.0
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]
let largest = interestingNumbers.map{$0.value}.flatMap{$0}.max()
print(largest)
Optional(25)