Karmmah

joined 2 years ago
[โ€“] Karmmah 2 points 2 months 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 months 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 3 months 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 3 months 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 3 months 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 3 months ago* (last edited 3 months 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))")

[โ€“] Karmmah 1 points 3 months ago* (last edited 3 months ago)

Julia

I did not try to make my solution concise and kept separate code for part 1 and part 2 with test cases for both to check if I broke anything. But after struggling with Day 2 I am quite pleased to have solved Day 3 with only a little bugfixing.

function calcLineResult(line::String)
	lineResult::Int = 0
	enabled::Bool = true
	for i=1 : length(line)
		line[i]!='m' ? continue : (i<length(line) ? i+=1 : continue)
		line[i]!='u' ? continue : (i<length(line) ? i+=1 : continue)
		line[i]!='l' ? continue : (i<length(line) ? i+=1 : continue)
		line[i]!='(' ? continue : (i<length(line) ? i+=1 : continue)
		num1Str::String = ""
		while line[i] in ['0','1','2','3','4','5','6','7','8','9'] #should check for length of digits < 3, but works without
			num1Str = num1Str*line[i]; (i<length(line) ? i+=1 : continue)
		end
		line[i]!=',' ? continue : (i<length(line) ? i+=1 : continue)
		num2Str::String = ""
		while line[i] in ['0','1','2','3','4','5','6','7','8','9'] #should check for length of digits < 3, but works without
			num2Str = num2Str*line[i]; (i<length(line) ? i+=1 : continue)
		end
		line[i]==')' ? lineResult+=parse(Int,num1Str)*parse(Int,num2Str) : continue
	end
	return lineResult
end

function calcLineResultWithEnabling(line::String,enabled::Bool)
	lineResult::Int = 0
	for i=1 : length(line)
		if enabled && line[i] == 'm'
			i<length(line) ? i += 1 : continue
			line[i]!='u' ? continue : (i<length(line) ? i+=1 : continue)
			line[i]!='l' ? continue : (i<length(line) ? i+=1 : continue)
			line[i]!='(' ? continue : (i<length(line) ? i+=1 : continue)
			num1Str::String = ""
			while line[i] in ['0','1','2','3','4','5','6','7','8','9']
				num1Str = num1Str*line[i]; (i<length(line) ? i+=1 : continue)
			end
			line[i]!=',' ? continue : (i<length(line) ? i+=1 : continue)
			num2Str::String = ""
			while line[i] in ['0','1','2','3','4','5','6','7','8','9']
				num2Str = num2Str*line[i]; (i<length(line) ? i+=1 : continue)
			end
			line[i]==')' ? lineResult+=parse(Int,num1Str)*parse(Int,num2Str) : continue
		elseif line[i] == 'd'
			i<length(line) ? i += 1 : continue
			line[i]!='o' ? continue : (i<length(line) ? i+=1 : continue)
			if line[i] == '('
				i<length(line) ? i += 1 : continue
				line[i]==')' ? enabled=true : continue
				#@info i,line[i-3:i]
			elseif line[i] == 'n'
				i<length(line) ? i += 1 : continue
				line[i]!=''' ? continue : (i<length(line) ? i+=1 : continue)
				line[i]!='t' ? continue : (i<length(line) ? i+=1 : continue)
				line[i]!='(' ? continue : (i<length(line) ? i+=1 : continue)
				line[i]==')' ? enabled=false : continue
				#@info i,line[i-6:i]
			else
				nothing
			end
		end
	end
	return lineResult,enabled
end

function calcMemoryResult(inputFile::String,useEnabling::Bool)
	memoryRes::Int = 0
	f = open(inputFile,"r")
	lines = readlines(f)
	close(f)
	enabled::Bool = true
	for line in lines
		if useEnabling
			lineRes::Int,enabled = calcLineResultWithEnabling(line,enabled)
			memoryRes += lineRes
		else
			memoryRes += calcLineResult(line)
		end
	end
	return memoryRes
end

if abspath(PROGRAM_FILE) == @__FILE__
	@info "Part 1"
	@debug "checking test input"
	inputFile::String = "day03InputTest"
	memoryRes::Int = calcMemoryResult(inputFile,false)
	try
		@assert memoryRes==161
	catch e
		throw(ErrorException("$e memoryRes=$memoryRes"))
	end
	@debug "test input ok"
	@debug "running real input"
	inputFile::String = "day03Input"
	memoryRes::Int = calcMemoryResult(inputFile,false)
	try
		@assert memoryRes==153469856
	catch e
		throw(ErrorException("$e memoryRes=$memoryRes"))
	end
	println("memory result: $memoryRes")
	@debug "real input ok"

	@info "Part 2"
	@debug "checking test input"
	inputFile::String = "day03InputTest"
	memoryRes::Int = calcMemoryResult(inputFile,true)
	try
		@assert memoryRes==48
	catch e
		throw(ErrorException("$e memoryRes=$memoryRes"))
	end
	@debug "test input ok"
	@debug "running real input"
	inputFile::String = "day03Input"
	memoryRes::Int = calcMemoryResult(inputFile,true)
	try
		@assert memoryRes==77055967
	catch e
		throw(ErrorException("$e memoryRes=$memoryRes"))
	end
	println("memory result: $memoryRes")
	@debug "real input ok"

end
[โ€“] Karmmah 4 points 3 months ago

Julia, since I used it for some projects this year but never for something "time critical" like AoC with a new problem each day. I really like that it's simple like python but with strong typing. Originally I wanted to use Ocaml to learn it, but on day 1 I realised I don't know how to do anything in it yet ๐Ÿ˜„.

[โ€“] Karmmah 3 points 3 months ago

I only have experience with Gnome out of the two but I haven't had the urge to switch yet. I like the look of it (I like that it looks different to Windows), the simplicity and the customisation with extensions (only a few and small ones, I recently started using OpenBar for some customization but I could do without). I keep my system rather minimal and I am not looking to put a lot of time into theming or customization.

I also tried Cosmic and I like the tiling aspect of it, but I also don't feel the need to switch. Maybe once it is released and I can figure out how to install it on Aeon.

[โ€“] Karmmah 7 points 3 months ago

If I remember correctly I got them from this collection on archive.org and honestly they are just really nice quality pictures. But probably also a bit of nostalgia. ๐Ÿ˜„

[โ€“] Karmmah 1 points 3 months ago (1 children)

The cars are just too big and maybe also too fast for Monaco at the moment. Maybe in the future this will change again.

[โ€“] Karmmah 5 points 3 months ago

Or make the cars smaller again. They're finally getting smaller in 2026 but in the long term they should aim for v10 era size cars IMO.

view more: โ€น prev next โ€บ