good game plan for AoC2015 day 4

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

good game plan for AoC2015 day 4

Roelof
Helllo,

a question about day4 of 2015
is it right that I can only solve this bruteforece
so begin at for example 1 , encode it, check for 5 zeros if found then I have found it otherwise increase the counter and do it again
Reply | Threaded
Open this post in threaded view
|

Re: good game plan for AoC2015 day 4

Roelof
Hello,

I got this code from the discord channel

secret := 'abcdef'.
zeros := '000'.
zerosSize := zeros  size.
count := 0.
[    
    [    candidate := secret , count printString.
        ((MD5 hashMessage: candidate) hex first: zerosSize) = zeros
    ] whileFalse: 
        [    (count \\ 10000) = 0 ifTrue: [ Transcript crShow: count ].
            count := count + 1.
        ].
    Transcript crShow: 'ANSWER = ' , count printString.
] forkAt: 35 named: 'Mining'

but I like that there is no transcipt in the code 

so my question is how can I change this part(
 Transcript crShow: 'ANSWER = ' , count printString.
) 

so it still returns the count.


I tried  ^count printstring but that is not allowed 


Regards, 


Roelof


Op 9-12-2018 om 12:29 schreef Roelof Wobben:
Helllo,

a question about day4 of 2015
is it right that I can only solve this bruteforece
so begin at for example 1 , encode it, check for 5 zeros if found then I have found it otherwise increase the counter and do it again

Reply | Threaded
Open this post in threaded view
|

Re: good game plan for AoC2015 day 4

Ben Coman
This is running the calculation in a new Process (in general terms, our "Process"es are "green-threads"). 
You can't "return" values between threads.  You need to pass it some other way through a variable. 
If you put that code into an instance method, then you could store the result in a class-variable.
Change the Transcript to ```self inform: 'FInished' ```  and then have a different method you call
after you see that to return the answer.

cheers -ben

On Mon, 10 Dec 2018 at 04:16, Roelof Wobben <[hidden email]> wrote:
Hello,

I got this code from the discord channel

secret := 'abcdef'.
zeros := '000'.
zerosSize := zeros  size.
count := 0.
[    
    [    candidate := secret , count printString.
        ((MD5 hashMessage: candidate) hex first: zerosSize) = zeros
    ] whileFalse: 
        [    (count \\ 10000) = 0 ifTrue: [ Transcript crShow: count ].
            count := count + 1.
        ].
    Transcript crShow: 'ANSWER = ' , count printString.
] forkAt: 35 named: 'Mining'

but I like that there is no transcipt in the code 

so my question is how can I change this part(
 Transcript crShow: 'ANSWER = ' , count printString.
) 

so it still returns the count.


I tried  ^count printstring but that is not allowed 


Regards, 


Roelof


Op 9-12-2018 om 12:29 schreef Roelof Wobben:
Helllo,

a question about day4 of 2015
is it right that I can only solve this bruteforece
so begin at for example 1 , encode it, check for 5 zeros if found then I have found it otherwise increase the counter and do it again

Reply | Threaded
Open this post in threaded view
|

Re: good game plan for AoC2015 day 4

Ben Coman
Forgot to add...    in a more complex program where this calculation is just a small-part 
you might use something like a Semaphore to signal between different threads.

cheers -ben

On Mon, 10 Dec 2018 at 06:10, Ben Coman <[hidden email]> wrote:
This is running the calculation in a new Process (in general terms, our "Process"es are "green-threads"). 
You can't "return" values between threads.  You need to pass it some other way through a variable. 
If you put that code into an instance method, then you could store the result in a class-variable.
Change the Transcript to ```self inform: 'FInished' ```  and then have a different method you call
after you see that to return the answer.

cheers -ben

On Mon, 10 Dec 2018 at 04:16, Roelof Wobben <[hidden email]> wrote:
Hello,

I got this code from the discord channel

secret := 'abcdef'.
zeros := '000'.
zerosSize := zeros  size.
count := 0.
[    
    [    candidate := secret , count printString.
        ((MD5 hashMessage: candidate) hex first: zerosSize) = zeros
    ] whileFalse: 
        [    (count \\ 10000) = 0 ifTrue: [ Transcript crShow: count ].
            count := count + 1.
        ].
    Transcript crShow: 'ANSWER = ' , count printString.
] forkAt: 35 named: 'Mining'

but I like that there is no transcipt in the code 

so my question is how can I change this part(
 Transcript crShow: 'ANSWER = ' , count printString.
) 

so it still returns the count.


I tried  ^count printstring but that is not allowed 


Regards, 


Roelof


Op 9-12-2018 om 12:29 schreef Roelof Wobben:
Helllo,

a question about day4 of 2015
is it right that I can only solve this bruteforece
so begin at for example 1 , encode it, check for 5 zeros if found then I have found it otherwise increase the counter and do it again

Reply | Threaded
Open this post in threaded view
|

Re: good game plan for AoC2015 day 4

Roelof
In reply to this post by Ben Coman

Hmm,

I thought I understand this idea but I do not.

I did this in the playground :


| answer |
answer := Key5Solver new solver.
 ^ answer Result

class :

Object subclass: #Key5Solver
    instanceVariableNames: ''
    classVariableNames: 'Result'
    package: 'AdventOfCode2015-Day4 - Part1'


solver :


zeros := '000'.
zerosSize := zeros  size.
count := 0.
[   
    [    candidate := secret , count printString.
        ((MD5 hashMessage: candidate) hex first: zerosSize) = zeros
    ] whileFalse:
        [   
            count := count + 1.
        ].
   
] forkAt: 35 named: 'Mining'.


but still I do not see the answer.

Maybe I have to go for the blocking answer.

Roelof



Op 9-12-2018 om 23:10 schreef Ben Coman:
This is running the calculation in a new Process (in general terms, our "Process"es are "green-threads"). 
You can't "return" values between threads.  You need to pass it some other way through a variable. 
If you put that code into an instance method, then you could store the result in a class-variable.
Change the Transcript to ```self inform: 'FInished' ```  and then have a different method you call
after you see that to return the answer.

cheers -ben

On Mon, 10 Dec 2018 at 04:16, Roelof Wobben <[hidden email]> wrote:
Hello,

I got this code from the discord channel

secret := 'abcdef'.
zeros := '000'.
zerosSize := zeros  size.
count := 0.
[    
    [    candidate := secret , count printString.
        ((MD5 hashMessage: candidate) hex first: zerosSize) = zeros
    ] whileFalse: 
        [    (count \\ 10000) = 0 ifTrue: [ Transcript crShow: count ].
            count := count + 1.
        ].
    Transcript crShow: 'ANSWER = ' , count printString.
] forkAt: 35 named: 'Mining'

but I like that there is no transcipt in the code 

so my question is how can I change this part(
 Transcript crShow: 'ANSWER = ' , count printString.
) 

so it still returns the count.


I tried  ^count printstring but that is not allowed 


Regards, 


Roelof


Op 9-12-2018 om 12:29 schreef Roelof Wobben:
Helllo,

a question about day4 of 2015
is it right that I can only solve this bruteforece
so begin at for example 1 , encode it, check for 5 zeros if found then I have found it otherwise increase the counter and do it again


Reply | Threaded
Open this post in threaded view
|

Re: good game plan for AoC2015 day 4

Ben Coman

On Mon, 10 Dec 2018 at 14:28, Roelof Wobben <[hidden email]> wrote:

Hmm,

I thought I understand this idea but I do not.

I did this in the playground :


| answer |
answer := Key5Solver new solver.
 ^ answer Result

You can't access the Result variable inside like that.  You need a accessor method to do it for you like this...

Key5Solver>>result
     ^ Result
 
But also, you never set the value of Result, see below...


class :

Object subclass: #Key5Solver
    instanceVariableNames: ''
    classVariableNames: 'Result'
    package: 'AdventOfCode2015-Day4 - Part1'

Thats good.  Actually I amend my suggestion from yesterday. An instance variable would do.


I've renamed your method here...
Key5Solver>>startCalculation

zeros := '000'.
zerosSize := zeros  size.
count := 0.
[   
    [    candidate := secret , count printString.
        ((MD5 hashMessage: candidate) hex first: zerosSize) = zeros
    ] whileFalse:
        [   
            count := count + 1.
        ].

           Result := count    "<<<<< need to store the result of the calculation" 
           self inform: 'Mining calculation is complete.  You can now ask me for the result'.
   
] forkAt: 35 named: 'Mining'.


but still I do not see the answer.


With the above, in Playground you can do...

solver := Key5Solver new startCalculation  .   "<<<evaluate this line only"
"wait for information message to appear"
solver result inspect   "<<<<now you can evaluate this line to get the answer"

cheers -ben
 
Maybe I have to go for the blocking answer.

Roelof



Op 9-12-2018 om 23:10 schreef Ben Coman:
This is running the calculation in a new Process (in general terms, our "Process"es are "green-threads"). 
You can't "return" values between threads.  You need to pass it some other way through a variable. 
If you put that code into an instance method, then you could store the result in a class-variable.
Change the Transcript to ```self inform: 'FInished' ```  and then have a different method you call
after you see that to return the answer.

cheers -ben

On Mon, 10 Dec 2018 at 04:16, Roelof Wobben <[hidden email]> wrote:
Hello,

I got this code from the discord channel

secret := 'abcdef'.
zeros := '000'.
zerosSize := zeros  size.
count := 0.
[    
    [    candidate := secret , count printString.
        ((MD5 hashMessage: candidate) hex first: zerosSize) = zeros
    ] whileFalse: 
        [    (count \\ 10000) = 0 ifTrue: [ Transcript crShow: count ].
            count := count + 1.
        ].
    Transcript crShow: 'ANSWER = ' , count printString.
] forkAt: 35 named: 'Mining'

but I like that there is no transcipt in the code 

so my question is how can I change this part(
 Transcript crShow: 'ANSWER = ' , count printString.
) 

so it still returns the count.


I tried  ^count printstring but that is not allowed 


Regards, 


Roelof


Op 9-12-2018 om 12:29 schreef Roelof Wobben:
Helllo,

a question about day4 of 2015
is it right that I can only solve this bruteforece
so begin at for example 1 , encode it, check for 5 zeros if found then I have found it otherwise increase the counter and do it again


Reply | Threaded
Open this post in threaded view
|

Re: good game plan for AoC2015 day 4

Roelof
Op 10-12-2018 om 08:29 schreef Ben Coman:
> solver := Key5Solver new startCalculation  .

Thanks

but still problems

I have this :

startCalculation


     | zeros zerosSize count secret candidate |
     secret := 'abcde'.
     zeros := '000'.
     zerosSize := zeros  size.
     count := 0.
     [
         [    candidate := secret , count printString.
             ((MD5 hashMessage: candidate) hex first: zerosSize) = zeros
         ] whileFalse:
             [
                 count := count + 1.


].
            result := count    "<<<<< need to store the result of the
calculation"
            self inform: 'Mining calculation is complete.  You can now
ask me for the result'.

] forkAt: 35 named: 'Mining'.


but I see this error message :  instance of smallInteger does not
understand @self.

So some debugging to do.

Roelof


Reply | Threaded
Open this post in threaded view
|

Re: good game plan for AoC2015 day 4

Roelof
In reply to this post by Ben Coman
Op 10-12-2018 om 08:29 schreef Ben Coman:
> solver := Key5Solver new startCalculation  .

Got it working
There was a dot missing

Roelof


Reply | Threaded
Open this post in threaded view
|

Re: good game plan for AoC2015 day 4

Richard O'Keefe
In reply to this post by Roelof
This is the puzzle where you have to find the smallest integer such that
'<some salt>' , (that integer) printString has an MD5 hash beginning with
5 hexadecimal zeros?

Brute force is just fine.  Calling libnettle's MD5 functions from a C
program, it found the right answer in under 0.2 seconds on a cheap laptop.
If using the MD5 class in Pharo doesn't take a reasonable time, you may
find that (MD5 isPluginAvailable) is false.  On my cheap laptop, the
obvious code took 30 seconds to find the right answer, which surely means
that the plugin is *not* available.  But there is absolutely no point in
looking for anything faster.

So,
  (0 to: 1000000) findFirst: [:n | |digest|
    digest := MD5 hashMessage: 'YOUR SALT GOES HERE' , n printString.
    ... bytes begins with 00000 ...]

Linear search.
  Compute string.
  Compute its MD5 hash.
  Check the result.

The only time-consuming thing was browsing the MD5 class (and its
superclass HashFunction) to figure out the interface.

Now it *could* have turned out to be too slow to be useful, in which
case another strategy would have been needed.  But it didn't.
(I started with a rather smaller bound to get an idea of how fast it
was, and it was fast enough.)



On Mon, 10 Dec 2018 at 00:30, Roelof Wobben <[hidden email]> wrote:
Helllo,

a question about day4 of 2015
is it right that I can only solve this bruteforece
so begin at for example 1 , encode it, check for 5 zeros if found then I have found it otherwise increase the counter and do it again
Reply | Threaded
Open this post in threaded view
|

Re: good game plan for AoC2015 day 4

Richard O'Keefe
PS: converting the result of MD5 hashMessage: to hex is a total waste of time.
Just ask:
 - is the first byte zero?
 - is the second byte zero?
 - is the third byte less than 16?

On Thu, 13 Dec 2018 at 00:07, Richard O'Keefe <[hidden email]> wrote:
This is the puzzle where you have to find the smallest integer such that
'<some salt>' , (that integer) printString has an MD5 hash beginning with
5 hexadecimal zeros?

Brute force is just fine.  Calling libnettle's MD5 functions from a C
program, it found the right answer in under 0.2 seconds on a cheap laptop.
If using the MD5 class in Pharo doesn't take a reasonable time, you may
find that (MD5 isPluginAvailable) is false.  On my cheap laptop, the
obvious code took 30 seconds to find the right answer, which surely means
that the plugin is *not* available.  But there is absolutely no point in
looking for anything faster.

So,
  (0 to: 1000000) findFirst: [:n | |digest|
    digest := MD5 hashMessage: 'YOUR SALT GOES HERE' , n printString.
    ... bytes begins with 00000 ...]

Linear search.
  Compute string.
  Compute its MD5 hash.
  Check the result.

The only time-consuming thing was browsing the MD5 class (and its
superclass HashFunction) to figure out the interface.

Now it *could* have turned out to be too slow to be useful, in which
case another strategy would have been needed.  But it didn't.
(I started with a rather smaller bound to get an idea of how fast it
was, and it was fast enough.)



On Mon, 10 Dec 2018 at 00:30, Roelof Wobben <[hidden email]> wrote:
Helllo,

a question about day4 of 2015
is it right that I can only solve this bruteforece
so begin at for example 1 , encode it, check for 5 zeros if found then I have found it otherwise increase the counter and do it again
Reply | Threaded
Open this post in threaded view
|

Re: good game plan for AoC2015 day 4

Ben Coman


On Wed, 12 Dec 2018 at 19:10, Richard O'Keefe <[hidden email]> wrote:
PS: converting the result of MD5 hashMessage: to hex is a total waste of time.
Just ask:
 - is the first byte zero?
 - is the second byte zero?
 - is the third byte less than 16?

Good point.
cheers -ben
 

On Thu, 13 Dec 2018 at 00:07, Richard O'Keefe <[hidden email]> wrote:
This is the puzzle where you have to find the smallest integer such that
'<some salt>' , (that integer) printString has an MD5 hash beginning with
5 hexadecimal zeros?

Brute force is just fine.  Calling libnettle's MD5 functions from a C
program, it found the right answer in under 0.2 seconds on a cheap laptop.
If using the MD5 class in Pharo doesn't take a reasonable time, you may
find that (MD5 isPluginAvailable) is false.  On my cheap laptop, the
obvious code took 30 seconds to find the right answer, which surely means
that the plugin is *not* available.  But there is absolutely no point in
looking for anything faster.

So,
  (0 to: 1000000) findFirst: [:n | |digest|
    digest := MD5 hashMessage: 'YOUR SALT GOES HERE' , n printString.
    ... bytes begins with 00000 ...]

Linear search.
  Compute string.
  Compute its MD5 hash.
  Check the result.

The only time-consuming thing was browsing the MD5 class (and its
superclass HashFunction) to figure out the interface.

Now it *could* have turned out to be too slow to be useful, in which
case another strategy would have been needed.  But it didn't.
(I started with a rather smaller bound to get an idea of how fast it
was, and it was fast enough.)



On Mon, 10 Dec 2018 at 00:30, Roelof Wobben <[hidden email]> wrote:
Helllo,

a question about day4 of 2015
is it right that I can only solve this bruteforece
so begin at for example 1 , encode it, check for 5 zeros if found then I have found it otherwise increase the counter and do it again