I am trying to solve the two WATER JUG PUZZLE using euclidean algorithm and Diophantine equation.
let gcd(m,n) = g
using euclidean aldortihm we get X' and Y' such that mX' + nY' = g
for mX + nY = d
if d%g!= 0 no solution exists
else i made X' as X' / g * d and Y' as Y' / g * d
this is one solution for mX + nY = d
now multiple solutions by m ( X' + ( k * n / g ) ) + n ( Y' - ( m * k / g ) ) = d
i just needed to output the SUM OF NO. OPERATIONS
so, i think of the solution as X' + Y' + k * ( n - m ) / g and i want to minimise this
my code below for the same (its giving wrong answers...)
int X, Y;
int gcd(int a, int b)
{
if (b == 0)
{
X = 1;
Y = 0;
return a;
}
int g = gcd(b, a % b);
int X1 = Y;
int Y1 = X - (a / b) * Y;
X = X1;
Y = Y1;
return g;
}
cin >> m >> n >> d;
int g = gcd(n, m);
if (d % g)
cout << -1 << endl;
else
{
X = X / g * d;
Y = Y / g * d;
int ans = X + Y;
int mn = ans;
while (ans > 0)
{
ans += ((m - n) / g);
mn = min(ans, mn);
}
while (ans < 10000)
{
ans += ((n - m) / g);
mn = min(ans, mn);
}
cout << mn << endl;
}
Related
I'm working on implementation of the Diamond-square algorithm but the outcoming heightmap looks strange like some points are not filled:
I've tried to change for stateents but I still can't find where these points can be missed. Here is my code of a function which is filling the one-dimensional heightMap of values between 0.0 and 1.0.
func diamond(x1 int, y1 int, x2 int, y2 int, l int, size int, r float32) {
var a, b, c, d float32
var cx, cy int
a = heightMap[x1 + y1*size]
b = heightMap[x1 + y2*size]
c = heightMap[x2 + y2*size]
d = heightMap[x2 + y1*size]
cx = (x2 - x1)/2
cy = (y2 - y1)/2
heightMap[cx + cy*size] = float32(a + b + c + d)/float32(4) + rand.Float32()*r
}
func square(cx int, cy int, l int, size int, r float32) {
var a, b, c, d float32
var isBorder = float32(0)
if cx == 0 {
isBorder = 1
a = 0
} else {
a = heightMap[cx - l/2 + cy*size]
}
if cy == size - 1 {
isBorder = 1
b = 0
} else {
b = heightMap[cx + (cy + l/2)*size]
}
if cx == size - 1 {
isBorder = 1
c = 0
} else {
c = heightMap[cx + l/2 + cy*size]
}
if cy == 0 {
isBorder = 1
d = 0
} else {
d = heightMap[cx + (cy - l/2)*size]
}
heightMap[cx + cy*size] = float32(a + b + c + d)/float32(4 - isBorder) + rand.Float32()*r
}
func initHeightMap(size int) {
rand.Seed(3256)
heightMap = make([]float32, size*size)
heightMap[0] = rand.Float32()
heightMap[size-1] = rand.Float32()
heightMap[(size-1)*size] = rand.Float32()
heightMap[size*size-1] = rand.Float32()
var t int
t = size - 1
for l := size - 1; l > 0; l /= 2 {
//diamond steps
for y := 0; y < size - 1; y += l {
for x := 0; x < size - 1; x += l {
diamond(x, y, x + l, y + l, l, size, float32(l)/float32(size-1))
}
}
//square steps
if l > 1 {
for y := 0; y < size - 1; y += l/2 {
if t%2 == 0 {
for x := l/2; x < size; x += l {
square(x, y, l, size, float32(l)/float32(size-1))
}
} else {
for x := 0; x < size; x += l {
square(x, y, l, size, float32(l)/float32(size-1))
}
}
t++
}
}
}
}
Size is a value which is always a power of 2 plus 1 and a random number range is halfed with l.
I've seen a similar heightmap in this question Unexpected Diamond square Algorithm results but there was a different mistake in the algorithm.
Abstract
Hi, suppose you have 128 bit automata (represented by four 32 bit words X, Y, Z, W) that changes it's state according to a following rule:
X = ...
Y = ...
Z = ...
W = ...
void next()
{
var t = X ^ (X << 11);
X = Y;
Y = Z;
Z = W;
W = W ^ (W >> 19) ^ (t ^ (t >> 8));
}
^ - denotes binary XOR operation
<< - denotes binary shift left operation
>> - denotys binary shift right operation
It is guaranteed that the above automata generates no collisions i.e. each state is a result of one (and only one) previous state. It is also guaranteed that the above state machine produces 2^128 unique states.
Question
For any given state (X,Y,Z,W) produce inverse to next, (i.e. prev) operation that would revert the state to previous one.
In other words, if you have the following state (X=1, Y=2, Z=3, W=4) and will call next, the state will change to (X=2, Y=3, Z=4, W=2061), it is supposed that after calling prev the state should be equal again to (X=1, Y=2, Z=3, W=4).
P.S.
The next operation is one of the implementations to XorShift pseudorandom number generators that was discovered by George Marsaglia
https://en.wikipedia.org/wiki/Xorshift
The inverse to this operation would be very useful in general, consider the implications of Guid.Next(...), Guid.Prev(...) availability
Edit
I have somewhat improved Niklas B.'s original answer and ported result to C#, so here's the final piece of code, hope someone will benefit from Random.Next() and Random.Prev() operations:
public class Xor128
{
public UInt32 X { get; set; }
public UInt32 Y { get; set; }
public UInt32 Z { get; set; }
public UInt32 W { get; set; }
public Xor128()
{
}
public Xor128(UInt32 x, UInt32 y, UInt32 z, UInt32 w)
{
X = x;
Y = y;
Z = z;
W = w;
}
//private UInt32 UnXorShl(UInt32 x, Int32 shift)
//{
// for (var i = shift; i < 32; i <<= 1) {
// x ^= x << i;
// }
// return x;
//}
//private UInt32 UnXorShr(UInt32 x, Int32 shift)
//{
// for (var i = shift; i < 32; i <<= 1) {
// x ^= x >> i;
// }
// return x;
//}
//public UInt32 Prev()
//{
// var t = UnXorShr(W ^ Z ^ (Z >> 19), 8);
// W = Z;
// Z = Y;
// Y = X;
// X = UnXorShl(t, 11);
// return W;
//}
public UInt32 Prev()
{
var t = W ^ Z ^ (Z >> 19);
t ^= t >> 8;
t ^= t >> 16;
W = Z;
Z = Y;
Y = X;
t ^= t << 11;
t ^= t << 22;
X = t;
return W;
}
public UInt32 Curr()
{
return W;
}
public UInt32 Next()
{
UInt32 t = X ^ (X << 11);
X = Y;
Y = Z;
Z = W;
return W = W ^ (W >> 19) ^ (t ^ (t >> 8));
}
}
btw. Here's a swift version:
public class Xor128 {
public var X: UInt32
public var Y: UInt32
public var Z: UInt32
public var W: UInt32
public convenience init(uuid: uuid_t) {
let xa = (UInt32(uuid.0 ) << 24)
let xb = (UInt32(uuid.1 ) << 16)
let xc = (UInt32(uuid.2 ) << 8 )
let xd = (UInt32(uuid.3 ) << 0 )
let ya = (UInt32(uuid.4 ) << 24)
let yb = (UInt32(uuid.5 ) << 16)
let yc = (UInt32(uuid.6 ) << 8 )
let yd = (UInt32(uuid.7 ) << 0 )
let za = (UInt32(uuid.8 ) << 24)
let zb = (UInt32(uuid.9 ) << 16)
let zc = (UInt32(uuid.10) << 8 )
let zd = (UInt32(uuid.11) << 0 )
let wa = (UInt32(uuid.12) << 24)
let wb = (UInt32(uuid.13) << 16)
let wc = (UInt32(uuid.14) << 8 )
let wd = (UInt32(uuid.15) << 0)
self.init(
x: xa + xb + xc + xd,
y: ya + yb + yc + yd,
z: za + zb + zc + zd,
w: wa + wb + wc + wd
)
}
public convenience init(uuid: UUID) {
self.init(uuid: uuid.uuid)
}
public init(x: UInt32, y: UInt32, z: uint32, w: UInt32) {
X = x
Y = y
Z = z
W = w
}
#discardableResult
public func next() -> UInt32 {
let t = X ^ (X << 11);
X = Y;
Y = Z;
Z = W;
W = W ^ (W >> 19) ^ (t ^ (t >> 8))
return W;
}
public var curr: UInt32 {
return W
}
#discardableResult
public func prev() -> UInt32 {
var t = W ^ Z ^ (Z >> 19);
t ^= t >> 8;
t ^= t >> 16;
W = Z;
Z = Y;
Y = X;
t ^= t << 11;
t ^= t << 22;
X = t;
return W;
}
}
The basic building block you need is an algorithm to reverse the XOR with left shift operation f(x) = x ^ (x << s) for some s > 0. Given f(x), you already know the lower s bits of x directly.
You can reconstruct the rest of the bits iteratively from low to high, because you already know at each point the two bits that have been XORed to get the bit of f(x). Here's an example in Python:
def reverse_xor_lshift(y, shift, w=32):
x = y & ((1<<shift) - 1)
for i in range(w - shift):
x |= (1 if bool(x & (1<<i)) ^ bool(y & (1<<(shift+i))) else 0)<<(shift+i)
return x
Now the rest becomes rather easy. Note that I'm reusing the left shift reversal for the right shift analogue:
def reverse_bin(x, w=32):
return int(bin(x)[2:].rjust(w, '0')[::-1], 2)
def reverse_xor_rshift(y, shift, w=32):
# for simplicity, we just reuse reverse_xor_lshift here
return reverse_bin(reverse_xor_lshift(reverse_bin(y), shift))
def forward(X, Y, Z, W):
t = (X ^ (X << 11)) & 0xffffffff
X = Y
Y = Z
Z = W
W = W ^ (W >> 19) ^ (t ^ (t >> 8))
return (X, Y, Z, W)
def backward(X, Y, Z, W):
t = reverse_xor_rshift(W ^ Z ^ (Z >> 19), 8)
return (reverse_xor_lshift(t, 11), X, Y, Z)
backward is the function that reverses the state transition. Some random testing:
import random
for _ in range(1000):
X, Y, Z, W = [random.randint(0,2**32-1) for _ in range(4)]
assert backward(*forward(X,Y,Z,W)) == (X, Y, Z, W)
Seems to work.
For Y, Z and W, we can easily reverse it. For X, we need to make some observations:
W' = W ^ (W >> 19) ^ (t ^ (t >> 8)), -> t ^ (t >> 8) = W' ^ (W ^ (W >> 19))
So, now, we have t ^ (t >> 8) = W' ^ (W ^ (W >> 19)) = a
t = X ^ (X << 11)
-> t ^ (t >> 8) = X ^ (X << 11) ^ ((X ^ (X <<11)) >> 8)
= X ^ (X << 11) ^ (X >> 8) ^ (X << 3)
Denoting each bit of X as x0, x1, x2, ... x31, and each bit of a as a0, a1, ... we can form following equation system:
x0 ^ x8 = a0
x1 ^ x9 = a1
.....
Or, equivalent to:
(x0 + x8) % 2 = a0
(x1 + x9) % 2 = a1
....
Which we can easily solve by applying Gaussian elimination.
In the grid constructed by grid points (M*x, M*y) and given the point A(x1,y1) and point B(x2,y2) where all the variables are integers. I need to check how many grid points lie on the line segment from point A to point B. I know that it can be done by using the extended euclidean algorithm somehow, but I have no clue on how to do it. I would appreciate your help.
Rephrased, you want to determine how many numbers t satisfy
(1) M divides (1-t) x1 + t x2
(2) M divides (1-t) y1 + t y2
(3) 0 <= t <= 1.
Let's focus on (1). We introduce an integer variable q to represent the divisibility constraint and solve for t:
exists integer q, M q = (1-t) x1 + t x2
exists integer q, M q - x1 = (x2 - x1) t.
If x1 is not equal to x2, then this gives a periodic set of possibilities of the form t in {a + b q | q integer}, where a and b are fractions. Otherwise, all t or no t are solutions.
The extended Euclidean algorithm is useful for intersecting the solution sets arising from (1) and (2). Suppose that we want to compute the intersection
{a + b q | q integer} intersect {c + d s | s integer}.
By expressing a generic common element in two different ways, we arrive at a linear Diophantine equation:
a + b q = c + d s,
where a, b, c, d are constant and q, s are integer. Let's clear denominators and gather terms into one equation
A q + B s = C,
where A, B, C are integers. This equation has solutions if and only if the greatest common divisor g of A and B also divides C. Use the extended Euclidean algorithm to compute integer coefficients u, v such that
A u + B v = g.
Then we have a solution
q = u (C/g) + k (B/g)
s = v (C/g) - k (A/g)
for each integer k.
Finally, we have to take constraint (3) into consideration. This should boil down to some arithmetic and one floor division, but I'd rather not work out the details (the special cases of what I've written so far already will take quite a lot of your time).
Let's dX = Abs(x2-x1) and dY = Abs(y2 - y1)
Then number of lattice points on the segment is
P = GCD(dX, dY) + 1
(including start and end points)
where GCD is the greatest common divisor (through usual (not extended) Euclidean algorithm)
(See last Properties here)
Following instructions of Mr. David Eisenstat I have managed to write a program in c++ that calculates the answer.
#include <iostream>
#include <math.h>
using namespace std;
int gcd (int A, int B, int &u, int &v)
{
int Ad = 1;
int Bd = 1;
if (A < 0) { Ad = -1; A = -A; }
if (B < 0) { Bd = -1; B = -B; }
int x = 1, y = 0;
u = 0, v = 1;
while (A != 0)
{
int q = B/A;
int r = B%A;
int m = u-x*q;
int n = v-y*q;
B = A;
A = r;
u = x;
v = y;
x = m;
y = n;
}
u *= Ad;
v *= Bd;
return B;
}
int main(int argc, const char * argv[])
{
int t;
scanf("%d", &t);
for (int i = 0; i<t; i++) {
int x1, x2, y1, y2, M;
scanf("%d %d %d %d %d", &M, &x1, &y1, &x2, &y2);
if ( x1 == x2 ) // vertical line
{
if (x1%M != 0) { // in between the horizontal lines
cout << 0 << endl;
} else
{
int r = abs((y2-y1)/M); // number of points
if (y2%M == 0 || y1%M == 0) // +1 if the line starts or ends on the point
r++;
cout << r << endl;
}
} else {
if (x2 < x1)
{
int c;
c = x1;
x1 = x2;
x2 = c;
}
int A, B, C;
C = x1*y2-y1*x2;
A = M*(y2-y1);
B = -M*(x2-x1);
int u, v;
int g = gcd(A, B, u, v);
//cout << "A: " << A << " B: " << B << " C: " << C << endl;
//cout << A << "*" << u <<"+"<< B <<"*"<<v<<"="<<g<<endl;
double a = -x1/(double)(x2-x1);
double b = M/(double)(x2-x1);
double Z = (-a-C*b/g*u)*g/(B*b);
double Y = (1-a-C*b/g*u)*g/(B*b);
cout << floor(Z) - ceil(Y) + 1 << endl;
}
}
return 0;
}
Thank you for your help! Please check if all special cases are taken into consideration.
This is a follow-up to my previous question. I still find it very interesting problem and as there is one algorithm which deserves more attention I'm posting it here.
From Wikipedia: For the case that each xi is positive and bounded by the same constant, Pisinger found a linear time algorithm.
There is a different paper which seems to describe the same algorithm but it is a bit difficult to read for me so please - does anyone know how to translate the pseudo-code from page 4 (balsub) into working implementation?
Here are couple of pointers I collected so far:
http://www.diku.dk/~pisinger/95-6.ps (the paper)
https://stackoverflow.com/a/9952759/1037407
http://www.diku.dk/hjemmesider/ansatte/pisinger/codes.html
PS: I don't really insist on precisely this algorithm so if you know of any other similarly performant algorithm please feel free to suggest it bellow.
Edit
This is a Python version of the code posted bellow by oldboy:
class view(object):
def __init__(self, sequence, start):
self.sequence, self.start = sequence, start
def __getitem__(self, index):
return self.sequence[index + self.start]
def __setitem__(self, index, value):
self.sequence[index + self.start] = value
def balsub(w, c):
'''A balanced algorithm for Subset-sum problem by David Pisinger
w = weights, c = capacity of the knapsack'''
n = len(w)
assert n > 0
sum_w = 0
r = 0
for wj in w:
assert wj > 0
sum_w += wj
assert wj <= c
r = max(r, wj)
assert sum_w > c
b = 0
w_bar = 0
while w_bar + w[b] <= c:
w_bar += w[b]
b += 1
s = [[0] * 2 * r for i in range(n - b + 1)]
s_b_1 = view(s[0], r - 1)
for mu in range(-r + 1, 1):
s_b_1[mu] = -1
for mu in range(1, r + 1):
s_b_1[mu] = 0
s_b_1[w_bar - c] = b
for t in range(b, n):
s_t_1 = view(s[t - b], r - 1)
s_t = view(s[t - b + 1], r - 1)
for mu in range(-r + 1, r + 1):
s_t[mu] = s_t_1[mu]
for mu in range(-r + 1, 1):
mu_prime = mu + w[t]
s_t[mu_prime] = max(s_t[mu_prime], s_t_1[mu])
for mu in range(w[t], 0, -1):
for j in range(s_t[mu] - 1, s_t_1[mu] - 1, -1):
mu_prime = mu - w[j]
s_t[mu_prime] = max(s_t[mu_prime], j)
solved = False
z = 0
s_n_1 = view(s[n - b], r - 1)
while z >= -r + 1:
if s_n_1[z] >= 0:
solved = True
break
z -= 1
if solved:
print c + z
print n
x = [False] * n
for j in range(0, b):
x[j] = True
for t in range(n - 1, b - 1, -1):
s_t = view(s[t - b + 1], r - 1)
s_t_1 = view(s[t - b], r - 1)
while True:
j = s_t[z]
assert j >= 0
z_unprime = z + w[j]
if z_unprime > r or j >= s_t[z_unprime]:
break
z = z_unprime
x[j] = False
z_unprime = z - w[t]
if z_unprime >= -r + 1 and s_t_1[z_unprime] >= s_t[z]:
z = z_unprime
x[t] = True
for j in range(n):
print x[j], w[j]
// Input:
// c (capacity of the knapsack)
// n (number of items)
// w_1 (weight of item 1)
// ...
// w_n (weight of item n)
//
// Output:
// z (optimal solution)
// n
// x_1 (indicator for item 1)
// ...
// x_n (indicator for item n)
#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>
using namespace std;
int main() {
int c = 0;
cin >> c;
int n = 0;
cin >> n;
assert(n > 0);
vector<int> w(n);
int sum_w = 0;
int r = 0;
for (int j = 0; j < n; ++j) {
cin >> w[j];
assert(w[j] > 0);
sum_w += w[j];
assert(w[j] <= c);
r = max(r, w[j]);
}
assert(sum_w > c);
int b;
int w_bar = 0;
for (b = 0; w_bar + w[b] <= c; ++b) {
w_bar += w[b];
}
vector<vector<int> > s(n - b + 1, vector<int>(2 * r));
vector<int>::iterator s_b_1 = s[0].begin() + (r - 1);
for (int mu = -r + 1; mu <= 0; ++mu) {
s_b_1[mu] = -1;
}
for (int mu = 1; mu <= r; ++mu) {
s_b_1[mu] = 0;
}
s_b_1[w_bar - c] = b;
for (int t = b; t < n; ++t) {
vector<int>::const_iterator s_t_1 = s[t - b].begin() + (r - 1);
vector<int>::iterator s_t = s[t - b + 1].begin() + (r - 1);
for (int mu = -r + 1; mu <= r; ++mu) {
s_t[mu] = s_t_1[mu];
}
for (int mu = -r + 1; mu <= 0; ++mu) {
int mu_prime = mu + w[t];
s_t[mu_prime] = max(s_t[mu_prime], s_t_1[mu]);
}
for (int mu = w[t]; mu >= 1; --mu) {
for (int j = s_t[mu] - 1; j >= s_t_1[mu]; --j) {
int mu_prime = mu - w[j];
s_t[mu_prime] = max(s_t[mu_prime], j);
}
}
}
bool solved = false;
int z;
vector<int>::const_iterator s_n_1 = s[n - b].begin() + (r - 1);
for (z = 0; z >= -r + 1; --z) {
if (s_n_1[z] >= 0) {
solved = true;
break;
}
}
if (solved) {
cout << c + z << '\n' << n << '\n';
vector<bool> x(n, false);
for (int j = 0; j < b; ++j) x[j] = true;
for (int t = n - 1; t >= b; --t) {
vector<int>::const_iterator s_t = s[t - b + 1].begin() + (r - 1);
vector<int>::const_iterator s_t_1 = s[t - b].begin() + (r - 1);
while (true) {
int j = s_t[z];
assert(j >= 0);
int z_unprime = z + w[j];
if (z_unprime > r || j >= s_t[z_unprime]) break;
z = z_unprime;
x[j] = false;
}
int z_unprime = z - w[t];
if (z_unprime >= -r + 1 && s_t_1[z_unprime] >= s_t[z]) {
z = z_unprime;
x[t] = true;
}
}
for (int j = 0; j < n; ++j) {
cout << x[j] << '\n';
}
}
}
great code man, but it sometimes crashed in this codeblock
for (mu = w[t]; mu >= 1; --mu)
{
for (int j = s_t[mu] - 1; j >= s_t_1[mu]; --j)
{
if (j >= w.size())
{ // !!! PROBLEM !!!
}
int mu_prime = mu - w[j];
s_t[mu_prime] = max(s_t[mu_prime], j);
}
}
...
For Ludum Dare 22, Notch programmed a game in 48 hours called Minicraft. It's like a 2D minecraft.
Anyway the source is available (here: http://www.ludumdare.com/compo/ludum-dare-22/?action=preview&uid=398 ), and I was taking a look since I am interested in random generation of terrain and levels. In the code is a block of code which runs the core generation, and the algorithm to me seems familiar, but I can't put a name to it. I'd like to know exactly what it is so I can read more about it and learn how it works.
Specifically, the code is from levelGen.java:
do {
int halfStep = stepSize / 2;
for (int y = 0; y < w; y += stepSize) {
for (int x = 0; x < w; x += stepSize) {
double a = sample(x, y);
double b = sample(x + stepSize, y);
double c = sample(x, y + stepSize);
double d = sample(x + stepSize, y + stepSize);
double e = (a + b + c + d) / 4.0 + (random.nextFloat() * 2 - 1) * stepSize * scale;
setSample(x + halfStep, y + halfStep, e);
}
}
for (int y = 0; y < w; y += stepSize) {
for (int x = 0; x < w; x += stepSize) {
double a = sample(x, y);
double b = sample(x + stepSize, y);
double c = sample(x, y + stepSize);
double d = sample(x + halfStep, y + halfStep);
double e = sample(x + halfStep, y - halfStep);
double f = sample(x - halfStep, y + halfStep);
double H = (a + b + d + e) / 4.0 + (random.nextFloat() * 2 - 1) * stepSize * scale * 0.5;
double g = (a + c + d + f) / 4.0 + (random.nextFloat() * 2 - 1) * stepSize * scale * 0.5;
setSample(x + halfStep, y, H);
setSample(x, y + halfStep, g);
}
}
stepSize /= 2;
scale *= (scaleMod + 0.8);
scaleMod *= 0.3;
} while (stepSize > 1);
Those two for loops are running some kind of sampling algorithm, and I would just like to know if this is known named algorithm, or if notch just rolled his own.
This looks like the diamond-square algorithm.