Karmmah

joined 2 years ago
[–] Karmmah 2 points 2 hours ago (2 children)

Would recommend it. Much better than having your brain rot away at a massively increased pace for the next four years.

[–] Karmmah 10 points 6 hours ago (4 children)

I think it's time to start blocking news about US politics.

[–] Karmmah 1 points 2 days ago

I switched to Commit Mono for Terminal not too long ago but I really like it. Otherwise I use Cantarell but only because it is default and I never felt the need to change it.

[–] Karmmah 10 points 4 days ago

So what music do you listen to? Me: ... can I just show you my playlists?

[–] Karmmah 2 points 1 week ago* (last edited 1 week ago)

Julia

Quite happy that today went a lot smoother than yesterday even though I am not really familiar with recursion. Normally I never use recursion but I felt like today could be solved by it (or using trees, but I'm even less familiar with them). Surprisingly my solution actually worked and for part 2 only small modifications were needed to count peaks reached by each trail.

Code

function readInput(inputFile::String)
	f = open(inputFile,"r")
	lines::Vector{String} = readlines(f)
	close(f)
	topoMap = Matrix{Int}(undef,length(lines),length(lines[1]))
	for (i,l) in enumerate(lines)
		topoMap[i,:] = map(x->parse(Int,x),collect(l))
	end
	return topoMap
end

function getTrailheads(topoMap::Matrix{Int})
	trailheads::Vector{Vector{Int}} = []
	for (i,r) in enumerate(eachrow(topoMap))
		for (j,c) in enumerate(r)
			c==0 ? push!(trailheads,[i,j]) : nothing
		end
	end
	return trailheads
end

function getReachablePeaks(topoMap::Matrix{Int},trailheads::Vector{Vector{Int}})
	reachablePeaks = Dict{Int,Vector{Vector{Int}}}()
	function getPossibleMoves(topoMap::Matrix{Int},pos::Vector{Int})
		possibleMoves::Vector{Vector{Int}} = []
		pos[1]-1 in 1:size(topoMap)[1] && topoMap[pos[1]-1,pos[2]]==topoMap[pos[1],pos[2]]+1 ? push!(possibleMoves,[pos[1]-1,pos[2]]) : nothing #up?
		pos[1]+1 in 1:size(topoMap)[1] && topoMap[pos[1]+1,pos[2]]==topoMap[pos[1],pos[2]]+1 ? push!(possibleMoves,[pos[1]+1,pos[2]]) : nothing #down?
		pos[2]-1 in 1:size(topoMap)[2] && topoMap[pos[1],pos[2]-1]==topoMap[pos[1],pos[2]]+1 ? push!(possibleMoves,[pos[1],pos[2]-1]) : nothing #left?
		pos[2]+1 in 1:size(topoMap)[2] && topoMap[pos[1],pos[2]+1]==topoMap[pos[1],pos[2]]+1 ? push!(possibleMoves,[pos[1],pos[2]+1]) : nothing #right?
		return possibleMoves
	end
	function walkPossMoves(topoMap::Matrix{Int},pos::Vector{Int},reachedPeaks::Matrix{Bool},trailId::Int)
		possMoves::Vector{Vector{Int}} = getPossibleMoves(topoMap,pos)
		for m in possMoves
			if topoMap[m[1],m[2]]==9
				reachedPeaks[m[1],m[2]]=1
				trailId += 1
				continue
			end
			reachedPeaks,trailId = walkPossMoves(topoMap,m,reachedPeaks,trailId)
		end
		return reachedPeaks, trailId
	end
	peaksScore::Int = 0; trailsScore::Int = 0
	trailId::Int = 0
	for (i,t) in enumerate(trailheads)
		if !haskey(reachablePeaks,i); reachablePeaks[i]=[]; end
		reachedPeaks::Matrix{Bool} = zeros(size(topoMap))
		trailId = 0
		reachedPeaks,trailId = walkPossMoves(topoMap,t,reachedPeaks,trailId)
		trailPeaksScore = sum(reachedPeaks)
		peaksScore += trailPeaksScore
		trailsScore += trailId
	end
	return peaksScore,trailsScore
end #getReachablePeaks

topoMap::Matrix{Int} = readInput("input/day10Input")
trailheads::Vector{Vector{Int}} = getTrailheads(topoMap)
@info "Part 1"
reachablePeaks = getReachablePeaks(topoMap,trailheads)[1]
println("reachable peaks: ",reachablePeaks)
@info "Part 2"
trailsScore::Int = getReachablePeaks(topoMap,trailheads)[2]
println("trails score: $trailsScore")

[–] Karmmah 3 points 1 week ago

Julia

Oh today was a struggle. First I did not get what exactly the task wanted me to do and then in part 2 I tried a few different ideas which all failed because I changed the disk while I was indexing into it. Finally now I reworked part 2 not moving the blocks at all, just using indexes and it works.

I feel that there is definitely something to learn here and that's what I like about AoC so far. This is my first AoC but I hope that I won't have to put this much thought into the rest, since I should definitely use my time differently.

Code

function readInput(inputFile::String)
	f = open(inputFile,"r"); diskMap::String = readline(f); close(f)
	disk::Vector{String} = []
	id::Int = 0
	for (i,c) in enumerate(diskMap)
		if i%2 != 0 #used space
			for j=1 : parse(Int,c)
				push!(disk,string(id))
			end
			id += 1
		else #free space
			for j=1 : parse(Int,c)
				push!(disk,".")
			end
		end
	end
	return disk
end

function getDiscBlocks(disk::Vector{String})::Vector{Vector{Int}}
	diskBlocks::Vector{Vector{Int}} = []
	currBlock::Int = parse(Int,disk[1]) #-1 for free space
	blockLength::Int = 0; blockStartIndex::Int = 0
	for (i,b) in enumerate(map(x->(x=="." ? -1 : parse(Int,x)),disk))
		if b == currBlock
			blockLength += 1
		else #b!=currBlock
			push!(diskBlocks,[currBlock,blockLength,blockStartIndex,i-2])
			currBlock = b
			blockLength = 1
			blockStartIndex = i-1 #start of next block
		end
	end
	push!(diskBlocks,[currBlock,blockLength,blockStartIndex,length(disk)-1])
	return diskBlocks
end

function compressDisk(disk::Vector{String})::Vector{Int} #part 1
	compressedDisk::Vector{Int} = []
	startPtr::Int=1; endPtr::Int=length(disk)
	while endPtr >= startPtr
		while endPtr>startPtr && disk[endPtr]=="."
			endPtr -= 1
		end
		while startPtr<endPtr && disk[startPtr]!="."
			push!(compressedDisk,parse(Int,disk[startPtr])) about AoC
			startPtr += 1
		end
		push!(compressedDisk,parse(Int,disk[endPtr]))
		startPtr+=1;endPtr-=1
	end
	return compressedDisk
end

function compressBlocks(diskBlocks::Vector{Vector{Int}})
	for i=length(diskBlocks) : -1 : 1 #go through all blocks, starting from end
		diskBlocks[i][1] == -1 ? continue : nothing
		for j=1 : i-1 #look for large enough empty space
			diskBlocks[j][1]!=-1 || diskBlocks[j][2]<diskBlocks[i][2] ? continue : nothing #skip occupied blocks and empty blocks that are too short
			diskBlocks[i][3] = diskBlocks[j][3] #set start index
			diskBlocks[i][4] = diskBlocks[j][3]+diskBlocks[i][2]-1 #set end index
			diskBlocks[j][3] += diskBlocks[i][2] #move start of empty block
			diskBlocks[j][2] -= diskBlocks[i][2] #adjust length of empty block
			break
		end
	end
	return diskBlocks
end

function calcChecksum(compressedDisk::Vector{Int})::Int
	checksum::Int = 0
	for (i,n) in enumerate(compressedDisk)
		checksum += n*(i-1)
	end
	return checksum
end

function calcChecksumBlocks(diskBlocks::Vector{Vector{Int}})::Int
	checksum::Int = 0
	for b in diskBlocks
		b[1]==-1 ? continue : nothing
		for i=b[3] : b[4]
			checksum += b[1]*i
		end
	end
	return checksum
end

disk::Vector{String} = readInput("input/day09Input")
@info "Part 1"
println("checksum: $(calcChecksum(compressDisk(disk)))")
@info "Part 2"
println("checksum: $(calcChecksumBlocks(compressBlocks(getDiscBlocks(disk)))")

[–] Karmmah 2 points 2 weeks ago

Julia

I was surprised when my solution worked for part 2 since I thought you also had to include fractions of antenna distances, but apparently not.

Code

function readInput(inputFile::String)::Matrix{Char}
	f = open(inputFile,"r")
	lines::Vector{String} = readlines(f)
	close(f)
	cityMap = Matrix{Char}(undef,length(lines),length(lines[1]))
	for (i,l) in enumerate(lines)
		cityMap[i,:] = collect(l)
	end
	return cityMap
end

function getAntennaLocations(cityMap::Matrix{Char})::Dict
	antennaLocations = Dict{Char,Vector{Vector{Int}}}()
	for l=1 : size(cityMap)[1]
		for c=1 : size(cityMap)[2]
			cityMap[l,c]=='.' ? continue : nothing
			if !haskey(antennaLocations,cityMap[l,c])
				antennaLocations[cityMap[l,c]] = []
			end
			push!(antennaLocations[cityMap[l,c]],[l,c])
		end
	end
	return antennaLocations
end

function countAntinodes(cityMap::Matrix{Char},antLoc::Dict{Char,Vector{Vector{Int}}},withHarmonics::Bool)::Int #antLoc: antenna locations
	lBounds = 1:size(cityMap)[1]; cBounds = 1:size(cityMap)[2]
	anodeLocs::Matrix{Bool} = zeros(size(cityMap))
	for key in keys(antLoc)
		for i=1 : length(antLoc[key])
			withHarmonics&&length(antLoc[key])>1 ? anodeLocs[antLoc[key][i][1],antLoc[key][i][2]]=1 : nothing #add antenna locations as antinodes
			#should also add fractions of antenna distances, but works without
			for j=i+1 : length(antLoc[key])
				harmonic::Int = 1
				while true
					n1l = antLoc[key][i][1]+harmonic*(antLoc[key][i][1]-antLoc[key][j][1])
					n1c = antLoc[key][i][2]+harmonic*(antLoc[key][i][2]-antLoc[key][j][2])
					n2l = antLoc[key][j][1]+harmonic*(antLoc[key][j][1]-antLoc[key][i][1])
					n2c = antLoc[key][j][2]+harmonic*(antLoc[key][j][2]-antLoc[key][i][2])
					if n1l in lBounds && n1c in cBounds
						anodeLocs[n1l,n1c] = 1
					end
					if n2l in lBounds && n2c in cBounds
						anodeLocs[n2l,n2c] = 1
					end
					withHarmonics ? nothing : break
					!(n1l in lBounds) && !(n1c in cBounds) && !(n2l in lBounds) && !(n2c in cBounds) ? break : harmonic+=1
				end
			end
		end
	end
	return sum(anodeLocs)
end

@info "Part 1"
println("antinode count $(countAntinodes(getAntennaLocations(readInput("day08Input"))),false)")
@info "Part 2"
println("antinode count $(countAntinodes(getAntennaLocations(readInput("day08Input"))),faltrue)")

[–] Karmmah 1 points 2 weeks ago

Julia

Took quite some time to debug but in the end I think it's a nice solution using base 2 and 3 numbers counting up to check all operator combinations.

Code

function readInput(inputFile::String)::Vector{Vector{Int}}
	f = open(inputFile,"r")
	lines::Vector{String} = readlines(f)
	close(f)
	equations::Vector{Vector{Int}} = []
	function getValues(line::String)
		return map(sp->parse(Int,sp),(sp=split(line," ");sp[1]=sp[1][1:end-1];sp))
	end
	map(l->push!(equations,getValues(l)),lines)
	return equations
end

function checkEq(eq::Vector{Int},withConCat::Bool)::Bool
	function calcEq(eq::Vector{Int},operators::Vector{Int},withConCat::Bool)::Int
		res::Int = eq[2]
		for (i,op) in enumerate(operators)
			if op == 0 #+
				res += eq[i+2]
			elseif op ==1 #*
				res *= eq[i+2]
			else #op==2 ||
				res = parse(Int,string(res)*string(eq[i+2]))
			end
		end
		return res
	end
	opInt::Int = 0
	operators = Vector{Int}(undef,length(eq)-2)
	while opInt < (withConCat ? 3^(length(eq)-2) : 2^(length(eq)-2))
		withConCat==true ? operators=digits(opInt,base=3,pad=length(eq)-2) : operators=digits(opInt,base=2,pad=length(eq)-2)
		#calcEq(eq,operators,withConCat)==eq[1] ? (return true) : opInt -= 1
		calcEq(eq,operators,withConCat)==eq[1] ? (return true) : opInt += 1
	end
	return false
end

function calcTotCalRes(equations::Vector{Vector{Int}},withConCat::Bool)::Int
	totCalRes::Int = 0
	for e in equations
		checkEq(e,withConCat) ? totCalRes+=e[1] : nothing
	end
	return totCalRes
end

@info "Part 1"
println("result: $(calcTotCalRes(readInput("day07Input"),false))")
@info "Part 2"
println("result: $(calcTotCalRes(readInput("day07Input"),true))")

[–] Karmmah 3 points 2 weeks ago (3 children)

I'm also struggling with part 2. At the moment I am following the path and in each place I look if can connect with an earlier part of the path to the right by placing an obstacle, but without cutting off another earlier part of the path with that obstacle. I have indexes for each path location to see where in the path they first appear.

However at the moment I still have a bug counting too many possibilities. Any other ideas?

[–] Karmmah 4 points 2 weeks ago

The Marvel universe is mainly there to create possibilities to make more money, not to tell a good story. Granted I have hardly seen any of the movies/series, but after Avengers I never saw a reason to. Marvel realised Avengers was good and now they pulled out as much stuff out of the universe to fill a seemingly endless stream of "storytelling".

[–] Karmmah 1 points 2 weeks ago

Julia

No really proud of todays solution. Probably because I started too late today.

I used a dictionary with the numbers that should be in front of any given number. Then I checked if they appear after that number. Part1 check. For part 2 I just hoped for the best that ordering it would work by switching each two problematic entries and it worked.

::: spoiler

function readInput(inputFile::String)
	f = open(inputFile,"r"); lines::Vector{String} = readlines(f); close(f)
	updates::Vector{Vector{Int}} = []
	pageOrderingRules = Dict{Int,Vector{Int}}()
	readRules::Bool = true #switch off after rules are read, then read updates
	for (i,line) in enumerate(lines)
		line=="" ? (readRules=false;continue) : nothing
		if readRules
			values::Vector{Int} = map(x->parse(Int,x),split(line,"|"))
			!haskey(pageOrderingRules,values[2]) ? pageOrderingRules[values[2]]=Vector{Int}() : nothing
			push!(pageOrderingRules[values[2]],values[1])
		else #read updates
			push!(updates,map(x->parse(Int,x),split(line,",")))
		end
	end
	return updates, pageOrderingRules
end

function checkUpdateInOrder(update::Vector{Int},pageOrderingRules::Dict{Int,Vector{Int}})::Bool
	inCorrectOrder::Bool = true
	for i=1 : length(update)-1
		for j=i+1 : length(update)
			!haskey(pageOrderingRules,update[i]) ? continue : nothing
			update[j] in pageOrderingRules[update[i]] ? inCorrectOrder=false : nothing
		end
		!inCorrectOrder ? break : nothing
	end
	return inCorrectOrder
end

function calcMidNumSum(updates::Vector{Vector{Int}},pageOrderingRules::Dict{Int,Vector{Int}})::Int
	midNumSum::Int = 0
	for update in updates
		checkUpdateInOrder(update,pageOrderingRules) ? midNumSum+=update[Int(ceil(length(update)/2))] : nothing
	end
	return midNumSum
end

function calcMidNumSumForCorrected(updates::Vector{Vector{Int}},pageOrderingRules::Dict{Int,Vector{Int}})::Int
	midNumSum::Int = 0
	for update in updates
		inCorrectOrder::Bool = checkUpdateInOrder(update,pageOrderingRules)
		inCorrectOrder ? continue : nothing #skip already correct updates
		while !inCorrectOrder
			for i=1 : length(update)-1
				for j=i+1 : length(update)
					!haskey(pageOrderingRules,update[i]) ? continue : nothing
					if update[j] in pageOrderingRules[update[i]]
						mem::Int = update[i]; update[i] = update[j]; update[j]=mem #switch entries
					end
				end
			end
			inCorrectOrder = checkUpdateInOrder(update,pageOrderingRules)
		end
		midNumSum += update[Int(ceil(length(update)/2))]
	end
	return midNumSum
end

updates, pageOrderingRules = readInput("day05Input")
println("part 1 sum: $(calcMidNumSum(updates,pageOrderingRules))")
println("part 2 sum: $(calcMidNumSumForCorrected(updates,pageOrderingRules))")

:::

[–] Karmmah 1 points 2 weeks ago* (last edited 2 weeks ago)

Julia

Had some time to clean up the code today since the solution was quite straight forward after making a plan on how to approach it.

spoiler

function readWordSearch(inputFile::String)::Matrix{Char}
	f = open(inputFile,"r")
	lines::Vector{String} = readlines(f)
	close(f)
	wordSearch = Matrix{Char}(undef,length(lines),length(lines))
	for (i,line) in enumerate(lines)
		wordSearch[i,:] = collect(line)
	end
	return wordSearch
end

function countXMASAppearances(wS::Matrix{Char})::Int
	appearanceCount::Int = 0
	for i=1 : size(wS)[1] #lines
		for j=1 : size(wS)[2] #columns
			wS[i,j]!='X' ? continue : nothing #continue if char is not X
			#if char is X, check surrounding area
			# check horizontals
			#left
			j>=4 ? (wS[i,j-1]*wS[i,j-2]*wS[i,j-3]=="MAS" ? appearanceCount+=1 : nothing) : nothing
			#right
			j<=size(wS)[2]-3 ? (wS[i,j+1]*wS[i,j+2]*wS[i,j+3]=="MAS" ? appearanceCount+=1 : nothing) : nothing
			# check verticals
			#up
			i>=4 ? (wS[i-1,j]*wS[i-2,j]*wS[i-3,j]=="MAS" ? appearanceCount+=1 : nothing) : nothing
			#down
			i<=size(wS)[1]-3 ? (wS[i+1,j]*wS[i+2,j]*wS[i+3,j]=="MAS" ? appearanceCount+=1 : nothing) : nothing
			# check diagonals
			#left up
			i>=4 && j>=4 ? (wS[i-1,j-1]*wS[i-2,j-2]*wS[i-3,j-3]=="MAS" ? appearanceCount+=1 : nothing) : nothing
			#right up
			i>=4 && j<=size(wS)[2]-3 ? (wS[i-1,j+1]*wS[i-2,j+2]*wS[i-3,j+3]=="MAS" ? appearanceCount+=1 : nothing) : nothing
			#left down
			i<=size(wS)[1]-3 && j>=4 ? (wS[i+1,j-1]*wS[i+2,j-2]*wS[i+3,j-3]=="MAS" ? appearanceCount+=1 : nothing) : nothing
			#right down
			i<=size(wS)[1]-3 && j<=size(wS)[2]-3 ? (wS[i+1,j+1]*wS[i+2,j+2]*wS[i+3,j+3]=="MAS" ? appearanceCount+=1 : nothing) : nothing
		end
	end
	return appearanceCount
end

function countX_MASAppearances(wordSearch::Matrix{Char})::Int
	appearances::Int = 0
	for l=2 : size(wordSearch)[1]-1
		for c=2 : size(wordSearch)[2]-1
			wordSearch[l,c]!='A' ? continue : nothing
			checkArr = [wordSearch[l-1,c-1],wordSearch[l-1,c+1],wordSearch[l+1,c-1],wordSearch[l+1,c+1]]
			if checkArr in [['M','M','S','S'],['M','S','M','S'],['S','S','M','M'],['S','M','S','M']]
				appearances += 1
			end
		end
	end
	return appearances
end

wordSearch::Matrix{Char} = readWordSearch(inputFile
prinltn("part 1 appearances: $(countXMASAppearances(wordSearch))")
prinltn("part 2 appearances: $(countX_MASAppearances(wordSearch))")

6
submitted 2 weeks ago* (last edited 2 weeks ago) by Karmmah to c/[email protected]
 

If so, how is it going and did you find any useful tricks to complete the tasks so far?

I myself just posted my solution in the Day 3 results post at https://lemmy.world/c/[email protected] but did not try to make it "clever". Just wanted to have a robust solution that works. Maybe in the next days I will start to explore more concise solutions if I find the time.

9
Cam de Leon rule (lemmy.world)
submitted 2 years ago by Karmmah to c/196
 
 

Hi everyone,

I just joined and am now exploring this place. I noticed there already are similar communities on different instances. For example there is a [email protected] and a [email protected]. Is there a way to "join" or "sync" these different spaces? Or will they just be separate?

I think It would be nice to connect places like these. As far as I understand it if one instance goes down all their communities disappear. With "synced" communities across instances this could be avoided since they act like a backup for each other.

So far I like it here and am looking forward to how this all works out.

Thanks everyone for contributing and running this place.

view more: next ›