Excel Random Number Generator Without Producing Duplicates? - excel

I have a column (D2:D49) using the code
=INT(RANDBETWEEN(0,51))
The idea is that this corresponds to playing card values from a deck.
The only issue is that numbers can appear more than once, meaning there is a chance of being dealt the exact same card (e.g. 4 of spades) twice in one hand, which is impossible - how can I amend the formula to avoid duplicates?

Put the numbers 1 to 51 in one column. In an adjacent column put the formula =RAND(). Sort both columns on the RAND column to get a randomly sorted set of numbers from 1 to 51.

Related

Getting number and off setting numbers from array in Excel

I have array of numbers in a single column like this:
I want only that numbers for which corresponding negative numbers exist. If number exist 2 times, but negative number exist only one time, then I wanted to retain one positive and one negative number. Similarly, if number exists 3 times, and negative number appears only two times, then I want 2 set of numbers including positive and negative. In this case, I wanted to get output:
5 2 -2 -5
Orders of numbers are not relevant for me. Please do not use VBA. You can create multiple column and apply filter at the end.
Thank you for the response, but I wanted to get the data in column next to the values. Like:
5
2
-2
-5
Please help.
Here's another Office 365 solution:
Name the data range DATA
Put this formula anywhere: =CONCAT(REPT(-ROW(A1:A100)&" "&ROW(A1:A100)&" ",COUNTIF(DATA,"="&ROW(A1:A100)*IF(COUNTIF(DATA,"="&-ROW(A1:A100))<COUNTIF(DATA,"="&ROW(A1:A100)),-1,1))))
That will output the pairs into one cell.
Here's a slightly modified Step 2, which excludes duplicates: =CONCAT(IF((COUNTIF(DATA,"="&-ROW(A1:A100))>0)*(COUNTIF(DATA,"="&ROW(A1:A100))>0),-ROW(A1:A100)&" "&ROW(A1:A100)&" ",""))
Looks like this:
The data doesn't need to be sorted. Both methods work up to 100, but you can easily expand that by changing A100 to A1000 or whatever you need.
Use the vlookup formula to identify the rows, and you can use the Filter & Unique formula to get the list, or a pivot table.
First, immediately next to your data use the formula:
=vlookup(A1*-1,$A$1:$A$1,1,0)
For non-365:
This will produce an error for each instance that doesn't have a match. You can filter at this point to get your list from the existing table. You can also create a pivot table under the Data tab of your ribbon and inserting a pivot table. Filter the #N/A from there to get an exclusive list without hidden rows.
For 365:
You can use the following combination of formulas to get the exclusive list as well.
=UNIQUE(FILTER(B1:B8,ISNUMBER(B1:B8)),0,0) or =UNIQUE(FILTER($B$1:$B$8,ISNUMBER($B$1:$B$8)),0,0) should yield the same results
As ScottCraner mentioned, you can circumvent the helper column in 365 by modifying the formula a bit more:
=UNIQUE(FILTER(A1:A8,ISNUMBER(MATCH(-A1:A8,A1:A8,0)),"")
The Match here is doing something similar to the Vlookup, but housing that logic within the formula, so it's a cleaner solution in my opinion.
Using your data the result was { -5,-2,2,5 }
These are spill formulas so you only need to put it in one spot and it will expand the formula over the adjacent cells below where it's entered for however many cells needed to list all the unique numbers that occur. It takes into account the negatives and so on. This may be a 365 formula, so if you're on another version of excel it may not work.
Edit: Adjusted the instructions to fully address the question.

Build proper sum formula in excel

I am trying to figure out how excel can fill down a column if i make a function like sum(A1:A2), sum(A1:A3) and so on. i have had no luck thus far with successfully filling as what would occur is the following result for the respective cells; sum(A1:A2), sum(A2:A3). I am sure there is a very simple fix but I am not typically an excel user.
While it may be tempting to enter the simple formula =SUM(A$2:A2) into B2 and copy it down, if you're going to sum large ranges this is actually incredibly inefficient on large ranges compared to the formula =SUM(B1,A2)
Why? Let's say you copy =SUM(A$2:A2) down 10 rows.
Your result at row 2 only had to sum 1 number: the number in A2.
Your result at row 3 has to sum 2 numbers: the numbers in A2:A3.
Your result at row 4 has to sum 3 numbers: the numbers in A2:A4.
...
Your result at row 11 has to sum 10 numbers: the numbers in A2:A11.
So how many numbers did Excel have to add in total to produce the answers you calculated in B2:B11?
1+2+3+4+5+6+7+8+9+10 = 55
But if we're using the other approach i.e. =SUM(B1,A2) then all we're doing for each row is adding the number to the left to the previously calculated sum above. So on each row, we sum only two numbers together. Meaning to produce the same 10 answers, the amount of numbers that Excel has to add to produce the exact same totals in B2:B11 are:
2+2+2+2+2+2+2+2+2+2 = 20
Now let's extrapolate that, to some sizeable ranges.
Yikes! So how much does this matter in the real world, given we've all got pretty fast computers good at math?
If you fill rows A2:A100000 with some numbers and then put =SUM(B1,A2) in B2 and fill down, it takes well under a second to calculate on my PC. But if you put =SUM(A$2:A2) instead, it takes almost a minute.
My advice: Get out of the habit of using =SUM(A$2:A2). One day you'll thank me for it.

Check for one, two or three digits in a VLOOKUP

I have around 30 numbers which are either 1, 2 or 3 digits which are codes. These codes are attached in front of other numbers. I want to know what code is in front of a number, for example for the number 35467036 the first two digits matches with the code 35. So I want the output for that to be 1.5.
This is my current setup, I have a table with all the codes followed by the output in the next column. If all the codes were three digits long I could just do this =VLOOKUP((LEFT(E6,3)&"*"),D1:E3,2,FALSE) but they are unfortunately not.
I have also tried using nested IF statements but I can only go so far as 7 levels.
Will this only be possible in VBS or is there anther way?
Edit:
The code column is formatted to text. If I enter the value 3 into LEFT it does not work for two digits. Is there anyway I can make it work for 1, 2 and 3 digit codes? Also the codes do not overlap, for example, there isn't going to be 96 and 965 in the code table.
Seven nested IFs as a limit points to a very old version of Excel. You may want to consider upgrading to a version that is still supported in this millennium.
But your main problem is that the data type of your lookup value is text, because you concatenate a string with a wildcard. Whereas your Lookup Table's first column is probably made up of numbers.
In order to solve this you will need to add a Text column to your lookup table that represents the numeric value as a text value.
IF you want to use Vlookup, that helper column will need to be the first column of your lookup range.
You can use an Index/Match instead of Vlookup to be independent of the column order, as this screenshot shows:
Column H shows the formula that has been applied in column G.
Edit:
According to the screenshot you posted, you want to look up from the table in columns E to F and this table only has the short codes. Therefore, it makes no sense to add a wildcard to the lookup value. You just need to extract the value you want to use for the lookup.
If you want to lookup only two digits, then you need to extract only two digits. Adding a wildcard does nothing to remove the third digit.
In the screenshot below, a helper column feeds the LEFT() function the number of characters to extract, then uses that value in the VLookup.
=VLOOKUP(LEFT(A1,B1),$E$1:$F$5,2,FALSE)
=INDEX($G$2:$G$5,
SMALL(
IF(LEFT(A1,3)*1=$F$2:$F$5,ROW($G$2:$G$5)-1,
IF(LEFT(A1,2)*1=$F$2:$F$5,ROW($G$2:$G$5)-1,
IF(LEFT(A1,1)*1=$F$2:$F$5,ROW($G$2:$G$5)-1))),1))
=INDEX(LookupValues,Small(ArrayOfRowsFromIfStatements,FirstRow))
This is an array formula so you will need to use Ctrl+Shift+Enter while still in the formula bar.
We use If to build an array of Row numbers where the conditions match or return FALSE if not. The Small function then returns the smallest result in the array which will be the first row where conditions match.
We then index the results returning that row number (-1 deducted from rows to offset the headers).
If your numbers in column A are always 6 digits + the code length you can use this:
=VLOOKUP(--LEFT(A1,LEN(A1)-6),E2:F5,2,FALSE)

Excel: Formula to place a random number in an array

This one has got me seriously stumped, so I thought I'd share it with you guys and see what I get :)
General Problem
I have the following data in a spreadsheet
As you can see I have two identical sets of headings 'Cat, Dog, Man...' (the precise names do not matter)
These two sets are classed under either the 'From' column or the 'To' row.
The bulk of the table is an array of numbers between 0 and 1, or empty cells.
Essentially what I want to do is find where a given Rand() number ranks along each row. I then return the item from the 'To' row corresponding to where the random number would be placed.
i.e. Reading along the 1st Cat row, a random number (between 1 and 0 too) is ranked. If it's,say, between 0 and 0.3658... I return Cat, 0.7193... and 1 gives me Van
So ideally I return the value from the To set of headings which is vertically above the upper bound within which the Rand() number lies.
Attempted Solution
To achieve this ranking I've been using the Match(value,array,0) function (0 as my numbers are in ascending order).
A simplified version of my formula is therefore:
=Index(To_Headings,MATCH(RAND(),From_Row,0))
where To_Headings is the array E3:I3 and From_Row is an array I generate using a further formula, resulting in D#:I# (# being a row number which is related to the From headings, so must be an integer between 4 and 8)
However if you are particularly observant, you can see this is where my solution falls short
As I say,ideally I want to find the upper bound of where RAND() lies, as this is always in the same column as my desired output To heading. MATCH() with a parameter of 0 returns the lower bound of where RAND() lies. Typically this is the column 1 to the left of the desired column.
e.g. Reading along the Cat row again - for a random number of 0.5, bounds within which it lies are 0.3658... and 0.7193... .The upper bound is directly below Dog, my desired output. The lower is 1 column to the left of the desired 1, so in my formula I simply shift back to the right when reading off using Index
HOWEVER the blank cells render this useless. For a random number between 0.719... and 1, the lower bound is now two columns to the left of the upper bound. In other instances it can be 3 or 4, in fact any number. This is because the blank cells push the upper bound further right.
Right, bearing all that in mind, can anyone tell me how to rank the RAND() number so it gives me the upper bound? Of course I've tried Match with -1 as the parameter, however because that requires descending order the problem flips too!
I'm thinking I could try counting if there are any blanks to the right of the lower bound, and offsetting my INDEX by that many instead of just 1, but I can see that will add a lot of lines to my code, and I really need to keep it streamlined, as it will be running in about 10000 cells!!
You can use this array formula.
Since your data is arranged in ascending order, this will find the first cell in which the random number is less than or equal to the number in the dataset:
=INDEX($E$3:$I$3,MATCH(TRUE,$J$2<=E4:I4,0))
Being an array formula it must be confirmed with Ctrl-Shift-Enter instead of Enter when exiting edit mode. If done correctly then Excel will put {} around the formula.
I've found another very simple answer through experiment with the Match function.
All you have to do is fill those blanks with the number on the left. Since Match doesn't look for the first instance of a number greater than the random number, but instead the last, by filling in the blanks all the adjustment is done for you.
So the example picture now becomes the following:
So for example, reading along the Cat row again, 0.719... is repeated. For a random input of 0.8, instead of stopping at the Dog column as before (since 0.8<1, therefore 0.719... is the biggest number smaller than the random input), the formula now stops 1 column to the left of the Upper bound every time.
Now I admit #ScottCraner gave a perfect answer to my problem as stated, however an Array formula is stuck to only one size (without VBA) whereas cell formulae can automatically fill a new range, so for my application I cannot use that answer. So I thought I'd add on this solution as a cell formula approach.

Using VLOOKUP or INDEX/MATCH to run a Lottery

I'm using Excel to run a sort of lottery.
The spreadsheet columns are set up thus:
COL1:Person Name; COL2: Chosen Number A; COL3: Chosen Number B; COL4: Chosen Number C
There is then a set of data, generated using RAND() and ROUND, that gives 3 winning numbers, each between 0 and 10.
What I'm trying to do is identify a winner, by using VLOOKUP or INDEX/MATCH, or some combination, or other function, to identify the winning person, so that there is a single cell that returns the name of the winner.
The added complexity is that by looking up each of the numbers individually by column, an individual selection of, say, 1,4,8, isn't a winning selection against a randomly selection of say, 4,8,1.
Ideas?
You can concatenate numbers to additionalcolumn so it will contain string "1,4,8," and then perform a VLOOKUP for concatenated in the same way winning numbers.
By the way, this solution will show only first person, but isn't it possible that several persons guessed same numbers and won?
If you want to generate a 3-digit number, by far the easiest thing to do is to use the formula
=RANDBETWEEN(0,999)
You can select the cells and then enter (via the format dialog accessible by right-clicking) the custom format 000 if you want it to display as 3 digits so that e.g. 7 displays as 007. This will allow you to directly use VLOOKUP on a single value. #kipar asks an excellent question about potential multiple winners.
I implemented the abovementioned solution and it was quite easy. After your 4 columns, you add one column with
=TEXT(B1;0)&TEXT(C1;0)&TEXT(D1;0)
which combines the number to one string. Then you put your winning number in a cell of preference mine was M28 and the value was 123. After your first five columns you use the following formula.
=IF.ERROR(INDEX(A$1:A$4;SMALL(IF(E$1:E$4=TEXT($M$28;0);ROW(E$1:E$4));RI-OW());1);"")
The IF.ERROR is used to put a blank when there are no multiple winners. The index is used to get the winners out of your first column, that'w why there's a one at the end. The small is used to find the first occurence of the winner. You also have to enter it as an array formula so press ctrl+shift+enter instead of just enter when the formula is completed. I hope this answer is satisfying.
PS. For extra information on the use of this function go here: http://chandoo.org/wp/2014/12/09/multiple-occurrences-lookup-and-extraction/

Resources