Friday, April 11, 2014

Problem 81 - Dogescript

The languages I have used in this blog have come from a number of sources. Many I had just heard of through word of mouth prior to working on this project (everyone has heard of many languages, even those not popular today like Fortran, BASIC, etc, even if they have no vague interest in working with them). Some I have found through searching lists of popular programming languages, languages that have some use but aren't overly famous were generally found this way, like D. The more esoteric languages, however, generally have to come out of either searching the interwebs on my part or from the suggestions of others. Today's language came as a suggestion from a friend of mine, this is her second suggestion, the first being the as-of-yet unused nyanscript which is basically a textual replace of brainfuck. Today's language is much less painful to use than brainfuck however, it is dogescript, a language based on that popular meme. I am a bit disappointed with the language, due to its lack of creativity (it is just a textual replace of javascript, but many things are left untranslated, thus the subtraction symbols, +=, and square bracket array accesses. Maybe in the future the language will more fully grow into its own, but for now , solving this problem in dogescript really just felt like solving it in javascript with a couple of very minor obstacles. My largest speed bump in solving this problem was spending a long time not knowing why my answer was wrong, only to find that I had computed the maximal path sum, when the minimal path sum was desired. Compiles and runs in about 1s on my machine.
very matrix is new Array
very row   is new Array with 4445 2697 5115 718 2209 ...
matrix dose push with row
...

shh Full table description in actual solution file, cut short here 

such max much x y
    very r is x
    rly x smaller y
        r is y
    wow
wow r

such min much x y
    very r is x
    rly y smaller x
        r is y
    wow
wow r

very numdiags is 160
very bigindex is 79
much very diag as 1 next diag smaller numdiags next diag more 1
    very hbound is plz min with diag bigindex
    very lbound is diag - bigindex
    lbound is plz max with 0 lbound
    much very col as hbound next col biggerish lbound next col less 1
        very row is diag - col
        very lparam is matrix[row][col]
        rly row bigger 0
            lparam += matrix[row-1][col]
        but
            lparam += 10000000
        wow

        very rparam is matrix[row][col]
        rly col bigger 0
            rparam += matrix[row][col-1]
        but
            rparam += 10000000
        wow
        matrix[row][col] is plz min with lparam rparam


    wow
wow

java.lang.System.out dose println with matrix[bigindex][bigindex]


Thursday, April 3, 2014

Prettification of solution to 12 in Shakespeare

So, as those who have been reading this blog may know, I am the creator and maintainer of an open-source Shakespeare compiler at https://github.com/drsam94/Spl/. I used Shakespeare for problem 12, but I wasn't entirely happy with it as it used an ugly feature of Shakespeare, which is that you had to write "Let us return to Scene I" to return to scene 1, etc. That is very unshakesperian! So, I recently added a language feature that allows you to go to acts/scenes by name, as exemplified by the following prettified version of my solution to problem 12 (it has about 3 gotos, but they look so much nicer now). "If so, let us proceed to the Final Judgment. If not, let us return to Real factoring."
The Tale of the 12th Euler.

Juliet, a young woman with a love for triangles.
Ophelia, another young woman who loves factors.
Octavia, a young woman who holds a big number.
Macbeth, a temporary young man who likes roots.
Romeo, a man who likes counting (and Juliet).
Julia, a young woman who also counts.

    Act I: Some smalltalk (not the Squeak kind)

    Scene I: Octavia's Initialization

[Enter Juliet and Octavia]

Juliet:
    You cute beautiful amazing sweet sunny trustworthy gentle 
    golden good girl! You are as pretty as the difference between 
    thyself and the sum of a brave charming bold noble warrior and 
    the evil dirty devil!

Octavia:
 You are a pretty girl too, thanks much for the accolades.

[Exeunt]
[Enter Macbeth and Romeo]
  
    Act II: A non-trifling time

    Scene I: Getting to work

Macbeth:
    You are as cunning as the sum of thyself and a hero.

[Exit Macbeth]

[Enter Juliet]
Romeo:
    You are as lovely as the quotient of the product of myself 
    and the sum of myself and Heaven and a good King!

[Exit Juliet]

[Enter Macbeth]
Romeo:
    You are as prompt as the square root of Juliet!
[Exit Macbeth]

[Enter Ophelia]
  
    Scene II: Getting ready to factor

Romeo: 
 You are nothing at all.

Ophelia: 
 Is the square of Macbeth as noble as Juliet?

Romeo: 
 If so, you are as beautiful as a flower.

[Exit Romeo]
[Enter Julia]

Ophelia: 
 You are an angel.


    Scene III: Real factoring

Ophelia: 
 Is the remainder of the quotient between Juliet and thee better than nothing?
         
Julia:
 If not, you are as pretty as the sum of thyself and a golden flower.

Ophelia:
 You are as cute as the sum of yourself and a plum. 
 Art thou more pretty than Macbeth?

Julia:
 If so, let us proceed to the Final Judgment. If not, let 
 us return to Real factoring.

    Scene IV: The Final Judgment.

[Exeunt]
[Enter Romeo and Ophelia]

Romeo:
 Are you more pretty than Octavia?

Ophelia:
 If so, let us proceed to printing the answer.

[Exit Ophelia]
[Enter Macbeth]

Macbeth:
 Let us return to getting to work.

    Scene V: Printing the Answer.

[Exeunt]
[Enter Juliet and Ophelia]

Ophelia: 
 Open Your Heart!

Juliet: 
 You are as beautiful as the product of a good man and the sum 
 of the lord and a cute golden girl. Speak Your Mind!

[Exeunt]

Problem 80 - Frink, and yay, another round number

Now I have solved problem 80, which means that I am done with the 70s and am moving on to another region. Problem 80 involves calculating square roots digit by digit. The method I found on wikipedia to do this requires doing arithmetic with very large integers (for 100 digits of the square root, you need a 100 digit integer). Luckily, doing stuff with big numbers is one of the reasons why Frink exists. And Frink made this problem fairly simple: my biggest issue with this problem was forgetting that 0 is indeed a legal digit in a square root...anyway, here is the solution, Frink is hard to time as it runs in java and pops up a gui, but including Frink startup time this runs in about 5 seconds, most of that being Frink startup time.

digisum = 0

for n = 2 to 100 
{
    if floor[sqrt[n]] * floor[sqrt[n]] < n 
    {
        p = 0
        c = n
        for i = 0 to 99 
        {
            x = 0
            do
            {
                x = x + 1
                y = x*(20*p + x)
            } while y <= c
            x = x - 1
            y = x*(20*p + x)
            digisum = digisum + x
            p = p*10 + x
            c = (c - y) * 100
        }
    }
}
println[digisum]

Wednesday, April 2, 2014

Problem 16 in (free)BASIC

Well, it was inevitable that I would have to use BASIC at some point. However, BASIC has far too many dialects. After some issues with getting it to run on my computer because of needing 32-bit versions of a lot of libraries, I decided to solve problem 16 in freeBASIC. I solved this problem to free up Frink for problem 80, as I think it will make that problem very tractable using its ability to use very large integers (indeed, that capability was why I used it on problem 16 in the first place, but I put in a little more work and managed digits by hand to solve it in BASIC). Didn't have too many issues with the language, other than having to discover that \ is integer division, while / will do float division and then round UP to the nearest integer. BASIC does indeed run quickly: solution runs in 34ms on my machine.
Dim digits(1000) As Integer
Dim numdigits As Integer
Dim i As Integer
Dim carry As Integer
Dim j As Integer
Dim prod As Integer
Dim ans As Integer

i = 0
numdigits = 1
digits(0) = 2
WHILE i < 999
    carry = 0
    j = 0
    WHILE j < numdigits
        prod = (digits(j) * 2) + carry
        digits(j) = prod Mod 10
        carry = prod \ 10
        j = j + 1
    WEND
    
    WHILE carry > 0
        digits(numdigits) = carry Mod 10
        numdigits = numdigits + 1
        carry = carry \ 10
    WEND
    i = i + 1
WEND

i = 0
ans = 0
WHILE i < numdigits
    ans = ans + digits(i)
    i = i + 1
WEND

print ans