Write a program that displays all numbers divisible by 3 and 4 within a range entered by user. Display five numbers per line. Numbers are separated by exactly two spaces.

This is my code

        public class Chapter4 {
            public static void main(String[] args) {
                Scanner input = new Scanner(System.in);
                final int NUMBER_OF_PRIMES_PER_LINE = 5;
                int count = 0;
                int[] vars = new int[10];

                for (int i = 0; i < vars.length; i++) {
                    System.out.println("Enter " + (i + 1) + " numbers: ");
                    vars[i] = input.nextInt();

                    if ((vars[i] % 3 == 0) && (vars[i] % 4 == 0)) {
                        count++;
                    }

                    if (count % NUMBER_OF_PRIMES_PER_LINE == 0) {
                        System.out.println(vars[i]+"  ");
                    }
                }
            }    
   }

I input value 120 10 times, but I only get one 120 displayed at the end.

Recommended Answers

All 25 Replies

Your explanation is not consistent. You state that the user is to enter a range as in "find me all numbers between x and y that are divisible by both 3 and 4." Later you state that you "input value 120 10 times". That is inconsistent with the problem so either the problem is stated incorrectly or you are not inputting the expected data. Decide what is the correct problem then write it up in pseudo-code before you write the actual code.

If a range is expected, make sure you test that it is a valid range (x <= y).

commented: Programmers consistently solve the other problems first. +14

Your code would do some very odd things. But first, name your variables and CONSTANTS with meaning. You use the word PRIMES and yet I see nothing in the assignment about primes.

Line 8 to 14 are your for loop collecting what looks to be numbers to be checked and then a variable count is incremented.

Finally line 16 and 17 are a true mystery as why we would expect this to not crash. Very strange to use your loop variable i outside the loop.

You may want to refactor this one.

From the OP...

divisible by 3 and 4

From RJ...

divisible by both 3 and 4.

I mentally stuck the word "both" in there like RJ did, but I believe there could be other interpretations of the problem as well.

You clearly are misunderstanding the problem. What I don't know is what the problem is in your head. If I was a grader or a helper on Daniweb, I could give you hints on how to approach the problem correctly, but I would not know how to help you debug YOUR code.

That is entirely preventable and has nothing to do with your coding ability. Comments and well-named variables are a must here. If I attempted to write this program in, say, Ruby, a language I know nothing about, I'd probably get it wrong, BUT Reverend Jim and RProffitt, assuming they know Ruby, would probably know how to help me because I would stick comments and descriptive variable names in my code and I would also put an example of what I WANTED the output to show plus what it actually showed.

In my opinion, the above is far more important than your actual coding and any bugs. Many times, in the process of forming a well-crafted Daniweb question, people who are stuck trying get unstuck before they even hit "Submit". I know that I have.

Seems to me that the program should run something like this...

Enter a lower range boundary? 16
Enter an upper range boundary? 99

The following values are between 16 and 99 and are divisible by both 3 and 4...

24 36 48 60 72
84 96

commented: The top post had me read again about rules of divisibility which was interesting all on its own. +14

@Assertnull - I've never so much as seen a single line of Ruby. However, the loop for the problem is 7 lines of vbscript.

OK folks, getting a bit off-topic here?... it's Java.

John: I don't see how you got from the problem definition to that code. It looks like you have tried to adapt a different program, with arrays of numbers and primes somehow.
Hacking a different program is almost always a bad idea.
The best thing to do is to go back to the start and sketch out your logic on a scrap of paper in pseudo-code, then write the Java to implement that. You could copy/paste the first 3 lines of the old code if you want, but no more than that.
If you get stuck come back here and someone will help.

Not that it matters, but here it is in Ruby.

Simple, elegant and concise. Dare I say, beautiful?

lower, upper = 20, 400

lower.upto(upper)
    .select{|i| i.modulo(3).zero? && i.modulo(4).zero?}
    .each_slice(5){|m| puts m.join("  ")}

.upto loops from the called number to the arg. Normally I'd have written this (lower..upper).select… but this makes it a bit clearer.

.select returns an array containing elements where the block returns true.

.each_slice iterates through the enumerable object in chunks (the first arg, 5 in this case) and executes the block for each chunk (printing the array joined by two spaces).

Yes, I'd say beautiful.
The equivalent in Java is quite pretty too...

int lower = 16, upper = 99;

IntStream.rangeClosed(lower,upper)
   .filter(i -> i%3 == 0 && i%4 == 0)
   .forEach(System.out::print);

,,, but I haven't been able to come up with a really elegant way to print 5 values per line - any ideas anyone?

Thanks guys for all the feedback. Just wonder how can I reply a comment ?

Conmments are attached to up and down votes, so unless yiu want to up/down vote, a simple reply is fine.

Actually results is numbers divisible by 12. Another way to find - check last 4 bits. It should be 1100

Sorry i was wrong about last 4 bits

Thanks all . I finally solved it.

      import java.util.Scanner;

        public class Chapter4 {

            public static void main(String[] args) {
                final int NUMBER_PER_LINE = 5;
                Scanner input = new Scanner(System.in);
                int count = 0;
                int firstNumber = 0;
                int secondNumber = 0;
                System.out.print("Enter first number: ");
                firstNumber = input.nextInt();
                System.out.print("Enter second number: ");
                secondNumber = input.nextInt();

                for (int i = firstNumber; i < secondNumber + 1; i++) {
                    if ((i % 3 == 0) && (i % 4 == 0)) {
                        count++;
                        if (count % NUMBER_PER_LINE == 0) {
                            System.out.println(i);
                        } else {
                            System.out.print(i + "  ");
                        }

                    }
                }
            }  
}
commented: Very nicely done John. +14

JamesCherrill: Very nicely done John.

Thanks James.

No worries - "praise where praise is due"
If I were to write that the only changes I would make would be:
1) Some kind of very simple validation on the user input so it crashes out of bad input with a friendly error message
and
2) instead of i < secondNumber + 1 I would write i <= secondNumber

(or, for fun, I would write it using Streams range and filter as in my earlier post)

I haven't been able to come up with a really elegant way to print 5 values per line...

OK, a bit off-topic, but I wanted to share this with anyone who may have been interested...
The problem is to print a Stream of numbers formatted at 5 per line.
I tackled this by creating a Collector that takes a Stream of Objects and returns a Stream of Strings in groups with different separators within groups and between groups, and threw in a formatting option for the Objects themselves.
In good Java 8 style I wrote a fluent builder to create Collectors with any or all of those options.
In use it looks like this

// adds a new line before each new group of 5

  (some arbitrary Stream)
. collect(new GrouperBuilder(5).groupPrefix("\n").build())
. forEach(System.out::print);

// build example with all the options
new GrouperBuilder(3) // 3 items per group
.prefix(", ")         // commas between them
.groupPrefix("\n")    // new lines between groups
.format("%4d")        // format items as 4 col ints
.build()              // create the Collector

// creates output like
//  24,   36,   48
//  60,   72,   84
//  96

and here (if anyone cares) is the builder code. Please comment and suggest improvements...

  class GrouperBuilder {

        // converts stream of Objects to stream of fornated Strings in groups

        private final int itemsPerGroup; // number of items in each group. Mandatory

        // optional formatting values...
        private String prefix = "";      // text to put between items within a group
                                         // default is no prefix
        private String groupPrefix = ""; // text to put between groups
                                         // default is no group prefix
        private String format = "%s";    // Formatter format for items
                                         // default is just to call toString()

        public GrouperBuilder(int itemsPerGroup) {
            this.itemsPerGroup = itemsPerGroup;
        }

        public GrouperBuilder prefix(String prefix) {
            this.prefix = prefix;
            return this;
        }

        public GrouperBuilder groupPrefix(String groupPrefix) {
            this.groupPrefix = groupPrefix;
            return this;
        }

        public GrouperBuilder format(String format) {
            this.format = format;
            return this;
        }

        public Collector<Object, ?, Stream<String>> build() {
            return Collector.of(
                    () -> new ArrayList<String>(),
                    (list, i) -> {
                        String s = String.format(format, i);
                        if (list.isEmpty())
                            list.add(s);
                        else if (list.size() % itemsPerGroup == 0)
                            list.add(groupPrefix + s);
                        else 
                            list.add(prefix + s);
                    },
                    (list1, list2) -> {
                        list1.addAll(list2);
                        return list1;
                    },
                    list -> list.stream()
            );
        }

    }

Have fun!
JC

commented: Kewl +15

Seems like a very complex way to do a very simple thing, but as an intellectual exercise, neat.

Do not multiply entities needlessly. (William of Ockham)

Well.... yes.

It was inspired by the Ruby each_slice(5) thing that pty posted. It looked like a neat and useful thing that Java doesn't have. So I started out trying to do a Java version. The print-oriented version was a step on the road, but since then I have got it a lot more generic and closer to the original.
Now I have a "slicer" Collector that breaks a Stream<T> into substreams of a given size ie a Stream<Stream<T>>
You can do lots of things with that, including printing stuff in comma-delimited blocks of 5, ie

(some stream)
.collect(new SlicerBuilder(5).build())
.map(s -> s.collect(Collectors.joining(", "))) 
.forEach(System.out::println);

.collect(new SlicerBuilder(5).build()) 
// break into substreams of length 5

.map(s -> s.collect(Collectors.joining(", "))) 
// convert each substream to a comma-delimited list

.forEach(System.out::println);
// print each comma-delimited list on a new line

The code for the builder is a bit longer :), but it's just a utility thing that can be re-used endlessly. It would also be pretty trivial to adapt or extend it to split a stream on any other criteria

    class SlicerBuilder {

         private final int itemsPerGroup; 

        public SlicerBuilder(int itemsPerGroup) {
            this.itemsPerGroup = itemsPerGroup;
        }

        public <T> Collector<T, ?, Stream<Stream<T>>> build() {
            ArrayList<T> temp = new ArrayList<>();
            return Collector.of(
                    () -> new ArrayList<Stream<T>>(),
                    (list, i) -> {
                        temp.add(i);
                        if (temp.size() >= itemsPerGroup) {
                            list.add(new ArrayList(temp).stream());
                            temp.clear();
                        }
                    },
                    (list1, list2) -> {
                        list1.addAll(list2);
                        return list1;
                    },
                    list -> {
                        if (!temp.isEmpty()) list.add(temp.stream());
                        return list.stream();
                    }
            );
        }

    }

Just for fun, if you have two values, lo and hi, the following line of APL displays the required values:

((0=3|r)∧(0=4|r))/r ← lo, lo + ⍳ hi - lo
commented: Close but no cigar - you have to print 5 values per line +14

Ah yes, APL. In 1970 I was given my own APL golfball for coding on a 16kB IBM 1130 computer. I used it to write an assembler for an IBM System 7 process control computer (we were developing software for it pre-release and coudn't wait for the labs to ship a proper working assembler). Oh what fun we had in those heady early days.
It was, and maybe still is, the world's first WOL - "write only language" - a reference to the fact that you coudn't read it.

commented: Maybe WOL is better than ROL (read only language.) +14

you have to print 5 values per line

Easy to do if you have multiple of 5 values. Harder if you don't. I had one of those golf balls as well back in '73. Expensive at the time but worth it so I didn't have to wait for one of the APL terminals.

What language is that ?

Which post/code are you referring to - there's Java, Ruby, APL and English so far.

Which post/code are you referring to - there's Java, Ruby, APL and English so far.

The code you posted 16 hours ago

Thats 100% pure standard Java SE.
It uses Streams, lambdas, and method references, all introduced with Java 8 in spring 2014.
Most Java courses are still waiting to be updated to relflect current Java, so your teacher may not be familiar with them.
Within the Java community the are considered to be very important extension to the original language.

It also uses the concept of a "fluent" API so you can chain calls together for greater readability. It's not a change to the language syntax, just a convention about how you define methods.

I can explain any of these in more detail if you're interested.
JC

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.