Add even elements in Prolog- Problem with 'amt' variable - prolog

I'm trying to figure out how to add even elements in a list (i've studied examples but cant do it on my own yet, need your help in pinning down my lack of understanding to a specific area).
The input I used is start([1,2,3,4,5]). There is no compilation error, but I dont get any output. I'm not sure what the logical error is..could you please advise?
(please see below for the latest update, after revising my code, now it works, and the problem lies in the way I use 'amt', but I dont know why!)
Original code that didnt work:
start(X):- add(X,1,amt), write(amt).
add([],_,0).
add([H|Tail],Cnt,amt):-
T is (Cnt mod 2), T == 0, Cnt1 is Cnt + 1, add(Tail,Cnt1,Y), amt is H+Y;
T is (Cnt mod 2), T =\=0, Cnt1 is Cnt + 1, add(Tail, Cnt1, amt).
Latest Update:
I replaced 'amt' with a 'S', and it works! But why wldnt it work with 'amt'?
here's the revised code that works:
start(X):- add(X,1,S), write(S).
add([],_,0).
add([H|Tail],Cnt,S):-
T is (Cnt mod 2), T == 0, Cnt1 is Cnt + 1, add(Tail,Cnt1,Y), S is H+Y;
T is (Cnt mod 2), T =\=0, Cnt1 is Cnt + 1, add(Tail, Cnt1, S).
Thanks :)

Are you intending to display amt1?

Related

How to design a heuristic algorithm to solve this location optimization problem?

I simplified the problem to the following description:
If produce a thing, we need to go through three devices : A, B, C, and it must pass through these devices the order of A->B->C. The device to select an address (from 0 to 7) for installation before it can be used, The installation cost of the device is different for different addresses, as shown in the figure below, as shown below
The addresses are in the order of the arrows. Device A can choose to install at address 0, and the cost is 800, or it can be installed at address 1, the cost is 700. Other devices have similar installation locations and costs The following is a correct placement method(A choose 2, B choose 3, C choose 5):
If we first install device A in 2 and device C in 3, then B has no address to install, which is a wrong installation method.
Finding a correct installation method is very simple, but because the cost of installing equipment at different addresses is different, how to find a cost-optimized solution under the correct premise? Because of the large scale of the problem, I want to use a heuristic search algorithm. How to design the algorithm? Thank you very much if you can answer my question!
This isn’t an assignment problem because of the ordering constraint on the installations. A dynamic program will do. In Python 3:
import math
input_instance = [
("A", [(0, 800), (1, 700), (2, 500), (3, 1000)]),
("B", [(2, 200), (3, 1500)]),
("C", [(3, 1000), (4, 200), (5, 500), (6, 700)]),
]
LAST_ADDRESS = 0
TOTAL_COST = 1
INSTALLATIONS = 2
solutions = [(-math.inf, 0, [])]
for device, address_cost_pairs in input_instance:
next_solutions = []
i = 0
for address, cost in sorted(address_cost_pairs):
if address <= solutions[i][LAST_ADDRESS]:
continue
while i + 1 < len(solutions) and solutions[i + 1][LAST_ADDRESS] < address:
i += 1
next_solutions.append(
(
address,
solutions[i][TOTAL_COST] + cost,
solutions[i][INSTALLATIONS] + [(device, address)],
)
)
del solutions[:]
total_cost_limit = math.inf
for solution in next_solutions:
if total_cost_limit <= solution[TOTAL_COST]:
continue
solutions.append(solution)
total_cost_limit = solution[TOTAL_COST]
if not solutions:
break
else:
print(*solutions[-1][1:])
Output:
1100 [('A', 1), ('B', 2), ('C', 4)]

Make Return[] do its proper (C++) task

I saw that there are many threads about the Return[] function on this site. There is even a very good description of its behavior. But what happens if I'm really new to Mathematica?
Without further ado, I want to use this function:
getBinIndex[eta_, pt_, etalimits_, ptlimits_] :=
List[
For[i = 1, i < Length[etalimits], i++,
If[eta < etalimits[[i + 1]], Return[i]]],
For[i = 1, i < Length[ptlimits], i++,
If[pt < ptlimits[[i + 1]], Return[i]]]
];
As you can see, I am really new. I suppose there are 1 million ways of doing this in Mathematica but I have a C background and I feel the need to tell the computer everything. The function works. It returns a list with 2 variables which, after lots of testing, are OK. But it puts the results as the argument of two Return's: {Return[4],Return[5]} which I can't use as indexes for a...Table, for example. What do you need to do to get these Return[x] into x?
To give you an idea of how much a newb I am, I tried N[Return[i]].
Cheers,
Adrian
Catch[For[ .... If[ Throw[i] ] ]
Of course in mathematica you hardly ever need loops..
something like
Position[etalimits,ei_/;ei<eta&][[1,1]]
will do.
edit .. try this:
For[i = 1, i < Length[etalimits], i++,
If[eta < etalimits[[i + 1]], Return[i,CompoundExpression]]];,
Note the extra semicolon which makes the For[] loop a CompoundExpression. Personally I find this weird and wouldn't use it..

Mathematica, define multiple functions using for loop

I am using usual for-loop for computation in Mathematica:
For[i=1,i<n+1,i++, ...calculation... ]
For each i I need to define a function F_i[x_,y_]:=.... Here "i" is suuposed to be a label of the function. This is however not the corrcet Mathematica expression.
The question is, how to define multiple functions distinguished by the label i? I mean, what is the correct syntax?
Thanks a lot.
I'm not exactly sure what you are trying to do, but I have some confidence that the for loop is not the way to go in Mathematica. Mathematica already has pattern matching that likely eliminates the need for the loop.
What about something like this
f[i_][x_,y_]:= i(x+y)
or something like this
f[s_String][x_,y_]:=StringLength[s](x+y)
or even
f[s_,x_,y_]:=StringLength[s](x+y)
Here are some steps which may help. There are two versions below, the second one includes the value of i on the RHS of the function definition.
n = 2;
For[i = 1, i < n + 1, i++,
f[i][x_, y_] := (x + y)*i]
?f
Global`f
f[1][x_,y_] := (x+y) i
f[2][x_,y_] := (x+y) i
Clear[i]
f[2][2, 3]
5 i
Quit[]
n = 2;
For[i = 1, i < n + 1, i++,
With[{j = i},
f[i][x_, y_] := (x + y)*j]]
?f
Global`f
f[1][x$,y$] := (x$+y$) 1
f[2][x$,y$] := (x$+y$) 2
Clear[i]
f[2][2, 3]
10

Nested IIF or SWITCH Statement syntax needed correctly

Can somebody please tell me what I am missing in this formula in SSRS? Or better yet can somebody please write this same thing in a NESTED IIF syntax?
Switch(
(Parameters!StartMonth.Value <= 1 And Parameters!EndMonth.Value >= 1),
(Code.CalculateFraction(
(Fields!retail1.Value -Fields!cost1.Value) , Fields!cost1.Value
) *100
),
(Parameters!StartMonth.Value <= 2 And Parameters!EndMonth.Value >= 2),
(Code.CalculateFraction(
(
(Fields!retail1.Value +Fields!retail2.Value)-
(Fields!cost1.Value + Fields!cost2.Value)
) ,
(Fields!cost1.Value + Fields!cost2.Value)
) *100
)
)
This is seriously driving me crazy. For simplicity I have just put 2 iterations here. I have 12 of these and every next step I have to sum up retail1 until retail12 and cost1 until cost12.
I cant get it right for these two in the first place.
EDIT:
I am trying this now and still returns the value in the first condition
=iif(
Parameters!StartMonth.Value <= 1 AND Parameters!EndMonth.Value >= 1,
ReportItems!txtTotal2.Value,
iif(
Parameters!StartMonth.Value <= 2 AND Parameters!EndMonth.Value >= 2,
ReportItems!txtTotal3.Value,
iif(
Parameters!StartMonth.Value <= 3 AND Parameters!EndMonth.Value >= 3,
ReportItems!txtTotal4.Value,
Nothing
)
)
)
EDIT 2:
FIGURED OUT WHAT WAS INCORRECT.
My entire logic was incorrect to get to the result that I was expecting. It was obvious in my case that whatever I use, be it IIF or switch only the first statement would execute because it was true.
But I had to change the logic to get to the result that I wanted.
iif(
Parameters!EndMonth.Value = 1,
ReportItems!txtTotal1.Value,
Parameters!EndMonth.Value = 2,
ReportItems!txtTotal2.Value,
and so on
)
This solved my problem. Thanks guys I appreciate it.
Try using separated IIF Statements:
=iif(
Parameters!StartMonth.Value <= 1 AND Parameters!EndMonth.Value >= 1,
ReportItems!txtTotal2.Value, Nothing
) OR
iif(
Parameters!StartMonth.Value <= 2 AND Parameters!EndMonth.Value >= 2,
ReportItems!txtTotal3.Value, Nothing
) OR
iif(
Parameters!StartMonth.Value <= 3 AND Parameters!EndMonth.Value >= 3,
ReportItems!txtTotal4.Value, Nothing
)
Syntax looks correct at first glance. Most places in SSRS you are required to have = to start your statement. Your code above refers to embedded code for CalculateFraction() Does that exist and is it used successfully elsewhere?

Need Mathematica short code like these same from Maple

I have one problem with exportation results from Mathematica. Two matrices A and B have to be exported in special form.
These two codes make a list of data exported from Maple.
It is important that exported file opened with wordpad looks like column (File attached).
Please, just if you already checked that it is working, write me answer, thank you! You can check your answer comparing with files down.
Codes are here
Matrices A and B with code in Maple and exported file
http://www.2shared.com/file/49wW8Z0-/EXAMPLE_EXPORT_MAPLE_FINAL.html
And also I will present it here to everybody can see easy
Code 1)
A := Matrix(2, 2, {(1, 1) = (455200000000/6133413)*w(1), (1, 2) = -(1792000000000/116534847)*w(1), (2, 1) = (455200000000/6133413)*w(2), (2, 2) = -(1792000000000/116534847)*w(2)})
precision := double: writeto(`Aexport.for`):
for i from 1 to 2 do:for j from 1 to 2 do:
if A[i,j]<>0 then codegen[fortran]([A00[i,j]=A[i,j]],optimized):
fi:od:od:writeto(terminal):
Code 2)
B := Matrix(2, 2, {(1, 1) = 6436781.609, (1, 2) = 0, (2, 1) = 0, (2, 2) = 3862068.966})
writeto(Bexport);
for i to 2 do
for j to 2 do
printf("%016.15E\n", B[i, j])
end do:
end do:
writeto(terminal)
This is a translation of the (B) part only:
matrix = {{6436781.609, 0}, {0, 3862068.966}}
Export["Bexport", Map[FortranForm, N#Flatten[matrix]], "Table"]
Please test it and let me know if it works for you.
Differences compared to the Maple version: the E is written as lowercase and the number of digits that are output is not fixed (but, as you can see, all significant digits are preserved). Will these differences cause problems in your application?
I believe this does what you want for matrix B:
b = {{6436781.609, 0}, {0, 3862068.966}}
bformatted =
NumberForm[
Flatten#b,
{16, 15},
NumberFormat -> (Row[{#, "E+", StringTake["00" <> #3, -2]}] &)
];
bstring =
StringReplace[
ToString#bformatted,
{"{"|"}"|" " -> "", "," -> "\n"}
];
WriteString["Bexport.dat", bstring, "\n"]
Close["Bexport.dat"]

Resources