The "recursive partition numbers" code written using GAP 4.10.2 are as follows.
For example, could you explain the working steps of the GAP programming for nrparts(15)? How did we get nrparts (15) = 176 step by step in the program?
nrparts:= function(n)
local np;
np := function(n, m)
local i, res;
if n = 0 then
return 1;
fi;
res:= 0;
for i in [1..Minimum(n,m)] do
res:= res + np(n-i, i);
od;
return res;
end;
return np(n,n);
end;
Related
I am working on the following proof and the invariant result_val is proved with an induction strategy on i using begin as the base case.
The sup case is trying to prove true which holds trivially using Frama-C 24.0. But when I switch to 25.0, it tries to prove a seemingly more complicated condition, which looks closer to a correct inductive inference because it did the weakest precondition computation explicitly.
However, all SMT solvers I tried cannot prove the condition generated by Frama-C 25.0.
I am a bit worried about the correctness of version 24.0's result because using true as the inductive proof goal seems to be unlikely. Can anyone hint to me at what happened? Is that a bug in 24.0 or just some difference in the implementation?
#include <stdbool.h>
#define SIZE 1000
bool data[SIZE] ;
/*#
logic integer count(integer begin, integer end)=
begin >= end ? 0 : (data[begin]==true) ? count(begin+1, end)+1 : count(begin+1, end);
*/
/*#
requires SIZE > begin >= 0;
requires SIZE >= end >= 0;
requires begin <= end;
assigns \nothing;
ensures \result == count(begin, end);
*/
unsigned int occurrences_of(int begin, int end)
{
unsigned int result = 0;
/*#
loop invariant i_bound: begin <= i <= end;
loop invariant result_bound: 0 <= result <= i-begin;
loop invariant result_val: result == count(begin, i);
loop assigns i, result;
loop variant end-i;
*/
for (unsigned int i = begin; i < end; ++i){
result += (data[i] == true) ? 1 : 0;
}
return result;
}
Below is the result from Frama-c 24.0
Proof:
Goal Invariant 'result_val' (preserved) (Induction: proved)
+ Goal Induction (Base) (proved)
+ Goal Induction (Induction (sup)) (proved)
+ Goal Induction (Induction (inf)) (proved)
Qed.
--------------------------------------------------------------------------------
Goal Induction (Induction (sup)):
Prove: true.
Below is the result from Frama-c 25.0
--------------------------------------------------------------------------------
Proof:
Goal Invariant 'result_val' (preserved) (Induction: pending)
+ Goal Induction (Base) (proved)
+ Goal Induction (Induction (sup)) (pending)
+ Goal Induction (Induction (inf)) (proved)
End.
--------------------------------------------------------------------------------
Goal Induction (Induction (sup)):
Let x_0 = to_uint32(end#L1).
Let x_1 = to_uint32(tmp#L12).
Let x_2 = data#L1[i#L6].
Let x_3 = result#L6.
Let x_4 = result#L13.
Let x_5 = to_uint32(1 + i#L6).
Assume {
Have: begin#L1 < i#L6.
Have: i#L6 <= end#L1.
Have: i#L6 < x_0.
Have: 0 <= x_3.
Have: x_5 <= end#L1.
Have: begin#L1 <= x_5.
Have: (begin#L1 + x_3) <= i#L6.
Have: (begin#L1 + x_4) <= x_5.
Have: is_uint32(i#L6).
Have: is_bool(x_2).
Have: is_uint32(x_3).
Have: if (x_2 = 1) then (tmp#L12 = 1) else (tmp#L12 = 0).
Have: forall i_0 : Z. let x_6 = L_count(data#L1, begin#L1, i_0) in
let x_7 = to_uint32(1 + i_0) in let x_8 = to_uint32(x_1 + x_6) in
let x_9 = data#L1[i_0] in ((i_0 <= end#L1) -> ((begin#L1 <= i_0) ->
((i_0 < i#L6) -> ((i_0 < x_0) -> ((0 <= x_6) -> ((x_7 <= end#L1) ->
((begin#L1 <= x_7) -> (((begin#L1 + x_6) <= i_0) ->
(((begin#L1 + x_8) <= x_7) -> (is_uint32(i_0) -> (is_bool(x_9) ->
(is_uint32(x_6) ->
((if (x_9 = 1) then (tmp#L12 = 1) else (tmp#L12 = 0)) ->
(L_count(data#L1, begin#L1, x_7) = x_8)))))))))))))).
[...]
Stmt { L6: }
Stmt { tmp = tmp_0; }
Stmt { L12: result = x_4; }
Stmt { L13: }
}
Prove: L_count(data#L1, begin#L1, x_5) = x_4.
Goal id: typed_occurrences_of_loop_invariant_result_val_preserved
Short id: occurrences_of_loop_invariant_result_val_preserved
--------------------------------------------------------------------------------
Prover Alt-Ergo 2.4.2: Timeout (Qed:52ms) (10s).
A bug on the typing of the induction tactic was indeed fixed between Frama-C 24 and 25 (https://git.frama-c.com/pub/frama-c/-/commit/6058453cce2715f7dcf9027767559f95fb3b1679). And the symptom was indeed that the tactic could generate ill-typed formulas with true instead of a term.
Proving this example in not that easy. For two main reasons:
the function and the definition work in the opposite directions,
the definition does not have an optimal expression for reasoning.
However, one can write a lemma function to solve the problem:
#include <stdbool.h>
#define SIZE 1000
bool data[SIZE] ;
/*#
logic integer count(integer begin, integer end)=
begin >= end ? 0 : ((data[begin]==true) ? count(begin+1, end)+1 : count(begin+1, end));
*/
/*# ghost
/# requires begin < end ;
assigns \nothing ;
ensures count(begin, end) == ((data[end-1]==true) ? count(begin, end-1)+1 : count(begin, end-1));
#/
void lemma(bool* d, int begin, int end){
/# loop invariant begin <= i < end ;
loop invariant count(i, end) == ((data[end-1]==true) ? count(i, end-1)+1 : count(i, end-1));
loop assigns i ;
loop variant i - begin ;
#/
for(int i = end-1 ; i > begin ; i--);
}
*/
/*#
requires SIZE > begin >= 0;
requires SIZE >= end >= 0;
requires begin <= end;
assigns \nothing;
ensures \result == count(begin, end);
*/
unsigned int occurrences_of(int begin, int end)
{
unsigned int result = 0;
/*#
loop invariant i_bound: begin <= i <= end;
loop invariant result_bound: 0 <= result <= i-begin;
loop invariant result_val: result == count(begin, i);
loop assigns i, result;
loop variant end-i;
*/
for (unsigned int i = begin; i < end; ++i){
result += (data[i] == true) ? 1 : 0;
//# ghost lemma(data, begin, i+1);
}
return result;
}
I'd suggest to use the following definition:
/*#
logic integer count(integer begin, integer end)=
begin >= end ? 0 : ((data[end-1]==true) ? 1 : 0) + count(begin, end-1);
*/
It works in the same direction as the function and avoids the duplication of the term count(begin, end-1) which makes reasoning easier.
I'm trying to write a function to find the lowest number that all integers between 1 and 20 divide. (Let's call this Condition D)
Here's my solution, which is somehow exceeding the call stack size limit.
function findSmallest(num){
var count = 2
while (count<21){
count++
if (num % count !== 0){
// exit the loop
return findSmallest(num++)
}
}
return num
}
console.log(findSmallest(20))
Somewhere my reasoning on this is faulty but here's how I see it (please correct me where I'm wrong):
Calling this function with a number N that doesn't meet Condition D will result in the function being called again with N + 1. Eventually, when it reaches a number M that should satisfy Condition D, the while loop runs all the way through and the number M is returned by the function and there are no more recursive calls.
But I get this error on running it:
function findSmallest(num){
^
RangeError: Maximum call stack size exceeded
I know errors like this are almost always due to recursive functions not reaching a base case. Is this the problem here, and if so, where's the problem?
I found two bugs.
in your while loop, the value of count is 3 to 21.
the value of num is changed in loop. num++ should be num + 1
However, even if these bugs are fixed, the error will not be solved.
The answer is 232792560.
This recursion depth is too large, so stack memory exhausted.
For example, this code causes same error.
function foo (num) {
if (num === 0) return
else foo(num - 1)
}
foo(232792560)
Coding without recursion can avoid errors.
Your problem is that you enter the recursion more than 200 million times (plus the bug spotted in the previous answer). The number you are looking for is the multiple of all prime numbers times their max occurrences in each number of the defined range. So here is your solution:
function findSmallestDivisible(n) {
if(n < 2 || n > 100) {
throw "Numbers between 2 and 100 please";
}
var arr = new Array(n), res = 2;
arr[0] = 1;
arr[1] = 2;
for(var i = 2; i < arr.length; i++) {
arr[i] = fix(i, arr);
res *= arr[i];
}
return res;
}
function fix(idx, arr) {
var res = idx + 1;
for(var i = 1; i < idx; i++) {
if((res % arr[i]) == 0) {
res /= arr[i];
}
}
return res;
}
https://jsfiddle.net/7ewkeamL/
This is a problem I'm working on right now without any idea how to solve. I'm supposed to write the pseudocode to the merge function, but I'm not sure what I'm supposed to do. What I've been given is as follows:
Begin MergeSort(L[], start, stop)
if (stop<=start) return;
int m = (start+stop)/2;
MergeSort(L, start, m);
Mergesort(L, m+1, stop);
merge(L, start, m, stop);
End MergeSort
The only other thing I've been told is that I'm supposed to find the "merge(L, start, m, stop);" line. I've been researching all day, and everything I've found says that you should have 2 arrays, called left and right, to assign the recursive lines, making:
Begin MergeSort(L[], start, stop)
if (stop<=start) return;
array left[];
array right[];
int m = (start+stop)/2;
left=MergeSort(L, start, m);
right=Mergesort(L, m+1, stop);
merge(L, start, m, stop);
End MergeSort
If I were given this problem, I would be able to solve it, but I'm stuck because once I've broken each sublist into single elements, I'm not even sure what I'm supposed to call them, so I'm not sure how to work with them.
I'm still a beginner when it comes to code (taking the very basics of C and Python), so please keep the answer simple, if possible.
Thank you very much for reading this, and I hope that I get an answer so I understand what I'm doing.
MergeSort consists of 2 functions: mergeSort and merge. First one you have already written correctly. So, the only you problem with merge function.
Because of merge sort is not in-space sort algorithm, it require extra space to store data. Bellow is pretty simplified version of merge function that creates extra array of size stop - start:
Begin merge(L[] array, int start, int m, int stop)
if (start == stop) {
return;
}
int leftPos = start;
int rightPos = m + 1;
int curPos = start;
L[] temp = new L[stop - start];
while(leftPos <= m && rightPos <= stop) {
if (array[leftPos] <= array[rightPos]) {
temp[curPos++] = array[leftPos++];
} else {
temp[curPos++] = array[rightPos++];
}
}
while(leftPos <= m) {
temp[curPos++] = array[leftPos++];
}
while(rightPos <= stop) {
temp[curPos++] = array[rightPos++];
}
for (int i = start; i <= stop; i++) {
array[i] = temp[i - start];
}
End merge
Given a bag with a maximum of 100 chips,each chip has its value written over it.
Determine the most fair division between two persons. This means that the difference between the amount each person obtains should be minimized. The value of a chips varies from 1 to 1000.
Input: The number of coins m, and the value of each coin.
Output: Minimal positive difference between the amount the two persons obtain when they divide the chips from the corresponding bag.
I am finding it difficult to form a DP solution for it. Please help me.
Initially I had to tried it as a Non DP solution.Actually I havent thought of solving it using DP. I simply sorted the value array. And assigned the largest value to one of the person, and incrementally assigned the other values to one of the two depending upon which creates minimum difference. But that solution actually didnt work.
I am posting my solution here :
bool myfunction(int i, int j)
{
return(i >= j) ;
}
int main()
{
int T, m, sum1, sum2, temp_sum1, temp_sum2,i ;
cin >> T ;
while(T--)
{
cin >> m ;
sum1 = 0 ; sum2 = 0 ; temp_sum1 = 0 ; temp_sum2 = 0 ;
vector<int> arr(m) ;
for(i=0 ; i < m ; i++)
{
cin>>arr[i] ;
}
if(m==1 )
{
if(arr[0]%2==0)
cout<<0<<endl ;
else
cout<<1<<endl ;
}
else {
sort(arr.begin(), arr.end(), myfunction) ;
// vector<int> s1 ;
// vector<int> s2 ;
for(i=0 ; i < m ; i++)
{
temp_sum1 = sum1 + arr[i] ;
temp_sum2 = sum2 + arr[i] ;
if(abs(temp_sum1 - sum2) <= abs(temp_sum2 -sum1))
{
sum1 = sum1 + arr[i] ;
}
else
{
sum2 = sum2 + arr[i] ;
}
temp_sum1 = 0 ;
temp_sum2 = 0 ;
}
cout<<abs(sum1 -sum2)<<endl ;
}
}
return 0 ;
}
what i understand from your question is you want to divide chips in two persons so as to minimize the difference between sum of numbers written on those.
If understanding is correct, then potentially you can follow below approach to arrive at solution.
Sort the values array i.e. int values[100]
Start adding elements from both ends of array in for loop i.e. for(i=0; j=values.length;i<j;i++,j--)
Odd numbered iteration sum belongs to one person & even numbered sum to other person
run the loop till i < j
now, the difference between two sums obtained in odd & even iterations should be minimum as array was sorted earlier.
If my understanding of the question is correct, then this solution should resolve your problem.
Reflect as appropriate.
Thanks
Ravindra
This question has been bugging me for quite a while: is it possible to write a factorial function (in any programming language) without any if statement (or similar) which returns 1 when called with 0 as argument too?
Many factorial functions are something like this (Python):
def factorial(n):
for x in range(1, n):
n *= x
return n if n > 0 else 1
But I don't know if it can be done without distinction between varied values of n... What do you think? It is not a matter of speed and optimizing, just my curiosity.
0! is defined as 1.
Here are the results from my code.
0 factorial = 1
1 factorial = 1
2 factorial = 2
3 factorial = 6
10 factorial = 3628800
And here's Java code with no if statement,
package com.ggl.testing;
public class Factorial {
public static void main(String[] args) {
int n = 0;
System.out.println(n + " factorial = " + factorial(n));
n = 1;
System.out.println(n + " factorial = " + factorial(n));
n = 2;
System.out.println(n + " factorial = " + factorial(n));
n = 3;
System.out.println(n + " factorial = " + factorial(n));
n = 10;
System.out.println(n + " factorial = " + factorial(n));
}
public static long factorial(int n) {
long product = 1L;
for (int i = 2; i <= n; i++) {
product *= (long) i;
}
return product;
}
}
Here's a Haskell version:
factorial n = product [1 .. n]
Not sure if that's considered cheating, though.
There are many ways to calculate the factorial of a number with code.
The original question shows how to do it by recursion, one answer shows how to use a for loop. The same could be achieved by a while loop.
Another answer shows the product function of an array in Haskell (similar to prod(1:n) in Matlab).
Another way to calculate factorial of n (including n=0) in Javascript whithout using a loop is:
function factorial(n){
return (new Array(n)).join().split(",").map((x,i) => i+1).reduce((x,y) => x*y)
}
def factor(n):
fact=1
for i in range (1,n+1):
fact= fact*1
return fact
try:
x=int(input('Input a number to find the factiorial: '))
print(factor(x))
except:
print('Number should be an integer')
x=int(input('Input a number to find the factiorial: '))
print(factor(x))
Hope this helps you!