How do I convert an int to an array?

Hello friendly Julia community,

Suppose I have an integer. How do I convert this to an array?

Specifically, I have a counter inside a local namespace of a function, call it, counts, and when I println it, I get:

1
2
4

What I am interested is only the last value: here, 4.

I cannot use the [array][end] on it because counts is not an array yet. I tried the manual and online suggestions but no cigar.

Any suggestion will be highly appreciated.

Abdul Naaser

I am not sure that you need an array to get the last value of a counter, just return counter after the last iteration.

Converting an int to an array

julia> a = 4
4

julia> typeof(a)
Int64

julia> b = [4]
1-element Array{Int64,1}:
 4

julia> typeof(b)
Array{Int64,1}

julia> b = [a]
1-element Array{Int64,1}:
 4

julia> typeof(b)
Array{Int64,1}
1 Like

I do not quite understand your question either.
Below is a solution, although there are probably more elegant approaches
Of course, if you do not need the array, you should comment that code.

function myStuff(n)
    returnvalue=0
    counter=0 
    counterArray=Vector{Int}(undef,n)
    for i=1:n
        #do stuff
        counter = i^2 + counter
        counterArray[i]=counter
        println(counter)
        if i==n
            returnvalue=counter
        end
    end
    #return counterArray
    return returnvalue
end

last_value_of_counter=myStuff(8);
last_value_of_counter
1 Like

Thank you Fred! this is what I needed as well. It is good to see that Julia type-conversion is hassle-free.

Good day! As a thank you, I suggest this excellent book for you! (Body by Science, By Little).

Hi Bernhard!

Exactly what I needed. While you were writing the answer, I tinkered as well and came up with this:

function eultest(n)
    p1, p2 = 0, 0 
    counts = []
    for i in 1:n
        p1, p2 = rand(1:6, 6), rand(1:4, 9)
        if sum(p1) == sum(p2)
            counts = push!(counts, 0)
        elseif sum(p1)> sum(p2)
            counts = push!(counts, 1)
            end 
        end
    println(sum(counts))
    end 

eultest(9)

Although not as Julian as yours, I think I obviated the type conversion by initializing an empty array for counts, instead of simply counts= 0.

This code is for #205 Dice Game - Project Euler so I guess I still need to modify it since it does not look right.

Here is a more-Julian way to do this efficiently:

function eultest(n)
	count = 0
	trials = 0
	x = rand(1:4, 9)
	y = rand(1:6, 6)
	while trials < n
		p1 = sum( rand!(x, 1:4) ) 
		p2 = sum( rand!(y, 1:6) )
		p1 == p2 && continue     # A draw
		p1 > p2  && (count += 1)
		trials += 1  
	end 
	return count / n  # the Probability of p1 > p2
end 

@time eultest(10^7)
  1.301851 seconds (8 allocations: 480 bytes)
0.6166369
1 Like

Thank you Seif_Shebl!

Your code is fast. :slight_smile:

OTOH, the answer it produces is not close to the correct one. The correct answer that unlocked the Project Euler quiz 205 is:

0.5731441. 

My code gave:

0.5732308  

Which is correct to three decimal places…good enough for me, since the code itself is extremely readable and easy to write, although I must say, slower than yours. Your code gives:

0.6166369

Here is the answer and time for my code:

0.5733318
2.434311 seconds (21.62 M allocations: 2.710 GiB, 6.77% gc time)

So while it gives a correct answer to 3 decimal places (each time a slightly different answer), the speed and memory alloc could be improved… which I am going to borrow from your code. Thanks! :slight_smile:

@Seif_Shebl’s code does not count the draws, that’s why the answer comes out wrong. The phrasing of the problem itself on the Project Euler page was a bit unclear.

Here’s a version that gives you the right answer, and is ~2x as fast as @Seif_Shebl’s one. It avoids creating any arrays at all:

function eultest(n)
	count = 0
	for trials in 1:n
		p1 = sum(rand(1:4) for _ in 1:9)
		p2 = sum(rand(1:6) for _ in 1:6)
		count += (p1 > p2)
	end 
	return count / n
end

It uses a generator for creating the sums, so zero allocations. Also, you can avoid branches (if or &&) by realizing that you can do count += (p1 > p2). This works because n + false == n+0 while n + true = n+1.

In order to get the correct number of significant digits, you should probably have some convergence criterion, so that you can tell when to stop iterating. Have you given any thought to that?

6 Likes

If you want an accurate answer, then you have to loop over all possibilities of outcomes for Peter’s rolls and compare each one with all the possibilities of outcomes for Colin’s rolls. This way, you will get the exact required probability. The algorithm of using random numbers converges very slowly, that is why you don’t get a correct answer in a reasonable time.

This can be done as follows (you can shrink all loops into just one using Iterator but I’ll keep it simple and verbose here):

using Printf 
function dice()
	count = 0
	total = 0
	for p1 = 1:4, p2 = 1:4, p3 = 1:4, p4 = 1:4, p5 = 1:4, p6 = 1:4, p7 = 1:4, p8 = 1:4, p9 = 1:4
		for c1 = 1:6, c2 = 1:6, c3 = 1:6, c4 = 1:6, c5 = 1:6, c6 = 1:6
			count += p1+p2+p3+p4+p5+p6+p7+p8+p9 > c1+c2+c3+c4+c5+c6
			total += 1
		end
	end
	@printf("%.7f\n", count/total)    # 0.5731441
end

julia> dice()
0.5731441
3 Likes

Hi!

Thank you for the neat code! Yup I think the value slightly changes because of the very good random-number generator in Julia.

But to get the ‘classical’ probability value I think a slightly longer code, like counting all the proportions would always give the same value…but I think it does not justify writing triple the amount of code just to get the same value each time.

Even Project Euler got it wrong in that true probabilistic outcomes solved by programming languages are always empirical and subject to some variation in the decimals.

I ran your code on 1 billion iterations for a time of 105 seconds–not bad–but the value is still:

0.573153872

Still, it makes for an interesting exercise. I spent a better part of the day trying to see if I could use binomial expansion to count all the proportions, but I am newbie to both probability and Julia, so still investigating…(it is surprising how poorly-written most probability texts are).

The solutions posted by all other people on Project Euler–frankly–were not impressive. The code is not readable, and most of the solutions at least double and in most cases triple the amount of code I have. They also use C++/Java which I really dislike, and the Python ones were also quite a mess. (no wonder I am here on Julia discourse).

Best,

Hi Seif_Shebl,

Much impressed with this. I was looking for something like this the whole day yesterday.

Thank you very much! As a little gift, I recommend this excellent FREE book: “The Anatomy of Melancholy” by that great thinker, Robert Burton. :slight_smile:

Is it a restriction that you have to use nested loops? It is not apparent to me from the description of 205. In any case, I would just do

using IterTools

die_distribution(sides) = [i => 1//sides for i in 1:sides]

combine(f, A, B) = [f(a, b) => p * q for (a, p) in A for (b, q) in B]

function aggregate(A)
    [first(first(g)) => sum(last, g)
     for g in groupby(first, sort(A, by = first))]
end

function total_distribution(As)
    reduce((A, B) -> aggregate(combine(+, A, B)), As)
end

T4 = total_distribution(fill(die_distribution(4), 9)) # Pete
T6 = total_distribution(fill(die_distribution(6), 6)) # Colin
P_beats_C = sum(((a, p),) -> a * p, combine(>, T4, T6))

so that

julia> Float64(P_beats_C)
0.5731440767829801

If you are not allowed to use libraries, groupby is fairly easy to substitute. If you are not allowed to use rationals, then you can keep track of denominators using integers, I was just lazy.

3 Likes

Project Euler doesn’t generally impose restrictions, rather the problem itself imposes enough restrictions most of the time, like really long runtimes with bad code or with a bad model of the problem.

Thanks. In that case, I think that simply using the convolutions (like I did) is by far the fastest and most accurate.

I was just surprised that people used Monte Carlo and nested loops and thought they were the result of a restriction.