input<-read_lines("Day12Sample1.txt")
### Garden Matrix
garden<-matrix(nrow=length(input),ncol=nchar(input[1]))
for(i in 1:length(input)){garden[i,]<-unlist(str_split(input[i],""))}
Part 1
Search - the search starts in the upper left hand corner and moves
through each cell to the bottom right hand corner. When it gets to a
plot that it hasn’t been to before, it searches around until it finds
every plot in the region and the area and perimeter of the region. The
area is the count of all plots. The perimeter is found by testing every
direction - if there’s a direction where you’d go into another region
(or off the edge of the garden), the perimeter increments by one
fencecost<-function(g){
###
maxc<-ncol(g)
maxr<-nrow(g)
beenthere<-dict()
totalfence<-0
### until everything has been found -
x<-1
y<-1
while(beenthere$size()<maxr*maxc){
### if have been there already, keep looking for somewhere that it hasn't been yet
while(beenthere$has(str_flatten(c(x,y),"~"))){
x<-x+1
if(x>maxc){
y<-y+1
x<-1}}
a<-0
p<-0
r<-g[y,x]
q<-queue()
### just to check
q$push(c(x,y))
while(q$size()>0){
nxt<-q$pop()
nxtx<-nxt[1]
nxty<-nxt[2]
## if have been there, next
if(beenthere$has(str_flatten(c(nxtx,nxty),"~"))){
next}else{beenthere$set(str_flatten(c(nxtx,nxty),"~"),r)}
### if this is a new place, add 1 to the area
a<-a+1
### check on all 4 sides
if(nxtx>1){
if(g[nxty,(nxtx-1)]==r){
q$push(c(nxtx-1,nxty))}else{
p<-p+1}}else{p<-p+1}
if(nxtx<maxc){
if(g[nxty,(nxtx+1)]==r){
q$push(c(nxtx+1,nxty))}else{
p<-p+1}}else{p<-p+1}
if(nxty>1){
if(g[(nxty-1),nxtx]==r){
q$push(c(nxtx,nxty-1))}else{
p<-p+1}}else{p<-p+1}
if(nxty<maxr){
if(g[(nxty+1),nxtx]==r){
q$push(c(nxtx,nxty+1))}else{
p<-p+1}}else{p<-p+1}
}
totalfence<-totalfence+(a*p)}
totalfence}
part1<-fencecost(garden)
part1
[1] 140
Part 2
Got the idea from online (subreddit) to count corners as there is one
corner for every side. Otherwise, it works a lot like part 1
cheapfencing<-function(g){
###
maxc<-ncol(g)
maxr<-nrow(g)
beenthere<-dict()
totalfence<-0
### until everything has been found -
x<-1
y<-1
while(beenthere$size()<maxr*maxc){
### if have been there already, keep looking for somewhere that it hasn't been yet
while(beenthere$has(str_flatten(c(x,y),"~"))){
x<-x+1
if(x>maxc){
y<-y+1
x<-1}}
a<-0
corner<-0
r<-g[y,x]
q<-queue()
### just to check
q$push(c(x,y))
while(q$size()>0){
nxt<-q$pop()
nxtx<-nxt[1]
nxty<-nxt[2]
## for cornering
up<-FALSE
left<-FALSE
down<-FALSE
right<-FALSE
## if have been there, next
if(beenthere$has(str_flatten(c(nxtx,nxty),"~"))){
next}else{beenthere$set(str_flatten(c(nxtx,nxty),"~"),r)}
### if this is a new place, add 1 to the area
a<-a+1
### check on all 4 sides
if(nxtx>1){
if(g[nxty,(nxtx-1)]==r){
q$push(c(nxtx-1,nxty))
left<-TRUE}else{
left<-FALSE}}else{left<-FALSE}
if(nxtx<maxc){
if(g[nxty,(nxtx+1)]==r){
q$push(c(nxtx+1,nxty))
right<-TRUE}else{
right<-FALSE}}else{right<-FALSE}
if(nxty>1){
if(g[(nxty-1),nxtx]==r){
q$push(c(nxtx,nxty-1))
up<-TRUE}else{
up<-FALSE}}else{up<-FALSE}
if(nxty<maxr){
if(g[(nxty+1),nxtx]==r){
q$push(c(nxtx,nxty+1))
down<-TRUE}else{
down<-FALSE}}else{down<-FALSE}
### to find corners - check in two cornerly directions. If both are false, corner
### if both are true, then check kitty corner - if it is a different region, then corner
if(up==FALSE && left==FALSE){corner<-corner+1}
if(up==FALSE && right==FALSE){corner<-corner+1}
if(down==FALSE && left==FALSE){corner<-corner+1}
if(down==FALSE && right==FALSE){corner<-corner+1}
if(up==TRUE && left==TRUE && g[(nxty-1),(nxtx-1)]!=r){corner<-corner+1}
if(up==TRUE && right==TRUE && g[(nxty-1),(nxtx+1)]!=r){corner<-corner+1}
if(down==TRUE && left==TRUE && g[(nxty+1),(nxtx-1)]!=r){corner<-corner+1}
if(down==TRUE && right==TRUE && g[(nxty+1),(nxtx+1)]!=r){corner<-corner+1}}
totalfence<-totalfence+(a*corner)}
totalfence}
part2<-cheapfencing(garden)
part2
[1] 80
LS0tDQp0aXRsZTogIkRheSAxMiBOb3RlYm9vayINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShyZXNoYXBlMikNCmxpYnJhcnkoa25pdHIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShzdHJpbmdyKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KHJlYWRyKQ0KbGlicmFyeShjb2xsZWN0aW9ucykNCm9wdGlvbnMoc2NpcGVuID0gOTk5KQ0KYGBgDQoNCmBgYHtyfQ0KaW5wdXQ8LXJlYWRfbGluZXMoIkRheTEyU2FtcGxlMS50eHQiKQ0KIyMjIEdhcmRlbiBNYXRyaXgNCmdhcmRlbjwtbWF0cml4KG5yb3c9bGVuZ3RoKGlucHV0KSxuY29sPW5jaGFyKGlucHV0WzFdKSkNCmZvcihpIGluIDE6bGVuZ3RoKGlucHV0KSl7Z2FyZGVuW2ksXTwtdW5saXN0KHN0cl9zcGxpdChpbnB1dFtpXSwiIikpfQ0KYGBgDQoNCmBgYHtyLGluY2x1ZGU9RkFMU0UsZXZhbD1GQUxTRX0NCmJnPC1tZWx0KGdhcmRlbikNCmJhc2ljZ3JhcGg8LWdncGxvdChkYXRhPWJnLGFlcyh4PC1WYXIyLHk9VmFyMSxmaWxsPXZhbHVlKSkrDQogIGdlb21fdGlsZSgpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50aWNrcy54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJub25lIikrDQogIHNjYWxlX3lfcmV2ZXJzZSgpKw0KICBjb29yZF9maXhlZCgpDQpiYXNpY2dyYXBoDQpgYGANCg0KYGBge3IgZWNobz1GQUxTRSwgZmlnLmNhcD0iR3JhcGggb2YgdGhlIGdhcmRlbiIsIG91dC53aWR0aCA9ICc1MCUnfQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoImdhcmRlbi5wbmciKQ0KYGBgDQoNCiMjIFBhcnQgMQ0KU2VhcmNoICAtIHRoZSBzZWFyY2ggc3RhcnRzIGluIHRoZSB1cHBlciBsZWZ0IGhhbmQgY29ybmVyIGFuZCBtb3ZlcyB0aHJvdWdoIGVhY2ggY2VsbCB0byB0aGUgYm90dG9tIHJpZ2h0IGhhbmQgY29ybmVyLiBXaGVuIGl0IGdldHMgdG8gYSBwbG90IHRoYXQgaXQgaGFzbid0IGJlZW4gdG8gYmVmb3JlLCBpdCBzZWFyY2hlcyBhcm91bmQgdW50aWwgaXQgZmluZHMgZXZlcnkgcGxvdCBpbiB0aGUgcmVnaW9uIGFuZCB0aGUgYXJlYSBhbmQgcGVyaW1ldGVyIG9mIHRoZSByZWdpb24uIFRoZSBhcmVhIGlzIHRoZSBjb3VudCBvZiBhbGwgcGxvdHMuICBUaGUgcGVyaW1ldGVyIGlzIGZvdW5kIGJ5IHRlc3RpbmcgZXZlcnkgZGlyZWN0aW9uIC0gaWYgdGhlcmUncyBhIGRpcmVjdGlvbiB3aGVyZSB5b3UnZCBnbyBpbnRvIGFub3RoZXIgcmVnaW9uIChvciBvZmYgdGhlIGVkZ2Ugb2YgdGhlIGdhcmRlbiksIHRoZSBwZXJpbWV0ZXIgaW5jcmVtZW50cyBieSBvbmUNCg0KYGBge3J9DQpmZW5jZWNvc3Q8LWZ1bmN0aW9uKGcpew0KICAjIyMNCiAgbWF4YzwtbmNvbChnKQ0KICBtYXhyPC1ucm93KGcpDQogIGJlZW50aGVyZTwtZGljdCgpDQogIHRvdGFsZmVuY2U8LTANCiAgIyMjIHVudGlsIGV2ZXJ5dGhpbmcgaGFzIGJlZW4gZm91bmQgLSANCiAgeDwtMQ0KICB5PC0xDQogIHdoaWxlKGJlZW50aGVyZSRzaXplKCk8bWF4ciptYXhjKXsNCiAgICAjIyMgaWYgaGF2ZSBiZWVuIHRoZXJlIGFscmVhZHksIGtlZXAgbG9va2luZyBmb3Igc29tZXdoZXJlIHRoYXQgaXQgaGFzbid0IGJlZW4geWV0DQogICAgd2hpbGUoYmVlbnRoZXJlJGhhcyhzdHJfZmxhdHRlbihjKHgseSksIn4iKSkpew0KICAgICAgeDwteCsxDQogICAgICBpZih4Pm1heGMpew0KICAgICAgICB5PC15KzENCiAgICAgICAgeDwtMX19DQogICAgYTwtMA0KICAgIHA8LTANCiAgICByPC1nW3kseF0NCiAgICBxPC1xdWV1ZSgpDQogICAgIyMjIGp1c3QgdG8gY2hlY2sNCiAgICBxJHB1c2goYyh4LHkpKQ0KICAgIHdoaWxlKHEkc2l6ZSgpPjApew0KICAgICAgbnh0PC1xJHBvcCgpDQogICAgICBueHR4PC1ueHRbMV0NCiAgICAgIG54dHk8LW54dFsyXQ0KICAgICAgIyMgaWYgaGF2ZSBiZWVuIHRoZXJlLCBuZXh0DQogICAgICBpZihiZWVudGhlcmUkaGFzKHN0cl9mbGF0dGVuKGMobnh0eCxueHR5KSwifiIpKSl7DQogICAgICAgIG5leHR9ZWxzZXtiZWVudGhlcmUkc2V0KHN0cl9mbGF0dGVuKGMobnh0eCxueHR5KSwifiIpLHIpfQ0KICAgICAgIyMjIGlmIHRoaXMgaXMgYSBuZXcgcGxhY2UsIGFkZCAxIHRvIHRoZSBhcmVhDQogICAgICBhPC1hKzENCiAgICAgICMjIyBjaGVjayBvbiBhbGwgNCBzaWRlcw0KICAgICAgaWYobnh0eD4xKXsNCiAgICAgICAgaWYoZ1tueHR5LChueHR4LTEpXT09cil7DQogICAgICAgICAgcSRwdXNoKGMobnh0eC0xLG54dHkpKX1lbHNlew0KICAgICAgICAgICAgcDwtcCsxfX1lbHNle3A8LXArMX0NCg0KICAgICAgaWYobnh0eDxtYXhjKXsNCiAgICAgICAgaWYoZ1tueHR5LChueHR4KzEpXT09cil7DQogICAgICAgICAgcSRwdXNoKGMobnh0eCsxLG54dHkpKX1lbHNlew0KICAgICAgICAgICAgcDwtcCsxfX1lbHNle3A8LXArMX0NCiAgICAgICAgDQogICAgICBpZihueHR5PjEpew0KICAgICAgICBpZihnWyhueHR5LTEpLG54dHhdPT1yKXsNCiAgICAgICAgICBxJHB1c2goYyhueHR4LG54dHktMSkpfWVsc2V7DQogICAgICAgICAgICBwPC1wKzF9fWVsc2V7cDwtcCsxfQ0KICAgICAgICANCiAgICAgIGlmKG54dHk8bWF4cil7DQogICAgICAgIGlmKGdbKG54dHkrMSksbnh0eF09PXIpew0KICAgICAgICAgIHEkcHVzaChjKG54dHgsbnh0eSsxKSl9ZWxzZXsNCiAgICAgICAgICAgIHA8LXArMX19ZWxzZXtwPC1wKzF9DQogICAgICB9DQogICAgdG90YWxmZW5jZTwtdG90YWxmZW5jZSsoYSpwKX0NCiAgdG90YWxmZW5jZX0NCg0KDQoNCmBgYA0KDQpgYGB7cn0NCnBhcnQxPC1mZW5jZWNvc3QoZ2FyZGVuKQ0KcGFydDENCmBgYA0KIyMgUGFydCAyDQpHb3QgdGhlIGlkZWEgZnJvbSBvbmxpbmUgKHN1YnJlZGRpdCkgdG8gY291bnQgY29ybmVycyBhcyB0aGVyZSBpcyBvbmUgY29ybmVyIGZvciBldmVyeSBzaWRlLiAgT3RoZXJ3aXNlLCBpdCB3b3JrcyBhIGxvdCBsaWtlIHBhcnQgMQ0KDQpgYGB7cn0NCmNoZWFwZmVuY2luZzwtZnVuY3Rpb24oZyl7DQogICMjIw0KICBtYXhjPC1uY29sKGcpDQogIG1heHI8LW5yb3coZykNCiAgYmVlbnRoZXJlPC1kaWN0KCkNCiAgdG90YWxmZW5jZTwtMA0KICAjIyMgdW50aWwgZXZlcnl0aGluZyBoYXMgYmVlbiBmb3VuZCAtIA0KICB4PC0xDQogIHk8LTENCiAgd2hpbGUoYmVlbnRoZXJlJHNpemUoKTxtYXhyKm1heGMpew0KICAgICMjIyBpZiBoYXZlIGJlZW4gdGhlcmUgYWxyZWFkeSwga2VlcCBsb29raW5nIGZvciBzb21ld2hlcmUgdGhhdCBpdCBoYXNuJ3QgYmVlbiB5ZXQNCiAgICB3aGlsZShiZWVudGhlcmUkaGFzKHN0cl9mbGF0dGVuKGMoeCx5KSwifiIpKSl7DQogICAgICB4PC14KzENCiAgICAgIGlmKHg+bWF4Yyl7DQogICAgICAgIHk8LXkrMQ0KICAgICAgICB4PC0xfX0NCiAgICBhPC0wDQogICAgY29ybmVyPC0wDQogICAgcjwtZ1t5LHhdDQogICAgcTwtcXVldWUoKQ0KICAgICMjIyBqdXN0IHRvIGNoZWNrDQogICAgcSRwdXNoKGMoeCx5KSkNCiAgICB3aGlsZShxJHNpemUoKT4wKXsNCiAgICAgIG54dDwtcSRwb3AoKQ0KICAgICAgbnh0eDwtbnh0WzFdDQogICAgICBueHR5PC1ueHRbMl0NCiAgICAgICMjIGZvciBjb3JuZXJpbmcNCiAgICAgIHVwPC1GQUxTRQ0KICAgICAgbGVmdDwtRkFMU0UNCiAgICAgIGRvd248LUZBTFNFDQogICAgICByaWdodDwtRkFMU0UNCiAgICAgICMjIGlmIGhhdmUgYmVlbiB0aGVyZSwgbmV4dA0KICAgICAgaWYoYmVlbnRoZXJlJGhhcyhzdHJfZmxhdHRlbihjKG54dHgsbnh0eSksIn4iKSkpew0KICAgICAgICBuZXh0fWVsc2V7YmVlbnRoZXJlJHNldChzdHJfZmxhdHRlbihjKG54dHgsbnh0eSksIn4iKSxyKX0NCiAgICAgICMjIyBpZiB0aGlzIGlzIGEgbmV3IHBsYWNlLCBhZGQgMSB0byB0aGUgYXJlYQ0KICAgICAgYTwtYSsxDQogICAgICAjIyMgY2hlY2sgb24gYWxsIDQgc2lkZXMNCiAgICAgIGlmKG54dHg+MSl7DQogICAgICAgIGlmKGdbbnh0eSwobnh0eC0xKV09PXIpew0KICAgICAgICAgIHEkcHVzaChjKG54dHgtMSxueHR5KSkNCiAgICAgICAgICBsZWZ0PC1UUlVFfWVsc2V7DQogICAgICAgICAgICBsZWZ0PC1GQUxTRX19ZWxzZXtsZWZ0PC1GQUxTRX0NCiAgICAgIGlmKG54dHg8bWF4Yyl7DQogICAgICAgIGlmKGdbbnh0eSwobnh0eCsxKV09PXIpew0KICAgICAgICAgIHEkcHVzaChjKG54dHgrMSxueHR5KSkNCiAgICAgICAgICByaWdodDwtVFJVRX1lbHNlew0KICAgICAgICAgICAgcmlnaHQ8LUZBTFNFfX1lbHNle3JpZ2h0PC1GQUxTRX0NCiAgICAgIGlmKG54dHk+MSl7DQogICAgICAgIGlmKGdbKG54dHktMSksbnh0eF09PXIpew0KICAgICAgICAgIHEkcHVzaChjKG54dHgsbnh0eS0xKSkNCiAgICAgICAgICB1cDwtVFJVRX1lbHNlew0KICAgICAgICAgICAgdXA8LUZBTFNFfX1lbHNle3VwPC1GQUxTRX0NCiAgICAgIGlmKG54dHk8bWF4cil7DQogICAgICAgIGlmKGdbKG54dHkrMSksbnh0eF09PXIpew0KICAgICAgICAgIHEkcHVzaChjKG54dHgsbnh0eSsxKSkNCiAgICAgICAgICBkb3duPC1UUlVFfWVsc2V7DQogICAgICAgICAgICBkb3duPC1GQUxTRX19ZWxzZXtkb3duPC1GQUxTRX0NCiAgICAgICMjIyB0byBmaW5kIGNvcm5lcnMgLSBjaGVjayBpbiB0d28gY29ybmVybHkgZGlyZWN0aW9ucy4gSWYgYm90aCBhcmUgZmFsc2UsIGNvcm5lcg0KICAgICAgIyMjIGlmIGJvdGggYXJlIHRydWUsIHRoZW4gY2hlY2sga2l0dHkgY29ybmVyIC0gaWYgaXQgaXMgYSBkaWZmZXJlbnQgcmVnaW9uLCB0aGVuIGNvcm5lcg0KICAgICAgaWYodXA9PUZBTFNFICYmIGxlZnQ9PUZBTFNFKXtjb3JuZXI8LWNvcm5lcisxfQ0KICAgICAgaWYodXA9PUZBTFNFICYmIHJpZ2h0PT1GQUxTRSl7Y29ybmVyPC1jb3JuZXIrMX0NCiAgICAgIGlmKGRvd249PUZBTFNFICYmIGxlZnQ9PUZBTFNFKXtjb3JuZXI8LWNvcm5lcisxfQ0KICAgICAgaWYoZG93bj09RkFMU0UgJiYgcmlnaHQ9PUZBTFNFKXtjb3JuZXI8LWNvcm5lcisxfQ0KICAgICAgaWYodXA9PVRSVUUgJiYgbGVmdD09VFJVRSAmJiBnWyhueHR5LTEpLChueHR4LTEpXSE9cil7Y29ybmVyPC1jb3JuZXIrMX0NCiAgICAgIGlmKHVwPT1UUlVFICYmIHJpZ2h0PT1UUlVFICYmIGdbKG54dHktMSksKG54dHgrMSldIT1yKXtjb3JuZXI8LWNvcm5lcisxfQ0KICAgICAgaWYoZG93bj09VFJVRSAmJiBsZWZ0PT1UUlVFICYmIGdbKG54dHkrMSksKG54dHgtMSldIT1yKXtjb3JuZXI8LWNvcm5lcisxfQ0KICAgICAgaWYoZG93bj09VFJVRSAmJiByaWdodD09VFJVRSAmJiBnWyhueHR5KzEpLChueHR4KzEpXSE9cil7Y29ybmVyPC1jb3JuZXIrMX19DQogICAgdG90YWxmZW5jZTwtdG90YWxmZW5jZSsoYSpjb3JuZXIpfQ0KICB0b3RhbGZlbmNlfQ0KDQoNCg0KYGBgDQoNCmBgYHtyfQ0KcGFydDI8LWNoZWFwZmVuY2luZyhnYXJkZW4pDQpwYXJ0Mg0KYGBgDQo=