Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: Compute Unique Numbers in a Set

306 views
Skip to first unread message

Bonita Montero

unread,
Jan 8, 2023, 12:01:08 AM1/8/23
to
Now it's perfect:

#include <iostream>
#include <unordered_set>
#include <charconv>
#include <random>

using namespace std;

int main( int argc, char **argv )
{
try
{
if( argc < 4 )
return
cout << argv[0] << " n from to" << endl,
EXIT_FAILURE;
auto parse = []( char const *str, char const *err )
{
size_t value;
if( from_chars_result fcr = from_chars( str, str + strlen( str ),
value ); (bool)fcr.ec || *fcr.ptr )
throw invalid_argument( err );
return value;
};
size_t
n = parse( argv[1], "wrong number of values" ),
from = parse( argv[2], "wrong from-value" ),
to = parse( argv[3], "wrong to-value" );
if( from > to )
swap( from, to );
if( !n || n - 1 > to - from )
return
cout << "n is too small" << endl,
EXIT_FAILURE;
unordered_set<size_t> already;
already.reserve( n );
mt19937_64 mt;
uniform_int_distribution<size_t> uid( from, to );
while( already.size() != n )
{
size_t value;
do
value = uid( mt );
while( already.contains( value ) );
already.emplace( value );
cout << value << endl;
}
}
catch( exception const &exc )
{
return
cout << exc.what() << endl,
EXIT_FAILURE;
}
}

Bart

unread,
Jan 8, 2023, 9:49:14 AM1/8/23
to
That's some torturous-looking code. My attempt for the same spec is give
below, in scripting code. Despite that, I'd argue that it would simpler
to use that as a starting point to create a C version rather than try
and adapt your C++ code, because it is basically pseudo-code.

Half of this is just reading and checking command line inputs which can
be in any manner at all. In any case it's of little relevance; of much
more use would be a function that returned a set of N unique random
numbers, that can be embedded into another program.

Note that your error message is wrong: N would be too large, not too small.

Neither version seeds the PRNG so they're both useless on repeated runs.

----------------------------------------------------------------

if ncmdparams<>3 then
println "Usage: N From To"
stop 1
fi

read n:"i", lower:"i", upper:"i"

if lower>upper then swap(lower,upper) fi

if n > upper-lower+1 then
abort("N is too large")
fi

a::=()

to n do
repeat
x:=random(lower..upper)
until x not in a
a &:= x
println x
od

Bonita Montero

unread,
Jan 8, 2023, 12:21:55 PM1/8/23
to
Am 08.01.2023 um 15:48 schrieb Bart:

> That's some torturous-looking code. My attempt for the same spec is give
> below, in scripting code. Despite that, I'd argue that it would simpler
> to use that as a starting point to create a C version rather than try
> and adapt your C++ code, because it is basically pseudo-code.

C++ is used when things are usually not that simple and you have a
performance requirement. If you strip the screen output and run the
code with a large number of values any the given C++ code is magni-
tudes faster than any scripting code.


Bart

unread,
Jan 8, 2023, 12:34:55 PM1/8/23
to
On 08/01/2023 14:48, Bart wrote:
> On 08/01/2023 05:01, Bonita Montero wrote:
>> Now it's perfect:
>>
>> <snip complicated C++ code>>

> That's some torturous-looking code.

I tested your [BM] code for speed, using N=1000000, and limits of 1..N+1.

The 'cout' in the loop was replaced with a count of all the values, so
that at the end the total was displayed to be able to compare results.

The C++ with gcc-O3 took 1.25 seconds.

My script initially took much longer due to using an unordered list
(storing up to 1M values). But I tweaked it use a bit-set.

Then it took 0.67 seconds.


(Revised script:)
>     a:=new(set,lower..upper)
> sum:=0

>     to n do
>         repeat
>             x:=random(lower..upper)
>         until x not in a
>         a[x]:=1
> sum+:=x
>     od

Bart

unread,
Jan 8, 2023, 12:46:39 PM1/8/23
to
I posted my last reply before I even saw this comment. I explained how I
did exactly that! My script was faster.

I've now tried N=10M and results are:

C++ 79 seconds (g++ -O0)
C++ 16 seconds (g++ -O3)
Script (1) 13 seconds (HLL only, unoptimised)
Script (2) 9.5 seconds (ASM-accelerated unoptimised)
Script (3) 7.3 seconds (HLL only, optimised via C/gcc/-O3)

The 'optimisation' refers to the interpreter; the program is still bytecode.

The interesting thing is that my unoptimised interpeter, executing
byte-code, is 6 times as fast as unoptimised C++ executing native code.

(However I don't know what's going on inside your C++ libraries; this is
where C has the advantage of transparency.)

Paavo Helde

unread,
Jan 8, 2023, 2:20:06 PM1/8/23
to
I see two issues with this perfect solution:

- repeated values are excluded, so the randomness is less than
perfect. But this seems to be by design.

- two lookups in 'already' instead of the optimal one. What's wrong
with insert() and checking its return value?






Ben Bacarisse

unread,
Jan 8, 2023, 2:20:26 PM1/8/23
to
Bonita Montero <Bonita....@gmail.com> writes:

> Now it's perfect:

Does not even compile for me (g++ -std=c++20 required).

--
Ben.

Ike Naar

unread,
Jan 8, 2023, 4:46:14 PM1/8/23
to
On 2023-01-08, Bart <b...@freeuk.com> wrote:
> On 08/01/2023 14:48, Bart wrote:
>> On 08/01/2023 05:01, Bonita Montero wrote:
>>> Now it's perfect:
>>>
>>> <snip complicated C++ code>>
>
>> That's some torturous-looking code.
>
> I tested your [BM] code for speed, using N=1000000, and limits of 1..N+1.
>
> The 'cout' in the loop was replaced with a count of all the values, so
> that at the end the total was displayed to be able to compare results.
>
> The C++ with gcc-O3 took 1.25 seconds.
>
> My script initially took much longer due to using an unordered list
> (storing up to 1M values). But I tweaked it use a bit-set.
>
> Then it took 0.67 seconds.
>
>
> (Revised script:)
>> ??? a:=new(set,lower..upper)
>> sum:=0
>
>> ??? to n do
>> ??????? repeat
>> ??????????? x:=random(lower..upper)
>> ??????? until x not in a
>> ??????? a[x]:=1
> > sum+:=x
>> ??? od

In the program below, each random number requires only constant time and
retries are not necessary.
For N=1000000 it runs in 0.01 second.


#include <stdlib.h>
#include <stdio.h>

enum {N = 1000000};
static int used;
static int numbers[N];
/*
numbers[0 .. N) contain a permutation of [0 .. N)
0 <= used <= N
numbers[0 .. used) are available
numbers[used .. N) are already used
*/

static void reset(void)
{
/* mark all numbers[0..N) as available */
used = N;
}

static void init(void)
{
/* fill numbers[0..N) with a permutation of [0..N) */
for (int i = 0; i != N; ++i)
{
numbers[i] = i;
}
}

static int getrandom(void)
{
/* pick a random value from the available numbers, and update the numbers array */
if (used == 0)
{
puts("ran out of available numbers");
abort();
}
int index = rand() % used;
--used;
int value = numbers[index];
numbers[index] = numbers[used];
numbers[used] = value;
return value;
}

static void run(int length)
/*
generate a run of 'length' unique numbers from the range [0..N)
*/
{
reset();
long long sum = 0;
for (int i = 0; i != length; ++i)
{
sum += getrandom();
}
printf("%lld\n", sum);
}

int main(void)
{
/* if necessary, seed the PRNG (not done here) */
init();
run(N);
return 0;
}

Bart

unread,
Jan 8, 2023, 6:13:51 PM1/8/23
to
So, this is more of a shuffle? Since the set of numbers is not really
random, it's a permutation of a consecutive range of values.

I tried your code on 10M numbers (to be easier to measure), and with
gcc-O3 it took 0.22 seconds.

However, on Windows RAND_MAX is only about 32K, and the resulting
numbers were not properly distributed. Doubling-up the rand calls was
better, but the timing went up to 1.2 seconds for some reason.

I then imported my own prng, now timings were 0.3 seconds. Trying a
similar shuffle on scripting code was about 3 seconds.

Chris M. Thomasson

unread,
Jan 8, 2023, 6:18:49 PM1/8/23
to
[...]

It looks like shuffle of a set of unique numbers.

Bonita Montero

unread,
Jan 8, 2023, 10:57:56 PM1/8/23
to
Am 08.01.2023 um 18:46 schrieb Bart:

> I've now tried N=10M and results are:
>
> C++                    79   seconds  (g++ -O0)
> C++                    16   seconds  (g++ -O3)
> Script (1)             13   seconds  (HLL only, unoptimised)
> Script (2)              9.5 seconds  (ASM-accelerated unoptimised)
> Script (3)              7.3 seconds  (HLL only, optimised via C/gcc/-O3)

Whatever you tested: you dindn't test my code.


Alf P. Steinbach

unread,
Jan 9, 2023, 6:04:13 AM1/9/23
to
On 2023-01-08 6:01 AM, Bonita Montero wrote:
>         if( !n || n - 1 > to - from )
>             return
>                 cout << "n is too small" << endl,
>                 EXIT_FAILURE;

Presumably you meant "n is too large".

Tip: you can get vastly more clear code by avoiding side effects in
expressions rather than trying to leverage such side effects.


>         unordered_set<size_t> already;
>         already.reserve( n );
>         mt19937_64 mt;
>         uniform_int_distribution<size_t> uid( from, to );
>         while( already.size() != n )
>         {
>             size_t value;
>             do
>                 value = uid( mt );
>             while( already.contains( value ) );
>             already.emplace( value );
>             cout << value << endl;
>         }

When n is large and is near or equal to the number of possible values,
this loop becomes inefficient: for the last number you can expect on
average n iterations to find that number, because each call of uid has a
1/n chance of finding it.

Not sure of the exact overall complexity but for that case I guess O(n^2).

However this can be a good way to generate distinct random numbers when
n is very small compared to the range size. But when n is close to the
range size, if the range size is small compared to available memory then
just store the sequence of numbers in the range and shuffle it, and use
the first n values in the shuffled sequence. When neither of these
conditions hold I don't know how to approach the problem; I'd probably
then start by looking it up in Wikipedia or general googling.

- Alf

Bart

unread,
Jan 9, 2023, 6:27:11 AM1/9/23
to
It wasn't /my/ code because I don't know C++. It was just tweaked from
yours:

#include <iostream>
#include <unordered_set>
#include <charconv>
#include <random>
#include <string.h>

using namespace std;

int main( int argc, char **argv )
{
try
{
int n=10000000, from=1, to=n+1;
unordered_set<size_t> already;
already.reserve( n );
mt19937_64 mt;
uniform_int_distribution<size_t> uid( from, to );
long long int sum=0;
int i=0;
while( already.size() != n )
{
size_t value;
do
value = uid( mt );
while( already.contains( value ) );
already.emplace( value );
sum+=value;
// cout << value << " " << sum << " " << ++i << endl;
}
cout << sum << endl;

}
catch( exception const &exc )
{
return
cout << exc.what() << endl,
EXIT_FAILURE;
}
}


(The calculated 'sum' is not the sum of all the final set of values; I
realised I had no idea how to access those in a separate loop.)

Bonita Montero

unread,
Jan 9, 2023, 9:57:03 AM1/9/23
to
You must have made sth. wrong.

Bonita Montero

unread,
Jan 9, 2023, 11:42:32 AM1/9/23
to
Am 09.01.2023 um 12:03 schrieb Alf P. Steinbach:

> When n is large and is near or equal to the number of possible values,
> this loop becomes inefficient: for the last number you can expect on
> average n iterations to find that number, because each call of uid has a
> 1/n chance of finding it.

I know that the loop becomes inefficient then, but tell me a better
alternative algorithm. You'd have a list of eligible numbers and
randomly chose one of them. That would also take a lot of time to
remove the number from the list.

Ben Bacarisse

unread,
Jan 9, 2023, 6:22:26 PM1/9/23
to
Bonita Montero <Bonita....@gmail.com> writes:

> Am 09.01.2023 um 12:03 schrieb Alf P. Steinbach:
>
>> When n is large and is near or equal to the number of possible
>> values, this loop becomes inefficient: for the last number you can
>> expect on average n iterations to find that number, because each call
>> of uid has a 1/n chance of finding it.
>
> I know that the loop becomes inefficient then, but tell me a better
> alternative algorithm.

An alternative that works well in those cases (and in some others) has
already been described where each candidate is chosen with the
appropriate probability. I originally set it out as an exercises since
I thought the OP was doing homework, but the gist of it was explained.

> You'd have a list of eligible numbers and
> randomly chose one of them. That would also take a lot of time to
> remove the number from the list.

No need:

void choose(int choose_n, int from_m, int *output)
{
for (int i = 0, j = 0; j < choose_n; i++)
if (true_with_probability(choose_n - j, from_m - i))
output[j++] = i + 1;
}

Obviously using one would not use this to choose 3 numbers from a set of
millions!

--
Ben.

Malcolm McLean

unread,
Jan 10, 2023, 8:11:27 AM1/10/23
to
Here's my go.
#include <random>
#include <vector>
#include <cstdio>

/*
Draw a enadom number form the hypergeomtric distribution (sampling
from a bi-valued population without replacement)
rndengine - a random number generator engine
Ngood - number of positives in the population
Nbad - number of negatives in the population
Nsample - number of samples to take (less than or equal to Ngood + Nbad)
Returns: the number of "good" elements drawn, randomly.
*/
template<class rndengine>
int rand_hypergeometric(int Ngood, int Nbad, int Nsample, rndengine &eng)
{
int answer = 0;
std::uniform_real_distribution<double> distr(0, 1);
for (int i =0; i < Nsample; i++)
{
double p = distr(eng);
if (p < ((double)Ngood)/(Ngood + Nbad))
{
answer++;
Ngood--;
}
else
{
Nbad--;
}
}

return answer;
}

/*
Recursive randunique function
out - vector to collect results
Nsamples - number of samples to take
Npopulation - size of population
indexbase - fiddle to have populations not starting from 0, pass 0 at top level.
eng - the random number engine

*/
template<class rndengine>
void randunique_r(std::vector<int> &out, int Nsamples, int Npopulation,
int indexbase, rndengine &eng)
{
if (Nsamples == 0)
return;
std::uniform_int_distribution<int> distr(0, Npopulation -1);
int i = distr(eng);
int Nsampleslow = rand_hypergeometric(i, Npopulation - i -1, Nsamples-1, eng);
randunique_r(out, Nsampleslow, i, indexbase, eng);
out.push_back(i + indexbase);
randunique_r(out, Nsamples - Nsampleslow -1, Npopulation - i -1, indexbase + i, eng);
}

/*
Draw a set of unique random samples from a population
Nsamples - the number of elemnts to choose.
Npopulation - the population size
eng - the random number engine
Returns: vector with indices of chosen members, sorted ascending.
*/
template<class rndengine>
std::vector<int> randunique(int Nsamples, int Npopulation, rndengine &eng)
{
std::vector<int> answer;
randunique_r(answer, Nsamples, Npopulation, 0, eng);

return answer;
}

int main(void)
{
std::mt19937 engine(123);
std::vector<int> result = randunique(10, 20, engine);
for (int i =0; i <result.size(); i++)
printf("%d, ", result[i]);
printf("\n");

return 0;
}

Not very efficient. But the rand_hypergeometric functon is written naively.
It can be rewritten to run a lot faster, though this isn't easy.

Malcolm McLean

unread,
Jan 10, 2023, 8:19:48 AM1/10/23
to
On Tuesday, 10 January 2023 at 13:11:27 UTC, Malcolm McLean wrote:
>
> randunique_r(out, Nsamples - Nsampleslow -1, Npopulation - i -1, indexbase + i, eng);
> }
Bug:: should be
indexbase + i + 1.

Tim Woodall

unread,
Jan 13, 2023, 1:40:21 AM1/13/23
to
On 2023-01-08, Chris M. Thomasson <chris.m.t...@gmail.com> wrote:
>
> It looks like shuffle of a set of unique numbers.
>

The original spec wasn't very clear but looked to me to be a choose m
from n - which can be implemented as shuffle then choose first m (with
further optimization that you only need to shuffle the first m slots)

Tim Woodall

unread,
Jan 13, 2023, 1:40:21 AM1/13/23
to
further optimization that you only need to shuffle *into* the first m slots)
>

Tim Woodall

unread,
Jan 13, 2023, 1:40:21 AM1/13/23
to
On 2023-01-08, Bonita Montero <Bonita....@gmail.com> wrote:
> Now it's perfect:
>

Hmmm, about 20 years ago I was told a story of someone who needed a
'shuffle' function - random permutation. I don't know or don't recall
the context but I'd guess it was part of a test harness.

They wrote it, tested it, deployed it, and things ground to a
standstill.

Instead of permuting, they'd randomly picked numbers, checked for dupes,
and then added to their output, quick for very small sets, 'never'
terminated for large ones.

Bonita Montero

unread,
Jan 13, 2023, 2:26:26 AM1/13/23
to
Now I make a list of eligible numbers, randomly chode one of them
and remove the item from the list:

#include <iostream>
#include <charconv>
#include <random>
#include <concepts>
#include <vector>

using namespace std;

int main( int argc, char **argv )
{
try
{
if( argc < 4 )
return
cout << argv[0] << " n from to" << endl,
EXIT_FAILURE;
auto parse = []( char const *str, char const *err )
{
size_t value;
if( from_chars_result fcr = from_chars( str, str + strlen( str ),
value ); (bool)fcr.ec || *fcr.ptr )
throw invalid_argument( err );
return value;
};
size_t n = parse( argv[1], "wrong number of values" );
if( !n )
return EXIT_SUCCESS;
size_t
from = parse( argv[2], "wrong from-value" ),
to = parse( argv[3], "wrong to-value" );
if( from > to )
swap( from, to );
if( n - 1 > to - from )
return
cout << "n is too small" << endl,
EXIT_FAILURE;
vector<size_t> free;
free.resize( to - from + 1 );
for( size_t i = from; size_t &v : free )
v = i++;
mt19937_64 mt;
size_t above = to;
while( free.size() )
{
auto pick = free.begin() + (uniform_int_distribution<size_t>( 0,
free.size() - 1 ))( mt );
//cout << *pick << endl;
free.erase( pick );
}
}
catch( exception const &exc )
{
return
cout << exc.what() << endl,
EXIT_FAILURE;
}
}

But that's _much_ slower.


Öö Tiib

unread,
Jan 13, 2023, 6:27:01 AM1/13/23
to
On Friday, 13 January 2023 at 09:26:26 UTC+2, Bonita Montero wrote:
> Am 09.01.2023 um 17:42 schrieb Bonita Montero:
> > Am 09.01.2023 um 12:03 schrieb Alf P. Steinbach:
> >
> >> When n is large and is near or equal to the number of possible values,
> >> this loop becomes inefficient: for the last number you can expect on
> >> average n iterations to find that number, because each call of uid has
> >> a 1/n chance of finding it.
> >
> > I know that the loop becomes inefficient then, but tell me a better
> > alternative algorithm. You'd have a list of eligible numbers and
> > randomly chose one of them. That would also take a lot of time to
> > remove the number from the list.
> Now I make a list of eligible numbers, randomly chode one of them
> and remove the item from the list:
>
Some kind of weird algorithm ... what it supposedly does?
Why you require n from user if the algorithm does nothing with it?
Variable above is also ignored, perhaps the algorithm is meant as
half-made complete-yourself pseudocode?

> But that's _much_ slower.
>
Very likely as it does do something odd.

Kenny McCormack

unread,
Jan 13, 2023, 7:22:05 AM1/13/23
to
In article <tpr12i$1i7r6$1...@dont-email.me>,
some lunatic <Bonita....@gmail.com> wrote:
...
>Now I make a list of eligible numbers, randomly chode one of them
>and remove the item from the list:
>
>#include <iostream>
>#include <charconv>
>#include <random>
>#include <concepts>
>#include <vector>

You still just don't seem to get this whole topicality thing, do ya?

--
Reading any post by Fred Hodgin, you're always faced with the choice of:
lunatic, moron, or troll.

I always try to be generous and give benefit of the doubt, by assuming troll.

Öö Tiib

unread,
Jan 13, 2023, 8:04:51 AM1/13/23
to
On Friday, 13 January 2023 at 08:40:21 UTC+2, Tim Woodall wrote:
> On 2023-01-08, Bonita Montero <Bonita....@gmail.com> wrote:
> > Now it's perfect:
> >
> Hmmm, about 20 years ago I was told a story of someone who needed a
> 'shuffle' function - random permutation. I don't know or don't recall
> the context but I'd guess it was part of a test harness.
>
> They wrote it, tested it, deployed it, and things ground to a
> standstill.
>
> Instead of permuting, they'd randomly picked numbers, checked for dupes,
> and then added to their output, quick for very small sets, 'never'
> terminated for large ones.
>
It's bit frustrating to read those stories.
The O(n) algorithm for when the range to pick from and set to be picked
are of close size is not that large or complicated, how they manage
to take tons of time?

size_t n, to, from;
// ...
// assign count to pick to "n" and range to "to" and "from"
// ...
size_t size = to - from + 1;
std::vector<size_t> result(size);

std::mt19937_64 gen(time(nullptr)); // or whatever generator

for(size_t i = 0; i < n; ++i) {
size_t choice = (std::uniform_int_distribution<size_t>( i, size - 1))( gen );
size_t& current = result[i];
size_t& picked = result[choice];
if (current == 0) current = i + 1;
if (picked == 0) picked = choice + 1;
if (current != picked) std::swap(current, picked);
current += from - 1;
// std::cout << current << '\n';
}
result.resize(n);

Bonita Montero

unread,
Jan 13, 2023, 8:10:50 AM1/13/23
to
Am 13.01.2023 um 13:21 schrieb Kenny McCormack:
> In article <tpr12i$1i7r6$1...@dont-email.me>,
> some lunatic <Bonita....@gmail.com> wrote:
> ...
>> Now I make a list of eligible numbers, randomly chode one of them
>> and remove the item from the list:
>>
>> #include <iostream>
>> #include <charconv>
>> #include <random>
>> #include <concepts>
>> #include <vector>
>
> You still just don't seem to get this whole topicality thing, do ya?

My code is beyond that topic. You may elect only a small number
of values like in the original code, but you might also chose
million of numbers.


Kenny McCormack

unread,
Jan 13, 2023, 8:56:18 AM1/13/23
to
In article <tprl89$1k839$1...@dont-email.me>,
some lunatic <Bonita....@gmail.com> wrote:
>Am 13.01.2023 um 13:21 schrieb Kenny McCormack:
>> In article <tpr12i$1i7r6$1...@dont-email.me>,
>> some lunatic <Bonita....@gmail.com> wrote:
>> ...
>>> Now I make a list of eligible numbers, randomly chode one of them
>>> and remove the item from the list:
>>>
>>> #include <iostream>
>>> #include <charconv>
>>> #include <random>
>>> #include <concepts>
>>> #include <vector>
>>
>> You still just don't seem to get this whole topicality thing, do ya?
>
>My code is beyond that topic. You may elect only a small number
>of values like in the original code, but you might also chose
>million of numbers.

Whoooooosh!!!

--
Many people in the American South think that DJT is, and will be remembered
as, one of the best presidents in US history. They are absolutely correct.

He is currently at number 46 on the list. High praise, indeed!

Bonita Montero

unread,
Jan 13, 2023, 9:01:44 AM1/13/23
to
Am 13.01.2023 um 14:55 schrieb Kenny McCormack:
> In article <tprl89$1k839$1...@dont-email.me>,
> some lunatic <Bonita....@gmail.com> wrote:
>> Am 13.01.2023 um 13:21 schrieb Kenny McCormack:
>>> In article <tpr12i$1i7r6$1...@dont-email.me>,
>>> some lunatic <Bonita....@gmail.com> wrote:
>>> ...
>>>> Now I make a list of eligible numbers, randomly chode one of them
>>>> and remove the item from the list:
>>>>
>>>> #include <iostream>
>>>> #include <charconv>
>>>> #include <random>
>>>> #include <concepts>
>>>> #include <vector>
>>>
>>> You still just don't seem to get this whole topicality thing, do ya?
>>
>> My code is beyond that topic. You may elect only a small number
>> of values like in the original code, but you might also chose
>> million of numbers.
>
> Whoooooosh!!!

It's not the absolute number of values which can be chosen
but the flexibility or finding the most efficient way to
have this flexibility.


Kenny McCormack

unread,
Jan 13, 2023, 9:17:59 AM1/13/23
to
In article <tpro7o$1ki63$1...@dont-email.me>,
Due anziani che convivono da una vita:
Lei: "Caro, ormai ci potremmo anche sposare...".
Lui: "Ma cara, alla nostra eta', chi ci prenderebbe?".

--
"Women should not be enlightened or educated in any way. They should be
segregated because they are the cause of unholy erections in holy men.

-- Saint Augustine (354-430) --

Bonita Montero

unread,
Jan 15, 2023, 10:05:29 AM1/15/23
to
Now it's perfect:

#include <iostream>
#include <unordered_set>
#include <charconv>
#include <random>
#include <concepts>

unordered_set<size_t> values;
mt19937_64 mt;
uniform_int_distribution<size_t> uid( from, to );
if( to - from != (size_t)-1 && to - from + 1 < n / 2 )
{
values.reserve( n );
while( values.size() < n )
{
size_t value;
do
value = uid( mt );
while( values.contains( value ) );
values.emplace( value );
}
}
else
{
if( to - from == (size_t)-1 )
throw bad_alloc();
values.reserve( to - from + 1 );
size_t i = from - 1;
do
values.emplace( ++i );
while( i != to );
while( values.size() > n )
for( ; ; )
{
auto itRemove = values.find( uid( mt ) );
if( itRemove == values.end() )
continue;
values.erase( itRemove );
break;
}
}
for( size_t value : values )
cout << value << endl;
}
catch( exception const &exc )
{
return
cout << exc.what() << endl,
EXIT_FAILURE;
}
}

If less than half of the range of numbers is selected (n < (to - from
+ 1) / 2) the unordered map is filled up to n elements and if an element
is found that's already there another value is chosen. If more than half
of the range is selected (n >= (to - from + 1) / 2) the set is filled up
to contain the whole range and the elements are incrementally removed at
a random value.

Ralf Goertz

unread,
Jan 15, 2023, 10:48:01 AM1/15/23
to
Am Sun, 15 Jan 2023 16:06:00 +0100
schrieb Bonita Montero <Bonita....@gmail.com>:

> Now it's perfect:

[snip]

> If less than half of the range of numbers is selected (n < (to - from
> + 1) / 2) the unordered map is filled up to n elements and if an
> element is found that's already there another value is chosen. If
> more than half of the range is selected (n >= (to - from + 1) / 2)
> the set is filled up to contain the whole range and the elements are
> incrementally removed at a random value.

What's wrong with a clean two line solution:


#include <algorithm>
#include <iostream>
#include <random>
#include <charconv>
#include <vector>
#include <cstring>
mt19937_64 mt;
vector<int> values( to - from );
// ------
//only two lines to find random subset of fixed size:
fill(values.begin(), values.begin() + n, 1);
shuffle(values.begin(), values.end(), mt);
// ------
for( size_t i=0; i < values.size(); ++i )
if( values[i]) cout << i+from << endl;

Bonita Montero

unread,
Jan 15, 2023, 11:13:01 AM1/15/23
to
Am 15.01.2023 um 16:47 schrieb Ralf Goertz:
> Am Sun, 15 Jan 2023 16:06:00 +0100
> schrieb Bonita Montero <Bonita....@gmail.com>:
>
>> Now it's perfect:
>
> [snip]
>
>> If less than half of the range of numbers is selected (n < (to - from
>> + 1) / 2) the unordered map is filled up to n elements and if an
>> element is found that's already there another value is chosen. If
>> more than half of the range is selected (n >= (to - from + 1) / 2)
>> the set is filled up to contain the whole range and the elements are
>> incrementally removed at a random value.
>
> What's wrong with a clean two line solution:

You might have less numbers than to - from + 1 (you omitted the 1 on
allocation of the vector).

Bart

unread,
Jan 15, 2023, 11:28:02 AM1/15/23
to
On 15/01/2023 15:06, Bonita Montero wrote:
> Now it's perfect:

You said that last time too:

On 08/01/2023 05:01, Bonita Montero wrote:
> Now it's perfect:
>


I guess it's more perfect?

Bonita Montero

unread,
Jan 15, 2023, 11:41:54 AM1/15/23
to
The code I've shown yet is also perfect in terms of performance,
but not just functionally.

Malcolm McLean

unread,
Jan 15, 2023, 11:57:34 AM1/15/23
to
Where N is the range and M the number of elements to choose, it's O(N)
in space and time. So unsuitable if N is very much larger than M.

Kenny McCormack

unread,
Jan 15, 2023, 12:11:44 PM1/15/23
to
In article <tq14n7$2cgbf$1...@dont-email.me>,
Bonita Montero <Bonita....@gmail.com> wrote:
>Now it's perfect:

I just need 11,780 votes. Give me a break here.

--
If Jeb is Charlie Brown kicking a football-pulled-away, Mitt is a '50s
housewife with a black eye who insists to her friends the roast wasn't
dry.

Ralf Goertz

unread,
Jan 16, 2023, 3:46:39 AM1/16/23
to
Am Sun, 15 Jan 2023 08:57:24 -0800 (PST)
schrieb Malcolm McLean <malcolm.ar...@gmail.com>:

> On Sunday, 15 January 2023 at 15:48:01 UTC, Ralf Goertz wrote:
> > Am Sun, 15 Jan 2023 16:06:00 +0100
> > schrieb Bonita Montero <Bonita....@gmail.com>:
> >
> > > Now it's perfect:
> >
> > [snip]
> > > If less than half of the range of numbers is selected (n < (to -
> > > from
> > > + 1) / 2) the unordered map is filled up to n elements and if an
> > > element is found that's already there another value is chosen. If
> > > more than half of the range is selected (n >= (to - from + 1) /
> > > 2) the set is filled up to contain the whole range and the
> > > elements are incrementally removed at a random value.
> > What's wrong with a clean two line solution:
> > …
> > // ------
> > //only two lines to find random subset of fixed size:
> > fill(values.begin(), values.begin() + n, 1);
> > shuffle(values.begin(), values.end(), mt);
> > // ------
> > …
> >
> Where N is the range and M the number of elements to choose, it's O(N)
> in space and time. So unsuitable if N is very much larger than M.

I just tried it out. Both methods (mine with the corrected off by 1
error) applied 100000 times outputting the last result:

./rg 10 1 1000
193 198 257 384 474 581 606 620 682 954
0.718732s

./rg 990 1 1000

0.715686s

./bonita 10 1 1000
919 888 875 567 563 499 323 306 61 34
14.0962s

./bonita 990 1 1000

4.7713s


The problem seems to be the unordered_set. I created it outside the loop
(just like my vector), but I had to empty it at the beginning of the
loop. (Is there another way to reuse it?) So in theory you're right but
I guess the set approach is a heavy burden.

My loop:

for (int k=0; k < 100000 ; ++k) {
fill( values.begin(), values.begin() + n, 1);
fill( values.begin() + n, values.end(), 0);
shuffle(values.begin(), values.end(), mt);
}

bonita's:

for (int k=0; k < 100000 ; ++k) {
values.erase( values.begin(), values.end());
//her stuff
}

Ralf Goertz

unread,
Jan 16, 2023, 4:21:39 AM1/16/23
to
Am Mon, 16 Jan 2023 09:46:15 +0100
schrieb Ralf Goertz <m...@myprovider.invalid>:
Surprisingly, Bonita's method also seems to be very dependent on the
range:

./rg 10 1 10000
214 2035 2188 3525 4142 5765 6021 6571 7000 8902
7.09215s

(No surprise here.)


./bonita 10 1 10000
7400 7185 5343 4357 2990 2011 1478 1078 859 719
184.93s

(Wow!)

Bonita Montero

unread,
Jan 16, 2023, 7:35:24 AM1/16/23
to
Am 16.01.2023 um 10:21 schrieb Ralf Goertz:

> Surprisingly, Bonita's method also seems to be very dependent on the
> range:
>
> ./rg 10 1 10000
> 214 2035 2188 3525 4142 5765 6021 6571 7000 8902
> 7.09215s
>
> (No surprise here.)
>
>
> ./bonita 10 1 10000
> 7400 7185 5343 4357 2990 2011 1478 1078 859 719
> 184.93s

Test the algorithm without screen output !

Ralf Goertz

unread,
Jan 16, 2023, 10:05:21 AM1/16/23
to
Am Mon, 16 Jan 2023 13:35:57 +0100
schrieb Bonita Montero <Bonita....@gmail.com>:
I did of course! The timer starts immediately before the loop and stops
after it, before only the last result is output. Your version:


#include <iostream>
#include <unordered_set>
#include <charconv>
#include <random>
#include <concepts>
#include <chrono>
#include <cstring>

using namespace std;
using namespace std::chrono;

int main( int argc, char** argv )
{
try
{
if( argc < 4 )
return
cout << argv[0] << " n from to" << endl,
EXIT_FAILURE;
auto parse = []( char const *str, char const *err )
{
size_t value;
if( from_chars_result fcr = from_chars( str, str + strlen( str ),
value ); (bool)fcr.ec || *fcr.ptr )
throw invalid_argument( err );
return value;
};
size_t n = parse( argv[1], "wrong number of values" );
if( !n )
return EXIT_SUCCESS;
size_t
from = parse( argv[2], "wrong from-value" ),
to = parse( argv[3], "wrong to-value" );
if( from > to )
swap(from, to);
if( n - 1 > to - from )
return
cout << "n is too small" << endl,
EXIT_FAILURE;
unordered_set<size_t> values;
mt19937_64 mt;
uniform_int_distribution<size_t> uid( from, to );
steady_clock::time_point t1 = steady_clock::now();
for (int k=0; k < 100000 ; ++k) {
values.erase( values.begin(), values.end());
if( to - from != (size_t)-1 && to - from + 1 < n / 2 )
{
values.reserve( n );
while( values.size() < n )
{
size_t value;
do
value = uid( mt );
while( values.contains( value ) );
values.emplace( value );
}
}
else
{
if( to - from == (size_t)-1 )
throw bad_alloc();
values.reserve( to - from + 1 );
size_t i = from - 1;
do
values.emplace( ++i );
while( i != to );
while( values.size() > n )
for( ; ; )
{
auto itRemove = values.find( uid( mt ) );
if( itRemove == values.end() )
continue;
values.erase( itRemove );
break;
}
}
}
steady_clock::time_point t2 = steady_clock::now();
for( size_t value : values )
cout << value << " ";
cout << endl << duration_cast<duration<double>>(t2 - t1)<<endl;
}
catch( exception const &exc )
{
return
cout << exc.what() << endl,
EXIT_FAILURE;
}
}


and mine:


#include <algorithm>
#include <iostream>
#include <random>
#include <charconv>
#include <vector>
#include <cstring>
#include <chrono>

using namespace std;
using namespace std::chrono;
vector<int> values( to - from + 1);
steady_clock::time_point t1 = steady_clock::now();
for (int k=0; k < 100000 ; ++k) {
fill(values.begin(), values.begin() + n, 1);
fill(values.begin() + n, values.end(), 0);
shuffle(values.begin(), values.end(), mt);
}
steady_clock::time_point t2 = steady_clock::now();
for( size_t i=0; i < values.size(); ++i )
if( values[i]) cout << i+from << " ";
cout << endl << duration_cast<duration<double>>(t2 - t1)<<endl;

Ralf Goertz

unread,
Jan 16, 2023, 10:05:21 AM1/16/23
to
Resent the reply, since I can't see it on my server.

Am Mon, 16 Jan 2023 13:35:57 +0100 schrieb Bonita Montero
<Bonita....@gmail.com>:
I did of course! The timer starts immediately before the loop and stops
after it, before only the last result is output. Your version:


#include <iostream>
#include <unordered_set>
#include <charconv>
#include <random>
#include <concepts>
#include <chrono>
#include <cstring>

using namespace std;
using namespace std::chrono;

int main( int argc, char** argv )
{
try
{
if( argc < 4 )
return
cout << argv[0] << " n from to" << endl,
EXIT_FAILURE;
auto parse = []( char const *str, char const *err )
{
size_t value;
if( from_chars_result fcr = from_chars( str, str + strlen( str ),
value ); (bool)fcr.ec || *fcr.ptr )
throw invalid_argument( err );
return value;
};
size_t n = parse( argv[1], "wrong number of values" );
if( !n )
return EXIT_SUCCESS;
size_t
from = parse( argv[2], "wrong from-value" ),
to = parse( argv[3], "wrong to-value" );
if( from > to )
swap(from, to);
if( n - 1 > to - from )
return
cout << "n is too small" << endl,
EXIT_FAILURE;
unordered_set<size_t> values;
mt19937_64 mt;
uniform_int_distribution<size_t> uid( from, to );
steady_clock::time_point t1 = steady_clock::now();
for (int k=0; k < 100000 ; ++k) {
values.erase( values.begin(), values.end());
if( to - from != (size_t)-1 && to - from + 1 < n / 2 )
{
values.reserve( n );
while( values.size() < n )
{
size_t value;
do
value = uid( mt );
while( values.contains( value ) );
values.emplace( value );
}
}
else
{
if( to - from == (size_t)-1 )
throw bad_alloc();
values.reserve( to - from + 1 );
size_t i = from - 1;
do
values.emplace( ++i );
while( i != to );
while( values.size() > n )
for( ; ; )
{
auto itRemove = values.find( uid( mt ) );
if( itRemove == values.end() )
continue;
values.erase( itRemove );
break;
}
}
}
steady_clock::time_point t2 = steady_clock::now();
for( size_t value : values )
cout << value << " ";
cout << endl << duration_cast<duration<double>>(t2 - t1)<<endl;
}
catch( exception const &exc )
{
return
cout << exc.what() << endl,
EXIT_FAILURE;
}
}


and mine:


#include <algorithm>
#include <iostream>
#include <random>
#include <charconv>
#include <vector>
#include <cstring>
#include <chrono>

using namespace std;
using namespace std::chrono;

vector<int> values( to - from + 1);
steady_clock::time_point t1 = steady_clock::now();
for (int k=0; k < 100000 ; ++k) {
fill(values.begin(), values.begin() + n, 1);
fill(values.begin() + n, values.end(), 0);
shuffle(values.begin(), values.end(), mt);
}
steady_clock::time_point t2 = steady_clock::now();
for( size_t i=0; i < values.size(); ++i )
if( values[i]) cout << i+from << " ";
cout << endl << duration_cast<duration<double>>(t2 - t1)<<endl;

Mut...@dastardlyhq.com

unread,
Jan 16, 2023, 11:41:04 AM1/16/23
to
On Mon, 16 Jan 2023 14:42:50 +0100
Ralf Goertz <m...@myprovider.invalid> wrote:
>Am Mon, 16 Jan 2023 13:35:57 +0100
>schrieb Bonita Montero <Bonita....@gmail.com>:
>
>> Am 16.01.2023 um 10:21 schrieb Ralf Goertz:
>>
>> > Surprisingly, Bonita's method also seems to be very dependent on the
>> > range:
>> >
>> > ./rg 10 1 10000
>> > 214 2035 2188 3525 4142 5765 6021 6571 7000 8902
>> > 7.09215s
>> >
>> > (No surprise here.)
>> >
>> >
>> > ./bonita 10 1 10000
>> > 7400 7185 5343 4357 2990 2011 1478 1078 859 719
>> > 184.93s
>>
>> Test the algorithm without screen output !
>
>I did of course! The timer starts immediately before the loop and stops
>after it, before only the last result is output. Your version:

But wait, didn't she state that her algorithm was "perfect"? I simply won't
believe Bonita has more hubris and self delusion than an angry mouse.


Bonita Montero

unread,
Jan 16, 2023, 3:06:09 PM1/16/23
to
Am 16.01.2023 um 17:38 schrieb Mut...@dastardlyhq.com:

> But wait, didn't she state that her algorithm was "perfect"? I simply won't
> believe Bonita has more hubris and self delusion than an angry mouse.

And you don't check that Ralf's code does sth. completely different.

Ralf Goertz

unread,
Jan 17, 2023, 3:20:01 AM1/17/23
to
Am Mon, 16 Jan 2023 21:06:41 +0100
schrieb Bonita Montero <Bonita....@gmail.com>:
I assume you don't mean to say, that I implemented your algorithm
incorrectly (if I'm wrong about that will you please care to elaborate?)
but that my algorithm is completely different from yours. Then, yes that
was my point. I don't understand why you use such a complicated
algorithm (compared to the very few lines I needed) if it doesn't
outperform a much simpler approach. Of course one could say that I hid
the complexity behind the call to std::shuffle() but you do the same
with std::unordered_set.emplace() an co.

Mut...@dastardlyhq.com

unread,
Jan 17, 2023, 4:33:06 AM1/17/23
to
On Tue, 17 Jan 2023 09:19:44 +0100
Ralf Goertz <m...@myprovider.invalid> wrote:
>Am Mon, 16 Jan 2023 21:06:41 +0100
>schrieb Bonita Montero <Bonita....@gmail.com>:
>
>> Am 16.01.2023 um 17:38 schrieb Mut...@dastardlyhq.com:
>>
>> > But wait, didn't she state that her algorithm was "perfect"? I
>> > simply won't believe Bonita has more hubris and self delusion than
>> > an angry mouse.
>>
>> And you don't check that Ralf's code does sth. completely different.
>
>I assume you don't mean to say, that I implemented your algorithm
>incorrectly (if I'm wrong about that will you please care to elaborate?)
>but that my algorithm is completely different from yours. Then, yes that
>was my point. I don't understand why you use such a complicated
>algorithm (compared to the very few lines I needed) if it doesn't

You must be new here :) Complexity is Bonitas calling card.

Bonita Montero

unread,
Jan 17, 2023, 8:13:37 AM1/17/23
to
If you want the code to be as short and as performant
as possible there's no way to program different.

Malcolm McLean

unread,
Jan 17, 2023, 10:48:11 AM1/17/23
to
A shuffle followed by taking the first elements of the vector isn't a particularly
efficient way of generating a sequence of unique random numbers. But it's
not all that ineffieicnt either, and there's often an advantage in writing something
simply ans quickly from pre-existing components, rather than writing a tailor-
made, customised solution.

Bonita Montero

unread,
Jan 17, 2023, 10:49:04 AM1/17/23
to
Am 17.01.2023 um 16:48 schrieb Malcolm McLean:

> A shuffle followed by taking the first elements of the vector isn't a particularly
> efficient way of generating a sequence of unique random numbers. But it's
> not all that ineffieicnt either, and there's often an advantage in writing something
> simply ans quickly from pre-existing components, rather than writing a tailor-
> made, customised solution.

You don't have real randomness by shuffling.

Mut...@dastardlyhq.com

unread,
Jan 17, 2023, 11:25:56 AM1/17/23
to
On Tue, 17 Jan 2023 07:48:02 -0800 (PST)
Malcolm McLean <malcolm.ar...@gmail.com> wrote:
>On Tuesday, 17 January 2023 at 13:13:37 UTC, Bonita Montero wrote:
>> If you want the code to be as short and as performant
>> as possible there's no way to program different.
>>
>A shuffle followed by taking the first elements of the vector isn't a
>particularly
>efficient way of generating a sequence of unique random numbers. But it's

Just out of interest, what would be a better way? You could randomly select
elements in a container then delete that particular element so it doesn't get
used again but I'm not sure that would be very efficient beyond single digit
container sizes. Ditto starting at a random point in the container and walking
it in a random direction until you find an unused element.


Bonita Montero

unread,
Jan 17, 2023, 11:32:04 AM1/17/23
to
I found that you can randomly shuffle with random_shuffle or you provide
a shuffling function-object since C++17. That would be nice but if you
have a large number of values and chose only a small portion from that
this would take a lot of memory.

Ralf Goertz

unread,
Jan 17, 2023, 11:32:11 AM1/17/23
to
Am Tue, 17 Jan 2023 16:49:37 +0100
schrieb Bonita Montero <Bonita....@gmail.com>:
What makes you say that? Have a look at the first answer to that
question:
<https://cs.stackexchange.com/questions/47338/whats-a-uniform-shuffle>.
It shows that a properly implemented shuffle makes every permutation
equally probable. What more do you need for “real randomness”? While I
haven't checked the implementation of my c++ library
(libstdc++6-devel-gcc12-12.2.1+git537-1.2.x86_64) I have no doubt that
the authors have created a suitable one.

Malcolm McLean

unread,
Jan 17, 2023, 12:08:21 PM1/17/23
to
You have the range 0 to N-1 to choose M unique elements from.
Pick a single element x using a unifrom random number. That now gives
us two ranges, 0 to x-1 and x+1 to N-1. And M-1 numbers left to pick.

The number we need to pick from each range is given by the hypergeometric
distribution. We have x "good" balls and N - x - 2 "bad" balls in an urn, and
we withdraw M-1 balls. The number of "good" balls we draw tells us how many
elemets to distribute to the first half of the range. The remainder of the elements
we choose from the second half of the range.
Then it's just recursive, with the range splitting on a random elemnet each level.

You cna write a generator for numbers with a hypergeometric distribution naively
and quite simply by taking M random numbers. Or you can do it in a far more complicated
way by calculating the cumulative distribution function. If you do it the naive way,
the algorithm is O(M log M) (M calls to the uniform function on each level, and log M
levels of recursion). If you do it the complicated way you can improve on that.

Mut...@dastardlyhq.com

unread,
Jan 17, 2023, 12:10:21 PM1/17/23
to
On Tue, 17 Jan 2023 17:31:57 +0100
Ralf Goertz <m...@myprovider.invalid> wrote:
>Am Tue, 17 Jan 2023 16:49:37 +0100
>schrieb Bonita Montero <Bonita....@gmail.com>:
>
>> Am 17.01.2023 um 16:48 schrieb Malcolm McLean:
>>=20
>> > A shuffle followed by taking the first elements of the vector isn't
>> > a particularly efficient way of generating a sequence of unique
>> > random numbers. But it's not all that ineffieicnt either, and
>> > there's often an advantage in writing something simply ans quickly
>> > from pre-existing components, rather than writing a tailor- made,
>> > customised solution. =20
>>=20
>> You don't have real randomness by shuffling.
>
>What makes you say that? Have a look at the first answer to that
>question:
><https://cs.stackexchange.com/questions/47338/whats-a-uniform-shuffle>.
>It shows that a properly implemented shuffle makes every permutation
>equally probable. What more do you need for =E2=80=9Creal randomness=E2=80=
>=9D? While I
>haven't checked the implementation of my c++ library
>(libstdc++6-devel-gcc12-12.2.1+git537-1.2.x86_64) I have no doubt that
>the authors have created a suitable one.

To be pedantic, there's no real randomness at all if its simply generated
from a mathematical function because you only need to know the seed to
reproduce the sequence. To be truly random you need a hardware source such as a
white noise generator. Even generators based on whats going on in the OS from
users, network input etc isn't truly random and can be biased.

Mut...@dastardlyhq.com

unread,
Jan 17, 2023, 12:16:17 PM1/17/23
to
Probably looks good on a whiteboard but there's a lot of shifting stuff
about going on there so I doubt it'll be any faster (or more random) than
simply doing random walks of an array until you find an unused element. But
then its obviously based on the same algo as quicksort and selecting the
optimal sorting function is a black art when copy costs vs comparison costs
are factored in.

Bonita Montero

unread,
Jan 17, 2023, 12:17:49 PM1/17/23
to
Am 17.01.2023 um 18:10 schrieb Mut...@dastardlyhq.com:

> To be pedantic, there's no real randomness at all if its simply generated
> from a mathematical function because you only need to know the seed to
> reproduce the sequence. To be truly random you need a hardware source
> such as a white noise generator. Even generators based on whats going
> on in the OS from users, network input etc isn't truly random and can
> be biased.

You can initialize mt19937_64( (random_device())() ).
That's enough randomness for this task.

Ben Bacarisse

unread,
Jan 17, 2023, 12:32:48 PM1/17/23
to
Mut...@dastardlyhq.com writes:

> On Tue, 17 Jan 2023 07:48:02 -0800 (PST)
> Malcolm McLean <malcolm.ar...@gmail.com> wrote:
>>On Tuesday, 17 January 2023 at 13:13:37 UTC, Bonita Montero wrote:
>>> If you want the code to be as short and as performant
>>> as possible there's no way to program different.
>>>
>>A shuffle followed by taking the first elements of the vector isn't a
>>particularly
>>efficient way of generating a sequence of unique random numbers. But it's
>
> Just out of interest, what would be a better way?

"Better" depends on the context. This thread has been split between
comp.lang.c and comp.lang.c++ and if you have not been reading both you
won't have seen all the many proposed algorithms. There are lots of
possible trade-offs between the number of random number call, the amount
of storage needed and sizes of the numbers involved.

It isn't even clear what's wanted. The OP might have wanted just a
random selection (all possible subsets equally probable) they might have
wanted a random permutation (where all possible sequences of all
possible subsets are equally probable).

--
Ben.

Bonita Montero

unread,
Jan 17, 2023, 1:24:10 PM1/17/23
to
Am 17.01.2023 um 17:32 schrieb Bonita Montero:

> I found that you can randomly shuffle with random_shuffle or you provide
> a shuffling function-object since C++17. That would be nice but if you
> have a large number of values and chose only a small portion from that
> this would take a lot of memory.
>

I made a compromise between memory-consumption and performance. For
the following code if more than a tenth of the range is chosen for
the values I use a random-shuffle like operation. If less than a
tenth of the range is chosen I an unordered_set to check for col-
lisions. The decision is made depening on the PARTITIAL_THRESHOLD
variable.

#include <iostream>
#include <vector>
#include <charconv>
#include <random>
#include <concepts>
#include <unordered_set>

using namespace std;

int main( int argc, char **argv )
{
try
{
if( argc < 4 ) [[unlikely]]
return
cout << argv[0] << " n from to" << endl,
EXIT_FAILURE;
auto parse = []( char const *str, char const *err )
{
size_t value;
if( from_chars_result fcr = from_chars( str, str + strlen( str ),
value ); (bool)fcr.ec || *fcr.ptr ) [[unlikely]]
throw invalid_argument( err );
return value;
};
size_t n = parse( argv[1], "wrong number of values" );
if( !n ) [[unlikely]]
return EXIT_SUCCESS;
size_t
from = parse( argv[2], "wrong from-value" ),
to = parse( argv[3], "wrong to-value" );
if( from > to ) [[unlikely]]
swap( from, to );
size_t range = to - from;
if( n - 1 > range ) [[unlikely]]
return
cout << "n is too large" << endl,
EXIT_FAILURE;
vector<size_t> values;
mt19937_64 mt;
uniform_int_distribution<size_t> uidRange( 0, range );
constexpr size_t PARTITIAL_THRESHOLD = 10;
if( ++range && range / n >= PARTITIAL_THRESHOLD )
{
unordered_set<size_t> valuesSet;
valuesSet.reserve( n );
while( valuesSet.size() < n )
for( ; ; )
if( size_t value = uidRange( mt ); !valuesSet.contains( value ) )
{
valuesSet.emplace( value );
break;
}
values.resize( n );
auto itSetValue = valuesSet.cbegin();
for( size_t i = 0; i != n; )
values[i++] = *itSetValue++;
}
else
{
if( !range )
throw bad_alloc();
values.resize( range );
for( size_t i = from; size_t &v : values )
v = i++;
for( size_t i = 0; i != n; )
swap( values[i++], values[uidRange( mt )] );
values.resize( n );
}
for( size_t i = 0; i != n; ++i )
; //cout << values[i] << endl;

Chris M. Thomasson

unread,
Jan 17, 2023, 3:48:45 PM1/17/23
to
Are you saying that there is no real randomness wrt shuffling a deck of
cards around seven times in a row?

Scott Lurndal

unread,
Jan 17, 2023, 4:21:24 PM1/17/23
to
That depends on how it is shuffled.

https://en.wikipedia.org/wiki/Faro_shuffle

Chris M. Thomasson

unread,
Jan 17, 2023, 4:29:16 PM1/17/23
to
Touche. How about riffle shuffles?

Mut...@dastardlyhq.com

unread,
Jan 18, 2023, 4:23:24 AM1/18/23
to
So is random() then.

Mut...@dastardlyhq.com

unread,
Jan 18, 2023, 4:24:08 AM1/18/23
to
On Tue, 17 Jan 2023 17:32:34 +0000
Ben Bacarisse <ben.u...@bsb.me.uk> wrote:
>Mut...@dastardlyhq.com writes:
>
>> On Tue, 17 Jan 2023 07:48:02 -0800 (PST)
>> Malcolm McLean <malcolm.ar...@gmail.com> wrote:
>>>On Tuesday, 17 January 2023 at 13:13:37 UTC, Bonita Montero wrote:
>>>> If you want the code to be as short and as performant
>>>> as possible there's no way to program different.
>>>>
>>>A shuffle followed by taking the first elements of the vector isn't a
>>>particularly
>>>efficient way of generating a sequence of unique random numbers. But it's
>>
>> Just out of interest, what would be a better way?
>
>"Better" depends on the context. This thread has been split between
>comp.lang.c and comp.lang.c++ and if you have not been reading both you

I wish people wouldn't do that, its very annoying.

Kenny McCormack

unread,
Jan 18, 2023, 7:27:11 AM1/18/23
to
In article <tq8dr8$ctf$1...@gioia.aioe.org>, <Mut...@dastardlyhq.com> wrote:
...
>>"Better" depends on the context. This thread has been split between
>>comp.lang.c and comp.lang.c++ and if you have not been reading both you
>
>I wish people wouldn't do that, its very annoying.

But it is the correct thing. Annoying (to you) or not.

--
Nov 4, 2008 - the day when everything went
from being Clinton's fault to being Obama's fault.

Bonita Montero

unread,
Jan 18, 2023, 7:30:48 AM1/18/23
to
Of course not. Mersenne Twister is the best of all non-cryptogra-
phical random number generators. It calculates a number of results
as a whole block for the next value-requests and thereby gets's a
unbeaten performance for this degree of randomness (mt19937_64 has
a period of of 2 ^ 19937 !). It's designed in a way that genrating
that block can easily optimized with vectoring instruction sets
like SSE or AVX.

Paul N

unread,
Jan 18, 2023, 9:50:41 AM1/18/23
to
I think a Faro shuffle is just a perfect riffle shuffle. 8 out-shuffles or 52 in-shuffles put the deck back into its original order.

Also, any sort of shuffle based on a 32-bit seed will give one of about 4 billion orders for the cards. This sounds a lot but is dwarfed by the 52! possible orders, and it means that once you've seen about 6 or 7 of the cards you can work out exactly what all the others are.

Mut...@dastardlyhq.com

unread,
Jan 18, 2023, 11:09:49 AM1/18/23
to
On Wed, 18 Jan 2023 12:26:53 -0000 (UTC)
gaz...@shell.xmission.com (Kenny McCormack) wrote:
>In article <tq8dr8$ctf$1...@gioia.aioe.org>, <Mut...@dastardlyhq.com> wrote:
>....
>>>"Better" depends on the context. This thread has been split between
>>>comp.lang.c and comp.lang.c++ and if you have not been reading both you
>>
>>I wish people wouldn't do that, its very annoying.
>
>But it is the correct thing. Annoying (to you) or not.

Says who, you? Why split a thread that is as relevant (or not) for both
groups?

Mut...@dastardlyhq.com

unread,
Jan 18, 2023, 11:16:20 AM1/18/23
to
On Wed, 18 Jan 2023 13:31:23 +0100
Bonita Montero <Bonita....@gmail.com> wrote:
>Am 18.01.2023 um 10:23 schrieb Mut...@dastardlyhq.com:
>
>> On Tue, 17 Jan 2023 18:18:25 +0100
>
>> Bonita Montero <Bonita....@gmail.com> wrote:
>
>>> Am 17.01.2023 um 18:10 schrieb Mut...@dastardlyhq.com:
>
>>> You can initialize mt19937_64( (random_device())() ).
>>> That's enough randomness for this task.
>
>> So is random() then.
>
>Of course not. Mersenne Twister is the best of all non-cryptogra-
>phical random number generators. It calculates a number of results
>as a whole block for the next value-requests and thereby gets's a
>unbeaten performance for this degree of randomness (mt19937_64 has
>a period of of 2 ^ 19937 !). It's designed in a way that genrating
>that block can easily optimized with vectoring instruction sets
>like SSE or AVX.

I'll say again - there is no such thing as random for formula generated
"random" number sequences. Given the same start conditions the same sequence
will be generated whether its 2^19937 or 2^infinity. You'd be better off using
/dev/random, at least its entropy comes from nominally external sources so
is unpredictable in a busy enviroment.

Bonita Montero

unread,
Jan 18, 2023, 11:19:48 AM1/18/23
to
Am 18.01.2023 um 17:16 schrieb Mut...@dastardlyhq.com:

> I'll say again - there is no such thing as random for formula generated
> "random" number sequences. ...

I was talking about a non-cryptographical PRNG, and you talk about sth.
different because you have a constant feeling of uncertainty and you
think nothing is reliable in that sense.

Mut...@dastardlyhq.com

unread,
Jan 18, 2023, 11:24:22 AM1/18/23
to
Pop psychology now? Really? Stick to writing over complicated code then
bragging about how perfect it is so someone else can prove you wrong. Again.

Bonita Montero

unread,
Jan 18, 2023, 11:58:33 AM1/18/23
to
Am 18.01.2023 um 17:24 schrieb Mut...@dastardlyhq.com:

> Pop psychology now? Really? Stick to writing over complicated code then
> bragging about how perfect it is so someone else can prove you wrong. Again.

No one uses this perfect randomness you suggest but only as a seed for
a cryptographic PRNG. And for the purpose here you even don't need this
quality of randomness. Your personal issues aren't practically relevant.

Mut...@dastardlyhq.com

unread,
Jan 18, 2023, 12:14:22 PM1/18/23
to
On Wed, 18 Jan 2023 17:59:08 +0100
Bonita Montero <Bonita....@gmail.com> wrote:
>Am 18.01.2023 um 17:24 schrieb Mut...@dastardlyhq.com:
>
>> Pop psychology now? Really? Stick to writing over complicated code then
>> bragging about how perfect it is so someone else can prove you wrong. Again.
>
>No one uses this perfect randomness you suggest but only as a seed for
>a cryptographic PRNG. And for the purpose here you even don't need this

I was simply making a point that if you don't care about actual randomness
then standard RPGs are fine.

>quality of randomness. Your personal issues aren't practically relevant.

I'm not the one with the issues in this discussion.

Bonita Montero

unread,
Jan 18, 2023, 12:23:21 PM1/18/23
to
Am 18.01.2023 um 18:14 schrieb Mut...@dastardlyhq.com:

> I was simply making a point that if you don't care about actual randomness
> then standard RPGs are fine.

With that ?

| I'll say again - there is no such thing as random for formula generated
| "random" number sequences. Given the same start conditions the same
sequence
| will be generated whether its 2^19937 or 2^infinity. You'd be better
off using
| /dev/random, at least its entropy comes from nominally external sources so
| is unpredictable in a busy enviroment.

Absolutely not.

Chris M. Thomasson

unread,
Jan 18, 2023, 2:59:55 PM1/18/23
to
On 1/18/2023 6:50 AM, Paul N wrote:
> On Tuesday, January 17, 2023 at 9:29:16 PM UTC, Chris M. Thomasson wrote:
>> On 1/17/2023 1:21 PM, Scott Lurndal wrote:
>>> "Chris M. Thomasson" <chris.m.t...@gmail.com> writes:
>>>> On 1/17/2023 7:49 AM, Bonita Montero wrote:
>>>>> Am 17.01.2023 um 16:48 schrieb Malcolm McLean:
>>>>>
>>>>>> A shuffle followed by taking the first elements of the vector isn't a
>>>>>> particularly
>>>>>> efficient way of generating a sequence of unique random numbers. But it's
>>>>>> not all that ineffieicnt either, and there's often an advantage in
>>>>>> writing something
>>>>>> simply ans quickly from pre-existing components, rather than writing a
>>>>>> tailor-
>>>>>> made, customised solution.
>>>>>
>>>>> You don't have real randomness by shuffling.
>>>>>
>>>>
>>>> Are you saying that there is no real randomness wrt shuffling a deck of
>>>> cards around seven times in a row?
>>>
>>> That depends on how it is shuffled.
>>>
>>> https://en.wikipedia.org/wiki/Faro_shuffle
>> Touche. How about riffle shuffles?
>
> I think a Faro shuffle is just a perfect riffle shuffle. 8 out-shuffles or 52 in-shuffles put the deck back into its original order.

I do not want a perfect shuffle.


> Also, any sort of shuffle based on a 32-bit seed will give one of about 4 billion orders for the cards. This sounds a lot but is dwarfed by the 52! possible orders, and it means that once you've seen about 6 or 7 of the cards you can work out exactly what all the others are.

How do the Casinos handle it?

Mut...@dastardlyhq.com

unread,
Jan 19, 2023, 4:32:10 AM1/19/23
to
Really? How would go about predicting what packets will arrive on the network
or when a user will press a key then?

Bonita Montero

unread,
Jan 19, 2023, 9:42:21 AM1/19/23
to
Are you the twin-brother of Amine Moulay Ramdane ?

Am 19.01.2023 um 10:31 schrieb Mut...@dastardlyhq.com:
> There are many people who believe that people don't change. As was said in a recent movie, “People don't change, they become more of what they are.” These people have obviously not studied history.
>
> In fact, people change all the time, for all sorts of reasons, and in all sorts of different directions. The Germans were complete jerks during the Second World War, but they are not now. The Jews were liberal pacifists before the Second World War, whereas Israeli Jews at this time are fascists.
>
> Many of the same people who claim to speak in favor of responsibility also claim that some people – such as sociopaths - are evil and can only be evil whatever they do. These two claims are mutually contradictory. If people are responsible for their actions, then anyone – even a sociopath - can choose to act rightfully; and if some people cannot act rightfully whatever they do, then people are not responsible for their actions. Two mutually contradictory claims are made by the same mentality. And that means that at least one of these claims is a lie.
>
> This foolishness has gone so far that now, in Australia, they attack people who have been born in disadvantaged situations under the claim that they are going to be criminals and abusers. As if they weren't already suffering enough. I know many people who come from disadvantage who are not abusers or criminals. Many of these people are very impressive individuals. They overcame disadvantage to become decent citizens; and, in a number of cases, are much more than just that.
>
> People do change. People change all the time and in all sorts of ways and for all sorts of reasons. To deny the same is to deny that people have the capacity for choice. Anything that is capable of choice is capable of right choice, and it is also capable of change. And yes, that includes sociopaths.
>
> When I was writing against someone who was shouting about sociopaths, I was asked why I was advocating for the scum of the earth. What I am advocating for is choice and free will. You have to make up your mind. Are people responsible for their actions or aren't they? If they are, then anyone can choose to act rightfully, and anyone can change. And if some people cannot do such a thing, then people are not responsible for their actions. Pick either one or the other; both cannot be.
>
> I am also advocating for constitutional intent. In America, people are meant to be protected from witch hunts and persecutions. I was never diagnosed as a sociopath or anything similar. I do however take seriously human rights and constitutional intent. And I know that the same extends to everyone, including sociopaths.
>
> When I see a hysteria and a witch hunt, I tell you about it. And this is exactly what we have seen. Precisely, we have seen the worst hysteria in America's history, something that makes Joseph McCarthy look like an angel. You have no idea what causes this disorder. You have no idea how to treat it. And yet you claim that people who have this disorder are evil and can only be evil whatever they do.
>
> What we are seeing here goes against most basic reason. Evil is not psychology, evil is choice. Anyone can act right, and anyone can act wrong. That is because of choice. And choice trumps psychology and neurology.
>
> If someone does not know how to cure a disorder, all that says is that he has no valuable insight on the subject. Valuable insight comes from somebody else. If you have been born with a neurological abnormality, that does not mean that you are damned for life or that you can only be evil. Use your mind. Understand how your actions affect others. And then use choice and intelligence to correct the effects of whatever is wrong with your brain.
>
> Anyone therefore can choose to act rightfully. This is the case even with sociopaths. Whereas there are any number of perfectly normal people out there who do horrible things. They do not have a bad neurology. What they have is bad values.
>
> Not all sociopaths are evil, and not all evil people are sociopaths. There are many sociopaths who've never committed a crime. And there are many perfectly normal people who murder, rape, scam, abuse and pollute. Spanish colonialists were perfectly normal, but they were at least as cruel as the Nazis. Most people in Texas Oil are perfectly normal, but they have poisoned the world.
>
> To believe that there is such a thing as a criminal personality is an Orwellian institution of crimethink. It says that people can be made criminal by virtue of how they think. And this creates a de facto totalitarianism that is so absolute that people are not allowed to be free from it even within the privacy of their minds.
>
> If you really want to treat people who actually have this disorder, the correct solution is to get them to use their minds. Teach them to see how what they do affects other people. And then they will be able to use the mind to do the job that the heart fails to do.
>
> As for people being able to change, that is a given. People change all the time and in all sorts of ways. Denying change is denying choice. It is denying the driving force for all action. And it is dehumanizing people and turning them into beasts.

David Brown

unread,
Jan 19, 2023, 10:19:16 AM1/19/23
to
On 19/01/2023 15:42, Bonita Montero wrote:
> Are you the twin-brother of Amine Moulay Ramdane ?
>
> Am 19.01.2023 um 10:31 schrieb Mut...@dastardlyhq.com:
>> There are many people who believe that people don't change. As was
...

And you thought it was necessary to quote the /entire/ post to make that
comment?

I think there has been some hiccup on a Usenet server somewhere - I've
seen a few posts end up in the wrong groups today. I have no idea if
Muttley's post is appropriate or not in rec.arts.books - I'm sure it
makes more sense in the context of threads there.

(By the way, Muttley, there is a term for people who write "The Germans
are this" or "The Jews are that" - it is "racist". Make comments about
individuals if you like, but sweeping statements about a group of people
based on irrelevant factors such as nationality, religion, gender, etc.,
is bigotry and has no place anywhere. I'm assuming you did not mean to
write that way, but you should choose your words more carefully in the
future.)

Mut...@dastardlyhq.com

unread,
Jan 19, 2023, 11:30:40 AM1/19/23
to
On Thu, 19 Jan 2023 15:42:54 +0100
Bonita Montero <Bonita....@gmail.com> wrote:
>Are you the twin-brother of Amine Moulay Ramdane ?
>
>Am 19.01.2023 um 10:31 schrieb Mut...@dastardlyhq.com:
>> There are many people who believe that people don't change. As was said in a
>recent movie, “People don't change, they become more of what they are.”
>These people have obviously not studied history.
>>
>> In fact, people change all the time, for all sorts of reasons, and in all
>sorts of different directions. The Germans were complete jerks during the
>Second World War, but they are not now. The Jews were liberal pacifists before
>the Second World War, whereas Israeli Jews at this time are fascists.

Given how complicated you make your code its odd how your grasp of geopolitics
is so simplistic.

>> Not all sociopaths are evil, and not all evil people are sociopaths. There
>are many sociopaths who've never committed a crime. And there are many
>perfectly normal people who murder, rape, scam, abuse and pollute. Spanish
>colonialists were perfectly normal, but they were at least as cruel as the
>Nazis. Most people in Texas Oil are perfectly normal, but they have poisoned
>the world.

People poisoned the world. No one forced us to drive cars everywhere, wear
artificial frabrics instead of cotton and wool, buy endless crap made of
plastic and particularly in small penis syndrome USA where you're not a real
man unless you drive a 2.5 ton pickup or SUV with some gas guzzling V8 that
barely manages double digit mpg.

Mut...@dastardlyhq.com

unread,
Jan 19, 2023, 11:33:09 AM1/19/23
to
On Thu, 19 Jan 2023 16:18:58 +0100
David Brown <david...@hesbynett.no> wrote:
>On 19/01/2023 15:42, Bonita Montero wrote:
>> Are you the twin-brother of Amine Moulay Ramdane ?
>>
>> Am 19.01.2023 um 10:31 schrieb Mut...@dastardlyhq.com:
>>> There are many people who believe that people don't change. As was
>....
>
>And you thought it was necessary to quote the /entire/ post to make that
>comment?
>
>I think there has been some hiccup on a Usenet server somewhere - I've
>seen a few posts end up in the wrong groups today. I have no idea if
>Muttley's post is appropriate or not in rec.arts.books - I'm sure it
>makes more sense in the context of threads there.
>
>(By the way, Muttley, there is a term for people who write "The Germans
>are this" or "The Jews are that" - it is "racist". Make comments about
>individuals if you like, but sweeping statements about a group of people
>based on irrelevant factors such as nationality, religion, gender, etc.,
>is bigotry and has no place anywhere. I'm assuming you did not mean to
>write that way, but you should choose your words more carefully in the
>future.)

I never wrote any such thing. The only post I've seen is Bonita "reposting"
something I apparently wrote. Either she wrote it herself or someone spoofed
by id which is hardly hard to do on usenet.

Öö Tiib

unread,
Jan 19, 2023, 11:40:52 AM1/19/23
to
On Thursday, 19 January 2023 at 17:19:16 UTC+2, David Brown wrote:
> On 19/01/2023 15:42, Bonita Montero wrote:
> > Are you the twin-brother of Amine Moulay Ramdane ?
> >
> > Am 19.01.2023 um 10:31 schrieb Mut...@dastardlyhq.com:
> >> There are many people who believe that people don't change. As was
> ...
>
> And you thought it was necessary to quote the /entire/ post to make that
> comment?
>
BM probably made it up. I can find no server with "quoted" post.

red floyd

unread,
Jan 19, 2023, 11:43:07 AM1/19/23
to
It showed up in my feed as well. The frickin' HEADER said
rec.arts.books, and it showed as from someone else, even though
it came as from Muttley.

I just figured it was a server glitch. (I use eternal sept).

red floyd

Mut...@dastardlyhq.com

unread,
Jan 19, 2023, 11:48:19 AM1/19/23
to
On Thu, 19 Jan 2023 15:42:54 +0100
Bonita Montero <Bonita....@gmail.com> wrote:
>Are you the twin-brother of Amine Moulay Ramdane ?

>Am 19.01.2023 um 10:31 schrieb Mut...@dastardlyhq.com:

Seems this post was written by someone calling themselves Ilya Shambat in
rec.arts.books only, not me and not in comp.lang.c++. So either your newsreader
is fucked up or you decided to pretend it was me because you're sore about
losing an argument or some other fatuous reason.

Kenny McCormack

unread,
Jan 19, 2023, 11:55:12 AM1/19/23
to
In article <tqbn12$1jgmh$1...@dont-email.me>,
...
>(By the way, Muttley, there is a term for people who write "The Germans
>are this" or "The Jews are that" - it is "racist". Make comments about

Um, being German is not a race. Being Jewish is not a race.

Therefore, making statements about these things is not "racist".

BTW, social science is all about making generalizations about populations.
Are you planning on outlawing social science? (You don't need to answer
that - the answer is obvious)

--
The randomly chosen signature file that would have appeared here is more than 4
lines long. As such, it violates one or more Usenet RFCs. In order to remain
in compliance with said RFCs, the actual sig can be found at the following URL:
http://user.xmission.com/~gazelle/Sigs/Pedantic

Mike Terry

unread,
Jan 19, 2023, 12:08:26 PM1/19/23
to
My news server (Giganews) has the original post in group rec.arts.books, but that post has From header:

From: Ilya Shambat <ibsh...@gmail.com>

Bonita's posting looks valid at first glance, so I'd guess Bonita found Ilya's post on
rec.arts.books, replied, cross-posting to comp.lang.c++ and manually changed the accreditation line
to say that Mutley wrote the OP. (Yeah, that would be bizarre behaviour, but Bonita does bizarre
stuff from time to time. Alternatively perhaps someone has hacked some usenet server to inject
mischievous posts - someone with knowledge of the characters of MR, BM, and D...)

Mike.

Mut...@dastardlyhq.com

unread,
Jan 19, 2023, 12:15:18 PM1/19/23
to
On Thu, 19 Jan 2023 17:08:04 +0000
Mike Terry <news.dead.p...@darjeeling.plus.com> wrote:
>On 19/01/2023 16:40, 嘱 Tiib wrote:
>> On Thursday, 19 January 2023 at 17:19:16 UTC+2, David Brown wrote:
>>> On 19/01/2023 15:42, Bonita Montero wrote:
>>>> Are you the twin-brother of Amine Moulay Ramdane ?
>> BM probably made it up. I can find no server with "quoted" post.
>>
>
>My news server (Giganews) has the original post in group rec.arts.books, but
>that post has From header:
>
> From: Ilya Shambat <ibsh...@gmail.com>
>
>Bonita's posting looks valid at first glance, so I'd guess Bonita found Ilya's
>post on
>rec.arts.books, replied, cross-posting to comp.lang.c++ and manually changed
>the accreditation line
>to say that Mutley wrote the OP. (Yeah, that would be bizarre behaviour, but
>Bonita does bizarre
>stuff from time to time. Alternatively perhaps someone has hacked some usenet
>server to inject
>mischievous posts - someone with knowledge of the characters of MR, BM, and
>D...)

Pretty unlikely. He/she/it seems to have deliberately changed the line for
whatever fucked up reason.

David Brown

unread,
Jan 19, 2023, 1:22:27 PM1/19/23
to
On 19/01/2023 17:32, Mut...@dastardlyhq.com wrote:

> I never wrote any such thing. The only post I've seen is Bonita "reposting"
> something I apparently wrote. Either she wrote it herself or someone spoofed
> by id which is hardly hard to do on usenet.
>

OK. That's good to know.

For your information, the post appeared as though it were a reply to one
of the current threads here in "comp.lang.c++", though it was marked
"rec.arts.books", and was marked with you as the author. (I suspect a
Usenet server mixup somewhere.) So I believe Bonita merely quoted it.

I have no idea if someone intentionally posted it in your name, or if
that too was part of the server fault.


Spiros Bousbouras

unread,
Jan 19, 2023, 3:00:24 PM1/19/23
to
What I see is
References: <36403165-3cf1-4b73...@googlegroups.com>
<tqbkrr$1ja1c$1...@dont-email.me> <tqbn12$1jgmh$1...@dont-email.me>
<tqbrbm$1htl$1...@gioia.aioe.org>

where <tqbkrr$1ja1c$1...@dont-email.me> is the post by Montero which allegedly
quotes Mut...@dastardlyhq.com but
<36403165-3cf1-4b73...@googlegroups.com> has as its author
Ilya Shambat. I don't know if people see something different (I see these
things using news2.informatik.uni-stuttgart.de) or did not bother to follow
the references.

Spiros Bousbouras

unread,
Jan 19, 2023, 3:10:25 PM1/19/23
to
On Thu, 19 Jan 2023 08:42:51 -0800
red floyd <no.spa...@its.invalid> wrote:
> It showed up in my feed as well. The frickin' HEADER said
> rec.arts.books, and it showed as from someone else, even though
> it came as from Muttley.

"It" being <36403165-3cf1-4b73...@googlegroups.com> ?
Using news2.informatik.uni-stuttgart.de or
paganini.bofh.team I see it as coming from Ilya Shambat. What do you
mean "it came as from Muttley" ?

Spiros Bousbouras

unread,
Jan 19, 2023, 3:17:48 PM1/19/23
to
On Thu, 19 Jan 2023 20:10:09 -0000 (UTC)
Spiros Bousbouras <spi...@gmail.com> wrote:
> On Thu, 19 Jan 2023 08:42:51 -0800
> red floyd <no.spa...@its.invalid> wrote:
> > It showed up in my feed as well. The frickin' HEADER said
> > rec.arts.books, and it showed as from someone else, even though
> > it came as from Muttley.
>
> "It" being <36403165-3cf1-4b73...@googlegroups.com> ?
> Using news2.informatik.uni-stuttgart.de or
> paganini.bofh.team I see it as coming from Ilya Shambat. What do you
> mean "it came as from Muttley" ?

And I see the same using news.aioe.org .

Mut...@dastardlyhq.com

unread,
Jan 20, 2023, 10:48:45 AM1/20/23
to
Quoting is done by the client and can easily be modified by the user. I can't
see how a server fault fault would cause it tbh.

Mut...@dastardlyhq.com

unread,
Jan 20, 2023, 10:49:24 AM1/20/23
to
On Thu, 19 Jan 2023 20:17:33 -0000 (UTC)
Spiros Bousbouras <spi...@gmail.com> wrote:
>On Thu, 19 Jan 2023 20:10:09 -0000 (UTC)
>Spiros Bousbouras <spi...@gmail.com> wrote:
>> On Thu, 19 Jan 2023 08:42:51 -0800
>> red floyd <no.spa...@its.invalid> wrote:
>> > It showed up in my feed as well. The frickin' HEADER said
>> > rec.arts.books, and it showed as from someone else, even though
>> > it came as from Muttley.
>>
>> "It" being <36403165-3cf1-4b73...@googlegroups.com> ?
>> Using news2.informatik.uni-stuttgart.de or
>> paganini.bofh.team I see it as coming from Ilya Shambat. What do you
>> mean "it came as from Muttley" ?
>
>And I see the same using news.aioe.org .

You think I'm the only person who uses that server?? Idiot.

Spiros Bousbouras

unread,
Jan 20, 2023, 12:22:11 PM1/20/23
to
This is a non sequitur response for several reasons. Either someone is
impersonating you (Mut...@dastardlyhq.com) with the intention of making you
look irrational or you completely misinterpreted my posts you are quoting and
I can't even imagine what interpretation would make your reply make sense.

james...@alumni.caltech.edu

unread,
Jan 20, 2023, 2:35:18 PM1/20/23
to
Background:
A message was posted to rec.arts.books titled "Change and Choice" with the following headers:
From: Ilya Shambat <ibsh...@gmail.com>
Date: Thu, 19 Jan 2023 01:42:00 -0800 (PST)

Bonita Moreno posted a reply to that message to comp.lang.c++ titled "Re: Compute Unique Numbers in a Set" saying:

Am 19.01.2023 um 10:31 schrieb Mut...@dastardlyhq.com:

followed by a quotation of the entire "Change and Choice" message. Regardless of what time zone Bonita was using, that attribution line can't refer to the same time as the message she was quoting.

You said you never wrote such a thing. David Brown responded by suggesting that a Usenet server mixup was responsible for posting something to the wrong newsgroup. But that doesn't explain Bonita's change of the Subject: header, nor her citation of the wrong time and wrong author when quoting that message.

On Friday, January 20, 2023 at 10:49:24 AM UTC-5, Mut...@dastardlyhq.com wrote:
> On Thu, 19 Jan 2023 20:17:33 -0000 (UTC)
> Spiros Bousbouras <spi...@gmail.com> wrote:
> >On Thu, 19 Jan 2023 20:10:09 -0000 (UTC)
> >Spiros Bousbouras <spi...@gmail.com> wrote:
> >> On Thu, 19 Jan 2023 08:42:51 -0800
> >> red floyd <no.spa...@its.invalid> wrote:
> >> > It showed up in my feed as well. The frickin' HEADER said
> >> > rec.arts.books, and it showed as from someone else, even though
> >> > it came as from Muttley.
> >>
> >> "It" being <36403165-3cf1-4b73...@googlegroups.com> ?
> >> Using news2.informatik.uni-stuttgart.de or
> >> paganini.bofh.team I see it as coming from Ilya Shambat. What do you
> >> mean "it came as from Muttley" ?

Text written by Spiros was snipped, which confirmed that he saw the same message, with Ilya Shambat as the author, on several different usenet servers, then he listed one more:

> >And I see the same using news.aioe.org .
> You think I'm the only person who uses that server?? Idiot.

I don't see how your response makes any sense in that context. Bonita and Red Floyd are the only ones who've suggested that you were responsible for that original message. David and Spiros believe it was posted by Ilya Shambat. The fact that it was visible on many different servers, including news.aioe.org, always with Ilya Shambat given as the author, was cited as evidence against a server error being the cause of Bonita's mis-attribution of the quoted text. That fact was not being used to argue that you must have been the author, so the fact that other people use that server is not relevant.

David Brown

unread,
Jan 21, 2023, 7:06:32 AM1/21/23
to
On 20/01/2023 20:35, james...@alumni.caltech.edu wrote:
> Background: A message was posted to rec.arts.books titled "Change and
> Choice" with the following headers: From: Ilya Shambat
> <ibsh...@gmail.com> Date: Thu, 19 Jan 2023 01:42:00 -0800 (PST)
>
> Bonita Moreno posted a reply to that message to comp.lang.c++ titled
> "Re: Compute Unique Numbers in a Set" saying:
>
> Am 19.01.2023 um 10:31 schrieb Mut...@dastardlyhq.com:
>
> followed by a quotation of the entire "Change and Choice" message.
> Regardless of what time zone Bonita was using, that attribution line
> can't refer to the same time as the message she was quoting.
>
> You said you never wrote such a thing. David Brown responded by
> suggesting that a Usenet server mixup was responsible for posting
> something to the wrong newsgroup. But that doesn't explain Bonita's
> change of the Subject: header, nor her citation of the wrong time and
> wrong author when quoting that message.
>

I saw the same post in c.l.c++ /before/ Bonita quoted it. It had ended
up in part of a different thread (that Muttley had been involved in),
and appeared to have been posted by Muttley to recs.art.books, and
somehow had appeared in c.l.c++ as well and had a jumbled subject.

I assume Bonita thought Muttley posted it, because that's how it looked.
(I assumed Muttley had written it and posted it to recs.art.books, and
merely the newsgroup was mixed up by a server fault.)

I think that a server fault jumbled several header lines - the author,
the subject, and the newsgroups, at the very least. I can't see any
reason for suspecting Bonita is somehow intentionally behind this - it
would be completely bizarre behaviour.

So AFAICS this is just "undefined behaviour" in a server somewhere that
resulted in jumbled cross-posts.



Mut...@dastardlyhq.com

unread,
Jan 21, 2023, 10:51:09 AM1/21/23
to
On Fri, 20 Jan 2023 17:21:57 -0000 (UTC)
Sorry, I obviously misread. I thought you were implying that because the
post on rec.... came from the same server as the one I used then it must have
been me who posted it.

Mut...@dastardlyhq.com

unread,
Jan 21, 2023, 10:56:50 AM1/21/23
to
On Sat, 21 Jan 2023 13:06:09 +0100
David Brown <david...@hesbynett.no> wrote:
>On 20/01/2023 20:35, james...@alumni.caltech.edu wrote:
>> something to the wrong newsgroup. But that doesn't explain Bonita's
>> change of the Subject: header, nor her citation of the wrong time and
>> wrong author when quoting that message.
>>
>
>I saw the same post in c.l.c++ /before/ Bonita quoted it. It had ended
>up in part of a different thread (that Muttley had been involved in),
>and appeared to have been posted by Muttley to recs.art.books, and
>somehow had appeared in c.l.c++ as well and had a jumbled subject.

I never saw it in this group, only Bonitas copy of it. I really can't see
how Bonita could reply to a post that clearly wasn't from me in a totally
unrelated group which somehow ends up quoting me and being coincidentally
crossposted to comp.lang.c++.

>I assume Bonita thought Muttley posted it, because that's how it looked.

I'm afraid I don't. I think he/she/it/whatever either did it on purpose or
someone hacked her account. The fact that she's vanished from this group for
a few days when she normally never stays away is rather telling.

>reason for suspecting Bonita is somehow intentionally behind this - it
>would be completely bizarre behaviour.

Well, I wouldn't say she's entirely rational sometimes.

Pluted Pup

unread,
Jan 21, 2023, 4:03:58 PM1/21/23
to
On Thu, 19 Jan 2023 07:18:58 -0800, David Brown wrote:

> On 19/01/2023 15:42, Bonita Montero wrote:
> > Are you the twin-brother of Amine Moulay Ramdane ?
> >
> > Am 19.01.2023 um 10:31 schrieb Mut...@dastardlyhq.com:
> > > There are many people who believe that people don't change. As was
> ...
>
> And you thought it was necessary to quote the /entire/ post to make that
> comment?
>
> I think there has been some hiccup on a Usenet server somewhere - I've
> seen a few posts end up in the wrong groups today. I have no idea if
> Muttley's post is appropriate or not in rec.arts.books - I'm sure it
> makes more sense in the context of threads there.

The crap post was from rec.arts.books, which has for about
15 years been subject to robo-posted spam by "Ilya Shambat".
Bonita reposted the crap with a crosspost.

>
> (By the way, Muttley, there is a term for people who write "The Germans
> are this" or "The Jews are that" - it is "racist". Make comments about
> individuals if you like, but sweeping statements about a group of people
> based on irrelevant factors such as nationality, religion, gender, etc.,
> is bigotry and has no place anywhere. I'm assuming you did not mean to
> write that way, but you should choose your words more carefully in the
> future.)

"Ilya Shambat" is Jewish.

I'm glad Object C programmers are wising up and improving
their coding by antisemitism, despite the ban on antisemitism.


Pluted Pup

unread,
Jan 21, 2023, 5:01:45 PM1/21/23
to
Think outside the box.


David Brown

unread,
Jan 22, 2023, 7:33:53 AM1/22/23
to
On 21/01/2023 16:56, Mut...@dastardlyhq.com wrote:
> On Sat, 21 Jan 2023 13:06:09 +0100
> David Brown <david...@hesbynett.no> wrote:
>> On 20/01/2023 20:35, james...@alumni.caltech.edu wrote:
>>> something to the wrong newsgroup. But that doesn't explain Bonita's
>>> change of the Subject: header, nor her citation of the wrong time and
>>> wrong author when quoting that message.
>>>
>>
>> I saw the same post in c.l.c++ /before/ Bonita quoted it. It had ended
>> up in part of a different thread (that Muttley had been involved in),
>> and appeared to have been posted by Muttley to recs.art.books, and
>> somehow had appeared in c.l.c++ as well and had a jumbled subject.
>
> I never saw it in this group, only Bonitas copy of it. I really can't see
> how Bonita could reply to a post that clearly wasn't from me in a totally
> unrelated group which somehow ends up quoting me and being coincidentally
> crossposted to comp.lang.c++.
>

I will say it again - it appears to be the result of a server glitch.
It may only have been visible in one server, it may have been passed on
to some other servers but not all servers. Some people (such as myself,
and Bonita) saw the original broken and header-jumbled cross post.
Others did not. Bonita replied to this mistaken cross-post, thinking it
was real. It is not actually that hard to understand, and does not need
paranoia or conspiracy theories as an explanation.

>> I assume Bonita thought Muttley posted it, because that's how it looked.
>
> I'm afraid I don't. I think he/she/it/whatever either did it on purpose or
> someone hacked her account. The fact that she's vanished from this group for
> a few days when she normally never stays away is rather telling.
>

Please stop.

Look, I know that both you and Bonita rub people the wrong way
sometimes, and you seem to have a particular dislike for each other.
But trust me on this, you are not that important. No one - not Bonita,
not anyone else - is going to hack a Usenet server to make a fake
cross-post to somehow pretend to be /you/. Hacking servers is a lot of
effort, as is writing a post like that one - even if Bonita doesn't like
you, you are not worth that much effort.

>> reason for suspecting Bonita is somehow intentionally behind this - it
>> would be completely bizarre behaviour.
>
> Well, I wouldn't say she's entirely rational sometimes.
>

She's not an idiot either.

It's unpleasant when people assume you have written something that you
did not write - whether it is due to a technical fault or intentional
behaviour. But do not fall for paranoia. Anyone here who doesn't like
you or doesn't like your posts will either ignore you, or say directly
what they dislike. And do not make matters worse by accusing Bonita of
doing things she clearly did not do - it is not any better for her to be
accused of writing the weird post than it is for /you/ to be accused of it.


Mut...@dastardlyhq.com

unread,
Jan 23, 2023, 4:35:15 AM1/23/23
to
On Sun, 22 Jan 2023 13:33:37 +0100
David Brown <david...@hesbynett.no> wrote:
>On 21/01/2023 16:56, Mut...@dastardlyhq.com wrote:
>>> I saw the same post in c.l.c++ /before/ Bonita quoted it. It had ended
>>> up in part of a different thread (that Muttley had been involved in),
>>> and appeared to have been posted by Muttley to recs.art.books, and
>>> somehow had appeared in c.l.c++ as well and had a jumbled subject.
>>
>> I never saw it in this group, only Bonitas copy of it. I really can't see
>> how Bonita could reply to a post that clearly wasn't from me in a totally
>> unrelated group which somehow ends up quoting me and being coincidentally
>> crossposted to comp.lang.c++.
>>
>
>I will say it again - it appears to be the result of a server glitch.

I will say it again - it is the CLIENT that does the quoting of the "From:"
field NOT the server. The original post I saw DID NOT have my name in that
field.

>It may only have been visible in one server, it may have been passed on
>to some other servers but not all servers. Some people (such as myself,
>and Bonita) saw the original broken and header-jumbled cross post.

And my id was in this jumbled header was it?

>Others did not. Bonita replied to this mistaken cross-post, thinking it
>was real. It is not actually that hard to understand, and does not need
>paranoia or conspiracy theories as an explanation.

She didn't reply, she effectivlty reposted it with no comments. Why would she
do that?

>>> I assume Bonita thought Muttley posted it, because that's how it looked.
>>
>> I'm afraid I don't. I think he/she/it/whatever either did it on purpose or
>> someone hacked her account. The fact that she's vanished from this group for
>> a few days when she normally never stays away is rather telling.
>>
>
>Please stop.

Not until she explains herself. Little sign of that so far.

>But trust me on this, you are not that important. No one - not Bonita,
>not anyone else - is going to hack a Usenet server to make a fake

Why would she need to hack it? Do even you understand how usenet works?

David Brown

unread,
Jan 23, 2023, 8:30:01 AM1/23/23
to
On 23/01/2023 10:34, Mut...@dastardlyhq.com wrote:
> On Sun, 22 Jan 2023 13:33:37 +0100
> David Brown <david...@hesbynett.no> wrote:
>> On 21/01/2023 16:56, Mut...@dastardlyhq.com wrote:
>>>> I saw the same post in c.l.c++ /before/ Bonita quoted it. It had ended
>>>> up in part of a different thread (that Muttley had been involved in),
>>>> and appeared to have been posted by Muttley to recs.art.books, and
>>>> somehow had appeared in c.l.c++ as well and had a jumbled subject.
>>>
>>> I never saw it in this group, only Bonitas copy of it. I really can't see
>>> how Bonita could reply to a post that clearly wasn't from me in a totally
>>> unrelated group which somehow ends up quoting me and being coincidentally
>>> crossposted to comp.lang.c++.
>>>
>>
>> I will say it again - it appears to be the result of a server glitch.
>
> I will say it again - it is the CLIENT that does the quoting of the "From:"
> field NOT the server. The original post I saw DID NOT have my name in that
> field.
>

You can say it as many times as you want - you are merely describing how
things are /supposed/ to work. This was the result of a server fault
that scrambled a post. We /know/ you did not write the post. We /know/
that many people saw a post in this newsgroup with /your/ name in the
"From" field. Somewhere, a Usenet server screwed up - the "From" field,
along with the newsgroup(s), threading, and perhaps other fields, from
one real post in a real c.l.c++ thread was mixed with the message
content from a completely unrelated post in an unrelated group.

The fact that the post /you/ saw did not appear to come from you, merely
re-enforces the server glitch theory - different people saw different
things on different Usenet servers.


>> It may only have been visible in one server, it may have been passed on
>> to some other servers but not all servers. Some people (such as myself,
>> and Bonita) saw the original broken and header-jumbled cross post.
>
> And my id was in this jumbled header was it?
>

Yes.

>> Others did not. Bonita replied to this mistaken cross-post, thinking it
>> was real. It is not actually that hard to understand, and does not need
>> paranoia or conspiracy theories as an explanation.
>
> She didn't reply, she effectivlty reposted it with no comments. Why would she
> do that?
>

In Usenet terms, she replied to the post. In stereotypical google
poster fashion, she did so by top-posting a single comment and quoting
the entire original message (as she saw it on her newsserver). Why do
some people repost entire messages just to tell others that it is spam
or make other single-line comments? I don't know. I can try to explain
what she saw on her server, but I won't attempt to explain her thought
processes!

>>>> I assume Bonita thought Muttley posted it, because that's how it looked.
>>>
>>> I'm afraid I don't. I think he/she/it/whatever either did it on purpose or
>>> someone hacked her account. The fact that she's vanished from this group for
>>> a few days when she normally never stays away is rather telling.
>>>
>>
>> Please stop.
>
> Not until she explains herself. Little sign of that so far.

I can't answer for her. For all I know, she's off on holiday somewhere.
But I can certainly understand why she might not want to respond to
someone who is making wild paranoid accusations without justification,
and contrary to the evidence and explanations received.

I can appreciate that you were confused initially - we all were, since
the post was not a normal Usenet post and was not visible on all
servers, giving different people a very different view. But you should
know better now.

>
>> But trust me on this, you are not that important. No one - not Bonita,
>> not anyone else - is going to hack a Usenet server to make a fake
>
> Why would she need to hack it? Do even you understand how usenet works?
>

Yes, I do. I know how to make fake posts, and how they work - and I
know this was /not/ a fake post. Making a post whose headers contain
only one group, but which appear in another group, is not a simple fake.
Basically, the header download from one or more newsservers (at least
news.eternal-september.org) differed completely from the headers in the
content of the message. You can't fake that, since it is (obviously)
not supported by the NNTP protocols. Either it is a sophisticated hack
- and that is not realistic - or it was the result of a server glitch.


It is loading more messages.
0 new messages