How can I generate a file of random negative and positive integers in serial? - language-agnostic

I want a file of randomly generated positive or negative serial integers. For now, I ask the file contain roughly (no guarantee required) equal numbers of negative and positive, but make it easy to change the proportions later. By "serial", I mean the kth random negative is equal to -k, and the kth random positive is equal to +k.
This GNU Bash script one-liner would satisfy the file format, but just wouldn't be random.
$ seq -1 -1 -5 && seq 1 5
-1
-2
-3
-4
-5
1
2
3
4
5
This example shows what I'm looking for even better, but is still not random since the integers alternate predictably between negative and positive.
$ paste <(seq -1 -1 -5) <(seq 1 5) | tr '\t' '\n'
-1
1
-2
2
-3
3
-4
4
-5
5
Sending one of these through the shuf command makes them randomly negative or positive, but they lose their serial-ness.
$ paste <(seq -1 -1 -5) <(seq 1 5) | tr '\t' '\n' | shuf
-5
4
3
2
-2
1
-1
-4
5
-3
Note: I'm trying to test algorithms that sort lists/arrays of bits (zeros and ones), but if I use 0s and 1s I won't be able to analyse the sort's behaviour or tell if stability was preserved.

If I understand correctly, you want to interleave the positive integers and the negative integers randomly. For example: 1 2 -1 3 -2 4 5- 3.
my $count = 10;
my $pos = 1;
my $neg = -1;
my #random = map {
int(rand 2)
? $pos++
: $neg--
} 1..$count;
print "#random\n";
Update:
To change proportions I'd do this:
use strict;
use warnings;
my $next = get_list_generator(.5);
my #random = map $next->(), 1..10;
print "#random\n";
my $again = get_list_generator(.25);
my #another = map $again->(), 1..10;
print "#another\n";
sub get_list_generator {
my $prob_positive = shift;
my $pos = 1;
my $neg = -1;
return sub {
return rand() <= $prob_positive ? scalar $pos++ : scalar $neg--;
}
}
The get_list_generator() function returns a closure. This way you can even have multiple list generators going at once.

Let's start golf contest? (44)
perl -le'print rand>.5?++$a:--$b for 1..10'
Edit: daotoad's 40 chars version
seq 1 10|perl -ple'$_=rand>.5?++$a:--$b'

Where 15 is the total amount of numbers generated and tp is the amount of positive numbers you want (effectively indicating the ratio of pos/neg):
tp=8
unset p n
for i in $(printf '%s\n' {1..15} | gsort -R); do
(( i <= tp )) && \
echo $((++p)) || \
echo $((--n))
done

#!/bin/bash
pos=0 neg=0
for i in {1..10}
do
if (( ($RANDOM > 16384 ? ++pos : --neg) > 0 ))
then echo $pos
else echo $neg
fi
done
I could not quite fit this into a one-liner. Anyone else?
edit: Ah, a one liner, 65 characters (need to set a and b if you're repeatedly invoking this in the same shell):
a=0 b=0;for i in {1..10}; do echo $(($RANDOM>16384?++a:--b));done

Here's a Bash one-liner (2?) inspired by lhunath and Brian's answers.
RANDOM=$$; pos=1; neg=-1; for i in {1..10}; do \
echo $(( $(echo $RANDOM / 32767 \> 0.5 | bc -l) ? pos++ : neg-- )); done
Here's an Awk script that competes in the golf contest (44).
seq 1 10|awk '{print(rand()>0.5?++p:--n);}'
This is the clearer idiomatic way to write it:
seq 1 10 | awk 'BEGIN{srand(); pos=1; neg=-1;}
{print (rand() > 0.5 ? pos++ : neg--);}'

There is no set of numbers that will fit all your criterion. You can't say you want random but at the same time say that the kth negative value == -k and the kth positive value == k. You can either have it random, or not.
As to what you're trying to do, why not separate the two concerns and test the sort on something like an array of pairs of integers length n. The first of the pair can be zero or 1 and the second of the pair will be your stability tracker (just a count from 0 to n).
Generate the list of 0's and 1's that you want and shuffle them then add on the tracker integer. Now sort the pairs by their first element.
The input to your sort will look something like this.
0, 1
1, 2
0, 3
1, 4
1, 5
0, 6
0, 7
1, 8
1, 9
1, 10
0, 11
0, 12
0, 13
Stable sorts will produce this
0, 1
0, 3
0, 6
0, 7
0, 11
0, 12
0, 13
1, 2
1, 4
1, 5
1, 8
1, 9
1, 10
Unstable ones will produce the 0's and 1's with the tracker integers out of order.

Related

Add 25 & 30 as binary number

Using 8 bit registers and signed magnitude representation.
I thought 25 in BCD is 010 0101 but my text book says it as 001 1001. Can somebody explain?
25 / 2 = 12r1 (12 with a remainder of 1)
12 / 2 = 6r0 (6 with a remainder of 0)
6 / 2 = 3r0 (3 with a remainder of 0)
3 / 2 = 1r1 (1 with a remainder of 0)
1 / 2 = 0r1 (0 with a remainder of 0)
So 11001 (working backward up the tree) is the binary equivalent to 25.
Another way to think about it is with powers of 2:
(1*16) + (1*8) + (0*4) + (0*2) + (1*1) = 25
And it's worth noting, just as in base 10, leading zeros do not change the value of a number. (00025 == 25) (0011001 == 11001).
The leading zeros are there in your case because your needing to populate an 8 bit register (there needs to be 8 binary digits regardless of their value).

Outputs of a program

I am new to programming and I would like to know how to solve questions like this. I was told to expect questions like this on the exam. Can someone please tell me how I would go about solving something like this? Thanks.
x = 0
for num in range(5):
if num % 2 == 0:
x = x + 2
else:
x = x + 1
print(x)
You need to work on a skill which is to "be the compiler", in the sense that you should be able to run code in your head. Step through line by line and make sure you know what is happening. In you code example, you have
for num in range(5) means you will be iterating with num being 0,1,2,3 and 4. Inside the for loop, the if statement num % 2 == 0 is true when num/2 does not have a remainder (how % mods work). So if the number is divisible by 2, x = x+2 will execute. The only numbers divisible by 2 from the for loop are 0,2 and 4. so x=x+2 will execute twice. The else statement x = x +1 runs for all other numbers (1,3) which will execute 2 times.
Stepping through the for loop:
num = 0 //x=x+2, x is now 2
num = 1 //x=x+1, x is now 3, print(x) prints 3
num = 2 //x=x+2, x is now 5
num = 3 //x=x+1, x is now 6, print(x) prints 6
num = 4 //x+x+2, x is now 8
Therefore the answer is that 3 and 6 will be printed
In my opinion,
Whatever language you are using, you need to learn some common elements of the modern programming languages, such as flow-control (if...else in your case), loop(for, in your case)
Some common used functions, in your case, you need to what does range do in Python,
docs.python.org is a good place for you.
As you are new to programming, you can go with the flow in you mind or draw it on the paper.
Using x to store our final result
loop through every item in [0, 1, 2, 3, 4] <- range(5)
a. if
the number is divisible by 2
then increase x by adding 2 to it.
b. else
increase x by adding 1 and print it out
So the result would be :
3
6

octave: using find() on cell array {} subscript and assigning it to another cell array

This is an example in Section 6.3.1 Comma Separated Lists Generated from Cell Arrays of the Octave documentation (I browsed it through the doc command on the Octave prompt) which I don't quite understand.
in{1} = [10, 20, 30, 40, 50, 60, 70, 80, 90];
in{2} = inf;
in{3} = "last";
in{4} = "first";
out = cell(4, 1);
[out{1:3}] = find(in{1 : 3}); % line which I do not understand
So at the end of this section, we have in looking like:
in =
{
[1,1] =
10 20 30 40 50 60 70 80 90
[1,2] = Inf
[1,3] = last
[1,4] = first
}
and out looking like:
out =
{
[1,1] =
1 1 1 1 1 1 1 1 1
[2,1] =
1 2 3 4 5 6 7 8 9
[3,1] =
10 20 30 40 50 60 70 80 90
[4,1] = [](0x0)
}
Here, find is called with 3 output parameters (forgive me if I'm wrong on calling them output parameters, I am pretty new to Octave) from [out{1:3}], which represents the first 3 empty cells of the cell array out.
When I run find(in{1 : 3}) with 3 output parameters, as in:
[i,j,k] = find(in{1 : 3})
I get:
i = 1 1 1 1 1 1 1 1 1
j = 1 2 3 4 5 6 7 8 9
k = 10 20 30 40 50 60 70 80 90
which kind of explains why out looks like it does, but when I execute in{1:3}, I get:
ans = 10 20 30 40 50 60 70 80 90
ans = Inf
ans = last
which are the 1st to 3rd elements of the in cell array.
My question is: Why does find(in{1 : 3}) drop off the 2nd and 3rd entries in the comma separated list for in{1 : 3}?
Thank you.
The documentation for find should help you answer your question:
When called with 3 output arguments, find returns the row and column indices of non-zero elements (that's your i and j) and a vector containing the non-zero values (that's your k). That explains the 3 output arguments, but not why it only considers in{1}. To answer that you need to look at what happens when you pass 3 input arguments to find as in find (x, n, direction):
If three inputs are given, direction should be one of "first" or
"last", requesting only the first or last n indices, respectively.
However, the indices are always returned in ascending order.
so in{1} is your x (your data if you want), in{2} is how many indices find should consider (all of them in your case since in{2} = Inf) and {in3}is whether find should find the first or last indices of the vector in{1} (last in your case).

What are w-bit words?

What are w-bit words in computer architecture ?
For two 7 bit words
1011001 = A
1101011 = B , how does multiplication returns
10010100110011 ?
Isn't there simple binary multiplication involved in these ?
Please provide an example.
w-bit is just the typical nomenclature for n-bit because w is usually short for word size
Both adding and multiplying are done just the same as in decimal (base 10). You just need to remember this truth table:
Multiplying
-----------
0 x 0 = 0
0 x 1 = 0
1 x 0 = 0
1 x 1 = 1
Adding
-----------
0 + 0 = 0
0 + 1 = 1
1 + 0 = 1
1 + 1 = 0 (w/ carry)
First adding. To add, you add just like you would in normal arithmetic, except follow the truth table above:
00000101 = 5
+ 00000011 = 3
--------------
00001000 = 8
How this works is that you start from the right and work left. 1 + 1 = 0, but you carry a 1 over to the next column. So the next column is 0 + 1, which would be 1, but since you carried another 1 from the previous column, its really 1 + 1, which is 0. You carry a 1 over the next column, which is 1 + 0, but really 1 + 1 because of the carry. So 0 again and finally move the 1 to the next column, which is 0 + 0, but because of our carry, becomes 1 + 0, which is 1. So our answer is 1000, which is 8 in decimal. 5 + 3 = 8, so we know we are right.
Next, multiplying:
00000101 = 5
x 00000011 = 3
----------
101 = 5
+ 1010 = 10
----------
1111 = 15
How this works is you multiply the top number 00000101 by the right most digit in the second row. So 00000011 is our second row and 1 is the right most digit, so 00000101 times 1 = 101. Next you put a 0 placeholder in the right most column below it, just like in normal multiplication. Then you multiply our top original number 00000101 by the next digit going left in our original problem 00000011. Again it produce 101. Next you simply add 101 + 1010 = 1111 ...That is the answer
Yes, it's simple binary multiplication:
>>> 0b1011001
89
>>> chr(_)
'Y'
>>> 0b1101011
107
>>> chr(_)
'k'
>>> ord('Y') * ord('k')
9523
>>> bin(_)
'0b10010100110011'
If you want to multiply, you simply do the multiplication the same as with decimal numbers, except that you have to add the carries in binary:
1011001
x1101011
-------
1011001
1011001.
0000000..
1011001...
0000000....
1011001.....
1011001......
--------------
10010100110011
w-bit words aren't anything by themselves. Assuming that the value of w has been previously defined in the context in which "w-bit word" is used, then it simply means a word that is composed of w bits. For instance:
A version of RC6 is more accurately specified as RC6-w/r/b where the word size
is "w" bits, encryption consists of a nonnegative number of rounds "r," and
"b" denotes the length of the encryption key in bytes. Since the AES
submission is targetted at w=32, and r=20, we shall use RC6 as shorthand to
refers to such versions.
So in the context of that document, a "w-bit word" is just a 32-bit value.
As for your multiplication, I'm not sure what you are asking. Google confirms the result as correct:
1011001 * 1101011 = 10010100110011

how do I convert fractional decimal numbers to fractional binary numbers using dc

So dc is a great tool for converting between bases - handy for those bit twiddling coding jobs. e.g to convert 1078 into binary I can do this:
bash> echo "2o1078p" | dc
10000110110
However I can't get it to print fractions between 0 and 1 correctly.
Trying to convert 0.3 into binary:
bash> echo "2o10k 0.3p" | dc
.0100
But 0.0100(bin) = 0.25 not 0.3.
However if I construct the value manually I get the right answer
bash> echo "2o10k 3 10 / p" | dc
.0100110011001100110011001100110011
Well it looks like its giving me more than the 10 significant figures I ask for but thats OK
Am I doing something wrong? Or am I trying to make dc do something that its not able to do?
bash> dc --version
dc (GNU bc 1.06) 1.3
...
Strange. My first thought was that maybe precision only applies to calculations, not conversions. But then it only works for division, not addition, subtraction, or multiplication:
echo "2o10k 0.3 1 / p" | dc
.0100110011001100110011001100110011
echo "2o10k 0.3 0 + p" | dc
.0100
echo "2o10k 0.3 0 - p" | dc
.0100
echo "2o10k 0.3 1 * p" | dc
.0100
As for precision, the man page says "The precision is always measured in decimal digits, regardless of the current input or output radix." That explains why the output (when you get it) is 33 significant bits.
It seems that dc is getting the number of significant figures from the input.
Now 1/log10(2)=3.32 so each decimal significant digit is 3.3 binary digits.
Looking at the output of dc for varying input SF lengths shows:
`dc -e "2o10k 0.3 p"` => .0100
`dc -e "2o10k 0.30 p"` => .0100110
`dc -e "2o10k 0.300 p"` => .0100110011
`dc -e "2o10k 0.3000 p"` => .01001100110011
A table of these values and expected value, ceil(log10(2)*SFinput) is as follows:
input : output : expected output
1 : 4 : 4
2 : 7 : 7
3 : 10 : 10
4 : 14 : 14
And dc is behaving exactly as expected.
So the solution is to either use the right number of significant figures in the input, or the division form dc -e "2o10k 3 10 / p"