Why this if statment only work at first step - prolog

calculateSum(_, _List, _Row, _Col, []).
calculateSum([M|Rest],List,Row,Col,[Y|Tail]):-
Col == Row -> Col1 is Col + 1,calculateSum(List,List,Row1,Col1,Tail);
calcHeu(Rest,L),
sum(L,S),
index(List, Row, Col, V),
Y is V + S,
%Row1 is Row + 1,
Col1 is Col + 1,
calculateSum(List,List,Row1,Col1,Tail).
Why this Col == Row if statement doest work. Is there any other way so that if Row == Col skip that step?
EDIT
By doing some thing like this.
(Col \= Row ->
calcHeu(Rest,L),
sum(L,S),
index(List, Row, Col, V),
Y is V + S,
Col1 is Col + 1,
calculateSum(List,List,Row1,Col1,Tail)
;
Col1 is Col + 1,calculateSum(List,List,Row1,Col1,Tail)
).
it print out [22,,,_...... infinitly

It's a bit hard to tell without knowing what your code is supposed to do and what inputs it gets, but you can definitely break your if-then-else statement into two rules with a cut (which in my opinion is preferable anyways: try to avoid using ";" as much as possible).
Try this (note that I've change the fir occurrence of "List" in the recursive call for "Rest", because I think that's what you want anyways):
calculateSum(_, _List, _Row, _Col, []).
calculateSum([_M|Rest],List,Row,Row,[_Y|Tail]):-
!,
Col1 is Col + 1,
calculateSum(Rest,List,Row1,Col1,Tail).
calculateSum([M|Rest],List,Row,Col,[Y|Tail]):-
calcHeu(Rest,L),
sum(L,S),
index(List, Row, Col, V),
Y is V + S,
Col1 is Col + 1,
calculateSum(Rest,List,Row1,Col1,Tail).

Related

FILTER has mismatched range sizes. Expected row count:

I have been using these 2 queries to fetch data in 2 different sheets
=query('Raw Data'!A3:P62481,"select B, D, E, F, G, H, I, J, K, L, M, N, O, P where B = date '"&text($B$1,"yyyy-mm-dd")&"'",1)
=sort(unique(FILTER('Raw Data'!$A:$P,'Raw Data'!$G:$G=$C$1,'Raw Data'!$B:$B=$F$1)))
Looking for a way to combine both. And get output in one single sheet, get data for specific DATE and C1.
Please help!
Already tried this:
=sort(unique(FILTER('Raw Data'!$A:$P,'Raw Data'!$G:$G=$C$1, QUERY(query('Raw Data'!A3:P62481,"select B, D, E, F, G, H, I, J, K, L, M, N, O, P where B = date '"&text($B$1,"yyyy-mm-dd")&"'",1)))))
=sort(unique(FILTER(QUERY('Raw Data'!$A:$P,"select B, D, E, F, G, H, I, J, K, L, M, N, O, P where B = date '"&text($F$1,"yyyy-mm-dd")&"'",1,'Raw Data'!$G:$G=$C$1))))
Error FILTER has mismatched range sizes. Expected row count: 2745.
column count: 1. Actual row count: 62481, column count: 1.
Link to the sheet: https://drive.google.com/file/d/1ymFGf9eNzCoWHLwLjolQliOMBwswgaPP/view?usp=sharing
in your first formula, the output is 14 columns while in your 2nd formula the output is 16 columns. there is no way how to combine it unless you have equal column count in the matrix. one of the ways would be adding two fake columns in the query like:
={QUERY('Raw Data'!A3:P62481,
"select B,D,E,F,G,H,I,J,K,L,M,N,O,P,' ',' '
where B = date '"&TEXT($B$1, "yyyy-mm-dd")&"'
label ' ''',' '''", 1);
SORT(UNIQUE(FILTER('Raw Data'!$A:$P, 'Raw Data'!$G:$G=$C$1, 'Raw Data'!$B:$B=$F$1)))}

Count sum of spaces between first element and a specific element prolog

Basically trying to figure out how you would make a predicate where given two parameters, a list and a number, you would sum up the amount of spaces from the first element to the specific letter.
Example, say 'w' is the letter, given the statement
h1([e,w,b,a,w,w,c], 10)
would return true since 10 = 1+4+5 where 1,4,5 are the distances from element 0 and would return false if not 10.
Heres what I have so far
h2(List, H) :- sum(List,0,H).
sum([],TotalCount,TotalCount):- !.
sum([w|T],CurrentCount, TotalCount) :-
NewCount is CurrentCount + CountSince,
sum(T, NewCount, 0)
sum([_|T], NewCount, 0) :-
CountSince is CountSince + 1,
sum(T, NewCount, CountSince).
As said in the comment, you can solve this problem with three lines of code, using findall/3 and sum_list/2. Here the code:
h2(L,E,V):-
findall(P,nth0(P,L,E),LP),
( LP = [] -> false;
sum_list(LP,V)).
I wrote h2/3 and not h2/2 to make it more modular (i.e. you can pass the element you want to find to the predcate). Since you want false as answer if the element is not in the list, i've added an if statement to check if the list from findall/3 is empty. If it's not, simply sum the elements with sum_list/2.
?- h2([e, w, b, a, w, w, c],f,V).
false
?- h2([e, w, b, a, w, w, c],w,V).
V = 10

How can i create new empty list and appending list in prolog

I have some problem with lists in prolog. Here is my code...
add(X,List,[X|List]).
append([],X,X).
append([X|Y],Z,[X|W]) :- append(Y,Z,W).
d([H1|T1],[H2|T2]) :-
( H1 > 0
-> ( H2 > 0
-> write(H1), write(H2), H4 is H1 - 1,
H5 is H2 - 1,
H5 > 0
-> length(Visited, Y),
( Y > 0
-> add(H5, Visited, Visited)
; add(H5, [], Visited)
),
add(H4, T1, X1),
d(X1, T2)
; add(H4, T1, Z1),
d(Z1,T2)
; d([H1|T1],T2)
)
; append(Visited, [H2|T2], NewList),
d(T1,NewList)
).
Input is: d([3,0,2,2,0,4,1],[1,1,3,3,1,1,2]).
Here first list is row and second list is column. My goal is to print the first element from the row and column and travel in the list. Here condition is that when i already visited element from row and column then i have to subtract that element by '1'. for example in above input first element of row is '3' and first element of column is '1' so when i picked elements from row and column then i have subtract by '1'. Therefore, final value will be [2,0,2,2,0,4,1] and [0,1,3,3,1,1,2]. Like wise i want to travel the list and. when we get column '0' then i should shift to next column same for row as well.
Here i'm doing, making column fix until it get '0' and iterating row one by one and storing the new values of row in another list but when i running the code its not printing anything. any help will be appreciate. Thanks

Get dimension in quadratic matrix

I have problem with computing dimension of Quadratic Matrix for instance [3x3].
when I run dim([[1,2],[3,4]], D). should return D=[1,4].
But I got an error that RowIndex is singleton... but it is defined in first line of dim function... there-> dim(M,D):-dim(M,0,[],D). and RowIndex at the beginning is equal to 0, this is second parameter of function with accumulator.
Could sb look at it and give me some advice? Thanks in advance.
:- use_module(library(lists)).
getElement(L,Index,Element):-
length(L,D),
( D>Index -> getElement(L,Index,Element,0)
; !,fail
).
getElement([H|L],Index,Element,Current):-
( Index =:=Current -> Element is H
; Current1 is Current + 1,
getElement(L,Index,Element,Current1)
).
dim(M,D):-
dim(M,0,[],D).
dim([],_,Acc,Acc).
dim([H|M],RowIndex,Acc,D):-
getElement(H,RowIndex,Element),
append(Acc,[Element],Acc1),
RowIndex1 is RowIndex + 1,
dim(M,RowIndex1,Acc1,D).

algorithm to get an unique group id from a combination of element in an integer set

Let's say if I have a row with 3+ attributes A, B, C and other Attrs
row1: A=1, B=5, C=10, Other Attrs
row2: A=1, B=5, C=10, Other Attrs
row3: A=2, B=5, C=10, Other Attrs
row4: A=2, B=5, C=10, Other Attrs
row5: A=3, B=6, C=11, Other Attrs
row6: A=3, B=6, C=11, Other Attrs
So if I want to assign each row a group ID by combination of A, B, C, row1, row2 have same group id x, row 3 row 4 have group id y, row 5 row 6 have group id z.
A simple solution is:
group id = A * S + B * S^2 + C * S^3 (S is the max integer number)
But my problem is I need an algorithm to back out each of A, B, C value from group id
for example, I need to be able to back out A=1, B=5, C=10 from group id x solely
First, this would be enough:
group id = A + B * S + C * S^2;
To get back A, B, and C:
A = id % S;
B = (id / S) % S;
C = (id / S^2);
Where / is integer division and % is modulo.
Based on your example a much simpler approach would be:
a * 10^6 + b*10^3 + c
which would give you
001005010
001005010
002005010
002005010
003006011
003006011
and the inverse of this function is very simple. If your numbers are possibly longer than 3 digits, adjust accordingly.

Resources