Total Pageviews

Tuesday, January 5, 2021

Project Euler - Rust Problem 5

Problem 5

2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.


What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?


This is an interesting problem.  There's a few things we can tell about the answer.

All numbers are evenly divisibly by 1. If it's divisible by 2 that means it's even.  If it's divisible by 20, then it's evenly divisible by 10 and 5.  

Our range is 2520..?

The most obvious direction would be to start at 2520, divide by all the digits with a Boolean trigger, if false then add 20 and do it again.

There prob is an easier way but this is what I went with.

Set up the loop.  I went with a while loop. I started 20 less than the starting number because if I put the increment after the bool test it will add 20 then evaluate the break criteria and the answer would be 20 more than the correct answer.  

I considered a for loop and if it had been c++ I would have but I don't know that you can set up the for loop any other way than x in range and I don't know the range... While for indefinite loop, for for definite, am I right? 


fn main() {

    let mut found: bool = false;

    let mut cur_num: i32 = 2500;

    while found == false{

    cur_num += 20;

    found = div_cur(cur_num);

    }

    println!("{}", cur_num);

}


That's the main function done.  I figure the actual calculation I can source out to a function for recursion.


fn div_cur(x:i32) -> bool{

let mut trigger = false;

let mut s_num = 20;


while s_num > 0{

trigger = even_div(x, s_num);

if trigger == false{

return false

}

s_num -= 1;

}

trigger

}

I considered putting some of this logic in the main while loop, and I could have but I opted to keep the math logic separate. I figured I could avoid a lot of nasty if then statements.

So this function takes in a number and returns a bool.  Default return value is false.  I started with 20 as a counter and am counting down.  I figured that it would be quicker to divide by 20, 19, 18 than 1, 2, 3 since if it would error out it's more likely to error out on the higher divisors in range.

we check the even divide and if false there's not reason to continue.  If it isn't then we're continuing the loop and so we increment. If all 20 in the divisor range return divisible it returns true.


fn even_div(x: i32, y: i32) -> bool{

return x % y == 0

}


This is function that gets called every time we want to test the division. Takes two numbers, the test number and the divisor and then returns true if it's evenly divisible and false if not.

Pretty straight forward.

Let's look at the other guys code.

Other Guy's Code

Weflown had a... different approach.

fn main() {

    let mut n: u128 = 4000000;

    while (n % 2) != 0 || (n % 3) != 0 || (n % 4) != 0 || (n % 5) != 0 || (n % 6) != 0 || (n % 7) != 0 || (n % 8) != 0 || (n % 9) != 0 || (n % 10) != 0 || (n % 11) != 0 || (n % 12) != 0 || (n % 13) != 0 || (n % 14) != 0 || (n % 15) != 0 || (n % 16) != 0 || (n % 17) != 0 || (n % 18) != 0 || (n % 19) != 0 || (n % 20) != 0 {

        n = n + 1;

    }

    println!("{}", n)

}

I'm not sure where he got the 4 million starting point but that's certainly a way to do it.

According to him, "this is the worst way to do this but I don't care"

This was the only other rust response.

Sunday, January 3, 2021

Project Euler - Rust Problem 4

Project Euler

Problem 4 - in Rust

A palindromic number reads the same both ways. 

The largest palindrome made from the product 

of two 2-digit numbers is 9009 = 91 × 99. 

 

Find the largest palindrome made from the 

product of two 3-digit numbers.

Fun times.  Love palindromes.  Taco Cat... anyone? :)

What isn't fun? Strings in Rust.

They are the bane of my existence in programing with Rust. I don't know why they're so hard to mess with but they are.  So we can approach this just straight numbers or ... we can convert them to strings and compare...

Numbers. for sure.

Breakdown

I'm starting to get into a groove with analyzing these problems and my approach. I realize my approach might be complete crap but it works and it's mine so :P.

Seriously thought, first rule of fight clu... of answering these things.  <whistles innocently> First thing is breaking it down into managable pieces. 

So, what is it asking?

Find - we're looking for something
the largest - biggest number (quantifier)
Palindrome - something the same forward and backwards.
made from the product of 2 (3) digit numbers -... ok

so we're taking two 3 digit numbers, I assume they are both different, and we are multiplying them together.  If the answer is a palindrome and there's no other palindrome answer above it, then that's the answer...

Sure.

So what's the first question?

Can we narrow down the pool of numbers we're using? Get a range?

We can take the two smallest 3 digit numbers and multiply those for the low.  Then take the two largest 3 digit number and multiply those for the high.

100 * 101 = 10,100   This is not a palindrome but it is the lowest product of two 3 digit numbers.

999 * 998 = 997,002 this is also not a palindrome but is the highest product of two 3 digit numbers.

Now we have a range. [10,100..997,002].  The number we seek is in there.

so if we use the variable ans then the following is true:

10100 < ans < 997002

This gives us the starting point. 986902 different possibilities for a product

Recognize 

As the great Warren G once said, Recognize.  That's what we have to teach the computer to do. 

If we have a number, say 4516.  We can mod by 10 and get 6.  if we take the number and divide by 10, we get 451.6 (rounded down, aka flat) 451.  mod 10 = 1, divide by 10 = 45, mod 10 = 5, ... and if we add these mod's to a vec we now have the reverse value divided by each digit and in reverse order.

Also, if you have an even numbered value with a zero in the one's place, it will never by a palendrom.  143580 reversed is 085341.  The computer will drop the 0 and honestly, it would never add a leading 0 in the first place.  So this can be the first step in the logic of determining if it's a palendrome.

psuedo code

for loop - 

num = a*b

If num % 10 == 0 {

continue

}

function call to pal_check(num)


We will save a lot of time skipping over the values evenly divisible by 10.

pal_check function - pseduo code

pass in the value we're checking
declare two Vec's, one for forwards, one for back
for loop - break apart the number and add it to the array, one push and one insert to 0
then return true if both vecs match
else return false

rinse repeat

Saturday, January 2, 2021

Project Euler - Rust Problem 3

 Project Euler

Problem 3

The prime factors of 13195 are 5, 7, 13 and 29.

What is the largest prime factor of the number 600851475143 ?


Ok...  this is basically a question asking two questions.

First Question

What are all the factors of a given number?

I realize that it's asking specifically about 600,851,475,143.  However, when looking at these problems, it's best to start with the abstract and assume that at any given time, you'll be given a different input.  The reason for this is sometimes you will.  Not to mention it's great to approach it this way, allows you to get used to thinking in ways that takes the unknown into account.

So, how do we find the factors of a given number? And before we start, what is a factor?

A factor is defined as...

any number that can be multiplied by another to get the original number.  

For instance, factors of 4 are 1,2,4.  1*4 = 4, 2*2 = 4.  We won't deal with the negative numbers and fractions are never a factor.

So how do we find these numbers?

The brute force method is to loop through all the numbers 1 to the given number and divide the given number by them. If they divide evenly, they are a factor.  Add those to a Vec.  Test them all to filter out all the prime ones and return the largest. 

You could also loop through, divide evenly, test if prime, add prime to the vec and take the largest.

This is a perfectly valid and extremely long way to do this.

NOTE: Prime numbers are numbers that are evenly divisible by 1 and themselves and that is it.

another way would be to loop through the numbers 1 to N and test if they're prime first and then see if they're a factor.  You could also take a list of known prime numbers and start there.

Determining a prime number is first asking is it odd? Even number can't, by definition be prime outside of the number 2.  So you're Even? You're out... (sad face).  So it's odd.  Now start dividing that number by all numbers less than half of that number rounded down.  If you get an evenly dividable number (aka N%x == 0) then it's not prime.


How many factors does the number have?

In the process of finding all the prime numbers. We can locate the number of factors, which could help.
Using the following formulas.

Take the given number and the first 3 prime factors and the number of them as powers

N = Xa × Yb × Zc



40 would be 40 = 2 * 20.  20 isn't prime so we factor that further. 40 = 2 * (10 * 2). 10 isn't prime. 40 = 2 * 2 * 2 * 5. or N = 2^3 * 5^1 * 1^1

Total number of factors can be calculated using

N = (a+1)(b+1)(c+1)  

In the case of 40 there are 4 factors. 3+1*1+1*1+1
4*2*2 = 16... well not quite

we remove the factor of c because of the 1 to the 1st power.  but that leaves 8. we can see that there are only 4 elements.  Three of the 2 and one 5. 

well, we're forgetting the negatives.  So you divide by 2. That leaves 4 factors which is what we have.

Irrelevant 


Now this is great info to have.  However, it doesn't help us here.  I will tell you that the given number here has 4 prime factors.  That means it comes out to 1+1 * 1+1 * 1+1 or 8 then divide by 2 for the negative numbers.  That number was specifically picked as it has only 4 factors and all of them are prime.  This method could be used to check the answer to make sure that all cases have been found.  However, the first prime in this case is the 20th prime number 71.  So this strategy for this problem doesn't really help us.


So how will we approach this?

NOTE: I did find after I solved this that some people use a math principal called the Sieve of Eratosthenes   I was unaware this existed but it's an interesting read.

Rust has a crate for that.

primes

once we use the crate, we can then iterate through all the prime factors of a number.

use primes;

fn main() { 
     println!("{:?}", primes::factors(600851475143)); 
}

Boom. We have a return with 4 values.

we can even make a function to accept any value.


use primes;

fn main(){
pr_fac(600851475143)
}

fn pr_fac(x: u64){
println!("{:?}", primes::factors(x));
}

That works. 

We can go on.  Basically, what I learned from this is you don't have to reinvent the wheel.  We all have built on the people before us.  We extend their work.  While I can certainly make a brute force function that finds all the primes and loops through and ... Yeah that's how I approached it with python.

Nope, there's an app for that, there's a crate for that.  That isn't to say this is the best way.  I realize, it's kind of cheap and a little lazy.  Shrug.


EDIT: Btw if you just want the largest change the following

println!("{:?}", primes::factors(x));

to...

println!("{:?}", primes::factors(x).pop());

will return the last value in the Vec

Second EDIT: it comes after EDIT but before third edits...

so I forgot to look through and go over the answers in Rust that were posted before.

Most of them are as I described the brute force approach above.  They work just fine and there's no issue.  I also didn't time mine cause rust playground isn't fun and I know I could do it on my computer but I like there's as a common benchmark among all the answers on here. so... yeah

Other Users Responses


User davxy submitted this yesterday 1/2/21


const NUM: u64 = 600851475143;

fn main() {
    let mut val = NUM;

    // Fast div by two
    while val & 1 == 0 {
        val >>= 1;
    }

    let mut i = 3;
    while val != 1 {
        if val % i == 0 {
            val /= i;
        } else {
            i += 2;
        }
    }
    println!("{}", i);
}

NOTE: Writing this after evaluating this code. davxy knows a thing or two... just saying.

Not sure what's going on here at a glance. I'll start at the top.

He declares the constant NUM as the number in question. He then assigns the value of the constant to a variable he's made mutable. 

Next he "fast divide by two" --


while val & 1 == 0 do this thing... val >>=1

So I looked up val >>= 1 and it references variable >>= expression right-shift and assignment.

I've never seen this before.  According to stack overflow, left shift by 1 is equal to multiplying by base 2.  Right shift by 1 is equal to dividing by base 2.  So val >>= 1 is the same as val = val >> 1 which is the same as val / (2^1).   

the example they give is pretty neat. Basically, you take the binary value of a number say 16.  16 in binary is 10000.  or 1 in the 16th's place.  if you shift it to the right (divide) you pull it down to 1000 or 1 in the 8th's place.  You've divided it by 2.  That's what's going on here.  I didn't even know that was an option. That's awesome.

Back to the val & 1 == 0 thing.  It says it could be a few things but in this context looks like a bitwise AND.  Under bitwise opporators, it explains it as it performs a boolean and operation on each of the arguments.  So a & b will resolve true/false and then... operation? and then that is evaluated again against 0 which resolves to another boolean.

According to the wiki on bitwise opps, the & bitwise compares both equal length numbers in biary and compares the corresponding values to each other.

    0101 (decimal 5)
AND 0011 (decimal 3)
  = 0001 (decimal 1)

Each bit is multiplied together.  in this case 0 and 0 in the 8th's place resolve to 0.  the 1 (in decimal 5) multiplies by the 0 (in decimal 3), both in the 4's place, resolving to 0.  The 0 (in decimal 5) multiplies by 1 (in decimal 3), in the 2's place, resolving to 0.  Finally, the 1's (in both decimal 5 and 3) in the one's place resolve to 1.  So the bitwise AND value of 5 and 3 is 1.

Bring that back to our current discussion.

val & 1 == 0

val in binary is 
1000101111100101100010011110101011000111  ... and the binary value of 1 at equal length is 
000000000000000000000000000000000000001

So what this is saying is that while val & 1, in binary form, resolve the bitwise and function and resolve to 0, move the bits over to the right by 1, effectively dividing the whole number by 2.


This is interesting that he did this because it means he added it knowing that it needed to be a first step logically even though the given number resolves to 1 and never runs the while.

 The rest of this runs off the principal of the odd numbers can only be prime after 2. 

So there's a variable i that = 3.  if the val does not equal 1 then evaluate the bool for val divided by i has no remainder.  if it does then divide val by i.  if not then add 2 to i and repeat.  once you've reduced val to 1, you know have an i value equal to the largest prime number that is a factor of the given number.

Friday, January 1, 2021

Project Euler - Rust Problem 2

 https://projecteuler.net/problem=2

Problem 2


Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:

1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.


Fibonacci sequences have always given me trouble.

The basic idea is that you are dealing with 3 terms at a time.

to start = 0,1,1

the first term 0 plus the second term 1 is equal to the third term 1.  Then we can move those along.  

If a is equal to the first term, b is equal to the second term, c is equal to the third term.  Now we have variables with names.

So we let mut a = 0;

let mut b = 1;

let mut c = 1;


To move through the terms, we need a loop of some kind.  We could use a for loop if we knew how many terms we would go through.  Since this isn't known, we ditch the for loop.  

Since the problem is giving us an upper limit, a while or do until loop would work great.  There is no do until loop in rust.  That leaves the while loop.

While c (the furthest term) is less than 4 million, do this code.

Here we can implement the basic logic needed to run through the Fibonacci sequence. I'm just glad that I don't have to store the values then go through them.  That would make this a bit more complex.

Loop

In the loop, we can just set a equal to b, b equal to c, and then c equal to a + b.  

This logic only goes through the sequence until c is greater than the upper limit.  


But that doesn't do anything.

Sum will still = 0.


We have to add c to the sum value.  But not every time.  only IF it's even, aka evenly divisible by 2.

So we add the if c % 2== 0{ sum += c;} logic and now all is right with the world.

 

fn main() {


    let mut sum: i32 = 0;

    let mut a: i32 = 0;

    let mut b: i32 = 1;

    let mut c: i32 = 1;

    

    while c < 4000000{

        a = b;

        b = c;

        c = a + b;

        if c %2 == 0{

            sum += c;

        }

        

    } 

    println!("{}", sum);

}

run time 1.05 seconds.


I would compare the other answers but honestly there's only one other rust answer it is very long and a bit complicated for reasons... I don't really understand.  I also couldn't get it to run in the playground.

I'm sure there are other ways to approach this.  I'm sure this isn't the greatest way to handle this.  We'll see, the more I learn.

Project Euler - Rust Problem 1

https://projecteuler.net/problem=1

 Project Euler is a site with challenges that people solve with programs and then submit that code to be commented on.  Normally, there's not a lot of comments unless you have a unique approach.  That's fine.

I've solved many of them in python but I'm going to go through them with Rust.

Problem 1

If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.

Find the sum of all the multiples of 3 or 5 below 1000.


The problem is asking that we find all of the natural numbers that are below 1000 that are multiples of 3 or 5. When we find them, add them together and then give the sum.


Natural Numbers are integers that are positive. So any whole number below 1000.


first we have to go through all those numbers.

for n in 0..1000 {}

A for loop will do the trick just fine.  0..1000 runs through all the numbers up to but not including 1000.  I could start at 3 instead of 0, 3..1000.  That would be fine as well since I know that 0, 1, and 2 aren't multiples of 3 or 5.

In the loop, we need to determine if the number (n) is divisible by 3 or 5.  One at a time, we can use simple if and else if statements.

if n%3 == 0{}

else if n%5 == 0{}


n % 3 == 0  

If we take n, the given number as we loop through, and divide it by 3, will it do so evenly or will there be a remainder?  If there's no remainder, we get 0.  The % used here will give us this answer.  The statement n%3 == 0 will result in a true or false.

The same is true of the else if statement.

Great! We have the logic for going through every number, 0 to 1000 and then figuring out if it's a multiple of 3 or 5.

We don't need an else statement.  If the given number (n) is not divisible by 3 or 5, then we will do nothing with it and can continue on.

Lastly, we need something to hold the sum of the values as we go through.

let mut sum: i32 = 0;

The variable sum is declared as mutable as we will need to change the value every time we find a multiple.

Finally, we need some way to see what the final value is.  We'll use the print to console macro for this.


The final code might look like this.


let mut sum: i32 = 0;

for n in 0..1000{

    if n%3 == 0{

        sum += n;

    }

    else if n%5 == 0{

        sum += n;

    }

}


println!("{}", sum);

 

Now I freely admit that this is not an inspired solution.  It doesn't take into account any kind of performance.  It's pretty brute force as it is but it's a beginner problem to highlight beginner problems in code.

This solution comes in at 1.29 seconds.

A more elegant approach


my friend showed me a way to make this a little more compact.


    let x = (0..1000).collect::<Vec<i32>>();

    let x: i32 = x.iter().filter(|&n| n%3 == 0 || n%5 == 0).sum();

    dbg!(x);


First, he declared a variable x as a vector collecting all the values from 0 to 1000.

Then he declared x as a number using shadowing.  Shadowing is convenient because it allows you to not only change the value of a variable but the type.  You're basically forcing the variable x as it exists to leave scope and release it's name and then assign it's name to a new value.  In this case, he used shadowing to iterate (iter()) through all the values in the vector and then filter out only the values that are divisble by 3 and 5 evenly.  Finally we added them altogether.

He did this in one line using what's called a Closure.  It's similar to a lambda in python.  
https://doc.rust-lang.org/rust-by-example/fn/closures.html

The dbg! macro is a debug macro that prints things to the console.  The rust documentation recommends that using this feature not be used, recommending the debug! macro from the log crate.  However, this is not a final release of a program and is simply a learning tool.

The logic is very elegant and works just the same as my code but it is smaller.  On Rust Playground it ran in 0.91 seconds versus the 1.3 seconds that my original code did.  It's not surprising really.  



Other solutions from other users -

Another user (forrin ) using Rust, posted this solution.

fn main() { println!("Result: {}", basic_solution(999)); } fn basic_solution(target: i32) -> i32 { let mut sum = 0; for n in 1..=target { if n % 3 == 0 || n % 5 == 0 { sum+= n; } } return sum; }

This solution is fine. It does basically what mine does except he isolated it into a function and filtered out the if/else if to a if this or that.

Runs 1.25seconds on Rust playground.


Another solution, similar to my friend's.

fn main() {

    let bound : i32 = 1000;

    println!("out {}", (1..bound).filter(|&n| n % 3 == 0 || n % 5 == 0).sum::<i32>().to_string())

}

This one filters the same but does all in the same line.  While I do like this solution and it runs at a 0.89 seconds on rust playground, it's hard to read and hard to understand at a glance what is going on.


Finally, another user (DMDM2 ) posted this solution, similar to my original answer.
let mut sum = 0; for x in 0..1000 { if (x % 3 == 0) | (x % 5 == 0) { sum += x; } } println!("Sum is: {}", sum);

This answer runs at 1.03 seconds. Faster than above, I assumed it's because the above user called another function.  However, if you remove the function call and put everything in the main scope, it still runs at 1.39, slower than above and slower than here.

let's compare the two answers from forrin and DMDM2 side by side.
Overall time is 1.25 seconds (forrin)  versus  1.03 seconds (DMDM2)


Before I continue, I'm not trying to call either of them out.  My solution for this wasn't exactly inspired.  I'm simply trying to delve into the workings of our answers and account for the performance differences.



We've already discussed that removing the function call actually makes it slower.
So let's compare the logic after the function call.

let mut sum = 0;

That's the same.  We all have to have a container to put the answer.

for n in 1..=target  vs for x in 0..1000

If we run 0..=999 on the right, we actually add some time on.  This makes sense, given that instead of stopping at a limit, we're evaluating if the number is = to 999 and only stopping after that.  

other than the left side looking for a variable and then referencing that value every time it evaluates (if it is running how I think it is and correct me if I'm wrong), the for loop is the same.

Once the for loop is concluded, the function on the left then passes the value back to the main function and prints it.  The one on the right just prints the variable.

I'm going to assume that the extra step of passing through a function call makes up some of that time.  I would love to know exactly what the differences here are.  Let me know if you have any thoughts about this below.  

Thursday, December 31, 2020

2021 and Programing

 I've decided to document this years progress through coding.

A friend of mine has been on me to learn Rust.  I've been reluctant for a variety of reasons.  I've committed to coding this year in nothing but Rust.

We'll see where it gets me.

Monday, March 11, 2019

has it been 3 months?


I wanted to share this information with a fellow reddit user but I feel like anyone could benefit form the information here.  Hope it helps someone.

I do not mean for this to be bragy, preachy, or long-winded. I'm sure it's all of those things.

If you are a beginner looking for advice but want to skip the drivel of my experience, skip to the bottom, there's some solid links for problems for beginners.

#################################################
#Project Euler experience
################################################

I was working on a project euler problem this morning, #19.

#################
Counting Sundays

Problem 19
You are given the following information, but you may prefer to do some research for yourself.

1 Jan 1900 was a Monday.
Thirty days has September,
April, June and November.
All the rest have thirty-one,
Saving February alone,
Which has twenty-eight, rain or shine.
And on leap years, twenty-nine.
A leap year occurs on any year evenly divisible by 4, but not on a century unless it is divisible by 400.
How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)?
#######################


I tried a few different approaches and I couldn't get it. I don't know exactly where my code went wrong yet but that's ok. I used a blog post to answer it. I know cheating right? except my project euler score isn't a bragging position for me, it's there for me to learn.  There are some I have solved honestly and with my own effort. I post my solutions if I solve them this way.  If I look them up I don't post.  I do give it an honest effort, trying my own code, looking up, researching different possible approaches or how to do certain things with code.  Sometimes, I just can't get it.  This was one I was scratching my head.

Once it's solved, you can look at other people's posted solutions.

I love python and C++.  So I look at both of those languages solutions but for the moment, I'll just discuss the differences in the python solutions.

Here is one solution I saw that was almost identical to mine.  That happens sometimes, similar approaches to the same problem.

 
    months = {1: 31, 2: 28, 3: 31, 4: 30, 5: 31, 6:30, 7: 31, 8: 31, 9: 30, 10: 31, 11: 30, 12: 31}
 
    year = 1900
    month = 1
    day = 7
    sundays = 0
    while year <= 2000:
        if year % 4 == 0:
            if year % 100 == 0 and year % 400 == 0:
                   months[2] = 29
            else:
                pass
            months[2] = 29
 
        else:
            months[2] = 28
 
        if month > 12:
            month = 1
            year += 1
 
        if day > months[month]:
            day = day - months[month]
            month += 1
            if day == 1 and 1901 <= year <= 2000:
                sundays += 1
        day += 7
 
    print(sundays)
 
Now, I plugged this into the python ide and it worked. Spit out the correct answer and is almost exactly how my code was setup.  I messed up with the calculation of leap years which is about what I figured.  This solution is brute_force straight forward, non pythonic, not elegant at all.

And more importantly, this taught me almost nothing because that's how I was approaching the problem in the first place.

Here's a far more pythonic/elegant approach to the problem and one I would never have dreamed of.


    from datetime import *
             
    print(len([1 for y in range(1901,2001) for m in range(1,13) if date(y,m,1).weekday()==6]))

ok so here is a solution I can learn from

They imported the date and time module.  They are looking to print the length of the list produced from the function.  The function says for each year in range of 1901 and 2001 while each month jan to dec (1 to 13) ###13 is used due to how the list is iterated through using the date/time module, ### if the date of any particular year/month being the 1st of that month is equal to the weekday 6... So if the 1st is a sunday, it adds it to the list.  finally it prints the length of the list because the question is how many sundays hit the first of the month during the time period of jan 1, 1901 to dec 31, 2000.

date.weekday()
Return the day of the week as an integer, where Monday is 0 and Sunday is 6. For example, date(2002, 12, 4).weekday() == 2, a Wednesday. See also isoweekday().

The documentation shows this to be solid, ran it through the ide, works perfect.

Now, does this mean I'll be an expert in pushing these problems to a one line solution (I don't count the imported library)? No, not at all, but it exposes me to other approaches that I hadn't considered.  Seeing how other people tackle real problems, even if you don't know the math behind it, can give you insight into how the language can be handled and ultimately helps you grow.

#######################
#A bit of history and the future
########################

I've been teaching myself how to code in python since Jan 2019.  So about 3 months.  I've been working on coding since 2017, Halloween.  I started with Ruby.  I moved on to C++. I got incredibly frustrated, like you because it wasn't clicking and memory management is a real thing in c++.

I got no where with Ruby/C++/ or Python at first because all I learned was some serious basics that are common between all the tutorials and I had taken them just about all the free ones.

Var types, var declaration, int manipulation, lists, dictionaries, pointers, class declarations, getters, setters, the basic terms that every programming language has but the syntax is slightly different.

I said ok, what do I want to learn, end goal? I made that decision. While games are not my end goal, I started going about learning how to code games.  The game part isn't what's important.  The important thing is I started building programs(projects) that were more than just solve this single problem.  I created my own problems, sometimes without knowing it and I had to find my own solution.  Granted my code looks like crap, I'm sure.  What of it works, does work and the rest does not.  I'm ok with that.  I'm learning, and the progress I've made in such a short time is immense.

You know what, there are things I don't have to think about when constructing a project, I can look and see the progression.  And those small things I don't have to think about, that come naturally now, help me make room to tackle the things I have no idea how to solve.  It lightens the load.  That's what you need to push for.

No matter what the project, get to a point where some of the things are done from muscle memory, get a good IDE, i recommend pycharm or sublime text (although it has annoying winrar type payment reminders, still good).  Work on projects.  I'll include some links to suggested beginner projects.  Even if you don't know the first thing about doing them. Think about (psudo code) how you would logically go about doing it. Break it down.  Ok first I would have a variable for this string or number.  Then I would have to do this to it.  I don't know how to do that.  I'm looking up how to do just that one thing.  Then next step.

if you break it down into smaller problems, it's much easier to tackle and you'll be surprised how much you learn.

#####################
#Not bragging, simply excited
####################


I started entering game jams.  These are timed events with lots of other coding/game creation enthusiasts.  It gives you a format/restrictions or boundaries to work in both theme, time, etc.  You go at it and see what comes of it.  They vary on these things as well as the time allotted.  The ones here are 3/4 day weekend jams.

here is my first game jam entry:

alakajam 5
https://youtu.be/DC0ZdK3I20s
https://github.com/psychicash/alakajam5


extra credit jam(second jam):
half way through
https://www.youtube.com/watch?v=ytva4MjX3P0
end of the jam
https://www.youtube.com/watch?v=1cWHGfxdW18
https://github.com/psychicash/lottery

Now I am not saying this to brag on myself, hell I didn't even finish either of the games.  The first one, all I had was a parallax background and an intro sequence, that's it.  3 days of disorganized coding and I found myself... more than floundering.  All original art btw. (everyone could tell) And sounds. (no one doubts this) That takes up time to be sure. But even after the game jam was over, the project is so... disjointed in my head, I have to scrap it and start over.

Second jam, much more organized, 3rd party art, sound, no title, no intro, but lots of game play, mechanics and though I did not get it finished, I learned so much.  There's a polish to the progression that though still rough, is there. I'm telling you man, doing projects and pushing your boundaries is the way to go.

I succeeded with both the jams because I learned so much.

Thomas Edison was once asked how he could continue with his light bulb project after failing over 10,000 times.  He replied, "I didn't fail. I just found 10,000 ways that didn't work."

He also is quoted as saying, “Negative results are just what I want. They’re just as valuable to me as positive results. I can never find the thing that does the job best until I find the ones that don’t.”

Do not get discouraged.

################################
Beginner Links
################################

If you don't want to tackle the "math problems" of the code abby, project euler...

try the following links.  But you'll get no further, at least from what I've found, from doing tutorial after tutorial after tutorial.

https://adriann.github.io/programming_problems.html
(caveat: forget #11 under beginner for now)
https://www.reddit.com/r/learnprogramming/comments/2a9ygh/1000_beginner_programming_projects_xpost/
(still working through #1 which is a link to another list of programming problems for beginners)
http://www.dreamincode.net/forums/topic/78802-martyr2s-mega-project-ideas-list/
(aforementioned #1 on the list) - did all up to text editor, personally not a fan of tkinter but I plan on returning to it shortly

if nothing else try automate the boring things:
https://automatetheboringstuff.com/
the whole book is online for free or you can buy a copy and support the author, upto you but he makes the information available.  He has other books too.  All his books are hands on and do things and you'll get stuff done and understand why it's working even if it isn't the prettiest cleanest code out there.

https://www.codewars.com/
site is... different but it has lots of training problems that aren't math based.  Challenges your skills and gives you access to other people that will help you if you run into a problem.