How to group all possible integers into three buckets - math

I want to be able to evenly, reproducibly, and predictably switch an inputted integer value into one of three cases. If it was two cases, it would be obvious.
Pseudo code:
switch (integer) {
if even:
something;
break;
if odd:
something else;
break;
}
I want to do the same thing but for three cases, and I'm kind of stumped as to how I can do that. Probably because I'm not really very good at math.
Any ideas?

How about dividing by 3?
switch (x % 3) { // compute the remainder
case 0: // 0, 3, 6, 9, ...
something;
break;
case 1: // 1, 4, 7, 10, ...
something;
break;
case 2: // 2, 5, 8, 11, ...
something;
break;
}
You need to watch out for the sign - some languages will compute (-5) % 3 as -2 instead of 1, so you might need to use abs(x) % 3 instead of x % 3 or add case statements:
switch (x % 3) { // compute the remainder
case 0: // -6, -3, 0, 3, 6, 9, ...
something;
break;
case 1: // 1, 4, 7, 10, ...
case -2: // ... -5, -2
something;
break;
case 2: // 2, 5, 8, 11, ...
case -1: // ... -4, -1
something;
break;
}
See remainder and modulus operation.
PS in Common Lisp you would use mod:
(ecase (mod x 3)
(0 ...)
(1 ...)
(2 ...))

Related

Most common term in a vector - PARI/GP

I feel like I'm being really stupid here as I would have thought there's a simple command already in Pari, or it should be a simple thing to write up, but I simply cannot figure this out.
Given a vector, say V, which will have duplicate entries, how can one determine what the most common entry is?
For example, say we have:
V = [ 0, 1, 2, 2, 3, 4, 6, 8, 8, 8 ]
I want something which would return the value 8.
I'm aware of things like vecsearch, but I can't see how that can be tweaked to make this work?
Very closely related to this, I want this result to return the most common non-zero entry, and some vectors I look at will have 0 as the most common entry. Eg: V = [ 0, 0, 0, 0, 3, 3, 5 ]. So whatever I execute here I would like to return 3.
I tried writing up something which would remove all zero terms, but again struggled.
The thing I have tried in particular is:
rem( v ) = {
my( c );
while( c = vecsearch( v, 0 ); #c, v = vecextract( v, "^c" ) ); v
}
but vecextract doesn't seem to like this set up.
If you can ensure all the elements are within the some fixed range then it is enough just to do the counting sorting with PARI/GP code like this:
counts_for(v: t_VEC, lower: t_INT, upper: t_INT) = {
my(counts = vector(1+upper-lower));
for(i=1, #v, counts[1+v[i]-lower]++);
vector(#counts, i, [i-1, counts[i]])
};
V1 = [0, 1, 2, 2, 3, 4, 6, 8, 8, 8];
vecsort(counts_for(V1, 0, 8), [2], 4)[1][1]
> 8
V2 = [0, 0, 0, 0, 3, 3, 5];
vecsort(counts_for(V2, 0, 5), [2], 4)[1][1]
> 0
You also can implement the following short-cut for the sake of convenience:
counts_for1(v: t_VEC) = {
counts_for(v, vecmin(v), vecmax(v))
};
most_frequent(v: t_VEC) = {
my(counts=counts_for1(v));
vecsort(counts, [2], 4)[1][1]
};
most_frequent(V1)
> 8
most_frequent(V2)
> 0
The function matreduce provides this in a more general setting: applied to a vector of objects, it returns a 2-column matrix whose first column contains the distinct objects and the second their multiplicity in the vector. (The function has a more general form that takes the union of multisets.)
most_frequent(v) = my(M = matreduce(v), [n] = matsize(M)); M[n, 1];
most_frequent_non0(v) =
{ my(M = matreduce(v), [n] = matsize(M), x = M[n, 1]);
if (x == 0, M[n - 1, 1], x);
}
? most_frequent([ 0, 1, 2, 2, 3, 4, 6, 8, 8, 8 ])
%1 = 8
? most_frequent([x, x, Mod(1,3), [], [], []])
%2 = []
? most_frequent_non0([ 0, 0, 0, 0, 3, 3, 5 ])
%3 = 5
? most_frequent_non0([x, x, Mod(1,3), [], [], []])
%4 = x
The first function will error out if fed an empty vector, and the second one if there are no non-zero entries. The second function tests for "0" using the x == 0 test (and we famously have [] == 0 in GP); for a more rigorous semantic, use x === 0 in the function definition.

Next number in the sequence || General approach

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}]

Swift for-in loop dictionary experiment

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)

unknown recursive method, must find how it runs

This was a past exam question and I have no idea what it does! Please can someone run through it.
public static int befuddle(int n){
if(n <= 1){
return n;
}else{
return befuddle(n - 1) * befuddle(n - 2) + 1;
}
}
this is computing the sequence: 0, 1, 1, 2, 3, 7, 22, 155, ...
Which can be expressed using this formula:
when dealing with numerical sequences, a great resources is The Online Encyclopedia of Integer Sequences!, a quick search there shows a similar sequence to yours but with:
giving the following sequence: 0, 0, 1, 1, 2, 3, 7, 22, 155, ...
you can find more about it here
public static is the type of member function it is. I'm assuming this is part of a class? The static keyword allows you to use it without creating an instance of the class.
Plug in a value of 'n' and step through it. For instance, if n = 1, then the function returns 1. If n = 0 -> 0; n = -100 -> -100.
If n = 2, the else branch is triggered and befuddled is called with 1 and 0. So n = 2 returns 0*1 + 1 = 1.
Do the same thing for n = 3, etc. (calls n = 2 -> 1, and n = 1 -> 1, so n=3 -> 1*1+1 = 2.)

How to multiply each digit in a number efficiently

I want to multiply every digit in a number to each other.
For example
515 would become 25(i.e 5*1*5)
10 would become 0(i.e 1*0)
111111 would become 1(i.e 1*1*1*1*1*1)
I used this code to do it
public static int evalulate(int no)
{
if(no==0)return 0;
int temp=1;
do
{
temp=(no%10)*temp;
no=no/10;
}while(no>0);
return temp;
}
problem is I want to evaluate for about a billion numbers like this
for(int i=0;i<1000000000;i++)evaluate(i);
This takes about 146 seconds on my processor.I want to evaluate it within some seconds.
So,is it possible to optimize this code using some shift,and,or operators so that I can reduce the time to evaluate without using multiple threads or parallelizing it
Thanks
First, figure out how many numbers you can store in memory. For this example, let's say you can store 999 numbers.
Your first step will be to pre-calculate the products of digits for all numbers from 0-999, and store that in memory. So, you'd have an array along the lines of:
multLookup = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
0, 2, 4, 6, 8, 10, 12, 14, 16, 18,
0, 3, 6, 9, 12, 15, 18, 21, 24, 27,
0, 4, 8, 12, 16, 20, 24, 28, 32, 36,
...]
Now, you'd break your number up into a bunch of 3 digit numbers. For example, if your number is 1739203423, you'd break it up into 1, 739, 203, and 423. You'd look each of these up in your multLookup array, and multiply the results together, like so:
solution = multLookup[1] * multLookup[739] * multLookup[203] * multLookup[423];
With this approach, you will have sped up your calculations by a factor of 3 (since we picked 999 items to store in memory). To speed it up by 5, store 99999 numbers in memory and follow the same steps. In your case, speeding it up by 5 means you'll arrive at your solution in 29.2 seconds.
Note: the gain isn't exactly linear with respect to how many numbers you store in memory. See jogojapan's reasoning in the comments under this answer for why that is.
If you know more about the order in which your numbers show up, or the range of your numbers (say your input is only in the range of [0, 10000]), you can make this algorithm smarter.
In your example, you're using a for loop to iterate from 0 to 1000000000. In this case, this approach will be super efficient because the memory won't page-fault very frequently and there will be fewer cache-misses.
But wait! You can make this even faster (for your specific for-loop iteration example)!! How, you ask? Caching! Lets say you're going through 10 digit numbers.
Let's say you start off at 8934236000. Based on the 999 digits in memory solution, you'd break this down into 8, 934, 236, and 000. Then you'd multiply:
solution = multLookup[8] * multLookup[934] * multLookup[236] * multLookup[0];
Next, you'd take 8934236001, break it down to 8, 934, 236, and 001, and multiply:
solution = multLookup[8] * multLookup[934] * multLookup[236] * multLookup[1];
And so on... But we notice that the first three lookups are the same for the next 997 iterations! So, we cache that.
cache = multLookup[8] * multLookup[934] * multLookup[236];
And then we use the cache as such:
for (int i = 0; i < 1000; i++) {
solution = cache * i;
}
And just like that, we've almost reduced the time by a factor of 4. So you take the ~29.2 second solution you had, and divide that by 4 to go through all billion numbers in ~7.3 seconds
If you can store the result of each operation for all your numbers.. Then you can use Memoization. That way you need to only calculate 1 digit.
int prodOf(int num){
// can be optimized to store 1/10 of the numbers, since the last digit will always be processed
static std::vector<int> memo(<max number of iterations>, -1);
if(num == 0) return 0;
if(memo[num] != -1 )return memo[num];
int prod = (num%10) * prodOf(num/10);
memo[num] = prod;
return prod;
}
Some test i made,
With simple C/C++ code on my PC (Xeon 3.2GHz),
last no = i = 999999999 ==> 387420489 nb sec 23
#include "stdafx.h"
#include <chrono>
#include <iostream>
#undef _TRACE_
inline int evaluate(int no)
{
#ifdef _TRACE_
std::cout << no;
#endif
if(no==0)return 0;
int temp=1;
do
{
temp=(no%10)*temp;
no=no/10;
}while(no>0);
#ifdef _TRACE_
std::cout << " => " << temp << std::endl;
#endif // _TRACE_
return temp;
}
int _tmain(int argc, _TCHAR* argv[])
{
std::chrono::time_point<std::chrono::system_clock> start(std::chrono::system_clock::now());
int last = 0;
int i = 0;
for(/*int i = 0*/;i<1000000000;++i) {
last = evaluate(i);
}
std::cout << "last no = i = " << (i-1) << " ==> " << last << std::endl;
std::chrono::time_point<std::chrono::system_clock> end(std::chrono::system_clock::now());
std::cout << "nb sec " << std::chrono::duration_cast<std::chrono::seconds>(end - start).count() << std::endl;
return 0;
}
I also tested the loop split over multiple thread with openMP and result is 0 second,
So I would say that it would be useful if you consider performance problem of using a real efficient language.
pragma omp parallel for
for(int i = 0;i<1000000000;++i) {
/*last[threadID][i] = */evaluate(i);
}

Resources