What is going on in this solution to the Fizzbuzz question? - fizzbuzz

for (let number = 0; number <= 100; number++ ) {
let output = ""
if (number % 3 == 0) output += "Fizz"
if (number % 5 == 0) output += "buzz"
console.log(output || number)
}
I understand why it finds the modulo for 3 and 5. But why does this also find the modulo for 15? (The question asks to also find the numbers that are divisible by 3 and 5 and print "Fizzbuzz").
I was able to solve the question in a different manner and was offered this as one of the ideal solutions.
Is the += after the output somehow multiplying the other two remainders?

If your question is about the use of +=, then it is a short form of writing output=output+"Fizz". Hence instead of writing the above one we can simply write output+="Fizz"

The answer to my question is that the program runs both checks independently. When it reaches 15 (or any other number divisible by both 3 and 5), it will simply add "Fizz" and "buzz" together to create "Fizzbuzz".

Related

Find the largest prime divisor of any predetermined number without using / (division) and % (remainder) in C [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 months ago.
Improve this question
I have some task:
You can use basic control structures–sequence, branch, loop, as well as addition, subtraction, and multiplication. You cannot use division: this module is designed to run on microcontrollers. Create an src/1948.c file which takes a number into stdin after compilation and launch, and calculates its largest prime divisor.
I can't figure out how this can be done without using devisor and reminder. Please help me to understand the issue.
By the Sieve of Eratosthenes
Suppose the predetermined integer is N.
Negate N if negative.
Store N as the 'highest prime divisor'.
Allocate an array with (N >> 1) + 1 elements and fill with 0.
Start with the first prime 2.
Check off every multiple of the prime in the array (with an addition loop).
Continue finding multiples right up to N.
If it hits N exactly, store this prime as the 'highest prime divisor'.
Find the next prime.
This will be the next unchecked element in the sieve - the array.
But if you've passed the end of the array then you are done.
Otherwise repeat as you did for the previous prime.
Of course you could just write a division function and then call that to do division.
Alternatively, you can write a square root function and use (a+b)(a-b) = a2 - b2. After removing the factors of 2, start with the smallest a >= sqrt(N), and then check every a2 - N to see if it's square.
A division function can be as easy as this:
// only works for num >= 0 and den>0
divide(num, den):
if (num < den):
return 0
q = divide(num, den*2) * 2
r = num - q*den
return r >= den ? q + 1 : q
Square root is just a little more complicated:
// only works for n >= 0
sqrt(n):
return sqrtScaled(n,1)
// return floor(sqrt(n)/scale). Must have n >= 0, scale > 0
sqrtScaled(n, scale):
if (n < scale*scale):
return 0
q = sqrtScaled(n, scale*2) * 2
test = (q+1)*scale
return test*test <= n ? q+1 : q

Is there a way to find the digit position in a recursion?

Backstory (not important to the question): I've got a question in one of my classes and I couldn't solve it for the past week, and I am just so stuck with it and trying to find a good solution for it, maybe it's just my limited thinking or being new to the whole recursion idea in general or new to learning the programming language we are working with (C language).
The problem: So our task is to build a "function" (I don't know the correct word for it) that for a given integer num:
if the digit is in an even index the digit in that spot has to be even.
if the digit is in an odd index the digit in that spot has to be odd.
indexes start from 0.
you can only use 1 parameter (num)
you need to return 1 if the conditions are met 0 otherwise (C language)
For example:
The number 343,418 will be a valid number because every digit in an odd index is odd and every digit in an even index is even.(the example + indexes)
The number 343,518 will be an invalid number because on the second index there is a number 5, even index odd number. (the example + indexes)
Any hints to a solution or a way to solve this will be greatly appreciated as I was trying to solve this for a while.
Here is a possible approach:
Since the one's (least significant) digit must be even, a valid number considered as a whole must also be even. So stop and return 0 if num % 2 != 0.
Get the ten's digit by tens = (num / 10) % 10, leveraging that integer division rounds down. If tens is zero, we are done validating the digits, so return 1 if tens == 0. Otherwise tens must be odd, so return 0 if tens % 2 == 0.
Now discard the bottom two digits with num /= 100 and go back to step 1.
The "go back to step 1" part could be done with a while loop or as a "tail call" if you want to express it recursively.
As suggested in the discussion in the comments, the idea here is to iterate over the digits and keep track of the index as you go, where in each step you compare the digit and index's evenness:
int compareDigitsToIndexes(int num) {
int ind = 0;
while (num > 0) {
int digit = num % 10;
if (ind % 2 != digit % 2) {
return 0;
}
num /= 10;
++ind;
}
return 1;
}

Algorithm to find number of palindromes in interval

I'm currently tasked with writing a program that calculates amount of palindromes in any base from interval of <2;36>. The problem is that my solution has time complexity of O(n^2) at best and that is, if I was frank, really slow.
So far I've tried naive solutions such as converting all numbers from the interval to the base that is required, saving the conversion of the number to array and then checking each of the elements one by one.
This is what I've got so far :
int isTrue = 1;
int arr[64];
while(n > 0)
{
arr[counter] = n % base;
n = n / base;
counter++;
}
for(int i = 0; i < counter; i ++)
{
if(arr[i] != arr[counter - i - 1])
{
isTrue = 0;
break;
}
}
It is not good by any stretch, but it does work for the basic test. The problem is that I'm currently trying to solve bonus one which works with much bigger numbers.
By much bigger numbers I mean intervals that span billions of numbers, one of the inputs is for example this:
c 15 62103360044 155888062462
Result : 123502
Where c is task that the program is supposed to do (there was option of l which listed all palindromes which doesn't occur in the bonus tests), 15 is base and the two other numbers are the limits of the interval.
I'm supposed to count palindromes of five such intervals under one second and honestly, I'm pretty stuck.
I would appreciate any help, I'm sorry if I formatted my question wrongly or if it was too drawn out - This is the first time I've asked a question here.
Doing a palindrome check faster is a minor optimisation.
Initially I would even use java's number to String conversion.
What you want is to step through the interval in larger leaps.
You can use recursion for simplification in the initial version of your algorithm.
Let's look for base 10:
62_103_360_044
155_888_062_462
6 ... 6 (recursion on the middle part)
7 ... 7
8 ... 8
9 ... 9
1 ... 1
You need:
Number of digits (your counter)
First most significant digit
Parameters start and end
For this step you only need to increment one digit, which even may be done as char.
Notice also that the recursive call on ... gives the same result for 7, 8 and 9 with start 000..000 and end 999..999.
This will be tremendously faster. Happy coding.
Usage of recursion:
I am not giving a clean answer, as that would defeat the task's challenge.
public BigInteger palindromesInInterval(int base, BigInteger from, BigInteger to) {
return palindromesRec(base, from.toString(base), to.toString(base));
}
private BigInteger palindromesRec(int base, String from, String to) {
// Do the simple work:
if (from.length() > to.length()) {
return BigInteger.ZERO;
}
if (from.length() == to.length() && from.compareTo(to) > 0) {
return BigInteger.ZERO;
}
if (from.length() == 1) {
...
}
// Do a step:
int highDigit = Integer.parseInt(from.substring(0, 1), base);
int lowDigit = Integer.parseInt(from.substring(from.length() - 1), base);
BigInteger sum = BigInteger.ZERO;
int digit = Math.max(highDigit, lowDigit);
String from2 = from.substring(1, from.length() - 2); // Can start with 0
String to2 = "1000...000" -1; // Niners so to say.
while (digit < base) {
...
sum = sum.add(palidromesRec(base, from2, to2)); // RECURSION
from2 = "000...000";
}
...
return sum;
}
Recursion calling oneself, here only once, without extra parameters, which often are used. For instance it is much easier to split the work in:
from 6 2_103_360_04 4
to 9 9 .. 9 9
from 1 00 .. 0 1
to 1 55_888_062_46 2
And calculate for every X
from X 000 X (n zeroes)
to X 999 X (n time (base-1))
as base(n+1)/2.
For that you need a level of abstraction/simplification. Keep-it-simple.

Interesting Powers Of 2 - algorithm/ Math (from Hackerrank ACM APC)

I came across a problem from a recent competition.
I was unable to figure out a solution, and no editorial for the question is yet available.
Question Link
I am quoting the problem statement here also in case the link doesn't work.
Find the number of integers n which are greater than or equal to A and less than or equal to B (A<= n <=B) and the decimal representation of 2^n ends in n.
Ex: 2^36 = 68719476736 which ends in “36”.
INPUT
The first line contains an integer T i.e. number of test cases. T lines follow, each containing two integers A and B.
Constraints
1 <= T <= 10^5
A<=B
A,B <= 10^150
OUTPUT
Print T lines each containing the answer to the corresponding testcase.
Sample Input
2
36 36
100 500
Sample Output
1
0
As often happens on programming competitions I have come up with an heuristics I have not proven, but seems plausible. I have written a short program to find the numbers up to 1000000 and they are:
36
736
8736
48736
948736
Thus my theory is the following - each consecutive number is suffixed with the previous one and only adds one digit. Hope this will set you on the right track for the problem. Note that if my assumption is right than you only need to find 150 numbers and finding each consecutive number requires checking 9 digits that may be added.
A general advice for similar problems - always try to find the first few numbers and think of some relation.
Also often it happens on a competition that you come up with a theory like the one I propose above, but have no time to prove it. You can't afford the time to prove it. Simply hope you are right and code.
EDIT: I believe I was able to prove my conjecture above(in fact I have missed some numbers -see end of the post). First let me point out that as v3ga states in a comment the algorithm above works up until 75353432948736 as no digit can be prepended to make the new number "interesting" as per the definition you give. However I completely missed another option - you may prepend some number of 0 and then add a non-zero digit.
I will now proof a lemma:
Lemma: if a1a2...an is an interesting number and n is more than 3, then a2...an also is interesting.
Proof:
2a1a2...an = 2a1*10n - 1*2a2a2...an
Now I will prove that 2a1*10n - 1*2a2a2...an is comparable to 2a2a2...an modulo 10n-1.
To do that lets prove that 2a1*10n - 1*2a2a2...an - 2a2a2...an is divisible by 10n-1.
2a1*10n - 1*2a2a2...an - 2a2a2...an =
2a2a2...an * (2a1*10n - 1 - 1)
a2a2...an is more than n-1 for the values we consider.
Thus all that's left to prove to have 10n-1 dividing the difference is that 5n-1 divides 2a1*10n - 1 - 1.
For this I will use Euler's theorem:
2phi(5n-1) = 1 (modulo 5n-1).
Now phi(5n-1) = 4*(5n-2) and for n >= 3 4*(5n-2) will divide a1*10n - 1(actually even solely 10n - 1).
Thus 2a1*10n - 1 gives remainder 1 modulo 5n-1 and so 5n-1 divides 2a1*10n - 1 - 1.
Consequently 10n-1 divides 2a2a2...an * (2a1*10n - 1 - 1) and so the last n - 1 digits of 2a1a2a2...an and 2a2a3a4...an are the same.
Now as a1a2a2...an is interesting the last n digits of 2a1a2a2...an are a1a2a2...an and so the last n-1 digits of 2a2a3a4...an are a2a3a4...an and consequently a2a3a4...an is also interesting. QED.
Use this lemma and you will be able to solve the problem. Please note that you may also prepend some zeros and then add a non-zero number.
In general, you can try solving these problems by finding some pattern in the output. Our team got this problem accepted at the contest. Our approach was to find a general pattern in the values that satisfy the criteria. If you print the first few such digits, then you will find the following pattern
36
736
8736
48736
948736
Thus the next number after 948736 should be of 7 digits and can be any one of 1948736, 2948736, 3948736, 4948736, 5948736, 6948736, 7948736, 8948736, 9948736. Thus check which value is valid and you have the next number. Continuing in this fashion you can back yourself to get all the 150 numbers.
But there is a problem here. There will be some numbers that do not immediately follow from the previous number by appending '1' to '9'. To counter this you can now start appending values from 10 to 99 and now check if there is a valid number or not. If there is still no valid number, then again try appending numbers from 100 to 999.
Now employing this hack, you will get all the 137 values that satisfy the criterion given in the question and easily answer all the queries. For example, working java code that implements this is shown here. It prints all the 137 values.
import java.io.*;
import java.math.*;
import java.util.*;
class Solution
{
public static void main(String[] args)throws java.lang.Exception{
new Solution().run();
}
void run()throws java.lang.Exception{
BigInteger[] powers = new BigInteger[152];
powers[0] = one;
for(int i=1; i<=150; i++){
powers[i] = powers[i-1].multiply(ten);
}
BigInteger[] answers = new BigInteger[152];
answers[2] = BigInteger.valueOf(36);
answers[3] = BigInteger.valueOf(736);
int last = 3;
for(int i=4; i<=150; i++){
int dif = i-last;
BigInteger start = ten.pow(dif-1);
BigInteger end = start.multiply(ten);
while(start.compareTo(end) < 0){
BigInteger newVal = powers[last].multiply(start);
newVal = newVal.add(answers[last]);
BigInteger modPow = pow(two, newVal, powers[i]);
if(modPow.equals(newVal)){
answers[i] = newVal;
System.out.println(answers[i]);
last = i;
break;
}
start = start.add(one);
}
}
}
BigInteger pow(BigInteger b, BigInteger e, BigInteger mod){
if(e.equals(zero)){
return one;
}
if(e.mod(two).equals(zero)){
BigInteger x = pow(b, e.divide(two), mod);
x = x.multiply(x).mod(mod);
return x;
}else{
BigInteger x = pow(b, e.divide(two), mod);
x = x.multiply(x).mod(mod);
x = x.multiply(two).mod(mod);
return x;
}
}
BigInteger ten = BigInteger.valueOf(10);
BigInteger zero = BigInteger.ZERO;
BigInteger one = BigInteger.ONE;
BigInteger two = BigInteger.valueOf(2);
}
This is very interesting property. During the contest, I found that 36 was the only number under 500 checking with python...
The property is : 2^36 last two digits are 36, last three digits are 736, so next number is 736. 2^736 has last three digits as 736, and next number is 8376...
And the series is : 36 , 736 , 8736 , 48736 , 948736 ...
And then started with BigInt class in C++.
But alas there was no time, and 4th problem wasn't solved. But after the contest, we did it in python.
here's link : Ideone it!
def powm(i):
j = 10
a = 1
while i:
if i % 2:
a = a * j
i /= 2
j *= j
return a
def power(n, i):
m = powm(i)
y = 1
x = 2
while n:
if n % 2 == 1:
y = y * x % m
x = x * x % m
n /= 2
return y
mylist = []
mylist.append(power(36, 2))
n = mylist[0]
print(n)
for i in range(3, 170):
p = power(n, i)
print p
if p != n:
mylist.append(p)
n = p
t = input()
while t:
x = raw_input().split(" ")
a = int(x[0])
b = int(x[1])
i = 0
#while i <= 150:
#print mylist[i]
#i += 1
#print power(8719476736,14)
while mylist[i] < a:
i += 1
ans = 0
while mylist[i] <= b:
i += 1
ans += 1
print ans
t -= 1
The final digits start to repeat after 20 increments. So for any n with the final digit 1, the final digit of the answer will be 2. So most values of n can be eliminated immediately.
2^1 = 2
2^21 = 2097152
2^101 = 2535301200456458802993406410752
2^2 = 4
2^22 = 4194304
2^42 = 4398046511104
In fact only two possibilities share a final digit:
2^14 = 16384
2^16 = 65536
2^34 = 17179869184
2^36 = 68719476736
If n is 14+20x or 16+20x, then it might work, so you'll need to check it. Otherwise, it cannot work.
I am not very good with such problems. But modular exponentiation appears to be key in your case.
Repeat for all n in the range A to B:
1. Find k, the no of digits in n. This can be done in O(logn)
2. Find 2^n (mod 10^k) using modular exponentiation and check if it is equal to n. This'll take O(n) time. (actually, O(n) multiplications)
EDIT
Actually, don't repeat the whole process for each n. Given 2^n (mod 10^k), we can find 2^(n+1) (mod 10^k) in constant time. Use this fact to speed it up further
EDIT - 2
This doesn't work for such large range.

How do I perform a duplicate check in code?

This might be a no-brainer to some, but I'm trying to check if there are any duplicate values in my code.
To be clearer, I am creating 5 variable Integers that randomizes a number once they are created. Let's say they're named i1, i2, i3, i4, i5.
I want to run a loop to check on each other to make sure they don't have any possible duplicates. If they do, I'll re-random the second Integer that's being checked. (e.g if (i1 == i4) { i4.rand(); }) That's to make sure i1 doesn't need to get re-checked against all the previously checked values or being stuck in a long loop until a different number is found.
This is what I'm thinking if it was an entire if else statement : if (i1 == i2), if (i1 == i3), if (i1 == i4), if (i1 == i5), if (i2 == i3), if (i2 == i4), if (i2 == i5), if (i3 == i4), if (i3 == i5), if (i4 == i5)
I know I can probably do it "manually" by creating lots of if / else statements, but is there a better way to do it? It probably isn't very feasible if I increase my Integer limit to 20 and I have to if / else my way through 20 value checks. I know there is, but I just can't remember. Search on Google is turning up nothing (maybe I'm searching for the wrong keywords), which is why I'm asking over here at StackOverflow.
All I want to know is how do I do it, theory-wise (how would you check for duplicates in theory?). The answer doesn't necessarily need to be a workable function.
If you want to create a demo code using the programming language I'm using for this problem, itsExcel VBA. But I think this information would be able to apply theory-wise to a lot of other programming languages, so feel free to write in javascript/jQuery, C++, C#, etc. Just remember to comment!
You are looking for Set;
Set<Integer> hs = new HashSet<Integer>();
hs.add(i1);
if(!hs.add(i2)){
randomize(i2);
}
Hope this helps. Let me know, if you have any questions.
The above is just a concept of what to do.
To get the logic for your code, it will be
Set<Integer> hs = new HashSet<Integer>();
for(int count=0; count<Array.length; count++){ // Store the data into the array and loop
dataToInsert = Array[count];
while(hs.add(dataToInsert)){
dataToInsert = randomize(dataToInsert);
}
}
Here is a simple way to get your integers assuming you want to generate them in the range from 1 to N
Generate an integer from 1:N
Generate an integer from 1:N-1
Generate an integer from 1:N-2
Generate an integer from 1:N-(k-1)
Now interpret these as the position of the integer that you generated (in the set of total available integers for that number) and construct your real integer.
Example, N = 5, k=4
3
1
2
2
i1 = 3
i2 = 1
i3 = 4 (the available integers are 2 4 5)
i4 = 5
Note that this requires the minimum amount of random number generations.
To be clear, what you are attempting is the wrong approach. Theoretically, checking for duplicates and "re-randomizing" when one is found, could execute for an infinitely long time because existing integers could continuously be chosen.
What you should be doing is constructing the collection of integers in such a way that there will be no duplicates in the first place. Dennis Jaheruddin's answer does this. Alternatively, if you have a specific set of integers to choose from (like 1-20), and you simply want them in a random order, you should use a shuffling algorithm. In any event, you should start by searching for existing implementations of these in your language, since it has almost certainly been done before.
What you could do is loop over the List<int> and, for each element x at index i, loop while list.Take(i-1).Contains(x) and replace x with a new random number.
If you simply wanted a relatively inexpensive check that a given List<int> is full of unique numbers, however, you could do something like:
bool areAllUnique = list.Count() != list.Distinct().Count()`
2 ways I can think of.
1: Looping over all the values in your set and comparing each one to what you're adding.
2: Creating a simplistic version of a hash map:
var set
var map_size
create_set(n):
set <- array of size n of empty lists
map_size <- n
add_number(num_to_add):
if num_to_add not in set[num_to_add % map_size]:
add num_to_add to set[num_to_add % map_size]
return success
else:
return failure
populate_set():
loop 5 times:
i <- random_number()
while(add_number(i) == failure):
i <- random_number()
This way, each time you add a number, instead of checking against every other number in your set, you're only checking against at most [max value of integer] / [map size] values. And on average [number of elements in set] / [map size] (I think, correct me if I'm wrong) values.
Try
ArrayList<Integer> list = new ArrayList<Integer>();
while (list.size() < 5)
{
int i = Math.random() * max;
if (!list.contains(i))
{
list.add(i);
}
}
and you'll got in list 5 different Integers.
Pseudo-code:
Create an empty set S.
Generate a pseudo-random number r.
If r is in S, go to 2. Else, go to 4.
Add R to S.
If there are still variables to initialize, go to 2.
Exemplary implementation in Java:
public static void main(String[] args)
{
System.out.println(getUniqueRandoms(5, 10));
}
public static Set<Integer> getUniqueRandoms(int howMany, int max)
{
final Set<Integer> uniqueRandoms = new HashSet<Integer>(howMany);
while (uniqueRandoms.size() < howMany)
{
uniqueRandoms.add((int) (Math.random() * max));
}
return uniqueRandoms;
}
Output:
[8, 2, 5, 6, 7]
If you would like to have them in array, not in Set, just call toArray() on your Set.
In R is pretty simple...
i <- as.integer(runif(5, 1, 10))
for(l in seq_along(i)){
while(any(i[l]==i[-l])) # checks each against all the other
i[l] <- as.integer(runif(1, 1, 10))
}
However in R there is the function sample that picks random elements from a given vector without duplicates ( even though you can choose to have them)
> sample(1:10, 5)
[1] 2 5 1 9 6
> sample(1:10, 5)
[1] 3 5 8 2 1
> sample(1:10, 5)
[1] 8 3 5 9 4
> sample(1:10, 5)
[1] 1 8 9 10 5
HashSet<Integer> set = new HashSet<Integer>();
for(int i = 0; i < 5; i++)
{
int x;
do
{
x = random();
}
while(!set.Add(x));
}
int i1 = set.ElementAt(0),
i2 = set.ElementAt(1),
i3 = set.ElementAt(2),
i4 = set.ElementAt(3),
i5 = set.ElementAt(4);

Resources