﻿ Belated - Advent of Code 2018 Day 2 | InterSystems Developer Community |
Article
· Apr 3, 2019 5m read

# Belated - Advent of Code 2018 Day 2

Continuing on from my last post, I am posting my succesful output for the Day 2 Part 1 below.

A full explanation of Day 2 part 1 can be found at: https://adventofcode.com/2018/day/2 and the input can be found

A brief description of this exercise is that you receive a sequence of strings.

You have to count the if any duplicate or triplicate chars exist in the string.  Multiples will exist, but if you find multiple ldupicates / triplicates you will count them once.

At the end of sequence of strings you have to SUM the no. of duplicate / triplicate chars and multiply them together to get a simple check sum value.

I created 2 methods, one to import the data and the second to analyse the strings and populate the duplicate count and triple count properties.

Please let me know of alternative ways of dealing with this, as it always helps to be 'enlightened' of tackling an issue in a different way.

I do realise that I could do this in one method, but it made it simpler to split it in my mind.

Here is the code I tried below:

``````ClassMethod Import(dir As %String = "C:\Users\kanga\OneDrive\Documents\Advent of Code\2018\Day2_Input.txt")
{
//Open my text file and check it exists
IF ##class(%File).Exists(dir) '=1 {
write !, "Unable to Open: "_dir
QUIT}
ELSE { write "File: "_dir_" is open"}

set file = ##class(%Stream.FileCharacter).%New()
WHILE ('file.AtEnd) {
//create incrememnt for going through each line of text from file
//read line of text from file
set nline = \$INCREMENT(nline)
//if line exists loop through each line until no more lines
IF (nline >= 1) & (line '= "") {
write !, "nline loop started"
//read line of text from file
set row = ##class(AOC2018.Day2).%New()
// get length of line
set lline = \$LENGTH(line)
write !, line
For i=1:1:lline {
set row.WholeLine = line
}
set status = row.%Save()
}
//set status = row.%Save()
//write status
}
Write !, "Import Complete"
}

/// Processes the input from Importv1 and looks to find duplicate values in the string
ClassMethod Part1()
{
//initialising varibles
set rowcount = ""
set line = ""
set doublecount = ""
set triplecount = ""
set CheckSum = ""
// Get the highest row number in the table WDA
&sql(SELECT TOP 1 ID INTO :rowcount FROM AOC2018.Day2 ORDER BY ID DESC)
Write !, "Row count is: "_rowcount
// Loop through each row in the table
FOR i=1:1:rowcount{
//reset doublecount and triplecount for each row
set doublecount = ""
set triplecount = ""
set duplicatecharlist = ""
&sql(SELECT WholeLine INTO :line FROM AOC2018.Day2 WHERE ID = :i)
write !, line
set linelength = \$LENGTH(line)
set currrentrow = ##class(AOC2018.Day2).%OpenId(i)
For char=1:1:linelength{
set firstrepeatchar = ""
set Secondrepeatchar = ""
/// get current character being looked for
set currentchar = \$EXTRACT(line,char,char)
write !, "CurrentChar is: "_currentchar
///use find to see if current char exists in the rest of the string
// write an IF statement to check if currentchar has already been identified as a duplicate.
IF \$LISTFIND(duplicatecharlist,currentchar) {
}
ELSE{
set firstrepeatchar = \$FIND(line,currentchar,char+1)
// IF we find a repeate findrepeatchar will be >0
IF firstrepeatchar >= 1 {
set duplicatecharlist = \$LB(currentchar)
write !, "Dupicatechar is: "_currentchar
write !, "Current duplicate char is: "_currentchar
//After finding first repeat, increment doublecount by 1
set doublecount = \$INCREMENT(doublecount)
//INSERT a statemnet to build a list of characters that are dups and use to stop counting dups twice.
IF firstrepeatchar-1 < linelength {
//look for second repeat of currentchar in string
set Secondrepeatchar = \$FIND(line,currentchar,firstrepeatchar)
IF Secondrepeatchar >= 1{
write !, "Current triplicate char is: "_\$EXTRACT(line,Secondrepeatchar-1,Secondrepeatchar-1)
//After finding second repeat, increment triplecount by 1
set triplecount = \$INCREMENT(triplecount)
//reduce doublecount by 1 as currnet char is a triplicate
write !, "Double count pre-reduction: "_doublecount
set doublecount = doublecount-1
write !, "Double count post-reduction for triplicate: "_doublecount
}
}
}
IF doublecount > 1 {
set doublecount = 1
}
IF triplecount > 1{
set triplecount = 1
}
}
write !, "For Row: "_i_". We found: "_doublecount_" duplicates & "_triplecount_" triplicates"
set currrentrow.DuplicateCount = doublecount
set currrentrow.TriplicateCount = triplecount
set status = currrentrow.%Save()
write !, "Save status is: "_status
}
}
//reset sum doublecount and tripcount variable so can be used for generating checksum outside of loops
set doublecount = ""
set triplecount = ""
&sql(SELECT SUM(DuplicateCount) INTO :doublecount FROM AOC2018.Day2)
&sql(SELECT SUM(TriplicateCount) INTO :triplecount FROM AOC2018.Day2)
write !, "DoubleCount is: "_doublecount_" TripleCount is: "_triplecount
set CheckSum = doublecount*triplecount
write !, "Final Checksum is: "_CheckSum
}
``````
Discussion (3)0

Here's one that worked for me.

```Day2(filename) PUBLIC {
set input=##class(%Stream.FileCharacter).%New()
set input.Filename=filename
set doubles=0,triples=0
while 'input.AtEnd {
kill chars
set D=0,T=0
for pos=1:1:\$length(string) {
set count=\$increment(chars(\$extract(string,pos)))
if (count=2) {
set D=D+1
} elseif (count=3) {
set T=T+1
set D=D-1
}
quit:((D>0)&&(T>0))
}
set doubles=doubles+(D>0)
set triples=triples+(T>0)
}
write !,"Doubles: "_doubles
write !,"Triples: "_triples
write !,"Checksum: "_(doubles*triples)
quit
}```

The object of part 2 is to compare the strings from the same input as part 1 and identify which 2 strings differ by 1 character in the same position.

Use the links above to find the exercise.

My code goes:

``````ClassMethod Part2SQL()
{
//initialising varibles
set rowcount = ""
set line = ""
// Get the highest row number in the table WDA
&sql(SELECT TOP 1 ID INTO :rowcount FROM AOC2018.Day2 ORDER BY ID DESC)
Write !, "Row count is: "_rowcount
// Loop through each row in the table
FOR i=1:1:rowcount{
// initialise looping variables
set mismatchcount = "0"
set complinelength = ""
set compline = ""
set compchar = ""
// run SQL query to look at last number for row loop.
&sql(SELECT WholeLine INTO :line FROM AOC2018.Day2 WHERE ID = :i)
set linelength = \$LENGTH(line)
set complinelength = linelength
//set currrentrow = ##class(AOC2018.Day2).%OpenId(i)
FOR comprow = i+1:1:rowcount{
set mismatchchar1 = ""
set mismatchchar2 = ""
set mismatchpos = ""
//IF comprow = rowcount+1 {QUIT}
&sql(SELECT WholeLine INTO :compline FROM AOC2018.Day2 WHERE ID = :comprow)
IF compline = "" {QUIT}
set mismatchcount = "0"
For char=1:1:linelength{
/// get current character being looked for
set currentchar = \$EXTRACT(line,char,char)
set compchar = \$EXTRACT(compline,char,char)
IF compchar '= currentchar{
set mismatchcount = \$INCREMENT(mismatchcount)
set mismatchchar1 = currentchar
set mismatchchar2 = compchar
set mismatchpos = char
}
QUIT:(mismatchcount >1)
}
QUIT:(mismatchcount =1)
}
QUIT:(mismatchcount =1)
}
write !, "The lines with only one mismatch are:"
write !, "1st line: "_line_" On row: "_i
write !, "2nd Line: "_compline_" On row: "_comprow
write !, "The char in the mismatch in line: "_i_". The char is: "_mismatchchar1
write !, "The char in the mismatch in line: "_comprow_". The char is: "_mismatchchar2
write !, "With character position: "_mismatchpos