I am new to Java and am currently learning about random numbers. In my book it has a challenge activity to generate a random number between 100 - 149. Then it will automatically output 2 numbers and see if your code matches what they outputted. The code seems to work just fine, but my numbers are not matching. I was wondering what I could be doing wrong in my code?
import java.util.Scanner;
import java.util.Random;
public class RandomGenerateNumbers {
public static void main (String [] args) {
Scanner scnr = new Scanner(System.in);
Random randGen = new Random();
int seedVal;
seedVal = scnr.nextInt();
randGen.setSeed(seedVal);
seedVal = randGen.nextInt(50) + 100;
System.out.println(seedVal);
seedVal = randGen.nextInt(50) + 100;
System.out.println(seedVal);
}
}
The issue is that the code is producing what I would expect, it just does not match what the book is getting.
The book is using the value 102 and it is producing 113 and 124. My outputs are coming back as 112 and 102
Related
I'm writing a code in JAVA that is going to be a Lucky Wheel Game. The game at this stage takes a number as input to start the wheel to turn, get a random element from a collection of prizes and outputs the price. As you can see the code below, I created an array and added it's elements to the ArrayList. The player have 3 turns and at each turn he gets a random price (element) from the ArrayList. Sounds good, but I'm stuck. The problem is, for some reason I get the error of "Cannot resolve symbol 'wheel'. I use IntelliJ IDEA. I just started coding so I'm sure there's gonna be more errors after I resolve this one. But first, I want to solve this, then I can continue the game and add more to it. Thanks for all the answers!
Here's the code:
import java.util.*;
public class Game {
public static void func1(String[] prizes) {
ArrayList<String> wheel = new ArrayList<>(5);
//Adds array elements to ArrayList
Collections.addAll(wheel, prizes);
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Random randomGenerator = new Random();
String[] prizes = {"Television", "iPhone", "Microwave", "Ventilator", "Gift Card"};
func1(prizes);
int turn = scanner.nextInt(1);
int tries = 0;
int index = randomGenerator.nextInt(wheel.size()); // I get the error here
//int wheel = wheel.size();
while(tries < 3) {
turn = scanner.nextInt(1);
System.out.println("You won a" + wheel.get(index)); // and here too
tries++;
}
}
}
Say there is a file too big to be put to memory. How can I get a random line from it? Thanks.
Update:
I want to the probabilities of getting each line to be equal.
Reading the entire file if you want only one line seems a bit excessive. The following should be more efficient:
Use RandomAccessFile to seek to a random byte position in the file.
Seek left and right to the next line terminator. Let L the line between them.
With probability (MIN_LINE_LENGTH / L.length) return L. Otherwise, start over at step 1.
This is a variant of rejection sampling.
Line lengths include the line terminator character(s), hence MIN_LINE_LENGTH >= 1. (All the better if you know a tighter bound on line length).
It is worth noting that the runtime of this algorithm does not depend on file size, only on line length, i.e. it scales much better than reading the entire file.
Here's a solution. Take a look at the choose() method which does the real thing (the main() method repeatedly exercises choose(), to show that the distribution is indeed quite uniform).
The idea is simple: when you read the first line it has a 100% chance of being chosen as the result. When you read the 2nd line it has a 50% chance of replacing the first line as the result. When you read the 3rd line it has a 33% chance of becoming the result. The fourth line has a 25%, and so on....
import java.io.*;
import java.util.*;
public class B {
public static void main(String[] args) throws FileNotFoundException {
Map<String,Integer> map = new HashMap<String,Integer>();
for(int i = 0; i < 1000; ++i)
{
String s = choose(new File("g:/temp/a.txt"));
if(!map.containsKey(s))
map.put(s, 0);
map.put(s, map.get(s) + 1);
}
System.out.println(map);
}
public static String choose(File f) throws FileNotFoundException
{
String result = null;
Random rand = new Random();
int n = 0;
for(Scanner sc = new Scanner(f); sc.hasNext(); )
{
++n;
String line = sc.nextLine();
if(rand.nextInt(n) == 0)
result = line;
}
return result;
}
}
Either you
read the file twice - once to count the number of lines, the second time to extract a random line, or
use reservoir sampling
Looking over Itay's answer, it looks as though it reads the file a thousand times over after sampling one line of the code, whereas true reservoir sampling should only go over the 'tape' once. I've devised some code to go over code once with real reservoir sampling, based on this and the various descriptions on the web.
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;
public class reservoirSampling {
public static void main(String[] args) throws FileNotFoundException, IOException{
Sampler mySampler = new Sampler();
List<String> myList = mySampler.sampler(10);
for(int index = 0;index<myList.size();index++){
System.out.println(myList.get(index));
}
}
}
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
public class Sampler {
public Sampler(){}
public List<String> sampler (int reservoirSize) throws FileNotFoundException, IOException
{
String currentLine=null;
//reservoirList is where our selected lines stored
List <String> reservoirList= new ArrayList<String>(reservoirSize);
// we will use this counter to count the current line number while iterating
int count=0;
Random ra = new Random();
int randomNumber = 0;
Scanner sc = new Scanner(new File("Open_source.html")).useDelimiter("\n");
while (sc.hasNext())
{
currentLine = sc.next();
count ++;
if (count<=reservoirSize)
{
reservoirList.add(currentLine);
}
else if ((randomNumber = (int) ra.nextInt(count))<reservoirSize)
{
reservoirList.set(randomNumber, currentLine);
}
}
return reservoirList;
}
}
The basic premise is that you fill up the reservoir, and then go back to it and fill in random lines with a 1/ReservoirSize chance. I hope this provides more efficient code. Please let me know if this doesn't work for you, as I've literally knocked it up in half an hour.
Use RandomAccessFile:
Construct a RandomAccessFile, file
Get the length of that file, filelen, by calling file.length()
Generate a random number, pos, between 0 and filelen
Call file.seek(pos) to seek to the random position
Call file.readLine() to get to the end of the current line
Read the next line by calling file.readLine() again
Using this method, I've been sampling lines from the Brown Corpus at random, and can easily retrieve a 1000 random samples from randomly chosen files in a few seconds. If I tried to do the same by reading through each file line-by-line it would take me much longer.
The same principle can be used for selecting random elements from a list. Rather than reading through the list and stopping at a random place, if you generate a random number between 0 and the length of the list, then you can index directly into the list.
Reading a random line from a file in java:
public String getRandomLineFromTheFile(String filePathWithFileName) throws Exception {
File file = new File(filePathWithFileName);
final RandomAccessFile f = new RandomAccessFile(file, "r");
final long randomLocation = (long) (Math.random() * f.length());
f.seek(randomLocation);
f.readLine();
String randomLine = f.readLine();
f.close();
return randomLine;
}
Use a BufferedReader and read line wise. Use the java.util.Random object to stop randomly ;)
This question already has answers here:
Scanner input accepting Strings skipping every other input inside a while loop. [duplicate]
(3 answers)
Closed 7 years ago.
Everything compiles, but when I print the size and the array elements, it indicates that not all of the values are added in because the size and the values would only be partial. Also, sometimes the sentinel value does not work( I have to enter it twice at times).What's wrong?
import java.util.ArrayList;
import java.util.Scanner;
public class BowlingScoresArrayList{
public static final int SENTINEL = -999;
public static final int MIN=-1;
public static void main (String [] Args) {
ArrayList<Integer> bowlingScores = new ArrayList<Integer>();
Scanner reader = new Scanner(System.in);
System.out.println("Enter your scores: ");
do {
bowlingScores.add(reader.nextInt());
} while (reader.nextInt()!= SENTINEL);
System.out.println(bowlingScores);
System.out.println(bowlingScores.size());
So I tried entering these values:
Enter your scores:
1
2
2
3
-999
-999
And it yields this:
[1, 2, -999]
3
You're problem is, you're using two nextInt statements...
do {
bowlingScores.add(reader.nextInt());
} while (reader.nextInt()!= SENTINEL);
So you're asking the user to provide input twice.
Instead, something like...
int in = SENTINEL;
do {
in = reader.nextInt();
if (in != SENTINEL) {
bowlingScores.add(in);
}
} while (in != SENTINEL);
would produce the desired results
I am trying to solve a question on Hackerearth. The competition had ended long time back.
http://www.hackerearth.com/lenskart-hiring-challenge/algorithm/big-p-and-punishment-5/description/
The Problem Statement
Big P has become a Physical Education teacher at Hack International School.
Today, the students of class XII have been very indisciplined and he decides to punish them all.
He makes all of the N student (numbered 1 to N ) to stand in a line and asks them to sit down on their knees.
Students know that Big P is a very cruel and sadistic person and students start to sit down themselves when they see a friend sit down.
However, there are always some students who do not follow the trend. Now when Big P sees that happen , he slaps that student and makes him sit down. The same process as above is followed and is stopped when any - one student in the line refuses to sit down by himself.
Given the students that Big P slaps to make them sit down , you need to tell the total no. of students who sat down in that line.
Note: It is not necessary that if A is friend of B then B is also friend of A.
Input Format :
First Line Contains an integer T denoting no of test cases. Each test case begins with a line containing three integers N, F, S where N is the number of students in the line . Next F lines have two integers A and B denoting the friendship between the students A and B. Next S lines have one integer X denoting the student that was slapped by Big P .
Output Format:
For each test case, output a line containing one integer, the total number of students that sit down in that line.
[ T<=10 , N ,F , S <=10000 ]
Sample Input
1
3 2 1
1 2
2 3
2
Sample Output
2
I have written a Java Code for the same.
import java.io.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Arrays;
#SuppressWarnings("unchecked")
class Graph
{
static int visited[];
public static void main(String[] args) throws IOException
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int testcases;
int N,F,S,n;
int a,b;
testcases=Integer.parseInt(br.readLine());
while(--testcases>=0)
{
String[] s = br.readLine().split(" ");
N=Integer.parseInt(s[0]);
F=n=Integer.parseInt(s[1]);
S=Integer.parseInt(s[2]);
visited=new int[N+1];
Arrays.fill(visited,0);
ArrayList[] adj=new ArrayList[N+1];
while(--n>=0)
{
s = br.readLine().split(" ");
a=Integer.parseInt(s[0]);
b=Integer.parseInt(s[1]);
if(adj[a]==null){
adj[a]=new ArrayList<Integer>();
}
(adj[a]).add(b);
}
int root;
for(int i=1;i<=S;i++)
{
root=Integer.parseInt(br.readLine());
dfs(adj,root);
}
int ans=0;
for(int i=1;i<=N;i++)
{
if(visited[i]==1){
++ans;
}
}
System.out.println(ans);
}
}
static void dfs(ArrayList adj[],int r)
{
int curr;
if(visited[r]!=1)
{
ArrayList base=adj[r];
if(base!=null)
{
Iterator itr=base.iterator();
while(itr.hasNext())
{
curr=(int)itr.next();
if(visited[curr]==0)
{
dfs(adj,curr);
}
}
}
visited[r]=1;
//System.out.println(r);
}
}
}
It passes for the 1st testcase,but gives an NZEC error for the remaining testcases.
I tried making changes like :
Used Scanner instead of Stream Reader.
Removing static arrays
None of these is helping.
Please help me out in identifying the fault.
Right, I am working on a program for school the purpose of the program is to find the minimum number of coins, I am a novice programmer and this is my first time so I dont know the thousands of other things and what not other people do. I wrote the code and it works, but I seem to have found a bug/glitch or w/e you want to call it.
my code
import java.util.Scanner;
public class Coin {
public static void main (String[] Args) {
int quarters = 25;
int dimes = 10;
int nickles = 5;
int pennies = 1;
System.out.println("Enter in a number between 1-99");
// "Input" Part of Code (Remember this and go back for reference)
Scanner Userinput = new Scanner(System.in);
int stuff = Userinput.nextInt();
int q = stuff/quarters;
String A = "Number of Quarters:" +q;
System.out.println(A);
int hold = stuff%quarters;
int d = hold/dimes;
String B = "Number of Dimes:" +d;
System.out.println(B);
int hold1 = stuff%dimes;
int n = hold1/nickles;
String C = "Number of Nickles:" +n;
System.out.println(C);
int hold2 = stuff%nickles;
int p = hold2/pennies;
String D = "Number of Pennies:" +p;
System.out.println(D);
System.out.println("Thank you for Using My Program");
}
}
Now, everything works fine I can input any number I like and get the desired result, however for some odd reason I cannot fathom I type in any number between 75-79 and there is an added Nickle for some odd reason and I have spent the better part of 2 hours trying to figure out exactly what is wrong but cannot. Hav tried dozens of toher numbers and they work fine except for that one little area.
Can someone tell me by chance what might be wrong?
Your hold = ... lines should be based on the previous hold value rather than the full amount (stuff).
int hold2 = hold%nickles;
You need to subtract off what has already been accounted for when adding previous, larger coins.
For example, if I say 77, then the program will check 77%10 and return 7. You would want to adjust your "stuff" value by any previously added coins. So in this case, after adding 3 quarters (75) we would want to set stuff = stuff - 75 (stuff -= 75).
EDIT: to be more precise, after every calculation you could run
stuff -= q * quarters;
of course, changing the variables to be appropriate for each part of your code.