diff --git a/2023/gareth/.idea/.gitignore b/2023/gareth/.idea/.gitignore
new file mode 100644
index 0000000..1c2fda5
--- /dev/null
+++ b/2023/gareth/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/2023/gareth/.idea/awesomeProject.iml b/2023/gareth/.idea/awesomeProject.iml
new file mode 100644
index 0000000..338a266
--- /dev/null
+++ b/2023/gareth/.idea/awesomeProject.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2023/gareth/.idea/modules.xml b/2023/gareth/.idea/modules.xml
new file mode 100644
index 0000000..100893f
--- /dev/null
+++ b/2023/gareth/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2023/gareth/day01/day01.go b/2023/gareth/day01/day01.go
new file mode 100644
index 0000000..e09ce7d
--- /dev/null
+++ b/2023/gareth/day01/day01.go
@@ -0,0 +1,61 @@
+package day01
+
+import (
+ "regexp"
+ "strconv"
+ "strings"
+)
+
+func Part1(input string) int {
+ total := 0
+ lines := strings.Split(input, "\r\n")
+ for _, line := range lines {
+ regex := regexp.MustCompile("[a-zA-Z]")
+ numbers := regex.ReplaceAllString(line, "")
+ number := string(numbers[0]) + string(numbers[len(numbers)-1])
+ i, _ := strconv.Atoi(number)
+ total += i
+ }
+
+ return total
+}
+
+func Part2(input string) int {
+ values := map[string]string{
+ "one": "1",
+ "two": "2",
+ "three": "3",
+ "four": "4",
+ "five": "5",
+ "six": "6",
+ "seven": "7",
+ "eight": "8",
+ "nine": "9",
+ }
+ lines := strings.Split(input, "\r\n")
+ s := ""
+
+ total := 0
+ for _, line := range lines {
+ numbers := []string{}
+ for _, c := range line {
+ s = s + string(c)
+ if num, err := strconv.Atoi(string(c)); err == nil {
+ numbers = append(numbers, strconv.Itoa(num))
+ s = ""
+ }
+ for key, value := range values {
+ if strings.Contains(s, key) {
+ numbers = append(numbers, value)
+ buffer := s[len(s)-1]
+ s = "" + string(buffer)
+ }
+ }
+ }
+ number := numbers[0] + numbers[len(numbers)-1]
+ i, _ := strconv.Atoi(number)
+ total += i
+ s = ""
+ }
+ return total
+}
diff --git a/2023/gareth/day01/day01_test.go b/2023/gareth/day01/day01_test.go
new file mode 100644
index 0000000..6c35978
--- /dev/null
+++ b/2023/gareth/day01/day01_test.go
@@ -0,0 +1,25 @@
+package day01
+
+import (
+ "github.com/stretchr/testify/assert"
+ "testing"
+)
+
+func TestPart1(t *testing.T) {
+ r := Part1(`1abc2
+pqr3stu8vwx
+a1b2c3d4e5f
+treb7uchet`)
+ assert.Equal(t, 142, r)
+}
+
+func TestPart2(t *testing.T) {
+ r := Part2(`two1nine
+eightwothree
+abcone2threexyz
+xtwone3four
+4nineeightseven2
+zoneight234
+7pqrstsixteen`)
+ assert.Equal(t, 281, r)
+}
diff --git a/2023/gareth/day01/input.txt b/2023/gareth/day01/input.txt
new file mode 100644
index 0000000..6c93f70
--- /dev/null
+++ b/2023/gareth/day01/input.txt
@@ -0,0 +1,1000 @@
+46threevqs8114
+threetwoonez1gtrd
+6ffxbtff
+769twotwo6rv9
+gjrcjrkvghthreegqqrg82qbct
+zkxjhgprtrlcfeight795five8
+99seven3vdcgvmvxtjtwodc5
+three5eightthree3four3vtkkqrgxs
+four863mrrnrsxrkone
+sevenntgvnrrqfvxh2ttnkgffour8fiveone
+49fbsfb
+3rbmlsksg
+ztgszqjjsrtmgqx6572
+3bqnfxkdbonesixseven
+mfgx32ftpbhgngm7
+fzrpfhbfvj6dbxbtfs7twofksfbshrzkdeightwoqg
+2xcftwo
+cshmmltsml4fiveeightdn
+eightthsix1
+two1gvfxcqnrfnbeightthreexznhbmmk
+3917sevenvxqxntcgxskh
+ksctcnfxdsk96drlbjkthreesfqlvnpvfbcbmg
+8nvrmzfs46
+5dbgltmgg1xvtqfkdxsrxzltwo1pgqlqndlc
+eight7four6rpbtmjzj5
+41seven
+gpmfhninexxgqr6
+15sixdrhxzcmqf
+8fivettgmcslxptwofivelckzvfkl
+67ninetjngsrvcpxb8eighteightwofh
+4nine7oneighthm
+njtwonefvhjplkjgvsevenbjg77
+eighthrspkszngkpdtzdpcsmjnvlnhcm9pqmpkxqmbtmbv
+ninehthhgbfsrrbpn2qpcflhgdvh9twotpzkvzmmsj
+6fourzpjthmkrkvqkvvp
+vnrnkfp6
+pfouronefour6
+87fourmznhvmt7
+nxbssjc1sevenvrcjlczct6ninekclbffs
+eightrpzsdggsixthree9dhrnqtjcbxthree9
+pkcmnktzvdjtbbkvxhxpsfp8
+sffd124fkqsq1bd
+txzsmrzlcnnine72kgfkcf
+dbfbdskfdn5nine2sdr
+eightseven47six57
+2eight634sixmlrkhrbslf
+hpeightwopgrqmblthree1fmfnvd
+2jbbf
+vdsbvmjseven4eight195vdkfc4
+five3xjzlrmxvqznine
+nine4vqxmzqxcvfhlm45
+rtwo1
+six8jddkprxvbh98hd
+five5sevenfourfour4
+seventhree4lnxcvdprp66hsjfive
+ninevrxxhgvkghmcs8gsvplvsfour
+6bkeight3fhkfqvvsbcsixljfive
+6sixktwo
+lmscbrnlzmbqpl75ptwo64eightwoxcm
+2sixfivetwoeightdpskxjtlrfive4
+87gfmklvnzfz4594qlksr5
+five3one65
+vxrnhpvrrdd7nqdjfqnhfglfive7qqtzhcrk
+7sixthree441pf16
+11hrfdvdkf
+vst7three2vtwojrkdkjltgdt5
+vqmtwo5
+nffpcvfpjleightfiveeightknmjfive2
+ddfhzdndxvhcgjrcmqq158
+kkeightwo14
+8onetwo
+sevenrslxphqpcpdnxhpzqdf1twoone9
+four8onelgqhkmxktf5six
+8ckshssfour73twoone
+threethree8onefourkkhvfive4five
+64xpzhxtsixseven59
+two8srjslxss
+sixsixninecpgjkfhzdqdjlc48seven
+lpjgghdtgk1sevenzpkmxzqxfourthreethree
+cvznpxfhj2jnlgmnbkdsix
+ninetwo1fournjqvsb
+sxhl3kc
+mtllnjrbscfkdhseveneightgjr4one
+qnineeighttwovjsnvs7five4svdmjt
+bcplhrpvmkxkjxlzl7zkbpdnoneninethreej
+1mbmfktgtwonine
+9threefkptqhhnine2six1fgxnvvfvplv
+8onefourtwoxl42shxq3
+38rlbhvlpeightfivelbcm3jfd
+97one1threexjfsljjz41
+kqmkvmh1three9three74
+3fivenineeightwod
+6sixkgnqqb6
+sevenjdn8csthpjxgnd83
+qhssrppqxlone649
+3gjpsncshmnhkdpzskmmfst3sixfive5
+fivejprgsxddzgcnrn6cpnxnj
+4three3ninedqknine
+61xfrcfseven6
+sfpqbxbdrhqkndfdpldvfive7gxmnthreetwofour
+lbvrzv2onec2six8three
+ninenine2grvzhgtgfourthree98
+1579416
+5fzcbbxzfjjtwo6k
+xmxbtqvnxf665lplnhlgjlkzhkkbknjcxqvkpsp3
+fivefive26fivefour5
+5dbxqcbbkjonehseven
+1k
+8sixqmone9zthx6
+ldsmxpbkkx1rppscjfour3six
+fivethreethreekxzgqmrz8
+lxklrjjmqsix5snb7
+threethreetwothree6
+8three6
+fnine7jmmseven3
+rfhlkhhlx8sjqgclvlsctwo
+vrzpdfjs5fxldpnhvhmmxhleight
+9tmqznszjgrnlhnpxbc
+3sxfscfseventhree
+565vs2
+four86six6
+16
+4vbcrh
+62jrjfrdcldbvjzhp
+onecsqpbrxpmqtrbbtxnrhkdlthree3s1six
+two798tqsjv
+znktgzzmtwo28
+8hllzrjqhvfone
+tgnlbtc2ninejmcsixfour
+fivek1five
+rklpvqfvtwo3
+lgdgchcpcl55hfdmdj
+onesix7onefive9
+jrnthree46seven
+qqptcnrxlllvccssrkkmkxnz8
+cmfour8threelthree
+xfgqc36oneightvlx
+xrvrchbdhftgpn22fgmnhbrscfqrqpgzjmgfive1
+stwotwofourfourthree2
+eightjcfqthcvcgpxxl6j
+cjvfdgmplfeight9
+591eightwoc
+jftninejfb11one1zqpnine
+threeqndgjdfive4fourhgcsbptb
+7pmxvqdhbhf8six
+67zhx64tlnjkvhvv5cblxd
+29zqfive3jkzmbj1
+smvlmnph1seven
+61four
+zjmgnbkoneczgsftnhtvfbtjvbjzpspcffrdkv8
+threesix4
+fhqm8
+ninefour1
+two422dqjqhvhbqkdqf4sixoneightgrd
+llnrdbhthree778dqzrcplfoureight
+eightjblmbgqhrj2onenineszr2two
+8cxbxqssfkzpponeppcqsx
+seventzlsxrskxqm8threecrclkpqjpmeight1
+nine1twonem
+6threeckmkktkvxjteight559ldn
+2zxhldmvpqdcddsxpnnvrvxmc99
+fourone4dzftfnccnvzjdrg49seven
+7eight44
+xmjqm8two47rpjfninethree
+7zhmjjhtrqjcmfprhsix5twobfive4
+rccsqlt8
+seven6three
+lrbp3five19zxb45
+8jlbtllzbtdgzbcfln929
+kdeightlfk9two2fhgshhbzhf
+dvxllmfourpzfpvch7
+four28
+3threefour4hxmfbmjdheight
+6twosphthbbqcltcgxm5ssvqndphrnine
+438rrxntninetwophsix
+eight3eightnine1sevenxsvfr
+4643kntqsvgqqtwo
+two8two
+7gbxkjonetncmeight52
+kg517
+onetwo933
+fbdmpjrjsscsfvfntwofive8tzbrbjsj
+7eightfive9nineninednsfhzvtonepccctxssbc
+93twofour2eight
+7bvzknzdmkjvrxkfngfnsd4foureight5
+onescsxpcfivelmqvfqxmc99vbshtgzjkjfour
+1hvdnine1
+542zhgcmvzcj3threefrvlcc
+sxfc95seven3
+nczqknxn4four7xj81r
+8threefive
+7zvhlf4
+drbxjhqp9gfgxxtkl4
+five2twotklsixfour
+9four9
+2jkeightthreekbqbkffpsztwonine
+3vtffqfkfh9onenine4rqxm7two
+4hlxllh7nrlxcpnrrcfivebkfkjdfjbksnine1
+drgsb3four
+fourhscfkzkjfcdlsjgjrbmlvvcfgcmxtsixjlhfrfmk8
+ncrkhfive1eight1
+8fz3zkhgleight9tqsgnbfoureight
+5six26twoone3two
+ptksmjfkl5twothree4fpshnrcfrmqxeight1
+jfkccclrrr49four6eighttwo5
+threefourgj7eight6
+73slt1one5
+six1zrlfk
+5six17
+qrsix7sixonexmclfz2
+3fivethreebplrfgklj
+xz9sixhlt4eightone
+gkknnbzkt6ffourvrjbfkqz8threesevenn
+2onenine9
+czsgh1five4qtxmtfksln
+eight6fourhpppr
+lpshxfqsddeightqrfgrdn1five6bnr
+5lmmlszndzfoureightqdbhlt7
+9eight5
+8sixrpctqfgf9dm95znhx
+1sixsix6qpmqmtwolh8
+six4threenine2four982
+8jbthree59nine
+q5
+9twosixone9fivehdsvpkttbkcjdbkone
+sixsix4cldngone3four
+9mvsggrgone9gjhfzdmvqbnqzlxgpckg
+gmtqnkdlfv8
+8seven7rxtzksl74four
+bmrtbjzqhbgzcjtwo74fourfourlvj
+twoone4five3twoljrznhdcggone
+42nine1eightseven
+45fiveoneseven6
+mxfoursixone8coned5
+sntmhcsix633seven
+eighttwolrcrl5four
+p22
+1vspmvx
+cpcsx9xgqlmblhshvnsix2hnczvdrrg
+grgtvsqdtslml4tlqrh
+hshgmv3
+fivethree63m3one
+95threecdfhqtmqb
+xjvd14dnfrjthqxvvq1xmqfhv7
+eightnzx48nkqhfssix
+8nzvck4hpfxbstf6fivesix
+4drxbsxgtskqtlnhgrrrz
+6foureightonezbpdbqflp5one88
+twofivefbhfourone4cpnrc79
+5trhksixfivesix2k7
+25three
+1phc9zhhn
+five8ptkczvqk87gkr8
+six61eightfourjjzrktr
+4gxrqrrvkshnpgnrjg2threekpcrfn
+7bclvsb1glbpss
+2eighthdbvxpz
+439
+3drtsf2two
+ninenine8hqqmfvddgspzdsnine7
+xzrjqdlrp2threedrhjztbsvg4mmqvchlhlp3
+99threesixzpgxnseven5one
+2hvst
+twohvrvp164one
+1nine9seven1eight8
+dfkdzprs95
+zthree925fourf
+kssmqhkonetwozcjgvjgxzr3gfdcvgm
+bbsqsix6
+onefour9seven73
+onesevenx1ncpgtczseightssevenone
+419d43dzjlvn
+ninefourb6threezgqvmzklghgsj1
+7crdxpfkcmtqvbvkk3
+8rvp2p
+gnvrlsfjxtfssqz8two6dcfive
+jgtwoneoneseven7oneoneeight
+dfsccdclmffourpsqggngjzn3
+22brtxbtkkdfmkbmv
+sixxlpxqdtwo7
+six8mrvhptlfbmczlnfqrgbvz5d
+84fiveeightsix8
+nine5rzqxp99gmklplmxtveightwombf
+seventhree7
+mfklcxxbhpqsdt2one1
+two7seven2
+63sevenpmdzdrkzjkjzgnnseightjztlvzqhx55
+8twosmrgbzzgmjbnthree
+twosksrj4mk
+onethreeseven4eight
+2kjldqzszg7twolfivethree
+3qdnbnzglheightjtnlqqqt5
+6l4vddmkphgmb3vcbsbgclkzhmmtmfour
+sixvtzmppfssl35eightqc
+six924lt5
+5sixnmmeight7
+mkggvlrdhkjxcr9jcs2fhsptxhj3
+nineggh1
+qzzckckm3
+hxgjhxthreetwo3x4
+7qonejntfsvpcftwogxkvpvbj
+2twoqlg3
+1sixhvsclvhshbr
+seven8tffqvgs
+twobktthxfqqthree38
+397
+lpm9six31seven
+75nrrfxrj
+8sixfour
+ccfbzbjjqlgkbqnxhgd2
+7eighttbrtddvbvrtmxjeight5nine1
+sixfourvbjv5six61two
+sixff4dskpsqsrcd7
+three5five8
+8sixthreethree6
+oneeight7cdjxfmfjbpbjlsevenjgthreexh
+ninetwo4xdxmxpmd86
+eight312
+pmvgbvn8seven
+djrftlbzvfxjjgrh37bmfkone
+ksf53onefourfive6
+7vzqrmklveightnine
+two55eight69
+kbjprbkcgpskbnthree6gznqk5fkttt
+22three37bvmsmjmx
+zpchdzmbjhzl1five26threesix
+2onetdppvzcbzfive29four35
+66one9clqlkbqpfdqkkxv
+lql5four
+two41sevenseventhreeone1seven
+fiverbkxdczfive6smlnbgn6sevensix
+lpveightwoeight9two4frfz54
+twohfkvxqrninesix1
+6twosix
+9ninefive47
+sixsixrjznqb33sevenhkl
+one5nineeight48zqkhjgqlcq
+foureight4seven83
+zzoneightvcnhxlmgjp4ctclzzztwo46six
+2gljzksrvdr21ms
+eight75twofive
+threexdsbjrf6
+lhvrfb3925six
+fgrlrvpnctkdblxvzone2tsxst43
+zpnbvs5foursevensevenjleight
+five89seven4seven
+5rnntxqsngssixonefb3fourdglmstvmft
+tmvldx3eight163
+hmnvbpr6516
+3jfqshjf
+9vgpgcflbbonejhmlncrrjvxdcshdflktr
+vgjmhqnvghc718sevencfdzknkhonesix
+dlzrjfklp3chqxjdpdrv
+eightseven4tcbdhrgssmpvxsxszxrmpzrt7
+five416sixp2
+2threefourj
+hmzoneightmvrksbxbjkvpslkv1tlxxkzsgdseven86four
+pzleightwo774five5
+dvsmtwokrzscgnvztznqh9
+6chqttwo
+67sn3dfdeight55
+4oneightqd
+jhlhcjnd6sixqptqlmrskfive1
+9mfxbvb138zxngghqs43
+2srctwohfplclone928j
+7eightsdsxsskkd8five82
+gccnsvpnfg1195nine
+8584threethreeskzkfpdhz7
+prhhdpfivenine5fsskx5eight7
+9nzhbn7mvczcqcfive7tslfive
+vqxseven5seven4332
+95sevenninefive
+eightzdnddmlrpbxnvxglqnqnr334hpjrl
+one6three
+13dhjftxnp5k
+92threeone3seven
+ncsfdmmft2eightmlfxxdbv
+four3ninethzh
+31five9ksssbdqzlfive
+twokghhrljdc72
+two6fourdktfpddftwoseven
+zgr3bdfqvnkdvpcntkrcfnhpnpdrtkzpthree
+9rnpxdtkbhjbjnf
+1247lqdnsgnp3xtdxnbxkrthfhsrm
+sevendcdbr38ninebljxshxdzqcknvld
+six3gpngxvdqlnrf9gjqjvzeight
+twogfxctgnb4sixqzdmhc2sevenbq
+sevenpjmrj2skcc5
+eightsix9threemxtx13zczqvtvsix
+1tmgrhxzfql9lbpgscnmlcghptbtmpfgct
+2foursdhmtqmfjlf77
+bmgttpr2eight177six9three
+1nmbnkszc
+three14six1lnlfpfmfhm9
+eight4four6five46nine
+26sevengdnoneeightfive
+vhz1fivejzjqnfgrpfbgfz11nlx
+4jnkzktpninejc
+ninefourone1five2four3
+cljtfplrgbv6fsrlfxqmxhtwo75two
+41htzjlzsdbg
+hfnvdnninezhhbsmxfour3ninesevenhdnflzlt
+8vlshckcch57
+28tsbvgmzd
+qccgcsqb5trsvmmdtninehbgsxqjftrvsix7
+3eightkfqlsone
+fgoneightsix4eighteight4one
+8csdgpcbfjbmsixmjztbrqdj5
+9two152
+onevseven1
+vfsjtpzttxdrfive6
+69mdbtdnqgxjmzt
+threemgzspvnvsjone7eightjxssg5
+threelfslcjhhgmfftmftfzsix3qs57
+onejhskmbxcqpkxjxh4threeeightseven
+hhvgnineeight8xrtvmqjnkccdptpvqxlrdkkgljmbnzx
+onezvj2threej5dlnrcbhfxlkkmkpx
+ninepmgbdcvpds3onefive2
+9tblnmmeight1xdmtwo
+cnczmrhjmmcsccnine54
+2fourggjjrxckgvsevencpkgqzzfnptwofivefive
+61threexnrhqbhxb9
+seven14
+32seven
+4cqtssgd3vdxbnllfb2
+smbqxbxgmeightthreeonedsfxfronec2nine
+3145fvqz2
+bgdgbptnr9dqmvvckb
+tpt2ndklfgxtthree
+four16vztcgtwo5xkjmp5
+59onelp
+ztwone9cnvbtpglsq78
+4rmmhxpqsknxhgqmlh9tfzfngqsnbqdmsgtcjsbntr
+4x6lcmrxhhkcscxgxtgpjz33seven
+cnzlsqbvk8sbbzphzkhmeightfive58
+twofour7
+jcsgmrgeightcpzbb8135
+4grxpsix7hgrrhtjvgq68zzbvsn
+qc6
+sgxdninevmmzqdkqmjxpksixfckbjjkgqtwoseven8
+6lhfcjc9
+zkpkjn18six51
+xtnhzzxceight6seventhree27
+qttwone3seven5
+threeone8ksgt9
+8fqkddzb
+nine3sixbprlvxpniner
+dmbvmrthreefcrqvmhp54neightcz3
+twosl6fdtwokrqrqtwo6eight
+8dkrshdpj8threer
+27snqfjdg
+nine7mdsonenine
+threefive2twotktc9
+1twoninesjgqjxphhnineeightthree7
+xxlcmbnctsszkjdhfzqbdr2szvkmscnrg
+tcmsnine6ct
+2tqmkfmc
+sevenpmceighteight1
+hnnthreefourknjznt5nine
+5fhjvttdmzdpkjdsgnpqxlxfninepgrsns
+psxzzdkspgmgnnhkzt6fsdmfour
+1lkb
+seventwo2dglxkrlvgthree
+seven27kzhnknqltvkbxrtvtwo
+7frmrdctninefive
+61twoninebbsbqsbhtxmxkffspd
+3nlzgzlntrk965nine8ljpj
+3pfxjjvcg42lzlkzfs
+7pkztnine54bq
+sixxbxvgsknjxsix4nine3
+fourvbch2cdrsrxzh9
+one1f4mtvslfczm
+456bkzhmxlmhfmkgxrmkbmvhhpmsfk8six
+one9rmbvtdp5oneeightfive8
+67zh4
+83hdqrsxfc2twoninekksg
+1gzmqcrtksixseven81three
+two6threefour2
+nine4rcmbhmhsttgqzfjdm
+jg63
+twofour3one1
+5eight1eightqdmgtszxvx26nine
+482three9seven
+cxdjmjsk1mgqsqkkbq97fourqflf
+bvfplgzj69pqfcpglsix6
+v3458fourcpqkn
+seven769sevenfive9
+dztdmlkjgonejjpxrsevennineninepkc3
+4ninehvgninethree
+tnvgjhzr6
+sevenfour5nineshrsknbbxxsgztrl
+four4flpgsixshxxtmnvxfivensznine3
+73cfxzzsfourzqghjqvkbf7six8qgcd
+fgqk133t
+vjbzpkvsxkoneoneeighteightfive1zrvgqbf
+9six6ntrmhtkgrj
+fournrrmxldk24mxhsevenfive
+8fiveninenine25ninenine
+seven1xb3vbzbqkjdvseightfive6qs
+five8dgqkhldbsfthree7
+six11three5zeight
+hgmqhchrdfivevmftjcgtl5
+oneonesix2bzfsqvkmjzbdq1
+fourx5threethree3mxhgtnine
+hzeightwozfcpkjvfour3three9b
+1oneseven
+hmdtcxld4fdgfgdbjlsevenzrkmnftsevenvsqc
+sevengzpnkfn1sevenjcbfxbg8six
+2sqjnbtskft5
+fknxnxg9944hvtxj
+nine3951
+94sixqslqtxleight
+1zpbxc3
+sixddscq1zxsvgbjnqjj6zknkfczj6fxcqmf
+threetfvhftlzjn72sevenljtwobhgvvsttg
+doneighttwo3vm
+llhzdtwovbxr2
+onemjkvtbsix39eight88
+lhzgpqmhm4ptmcxhseven4eightcrvnqzplrnb6
+3tqljjnx47sixsixmxqbflxjp1
+tkvdxbbsdpkdjl3gtnmjdxhrj5
+qgnnghvnkppvvnine8
+89sixeighthmhsvbsg
+67hqvxtmq
+fiveeighteight7cfmdmfhdld
+nnsxvrgpeightjvcfj3fjeight27
+8ninefourfourcjrbxone
+1bx482
+pponeight1seventllldzgdvgcdmr
+tworrjfkmntbvkpseven4jnrllr4
+ninesixsix9
+csv2ninesixtwo3
+9vzrvg9twokbjcnvcghthreeskfpgssbdxq
+foureight6133rszlz2zvxdx
+6jfklqcdrgm
+3sixhds1kgfvzknhthreefive
+fbgnjqhnghssthzshktxll7rqnhjqjb
+5xjkchhffgz2
+threexjkeight86
+three8eightztthtfvzdxthreethree
+gdxjvzlktltseight5
+twomxfqrxqkrjhs4
+fiveeightnine1ninekhrjbmqhmpjqxtqsjpzbbvnbbzmfour
+nxnrqtsplonefive6zrthree
+8fivejmr1lzbdmvdpdrhvsthpvone2
+2sdfs1threejjxvjxp
+jhkeightskq7
+1eightfive4
+fivefqpmq7twoeightkggxgvrbmbhjdzrmn
+5twozrcnf9fourtmxjtkmfiveone
+hghfivedpgntxbpndqm4
+twodzbplxm9xlgvnmfvxh7oneightzvm
+77eightsixxlvkzfive3
+qrgz7
+eightkdcvchgfourqtrtxtnzeighteightseven1
+69onefivetwoone6
+2onetwothree81qvsmzxpvmpbgsd
+263383seven3rrmskzfgcj
+threeeightthreesixnzgkggflxfour3
+ggk6two2sixeight
+eighteightseven8nine9six
+pzthreenine2nine
+5threefivecpxfjoneightjcn
+mdmhone4ninesix92two7
+nm2twoonerqvckjtxjlzvldq
+6fourzxgncsixninenine4ninethree
+xxflpfeight5nine13qsgrqvsz8
+1threeseven4mvfzm653
+eight23three7dkgdxkrk
+9lqvhv115threezmcnbplgfzjlqmgrpjn
+2pgphcxbglfive5vtldzlrrnx
+dshlq2zcqhzssbdseven5twothree
+eightpvqcqnsprhtvlh5
+789sixtwo3
+eighttmzkfzksd39sevensix8six
+bkk5two
+gkgqxksdpn78
+577gnmbvzf7
+rcfl6foureight4mszdbmkl8one
+17n
+fvnkgxqlpflmmnf8eightsix3twokgj
+lh84twosvptcklvt
+62one
+lmlbfcxpdqlmeight94nineknk
+threenine5three4qqhtfkg
+3nine8threetwoc5ninecxcc
+sgxrhdonefcpone1tsb
+oneqjkppzkpmzcgqv7nine
+lfngqdlhone4rhfsrgdldl5mrpvzr9
+vvvhfbz52eighttbbr
+9threethree
+cnntzjvnplnineeightzdmtsx6
+4ninefourdndsvnbthree
+3zbt3nine28
+1seventhreedfggtfvvsngszlsix3
+six13nine14
+9gjzdmdzssixone
+nnxbmrdmjdhrjnhktlprtbvknninefive3662
+6rrmxmfm479tcxmvk
+ninedfchdzxbmlrjkckkjpqqxchz58
+three22sixeightrbzmdlfztwo
+jqljmhxgmfxkgsevenone77ffour
+9xbphsix
+onetwo271sixninek
+sevenbdxtwofivexscbkflmkncvh7
+jxlqvscdjz7six62
+six4five
+eightsevensixone7eight
+five4five9
+btsjninegdrcbxdrgmmg23q
+67mqtphlkhtp
+3drdmqx77
+8twoninenine
+eightfcng16kzgtfzbdfxbltn113
+fc68
+3rkqrhlskj8one8
+eightqtkls21five99
+41clcg5qmfkdkq6snghpone
+pdmnvqhg8vjrvlld9ninexcglqpgm62
+7one4two2ninencplhmrztsqjgt
+6cvdc
+2sixone76eighthqrlmfxzk
+six512nrsstwoeight
+2fourfourqlctwo
+sixb23seven3eightcbmvk
+jxthree1bvtwombbmcdbsbf
+eightzdqnjbjzd9sevenflcqqflk
+four88sixtwotnmzrltlnineoneddrsxk
+9six5
+5ninegfhvsqblftwogmmfgddncqfmqjtqvbc6
+9svv5jlfbrvpntgpqkkg68
+khglrpxfqqfour4
+qkfour1sixfnpzxkdzr
+22onefivemhsxvhllnzr2
+1onehpdqbrklhg
+bs6sjsndrz2
+8five9
+ninetwo3five5xmpkzrnqzq5
+2797two2
+91tdmpxtrkfourq7fourcvtbmsk
+four82
+three3sjgxtp86eightwof
+sszzthsixvrdbglczld3
+four1fourfour5sqknhn
+vlhzqfbht8px7kznvtffourq
+jshqhczgr3
+4two1fvvxdfms
+seight3fghflv
+tgqdzsdzdthree787
+45nrdlxtqggcseveneight
+87tkbsmfvhl5five3zqx
+6rmpdxvrlszpjtqmhcd
+fourtwothree49346eightwohq
+9kkgdv
+ndoneightsevenfive8
+threeonecc63pvgxd7
+ctwone8zbxbf
+foursevenrpkshs75two8one
+2jsvxtrrkjxjzxmh
+nkf8three
+gzbplsixeight86lxpcrzxpbx7seven
+5pzpfs
+six12ssffeightfourfivefive
+one2four71
+5onebhrjgrrltbsix
+hclv99two89nsfdfour4
+8qk8fbflndsix9
+lmvcprone16
+rknqlczt15thqlpvk4pgllfmsix16
+seven8jgpq427sixtwo1eightwokb
+nine8xgghnfive
+nineeight7ninefourrtbtd
+threetwothbdmvtcrjgsm3fivehdqlxtxnkdstgs
+4sevenfourvrqfkhspbkqjcxjkjfniner
+5three69mzqfqrhrjdqhbpmscz
+478kj1
+5bhcrpjtvjsxpskmscxclpzxkzc8five
+sevenhlxgzntwo4knxtcqscdone1
+three5dmjg
+ssxtz342sevenfivefive7
+84two9vsqlbh5fivefour
+4fiveninetwo
+8cqz
+twoptxmcmnsbgrrndfdgtwo2ppglmzcfour
+hdqfnlzrscveight5plplhvbg
+sevenmgxjzjtwonine5
+2thfbhzjsdk
+jmzsvtqjxmgstbqctdv8qc
+gv8glpnsixninesxhzbmfqxkqfd8eightwonj
+88vsqztnhst
+sixgf2sssrzvqlsm9one26twonedzq
+4five611one
+sixdvbsctpqbqfive6
+one3c
+xcnkrcdxtfivefour3nine
+7srqvlkftzztpgrfive2threesix3gtzcnfdvs
+3hqsevenlzgbf
+cggclvfppfive1dgnnqgzqzsdhdpbg
+noneight9tktnzqnttwo9fivenine
+2nfourfourmmfltjvxzfivezfntcxfctqsdckcjl
+htzvlsixsix8twoone
+91xnrqfdqsbrvf6sixtfour
+hvtwonenzqnine9fourvtcdndzptfourx
+sixfiverp8fourbnfgnlkqld
+1728
+18nineonejhbvdbm22jgrbsgf
+2rcpqxgsix8fivebscvblxzcmbztrlsx
+9threetwoeightxbsrxpjns4zkpztwo
+six6sixfive
+zpqjsckrcztv5
+3nvsixdnmfqplqtqpq9
+onesixeightthree6nine74
+66sdh
+235lmnrgxztt2nctntsgfive57
+fivegnzfnbfpvnl72fournine
+3jrfive9srqvsxxfz
+vs4threeeighttwotrcpphdq
+zlfcpfptwoninescshbtcdv58sixrkxfour
+eightfour8
+4onesfkbnnfsevensix
+fourhjsbvjgqhrvtdvmrzrtsixpglhrlcrrkr2
+fourthreedczqpjskdsqnnhczhdc47
+3sevenfourtwobn
+3fivesix1
+4qbtlplbl25
+66grjtlgsbflfjbcdmdnnine6
+1rbszctwo7pkmvsixsevenoneightqc
+snpvmbppvtwofiveeight1rnmfkrsfbhs
+5frcvcsixmlhfcv
+2nbd
+557sevengrvxddpdgfzsqsqx6three
+five41lrlkdmhsbjq
+eight3vzzgspkgqh4eighteightstthdqm
+vqctjspmq9
+four12clqrgts
+45two8zv
+c4xklll3
+four3hhfivedtj
+six55two3
+gxdttwo256
+njthree45
+7threevl5174
+bkvcbfournine6seven
+four8jjg
+725rgkxrztbhjmsbxgvc2
+ninetjqd48
+xbpthl9x
+1sbf8seven
+qfsbld6five7four18
+9kvbcnlctngbthqlbqlbfhttmf51
+98eight3vfcxzbsvfour4one
+tlbpdxbglrcqppkcb6two6rbffxpzmnntpdr
+fivevgnzjkjcfeight7twozvseven
+vjmdjsrl8onetrnlgsclrfmpvkdblfourktwonet
+tvvkszfvnineeightninetwo9
+2twollqsbnconescjjj
+one23qz
+nine2vbglpdpvfhrqp8eight
+threeone7seven
+vxxone8onetbgplp3
+two1mlqrfour7
+ninezdkbvkbonetmzxgszqxdnttkgsgqd7eight
+vrfbzcfourfivenlgmvktszpthreepqkgfnjfc9rfmkxbv
+ninezhsfngmbc5fivers
+tzjxrncfnine1cglgmnmxhssevenbdmxfjtg
+sevenseventwo5five9seventhreeflvgdbstfr
+7rggpvgkmone
+1veight
+41vk7two5
+7onetwoone6
+kvm25nine
+onekzcjprtxbncpqchpxpvtttvgmqfour3pxpcmfourtwo
+chrrlnddfivefive5
+ttvnlchqz8hrxhmgqrfour9rmkkdlr14
+5jcmdfnldlq
+6431khcknnine7
+onegtmzngkqgfggfmhxshnzltdbkvmkjjvnfpkclhxntvngvlnqd3
+q4fzzrpt
+cllbnine5
+six18ddmk22six
+2knsdjp2nphnonesevenfive
+vqjkllm1threemfrnlvrmjzzsnhmxsxtwosgxjgjcqrtwo
+six4onefhpxkpnqfivekbxhmxtbx
+djsptzspn3eighthb9nthreelhpzd
+twofdvrmxrcmfive27zdcssbvcsthree
+5eight5ptfgcnthree1zjvkk3l
+3one8two
+bsdphtbdfour1twosevensevensix92
+four7six4smppkbtwo4
+87dpqjbbtwo78662
+1ninefour8four32
+232spbt1jfzfourthree
+3cxxkqldtwosevenninetwomcdvls7
+5seven7pgnkdjgckfive
+rvmfpjs2threespszkcvfklpdhtmbnseven2seventjrhx
+eightfive3twonbxs5
+3frglvrm32
+19778gmtrsjkcrdqlptpjzg
+zpvskbdztrone5eight3sixnmcpdshrgblddrht
+7seven2tdnblk782eight
+mjjldone2cqmlmmzxbt
+hfponeightoneplk66threezzklrkrmvronekhqsrnvm
+lghjkgdssfour423sevensix
+sevenfmqtwo1onecmrhrzhl
+dmpf2fivethxhpss27jn
+2lnpfrdfour6x
+onetpztmmfr2
+66qlzhrrlchcxznsjrfxqxkone
+9fivenlzrgm
+mstbglvtxnzlnhjrltwo238bsfourczkvctl
+zkz6dcdsfgssl8b
+cgnqsdeighteightfourhnpkdvggdsixfour3
+96xschgpnlktsix4eight537
+31c
+4smrxzzpvqmrxhmltcmgq8zrxftd38
+onemncsrqlklxdx9ngpbxhxpk7
+gzr2sevenhjsczr5twoqsmhj
+nkfh4eight9gzpkvvxjsqfjbt
+two2nine
+cxxqmzfnm3mbsmltpkpfour6fourfrjjcztt5
+lxnqtpzldptcvnlcggonehndzmx7863
+3fmgl36lbcvrrczdfqdss
+fourfour4xjxgmnctwothree
+nineseveneightgrdvffkntwo948
+fouronenine8
+8xfktsxszhn53
+6onedgffr57
+krmvzbhctztlpfour9fcmdscctdhsf535
+fbjgdrzxv1four573vljtseven
+8three9ngrjrhh
+1gqfoneninegzpbjtbd74
+6vkf
+9eightzmfsbxqttg1one
+56k9ninerqprllq
+jnhlpkbxvm6three6seventwonegp
+j929
+sevensixnxgbtfksix5fbdvgkbd77
+39sevencpdcbnshpcsevenhggbcthree1znldhfngnk
+618fourtzfrql
+kldcjxktwo5fivetwoninehsbmrgtn
+msvjzqteightthree3
+2xtvr581xsbctkfftjprmb
+seven13dvstp848dsbllng
+sevencqhmth7tdshrtrphx9
+three2eight8six6
+fourprlhnl7vczqdtl8bjmncrrfpzk
+5four1one5
+seventhreethknine5
+two6vqgpzvmhlhfourklvxvhmnlqnmrhknstwo
+4bvxhmfz2bktbfltj
+nk9
+xjb713vmxzcfxl3ninegkjrcq
+rrmplxeight1znine
+zsjgngpfourfoureighttwo1
+99twojqzlggpseven
+eightfivetwo7
+8ninevlkxsptd2ninenine
+4hrzzjxp26sixpxjxphmkpc8
+vlqsf4ntssmfrz
+eight93tflqhb9two76six
+ttxfgqtrfournine9pqqgd
+7274mmjgcssvrsix
+1threesix5dmkdtjsmptthreeqgfgsix
+msrtbbschxmvcm2ctprdlnkdzthree
+dztlvgn3two
+h7crsblhtp
+seven5eight7qrgxlninethreetwobbsjdbxcvt
+2hfbeight
+eightrdlfourtwo3vzrlsbcjndnineone
+ljxbtvhztkkb4three94fiveeight
+3fourkbpmpctthreetwovzhgq
+6xznbcgdmng
+3jl5zlkbjpeight1tvmrqdlk
+23sjvtghccsevenninesixzlhgzqtkhb
+xptf34eightp4cdqcv
+gfneighthvf3nine
+threeeightthreenineninethreetwoone5
+9nine22qdfzgbdsd7two
+gfourtwotbxddnxzc2
+four84gxllvp76four
+t86
+nheightwofive525two
+hh115
+lqvxpsxthreethreefive34three
+sgvqhjqdvtzfnine6bgjcbn2tqrvgfmdtdbh
+nine2seventwop
+7hllxxndzggvsrsh9zrktwoone2rxqczzbqpx
+s2one574
+9fourseventzqfseven
+62six1jdqcnqm4sixjsjvnx
+five6fpktwo1l3
+five1d2
+fbnoneightknthree6
+4fbtxqsix6dxpjclhtlk
+8vggprkfjrpqz8hhlvffmfiveone8
+rz29eightfghseven
+two9four98cgmntgcncsmppz
+bmrvhsz4twotwo
+1oneeightthreeeightfourtwo
+fivethreefvz9rzvzdqxqbmtxcnqc
+3oneqvseight56lkxjk
+6l99six
+dsevenninefour48kjs
+1sixxvrsevenone7
+lpmdghtcdj3nine28g77glk
+tnkhrdone1hhtfzhnz
+4cpzzht
+foursixlmtmvrptqonejmssjldcnz8one
+1bnd5slzddmkmvthreep4three
+7jlrm
+seventhree3
+vmjsix8sevenktbrxnftfour
+gmczxbkcgsixseven6six
+9oneone2hhnj8
+bbpeightjbtp4qfpks2four
+twoeight3
+7mqnzkddm3hrqvhdvzgvgbnfcjtfour
+4onesixgkcsix
+chmkonenine1btgnldh
+dpxzrthkjzdfkgpkdfvxveight5
+hxlfiveeight6
+3xlkg23fivethreesixeightksmc
+nfourrjdqx4four6
+ptzrcdzthreer3phpkqlftwo24
+five7sevenjpjmmppfive
+11sevenfivezcglsdkhqffivethreeseven5
+4eight5mjlkzrgnmlnmxntqmtlxmqlkjccttcpmgznfouroneightk
+1oneightx
+25fivevhtpblpfthreefour2xrzsix
+eightfour41four8fiveone3
+pxmrbcqt22vfvzvvp4seven3
+3zqbqnnonesxtgz9eightonepqnld
+d2six5dmlqczzrtp79brzzq
+nine48
+ninevbjkjcd11qhtvb
+six4nine1four2three5
+lcnvnxgzssonethree5mnvlsevenclrcpxbjbzvhlj9
+8onethree6n1
+98ddgtwov6nzvjzsscd
+bklvmzjrqgfqx7
+5eight95ninetwo8
+qcrgbmzlztvtzrsjsixmvps2
+jsnmkd9seveneight
+mkdzj28twohhmkctnsix
+kb38sixttdhv9three
+8eightninetwo
+twoppvc7
+sixfour5sj6cdfjsskfb
+242p28mxh8zrkvzp
+sixnine5kqqrhxms
+21sixfivepmspvnbscjc
+threetjgcjpvflndq98
+sgonefivefive8
+nine5sevenfouronedsqpkgpthbeight3hrfdmcql
+1sixkhqpcv5
+bsnnone3
+46sevenbnfsgnjldbtjnsjlmhvjrp8sevenx
+twotwosevenonelzlpnmkdqq2rqthff
+sixfournbzqfhff6jdlfhpt974
+5sixnvs2trqprv
+nine8ninefourninelgcxntninektmhgjqrpd1
+hsjmpqkpkqzjnmgbz2nine6four
+6two7jzfivethree25four
+twobxtwosixfbhj5prfntlmfour
+4lfsevenxsvvlmbzcnprsix
+45lxtrdvsgfzzcmzjz7ninenvcvc
+qfzvfthree9
+sevenlxfzcsevenseven4
+sjpqvfmx9twonep
+qsljtpgdprjbkgzcnv5seveneightseven
+zmhdkvltbxv3qftmt143
+5sevennh68
+sevenfour6rg
+1sixonesixfournbbz9hfeight
+sevensevenfour265one
+88sixtwo
+one5rcczjeightknjeight
+qgftwohszlmfgjnn7
+xbtcpx3htlseven
+7tnmvjdj4zlltljq8pdlnfghnd
+jcpcgznmmnine4ninenine
+zvdsbmlvn5four555
+threejpnbcbttggm9onefour4vtjhdfjsnz
+7x7
+veightone1
+eightjlkckhqjfonesix94twoeightvggdqxgcn
+2two2fdzkxgfour9sjtfourvxklldpvjm
+849ndjngjhs65hgvdbcxps
+fiveeightsevenseventfqzdxnhxkxgmnqmdjmxmdc35
+4sevenqnhvszlfour
+seightwozbjkfsgk5three1tcpbshgfzeightfive
+fourgxmqgpgbtwo4
+4nine9
+twokfvsvfgdtmtwom2xlkjseven
+9one43ninedrtznff
+zlfive98rfpmnsevennljlhbxhcn
+lmfgxfdsevenchrkbhxlrrssbcqqf7fivectglcvrsrg8
+6twofive3two
+mchm6
+mbvtbcjvv33rqfsllshb
\ No newline at end of file
diff --git a/2023/gareth/go.mod b/2023/gareth/go.mod
new file mode 100644
index 0000000..f7f4473
--- /dev/null
+++ b/2023/gareth/go.mod
@@ -0,0 +1,14 @@
+module awesomeProject
+
+go 1.21
+
+require (
+ github.com/stretchr/testify v1.8.4
+ golang.org/x/exp v0.0.0-20231127185646-65229373498e
+)
+
+require (
+ github.com/davecgh/go-spew v1.1.1 // indirect
+ github.com/pmezard/go-difflib v1.0.0 // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
+)
diff --git a/2023/gareth/go.sum b/2023/gareth/go.sum
new file mode 100644
index 0000000..0c24d34
--- /dev/null
+++ b/2023/gareth/go.sum
@@ -0,0 +1,12 @@
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No=
+golang.org/x/exp v0.0.0-20231127185646-65229373498e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/2023/gareth/main.go b/2023/gareth/main.go
new file mode 100644
index 0000000..ffb146a
--- /dev/null
+++ b/2023/gareth/main.go
@@ -0,0 +1,12 @@
+package main
+
+import (
+ "awesomeProject/day01"
+ "awesomeProject/utils"
+ "fmt"
+)
+
+func main() {
+ fmt.Printf("part 1: %d\n", day01.Part1(utils.Readfile(01)))
+ fmt.Printf("part 2: %d\n", day01.Part2(utils.Readfile(01)))
+}
diff --git a/2023/gareth/utils/grid2d/grid2d.go b/2023/gareth/utils/grid2d/grid2d.go
new file mode 100644
index 0000000..4c9ab75
--- /dev/null
+++ b/2023/gareth/utils/grid2d/grid2d.go
@@ -0,0 +1,74 @@
+package grid2d
+
+import (
+ "strings"
+
+ "adventofcode2022/utils"
+)
+
+type Grid[T any] struct {
+ sizeX, sizeY int
+ matrix [][]T
+ empty T
+}
+
+func NewGrid[T any](sizeX, sizeY int, empty T) *Grid[T] {
+ matrix := make([][]T, sizeY)
+ rows := make([]T, sizeX*sizeY)
+ for i := 0; i < sizeX*sizeY; i++ {
+ rows[i] = empty
+ }
+
+ j := 0
+ for i := 0; i < sizeY; i++ {
+ matrix[i] = rows[j : j+sizeX : j+sizeX]
+ j += sizeX
+ }
+ return &Grid[T]{
+ sizeX: sizeX,
+ sizeY: sizeY,
+ matrix: matrix,
+ empty: empty,
+ }
+}
+
+func (g *Grid[T]) SizeX() int {
+ return g.sizeX
+}
+
+func (g *Grid[T]) SizeY() int {
+ return g.sizeY
+}
+
+func (g *Grid[T]) Get(x, y int) T {
+ if x < 0 || x >= g.sizeX {
+ return g.empty
+ }
+ if y < 0 || y >= g.sizeY {
+ return g.empty
+ }
+ return g.matrix[y][x]
+}
+
+func (g *Grid[T]) Set(x, y int, v T) {
+ if x < 0 || x >= g.sizeX {
+ panic("invalid x")
+ }
+ if y < 0 || y >= g.sizeY {
+ panic("invalid y")
+ }
+ g.matrix[y][x] = v
+}
+
+func (g *Grid[T]) StringWithFormatter(formatter func(T, int, int) string) string {
+ var r strings.Builder
+ for j := 0; j < g.sizeY; j++ {
+ for i := 0; i < g.sizeX; i++ {
+ _, err := r.WriteString(formatter(g.matrix[j][i], i, j))
+ utils.PanicOnErr(err)
+ }
+ _, err := r.WriteRune('\n')
+ utils.PanicOnErr(err)
+ }
+ return r.String()
+}
diff --git a/2023/gareth/utils/inputs/inputs.go b/2023/gareth/utils/inputs/inputs.go
new file mode 100644
index 0000000..2f6ed1e
--- /dev/null
+++ b/2023/gareth/utils/inputs/inputs.go
@@ -0,0 +1,45 @@
+package inputs
+
+import (
+ "strings"
+
+ "adventofcode2022/utils"
+ "adventofcode2022/utils/grid2d"
+ sparsegrid "adventofcode2022/utils/sparseGrid"
+)
+
+func ToInts(input string, sep string) []int {
+ var r []int
+ for _, line := range strings.Split(input, sep) {
+ if line != "" {
+ r = append(r, utils.MustAtoi(line))
+ }
+ }
+ return r
+}
+
+func ToGrid2D[T any](input, rowSep, colSep string, empty T, conv func(string) T) *grid2d.Grid[T] {
+ lines := strings.Split(input, rowSep)
+
+ grid := grid2d.NewGrid(len(lines[0]), len(lines), empty)
+ for y, line := range lines {
+ for x, v := range strings.Split(line, colSep) {
+ grid.Set(x, y, conv(v))
+ }
+ }
+
+ return grid
+}
+
+func ToSparseGrid[T comparable](input, rowSep, colSep string, empty T, conv func(string) T) *sparsegrid.SparseGrid[T] {
+ lines := strings.Split(input, rowSep)
+
+ grid := sparsegrid.NewGrid(empty)
+ for y, line := range lines {
+ for x, v := range strings.Split(line, colSep) {
+ grid.Set(x, y, conv(v))
+ }
+ }
+
+ return grid
+}
diff --git a/2023/gareth/utils/sparseGrid/sparseGrid.go b/2023/gareth/utils/sparseGrid/sparseGrid.go
new file mode 100644
index 0000000..0c5ca29
--- /dev/null
+++ b/2023/gareth/utils/sparseGrid/sparseGrid.go
@@ -0,0 +1,81 @@
+package sparsegrid
+
+import (
+ "fmt"
+ "strings"
+
+ "adventofcode2022/utils"
+)
+
+type SparseGrid[T comparable] struct {
+ minX, maxX, minY, maxY int
+ data map[string]T
+ empty T
+}
+
+func NewGrid[T comparable](empty T) *SparseGrid[T] {
+ return &SparseGrid[T]{
+ minX: utils.MaxInt,
+ maxX: utils.MinInt,
+ minY: utils.MaxInt,
+ maxY: utils.MinInt,
+ data: map[string]T{},
+ empty: empty,
+ }
+}
+
+func (g *SparseGrid[T]) SizeX() (int, int) {
+ return g.minX, g.maxX
+}
+
+func (g *SparseGrid[T]) SizeY() (int, int) {
+ return g.minY, g.maxY
+}
+
+func (g *SparseGrid[T]) Visited() int {
+ return len(g.data)
+}
+
+func (g *SparseGrid[T]) Get(x, y int) T {
+ k := key(x, y)
+ v, ok := g.data[k]
+ if !ok {
+ return g.empty
+ }
+ return v
+}
+
+func (g *SparseGrid[T]) Set(x, y int, v T) {
+ k := key(x, y)
+ current, ok := g.data[k]
+ if ok && v == current {
+ return
+ } else if !ok && v == g.empty {
+ return
+ } else if v == g.empty {
+ delete(g.data, k)
+ } else {
+ g.data[k] = v
+ g.minX = utils.Min(g.minX, x)
+ g.maxX = utils.Max(g.maxX, x)
+ g.minY = utils.Min(g.minY, y)
+ g.maxY = utils.Max(g.maxY, y)
+ }
+}
+
+func (g *SparseGrid[T]) StringWithFormatter(formatter func(T, int, int) string) string {
+ var r strings.Builder
+ for j := g.minY; j <= g.maxY; j++ {
+ for i := g.minX; i <= g.maxX; i++ {
+ _, err := r.WriteString(formatter(g.Get(i, j), i, j))
+ utils.PanicOnErr(err)
+ }
+ _, err := r.WriteRune('\n')
+ utils.PanicOnErr(err)
+ }
+ return r.String()
+}
+
+func key(x, y int) string {
+ return fmt.Sprintf("%d:%d", x, y)
+}
diff --git a/2023/gareth/utils/utils.go b/2023/gareth/utils/utils.go
new file mode 100644
index 0000000..973c9ad
--- /dev/null
+++ b/2023/gareth/utils/utils.go
@@ -0,0 +1,207 @@
+package utils
+
+import (
+ "bufio"
+ "fmt"
+ "io"
+ "os"
+ "reflect"
+ "regexp"
+ "strconv"
+ "strings"
+
+ "golang.org/x/exp/constraints"
+)
+
+func PanicOnErr(err error) {
+ if err != nil {
+ panic(err)
+ }
+}
+
+const MaxInt = int(^uint(0) >> 1)
+const MinInt = ^MaxInt
+
+func Max[T constraints.Ordered](a, b T) T {
+ if a > b {
+ return a
+ }
+ return b
+}
+
+func Min[T constraints.Ordered](a, b T) T {
+ if a < b {
+ return a
+ }
+ return b
+}
+
+func SliceMinMax[T constraints.Ordered](slice []T) (*T, *T) {
+ if len(slice) == 0 {
+ return nil, nil
+ }
+ min := &slice[0]
+ max := &slice[0]
+ for i, v := range slice {
+ if v < *min {
+ min = &slice[i]
+ }
+ if v > *max {
+ max = &slice[i]
+ }
+ }
+ return min, max
+}
+
+func MustAtoi(s string) int {
+ v, err := strconv.Atoi(s)
+ PanicOnErr(err)
+ return v
+}
+
+// Returns key from map[T]int which has the max value
+func MapFindMax(m interface{}) interface{} {
+ var maxK interface{} = nil
+ var maxV = MinInt
+ iter := reflect.ValueOf(m).MapRange()
+ for iter.Next() {
+ k := iter.Key()
+ v := int(iter.Value().Int())
+ if v > maxV {
+ maxV = v
+ maxK = k.Interface()
+ }
+ }
+ return maxK
+}
+
+// Returns key from map[T]int which has the min value
+func MapFindMin(m interface{}) interface{} {
+ var minK interface{} = nil
+ var minV = MaxInt
+ iter := reflect.ValueOf(m).MapRange()
+ for iter.Next() {
+ k := iter.Key()
+ v := int(iter.Value().Int())
+ if v < minV {
+ minV = v
+ minK = k.Interface()
+ }
+ }
+ return minK
+}
+
+func Readfile(day int) string {
+ filename := fmt.Sprintf("day%02d/input.txt", day)
+ file, err := os.Open(filename)
+ PanicOnErr(err)
+ defer file.Close()
+
+ reader := bufio.NewReader(file)
+ contents, err := io.ReadAll(reader)
+ PanicOnErr(err)
+
+ return strings.TrimSuffix(string(contents), "\n")
+}
+
+func ParseToStruct(re *regexp.Regexp, input string, target interface{}) bool {
+ m := re.FindStringSubmatch(input)
+ if m == nil {
+ return false
+ }
+
+ var useOffset bool
+
+ for i, name := range re.SubexpNames() {
+ if i == 0 {
+ continue
+ }
+ var field reflect.Value
+ if name == "" {
+ // use offset
+ if i == 1 {
+ useOffset = true
+ } else if !useOffset {
+ panic("can't mix named and unnamed subexpressions")
+ }
+ field = reflect.ValueOf(target).Elem().Field(i - 1)
+ } else {
+ // use name
+ if i == 1 {
+ useOffset = false
+ } else if useOffset {
+ panic("can't mix named and unnamed subexpressions")
+ }
+ field = reflect.ValueOf(target).Elem().FieldByName(name)
+ }
+ if field.Kind() == reflect.String {
+ field.SetString(m[i])
+ } else if field.Kind() == reflect.Int {
+ v, err := strconv.Atoi(m[i])
+ PanicOnErr(err)
+ field.SetInt(int64(v))
+ } else if field.Kind() == reflect.Uint8 {
+ if len(m[i]) != 1 {
+ panic(fmt.Sprintf("expecting 1 char, got: %s", m[i]))
+ }
+ field.SetUint(uint64(m[i][0]))
+ } else {
+ panic(fmt.Sprintf("unknown kind: %s", field.Kind()))
+ }
+ }
+ return true
+}
+
+func MustParseToStruct(re *regexp.Regexp, input string, target interface{}) {
+ if !ParseToStruct(re, input, target) {
+ panic(fmt.Errorf("failed to parse: %s", input))
+ }
+}
+
+func CharToLower(c byte) byte {
+ return strings.ToLower(string(c))[0]
+}
+
+func CharToUpper(c byte) byte {
+ return strings.ToUpper(string(c))[0]
+}
+
+func Contains(haystack []string, needle string) bool {
+ for _, s := range haystack {
+ if s == needle {
+ return true
+ }
+ }
+ return false
+}
+
+func Abs[T constraints.Signed](x T) T {
+ if x < 0 {
+ return -x
+ }
+ return x
+}
+
+func Gcd(x, y int) int {
+ if x <= 0 || y <= 0 {
+ panic(fmt.Errorf("invalid input: %d, %d", x, y))
+ }
+ if x == y {
+ return x
+ }
+ if x > y {
+ return Gcd(x-y, y)
+ } else {
+ return Gcd(x, y-x)
+ }
+}
+
+func Sign[T constraints.Signed](x T) int {
+ if x < 0 {
+ return -1
+ } else if x > 0 {
+ return 1
+ } else {
+ return 0
+ }
+}