Prolog - Counting matches in two lists - list

I'm trying to understand the language of the prologue (using the program Visual Prolog 5.1/5.2)
There is a task - to realize the game "Bulls and Cows" (or an Outstanding mind).
The player makes a number (composed of numbers from 0 to 9, without repetition), for example, 1458, and enters it into the program.
The computer tries to guess this number, putting forward assumptions. And then he asks the player how many “bulls” (exact matches), and how many “cows” (matched numbers that are not in their proper places).
I wrote a program that does it. It works.
Now I want the computer to count the number of bulls and cows. How to do it right?
This is a work with two lists.
DOMAINS
list = integer*
list1 - Key (hidden number), list2 - assumption (computer)
I tried to write a predicate for bulls counting, but the program produces "No solution" (perhaps because of the reason below (converting))
comparison(_Key, Assemption, Bulls /*, Cows*/):-
find_bulls(_Key, Assemption, Bulls),
%find_cows(_Key, Assemption, Cows).
find_bulls(Key, Assemption, Bulls):-
find_bulls(Key, Assemption, Bulls, 0).
find_bulls([],[], Bulls, Amount):- Bulls=Amount,!.
find_bulls([A1|L1],[A2|L2], Bull, Amount):-
A1 = A2,
Am = Amount + 1,
find_bulls(L1, L2, Bull, Am).
I also read the number through readint(_Key), but _Key not a list, is it? how do I convert the integer to the list to feed the predicate?
question(Assemption,_Key):-
assemption(Assemption),
not(contradictory(Assemption)),
%------------------------------------------------------------
comparaison(_Key,Assemption, Bulls /*,Cows*/),
%------------------------------------------------------------
write(" My assemption: ", Assemption), nl,
write("How much bulls? -----> ", Bulls), nl, %readint(Bulls),
write("How much cows? -----> "), /*Cows)*/ readint(Cows), nl,
Bulls + Cows <= size,
assert(request(Assemption, Bulls, Cows)),
Bulls = size,
!.
Thank You!
/-----------------------------------------------------------------------------/
new Addition (read list from keyboard, stoped while input char):
domains
list=integer*
predicates
readlist(list)
clauses
readlist([H|T]):-
write("> "),
readint(H),!,
readlist(T).
readlist([ ]).

[SOLVED]
find_bull_and_cows(OldAssemption,Assemption,Bulls,Cows):-
exact_match(OldAssemption,Assemption,Bulls),
common_numbers(OldAssemption,Assemption,N2),
Cows= N2 - Bulls.
%bulls finding
exact_match(X,Y,N):- exact_match(X,Y,0,N).
exact_match([Digit|OldPin],[Digit|NewPin],K,N):- !,
K1=K+1,
exact_match(OldPin,NewPin,K1,N).
exact_match([_|OldPin],[_|NewPin],K,N):- exact_match(OldPin,NewPin,K,N).
exact_match([],[],N,N).
%cows finding
common_numbers(X,Y,N):- common_numbers(X,Y,0,N).
common_numbers([Digit|OldPin],NewPin,K,N):-
member(Digit,NewPin), !,
K1=K+1,
common_numbers(OldPin,NewPin,K1,N).
common_numbers([_|OldPin],NewPin,K,N):- common_numbers(OldPin,NewPin,K,N).
common_numbers([],_,N,N).
%member of list
member(A,[A|_]):- !.
member(A,[_|L]):- member(A,L).

Related

How to generate derivative list with frequencies

I have some C++ code that picks a random item from a list. I need it to weight that randomness so that an item at place "n" has a chance equal to x/n where "x" is the chance that item one in the list will be selected. My current code is like this:
srand(time(NULL));
string a[≈9000] = {"String#1", "String#2", . . ., "String #≈9000"};
int value = rand() % ≈9000;
cout << a[value]
Note that the number notated as "≈9000" is a precise integer obscured for confidentiality. Variable names may be changed.
How can I weight it? I've come up with an equivalent formula
List B[≈9000] = "Item 'n' of 'a' times ≈9000 ÷ n"
Though you might notice that that isn't accurate CPP notation. Do y'all have any ideas how I can implement this?
This is not possible.
You need somehow to allow a variation on your conditions to have a proper distribution.

Have to find the longest word possible out of a list of given letters PROLOG

:-consult(words.pl). % words is basically a big database of the
% 30.000 most used words in the english language
topsolution([], _, P) :- %basecase, in case the given list of letters is
%empty, output no word and give the amount of letters
%and call it P
word(X), %sees if X is a word
P = 0.
topsolution(WordList, X, P) :- %Makes the longest word it can out of a list
%of letters and outputs said word as X, and the
%amount of letters it has as P
Y = 0,
solution(WordList, X, Y), %Determines what words you can make with a given
%list of letters and a given length of said word
Y1 is Y + 1,
solution(WordList, X, Y1), %Determines the longest word of Y + 1
wordLength(P, X). %Defines how many letters a word X has and calls that amount P
So this is the piece of code that I made to find that word. The only problem I'm struggling with is that I can't find a way to make the recursion stop. Currently if I input:
?- topsolution([g,i,g], Word, Y).
Prolog outputs this:
false
Even though it should output:
Word = gig
Y = 3
true
I know why it does this. It is because Y will keep increasing by 1, until it reaches Y = 4. Since there are no possible words with 4 letters out of a list consisting of only 3 letters. This obviously fails.
So how would you guys recommend fixing this? How do I basically tell prolog that it should stop if it encounters a case where it cannot output a word?
You should be extremely suspicious of your base case because of the singleton value warning. It's important for you to treat singletons in Prolog as errors, because they always represent a misunderstanding between you and Prolog.
I think your base case here is wrong. When Prolog fails to make a unification, it will output false; this is just what's supposed to happen. If you call topsolution([g,g,g,g], Word, P), it should output false rather than saying P = 0 and nothing about Word. There is no solution. To say P = 0 is to say "I found a solution of length 0 but I'm not telling you what it is." It would be better to say "I didn't find a solution."
I think you really have two cases:
I found a word based on a permutation of the letters I have right here
I found a word by trying #1 on a subset of the letters I have right here
Your base case is actually #1: what I have in hand is a permutation of the letters of a word, here's the word:
topsolution(Letters, Word, P) :-
permutation(Letters, WordLetters), % permute the letters
atom_chars(Word, WordLetters), % make a permuted atom
word(Word), % guard: it's a word
length(Letters, P). % what's its length?
Then your inductive case is to strip out a letter and try again:
topsolution(Letters, Word, P) :-
select(_, Letters, RemainingLetters), % remove a letter
topsolution(RemainingLetters, Word, P). % try again
The recursion will stop when you've entered the second predicate body after exhausting all the permutations, for every letter in the sequence. select(_, [], _) is false. So there is no P = 0 case to worry about here.

What is causing the syntax error here?

I'm trying to implement this algorithm but I keep getting a syntax error on the 12th line but I cannot pinpoint what is causing it. I'm new to ocaml and any help would be greatly appreciated.
"To find all the prime numbers less than or equal to a given integer n by Eratosthenes' method:
Create a list of consecutive integers from 2 through n: (2, 3, 4, ..., n).
Initially, let p equal 2, the first prime number.
Starting from p, enumerate its multiples by counting to n in increments of p, and mark them in the list (these will be 2p, 3p, 4p, ... ; the p itself should not be marked).
Find the first number greater than p in the list that is not marked. If there was no such number, stop. Otherwise, let p now equal this new number (which is the next prime), and repeat from step 3."
let prime(n) =
let arr = Array.create n false in
let set_marks (arr , n , prime ) = Array.set arr (n*prime) true in
for i = 2 to n do
set_marks(arr,i,2) done
let findNextPrimeNumberThatIsNotMarked (arr, prime , index ) =
let nextPrime = Array.get arr index in
let findNextPrimeNumberThatIsNotMarkedHelper (arr, prime, index) =
if nextPrime > prime then nextPrime
else prime in
;;
Adding to Jeffrey's answer,
As I have already answered to you at " What exactly is the syntax error here? ",
What you absolutely need to do right now is to install and use a proper OCaml indentation tool, and auto-indent lines. Unexpected auto-indent results often indicate syntactic mistakes like forgetting ;. Without such tools, it is very hard even for talented OCaml programmers to write OCaml code without syntax errors.
There are bunch of auto indenters for OCaml available:
ocp-indent for Emacs and Vim https://github.com/OCamlPro/ocp-indent
Caml mode and Tuareg mode for Emacs
Vim should have some other indenters but I do not know...
OCaml has an expression let a = b in c. Your code ends with in, but where is c? It looks like maybe you should just remove the in at the end.
Looking more closely I see there are more problems than this, sorry.
A function in OCaml is going to look like this roughly:
let f x =
let a = b in
let c = d in
val
Your definition for prime looks exactly like this, except that it ends at the for loop, i.e., with the keyword done.
The rest of the code forms a second, independent, function definition. It has a form like this:
let f x =
let a = b in
let g x = expr in
The syntactic problem is that you're missing an expression after in.
However, your use of indentation suggests you aren't trying to define two different functions. If this is true, you need to rework your code somewhat.
One thing that may be useful (for imperative style programming) is that you can write expr1; expr2 to evaluate two expressions one after the other.

Creating a histogram with C++ (Homework)

In my c++ class, we got assigned pairs. Normally I can come up with an effective algorithm quite easily, this time I cannot figure out how to do this to save my life.
What I am looking for is someone to explain an algorithm (or just give me tips on what would work) in order to get this done. I'm still at the planning stage and want to get this code done on my own in order to learn. I just need a little help to get there.
We have to create histograms based on a 4 or 5 integer input. It is supposed to look something like this:
Calling histo(5, 4, 6, 2) should produce output that appears like:
*
* *
* * *
* * *
* * * *
* * * *
-------
A B C D
The formatting to this is just killing me. What makes it worse is that we cannot use any type of arrays or "advanced" sorting systems using other libraries.
At first I thought I could arrange the values from highest to lowest order. But then I realized I did not know how to do this without using the sort function and I was not sure how to go on from there.
Kudos for anyone who could help me get started on this assignment. :)
Try something along the lines of this:
Determine the largest number in the histogram
Using a loop like this to construct the histogram:
for(int i = largest; i >= 1; i--)
Inside the body of the loop, do steps 3 to 5 inclusive
If i <= value_of_column_a then print a *, otherwise print a space
Repeat step 3 for each column (or write a loop...)
Print a newline character
Print the horizontal line using -
Print the column labels
Maybe i'm mistaken on your q, but if you know how many items are in each column, it should be pretty easy to print them like your example:
Step 1: Find the Max of the numbers, store in variable, assign to column.
Step 2: Print spaces until you get to column with the max. Print star. Print remaining stars / spaces. Add a \n character.
Step 3: Find next max. Print stars in columns where the max is >= the max, otherwise print a space. Add newline. at end.
Step 4: Repeat step 3 (until stop condition below)
when you've printed the # of stars equal to the largest max, you've printed all of them.
Step 5: add the -------- line, and a \n
Step 6: add row headers and a \n
If I understood the problem correctly I think the problem can be solved like this:
a= <array of the numbers entered>
T=<number of numbers entered> = length(a) //This variable is used to
//determine if we have finished
//and it will change its value
Alph={A,B,C,D,E,F,G,..., Z} //A constant array containing the alphabet
//We will use it to print the bottom row
for (i=1 to T) {print Alph[i]+" "}; //Prints the letters (plus space),
//one for each number entered
for (i=1 to T) {print "--"}; //Prints the two dashes per letter above
//the letters, one for each
while (T!=0) do {
for (i=1 to N) do {
if (a[i]>0) {print "*"; a[i]--;} else {print " "; T--;};
};
if (T!=0) {T=N};
}
What this does is, for each non-zero entered number, it will print a * and then decrease the number entered. When one of the numbers becomes zero it stops putting *s for its column. When all numbers have become zero (notice that this will occur when the value of T comes out of the for as zero. This is what the variable T is for) then it stops.
I think the problem wasn't really about histograms. Notice it also doesn't require sorting or even knowing the

How do I build this finite automaton?

I'm studying for a Discrete Mathematics test and I found this exercise which I can't figure out.
"Build a basic finite automaton (DFA,NFA,NFA-lambda) for the language in the alphabet Sigma = {0,1,2} where the sum of the elements in the string is even AND this sum is more than 3"
I have tried using Kleene's Theorem concatenating two languages like concatenating the one associated with this regular expression:
(00 U 11 U 22 U 02 U 20)* - the even elements
with this one
(22 U 1111 U 222 U 2222)* - the ones whose sum is greater than 3
Does this make any sense?? I think my regex are flabby.
I find your notation a bit fuzzy, so perhaps I'm completely misunderstanding. If so, disregard the following. It seems you're not there yet:
I assume the * means '0 or more times'. However, one of the strings with sum >= 3 must occur. It's say you need a + ('1 or more times').
112 and 211 are missing in the list of strings with sum >= 3.
222 and 2222 in that list are superfluous.
All of these strings may be arbitraryly interspersed with 0s.
The sum of 00 is no more even than the sum of 0.
Edit: how about this (acc is the only accepting state, dot-source):
automaton http://student.science.uva.nl/~sschroev/so/885411.png
At states a and c the string sum is always odd. At states start, b and acc the sum is always even. Furthermore, at start the sum is 0, at b it is 2 and at d it is >= 4. This can be proved rather easily. Hence the accepting state acc meets all criteria.
Edit 2: I'd say this is a regex which accepts the requested language:
0*(2|(1(0|2)*1))(0*(2|(1(0|2)*1))+
Not sure if this is answering your question, but: do you need to submit a regular expression? or will an FSM do?
At any rate, it might be helpful to draw the FSM first, and I think this is a correct DFA:
FSM http://img254.imageshack.us/img254/5324/fsm.png
If that is the case, when constructing your regular expression (which, remember, has different syntax than programming "regex"):
0* to indicate "0 as many times as you want". This makes sense, since 0 in your string doesn't change the state of the machine. (See, in the FSM, 0 just loops back to itself)
You'd need to account for the different combinations of "112" or "22" etc - until you reach at least 4 in your sum.
If your sum is greater than 3, and even, then (0|2)* would keep you at a final state. Otherwise (sum > 3, and odd) you'd need something like 1(0|2)* in order to put you at an accepting state.
(don't know if this helps, or if its right - but it might be a start!)
Each expression, as guided by Stephan, may be:
(0*U 2* U 11)* - the even sums
with this one
(22 U 11 U 222 U 112 U 211 U 121)+ - the ones whose sum is greater than 3
I don't know if it could be simplfied more, it would help designing the automaton.
I find it easier just to think in terms of states. Use five states: 0, 1, 2, EVEN, ODD
Transitions:
State, Input -> New State
(0, 0) -> 0
(0, 1) -> 1
(0, 2) -> 2
(1, 0) -> 1
(1, 1) -> 2
(1, 2) -> ODD
(2, 0) -> 2
(2, 1) -> ODD
(2, 2) -> EVEN
(ODD, 0) -> ODD
(ODD, 1) -> EVEN
(ODD, 2) -> ODD
(EVEN, 0) -> EVEN
(EVEN, 1) -> ODD
(EVEN, 2) -> EVEN
Only EVEN is an accepting state.