Here's our discussion for day 2
I'm not sure how early is too early for posting solutions. jbrown, do you want to establish a rule of thumb or should we just ignore solution posts until we want to compare?
Problem 1: (.11s)
For each value:
Problem 2: (.19s)
Check 1st column_bcde
Check 2nd columna_cde
*(Where _ means empty)
2. Once I found the list with duplicate values, I sorted that list and then scanned for adjacent duplicates.
The SPOILERS first line is fine, but it is still too easy to read. But I guess it's all we can do.
I'm working on the 2nd part now.
Both were done kind of brute-forcey, but still pretty quick.
The first meant looping through the list, looping through each character (substituting out each as we moved through), finding the doubles and triples.
The second problem was a little tougher, especially because I decided to convert the input from a list of values to an expression that used Replace() to convert each line from a 26 character one to a 25 character one...
"Replace ( \"myhposlqgeauywfikztndcvrqr\" ; $counter ; 1 ; \"\")" & " & \"¶\" & " &
"Replace ( \"mbhposlxfeauywoikztndcvjqi\" ; $counter ; 1 ; \"\")" & " & \"¶\" & " &
"Replace ( \"mbhpoulxgeagywfikytndcvjqr\" ; $counter ; 1 ; \"\")" ...etc
UniqueValues() would tell us if there's a dupe. This would take at most, 26 passes.
Then I looped again, comparing the values in that group to each other. At most 248 passes.
Overall, about 2.5 seconds to run.
If you all get stuck I am part of a group that solves these in different languages (FileMaker would be great to have there), but you can get clues from how other think about it
GitHub - kodsnack/advent_of_code_2018: Contribute your solutions to Advent of Code 2018 and be inspired by others.
The Swedish is just telling you to fork the repo and add a folder with your name-programmingLanguage feel welcome and join us and I love to see the solutions in FileMaker!
OK, day 2 taken down!
Part one solved (by my solution, that is ;-) ) in just under half a second, part two in 137 ms.
P1 I implemented using a repeated substitute
P2 uses a custom function to get the matching chars ... and brute force to find the matching pairs ...
Check out the file to see how I (may have) sneakily improved the result time.
Happy Advent everybody!
(P.S. My template file has a glitch somewhere, which is causing the chosen Day to be reset to 1 ... I'll see if I can get it fixed ... otherwise just reset the day in the [...] menu top right)
Cool ... they now have a countdown timer for the next day:
It's nearly midnight here ... so I guess I'd have to get up at 6 a.m. if I wanted to be keen!
Wow, I haven't looked into CustomList() before. We have basically the same solution, I just built my function from scratch, which was tough! Debugging was a bear.
I'm definitely considering using that function next time!
For each line using 'repeating' variables to keep track of the count of each character.
Then looped through to find the 2's and 3's.
Created a list with each 'column' deleted and then compared with a UniqueValues list to find if there was a duplicate.
This is getting addictive.
Also hadn't come across CustomList() before and agree, wow
CustomList is a TRUE work of art. I marvel at the fact that it is not recursive. So many props to Agnès Barouh.
I solved 2.1 the same way as others: filter() and remove characters as I've filtered/counted them.
In Geist Interactive fashion, I wrote it as a modular script. The scirpt that does the work is self-contained. It accepts a line and spits out a result (A JSON Object (of course) that showed how the 'two' and 'three' values there were.
Overkill, but it worked.
This is fun, huh? These problems are completely out of our normal day-to-day operations. But they introduce us to good concepts of programming and FileMaker.
I'm glad you're having fun.
Completed both puzzles. I've kind of decided to take a path of only using scripts for these challenges. We will see how far I get.
- Puzzle 1
- Puzzle 2
Completed both for Day 2
Script for 2.1 runs in 0.535sec.
Used a script which finds values with a specified number (by parameter) of repeated characters, then increments the number of those found in a Set Field by Name (e.g. Reps2, Reps3...).
Script for 2.2 runs in 0.11sec (and up to 0.355sec if I deliberately put the two codes at the end of the 250 codes).
At the start, I used the SortValues function on the input to make it easier to loop through the list
Simple to find what letters are common between the two correct box IDs:
davidhead wrote: At the start, I used the SortValues function on the input to make it easier to loop through the list compare value 1 with value 2compare value 2 with value 3etc... and stop when you find the first match
The two matching answers may not be neighbours! If it worked like this then it was just luck.
Consider the following sorted list:
The matching pair in this case is #1 and #3 ...
Whereas sorting the list may help you to find the result quicker - because it is *likely* that the two values are neighbours, you do have to compare every element with every other element.
davidhead wrote: Simple to find what letters are common between the two correct box IDs:Filter ( $v1 ; $v2 )
This does not work in all cases.
if $v1 = abcdef and $v2 = bacdef the Filter function returns the wrong results, because it is not considering POSITION of the letters.
mrwatson-gbs wrote:davidhead wrote: Simple to find what letters are common between the two correct box IDs:Filter ( $v1 ; $v2 ) This does not work in all cases. if $v1 = abcdef and $v2 = bacdef the Filter function returns the wrong results, because it is not considering POSITION of the letters.
Simple to find what letters are common between the two correct box IDs:Filter ( $v1 ; $v2 )
That may be the case with random data. However, in this case, we have already processed the data such that we have isolated two values where only one letter is different. The example you have used here would not apply in this case with the given rules.
However, upon closer inspection, my solution CAN break:
if $v1 = "abcdegg" and $v2 = "abcdefg", then it will return "abcdegg"
So I defer to a looping script process (as you and others have used) or recursive custom function for this. Thanks for the input.
I fell to the trap of FIlter() for awhile, but realized what I need to do.
so I just compared Middle ($one ; $i ; 1) to Middle ($two ; $i ; 1) to see if they were the same or not. If not, I kept track of the number of differences and exited out of my subscript if I got more than one difference.
Here's mine. Again. I'm using subscripts to actually process the lines. It's a bit overkill, but I can test the "process" line with sample text.
And I'm using JSON to pass parameters /results between scripts. I have to.
mrwatson-gbs wrote:The two matching answers may not be neighbours! If it worked like this then it was just luck. Consider the following sorted list:abcdefabddgfaccdef The matching pair in this case is #1 and #3 ...Whereas sorting the list may help you to find the result quicker - because it is *likely* that the two values are neighbours, you do have to compare every element with every other element.
Good point there!
Luckily for me they were neighbours
this is my script for day 2 - 1, slightly different approach, takes 0.42s:
Set Variable [ $list ; Value: AdventOfCode2018::Challenge ]
Set Variable [ $nlist ; Value: ValueCount ( $list ) ]
Set Variable [ $n ; Value: 1 ]
Set Variable [ $two ; Value: 0 ]
Set Variable [ $three ; Value: 0 ]
# loop through all list elements
Set Variable [ $i ; Value: 97 ]
Set Variable [ $hastwo ; Value: 0 ]
Set Variable [ $hasthree ; Value: 0 ]
Set Variable [ $value ; Value: GetValue ( $list ; $n ) ]
# loop through all 26 letters or exit if twos and threes are found
Set Variable [ $char ; Value: Char ( $i ) ]
If [ not $hastwo ]
Set Variable [ $hastwo ; Value: PatternCount ( $value ; $char ) = 2 ]
If [ not $hasthree ]
Set Variable [ $hasthree ; Value: PatternCount ( $value ; $char ) = 3 ]
Exit Loop If [ ( $hastwoo and $hasthree ) or Let ( $i = $i + 1 ; $i > 122 ) ] //typo here must be $hastwo
# increment $two if $hastwo and $three if $hasthree
Set Variable [ $two ; Value: $two + $hastwo ]
Set Variable [ $three ; Value: $three + $hasthree ]
Exit Loop If [ Let ( $n = $n + 1 ; $n > $nlist ) ]
Set Field [ AdventOfCode2018::Result ; $two * $three ]
In your Exit Loop it says "$hastwoo". Your script should run even faster without the second "o". And then I think you could also ditch the `If [ $hastwo ]` and `If [ $hasthree ]` blocks since the loop will always exit if either is true.
Because the string is a fixed length, using a single calculation is much, much faster. See my file. It finishes part one in 0.089 secs. Compared to looping through each character, which takes roughly 0.5 secs.
Interesting. I'll probably start sounding like a broken record but I think runtime comparisons are somewhat unreliable for comparing approaches. The most striking example for me so far is Day 1, in which DavidJondreau posted a solution that ran in 8s on his computer, but when I ran his script on my laptop it took 14s. So you guys are all packing some heat!.
Anyway, I just looked at your script (+1 for elegance). When I ran it took .13s and when I re-ran my old one it took .11s, which is a bet I would have lost. It really seems like yours should run faster since it didn't loop through each letter like mine.
Either way I think I got the runtime down even further to .065s on my comp (should be ~.052s for you). I loaded your data into record 4 in the attached file.
Just for reference, my runtime on that script was 0.042.
What are your machine specs? I have a 2015 MacBook Pro, 2.5 GHz i7, 16GB RAM.
That's pretty snappy. I'm on a 2012 MBP 2.7 GHz i7, 16GB.
They must've improved something in those 3 years.
bruderdog thanks for the finding, comes down to 0.4s;-)
But I'm not sure about the 2nd suggestion as it's if ( not $has... If I take those out, it gets evaluated on every cycle what would toggle a already found match back to false
Oh, my bad! I definitely misread that your're checking for ($hasTwo and hasThree) instead of "or". You're right!
Good morning! I'm a few days late to this party, but wanted to ask a few stylistic questions about the Part One script. I put the original data into records because I thought this would be easier to keep track. Of course I could've just done this as a list as well.
1. What are people's opinions about using PatternCount vs Filter?
2. Pros and cons of checking using the actual values vs using the alphabet? Or, okramis, unicode characters (also, PS, how did you make your code copy out so nicely?)?
i.e. jormond it looks like you used PatternCount and the alphabet in your calc, jbrown you used Filter and the actual values... I know they all work, but I've noticed folks tend to have opinions about why they do things the way they do.
What I used was:
Go to Record/Request/Page [ First ]
# If not all values are unique
If [ Length ( UniqueValues ( Data::input ) ) ≠ Length ( Data::input ) ]
Set Variable [ $i; Value:$i+1 ]Set Variable [ $x; Value:GetValue ( abcdefghijklmnopqrstuvwxyz ) ; $i ) ]
Set Variable [ $rep; Value:Length ( Filter ( Data::input ; $x ) ) ] # If "x" shows up twice, check "twice" field If [ $rep = 2 ]
Set Field [ Data::twice; "x" ]
If [ $rep = 3] Set Field [ Data::threeTimes; "x" ]
End IfExit Loop If [ $i = 26 ]
Set Variable [ $i; Value:"" ]
Go to Record/Request/Page [ Next; Exit after last ]
Hi krissy, the script copying is one of the goodies you get with the MBS-Plugin;-)
Retrieving data ...