• 0 Posts
  • 110 Comments
Joined 1 年前
cake
Cake day: 2024年7月2日

help-circle


















  • Elixir

    This one took way to long to do because I got hung up on what turned out to just be forgetting to rename functions when copying code from part 1 to part 2.

    I did part 1 in language but turned to regex for part 2.

    #!/usr/bin/elixir
    
    defmodule GiftShopDatabase do
    
    def getRanges(filename) do
    	{:ok, content} = File.read(filename)
    	input = String.trim(content)
    	ranges = []
    	currLowerLim = ""
    	currNum = ""
    	parseRanges(input, ranges, currLowerLim, currNum)
    end
    
    defguardp isDigit(c) when c in ?0..?9
    
    defp parseRanges(input, ranges, currLowerLim, currNum) do
    	case input do
    		<<>> -> Enum.reverse([{currLowerLim,IO.iodata_to_binary(currNum)} | ranges])
    		<<",", rest::binary>> ->
    			#newUpperLim = IO.iodata_to_binary(currNum) |> String.to_integer
    			newUpperLim = IO.iodata_to_binary(currNum)
    			parseRanges(rest, [{currLowerLim,newUpperLim} | ranges], currLowerLim, "")
    		<<"-", rest::binary>> ->
    			#newLowerLim = IO.iodata_to_binary(currNum) |> String.to_integer
    			newLowerLim = IO.iodata_to_binary(currNum)
    			parseRanges(rest, ranges, newLowerLim, "")
    		<<char::utf8, rest::binary>> when isDigit(char) ->
    			parseRanges(rest, ranges, currLowerLim, [currNum | <<char>>])
    		other -> raise "[ ERROR ] unkown input:#{inspect(other)}"
    	end
    end
    
    def getInvIDSum(ranges, invIDSum) do
    	case ranges do
    		[] -> invIDSumString.to_integer(elem(range,0)), invIDSum))
    		[range | rest] -> getInvIDSum(rest, invIDSum+checkRange(range, String.to_integer(elem(range,0)), 0))
    		other -> raise "[ ERROR ] invalid ranges given:#{inspect(other)}"
    	end
    end
    
    defp checkRange(range, currID, invIDSum) do
    	strUpperLim = String.to_integer(elem(range,1))
    	unevenDigitCount = rem(String.length(Integer.to_string(currID)),2)
    	case currID do
    		_ when currID > strUpperLim -> invIDSum
    		_ when unevenDigitCount == 1 -> checkRange(range, currID+1, invIDSum)
    		_ -> checkRange(range, currID+1, invIDSum + checkID(currID))
    	end
    end
    
    defp checkID(currID) do
    	pow = :math.pow(10,String.length(Integer.to_string(currID))/2)
    	front = floor(currID/pow)
    	back = currID - floor(front*pow)
    	if front == back, do: currID, else: 0
    end
    
    def getInvIDSumPart2(ranges, invIDSum) do
    	case ranges do
    		[] -> invIDSum
    		#[range | rest] -> getInvIDSumPart2(rest, invIDSum+checkRangePart2(range, elem(range,0), invIDSum))
    		[range | rest] -> getInvIDSumPart2(rest, invIDSum+checkRangePart2(range, elem(range,0), 0))
    		other -> raise "[ ERROR ] invalid ranges given:#{inspect(other)}"
    	end
    end
    
    def checkRangePart2(range, currID, invIDSum) do
    	numID = String.to_integer(currID)
    	numUpperLim = String.to_integer(elem(range,1))
    	case currID do
    		_ when numID > numUpperLim -> invIDSum
    		_ when numID < 10 -> checkRangePart2(range, Integer.to_string(String.to_integer(currID)+1), invIDSum)
    		_ -> checkRangePart2(range, Integer.to_string(String.to_integer(currID)+1), invIDSum + checkIDPart2(currID,1,floor(String.length(currID)/2)))
    	end
    end
    
    def checkIDPart2(currID, currLen, maxLen) do
    	regex = "(#{String.slice(currID,0,currLen)})+"
    	regexComp = Regex.compile(regex)
    	res = Regex.run(elem(regexComp,1), currID)
    	case res do
    		[_, _] when currLen > maxLen or maxLen == 0 -> 0
    		[longestMatch, _] when longestMatch == currID -> String.to_integer(currID)
    		[_, _] -> checkIDPart2(currID, currLen+1, maxLen)
    		_ -> 0
    	end
    end
    
    end #module
    
    
    IO.puts "### Part 1 ###"
    ranges = GiftShopDatabase.getRanges("input/day02Input.txt")
    IO.puts "[ INFO ] ranges:#{inspect(ranges)}"
    invIDSum = GiftShopDatabase.getInvIDSum(ranges, 0)
    IO.puts "[ INFO ] invalid ID sum:#{invIDSum}"
    
    IO.puts "### Part 2 ###"
    ranges = GiftShopDatabase.getRanges("input/day02Input.txt")
    IO.puts "[ INFO ] ranges:#{inspect(ranges)}"
    invIDSum = GiftShopDatabase.getInvIDSumPart2(ranges, 0)
    IO.puts "[ INFO ] invalid ID sum:#{invIDSum}"
    

  • Elixir

    Oh wow I’m late but that’s because I decided to do this year in Elixir which I am not really experienced enough yet as it seems. Part 1 was ok but I didn’t really put enough thought into Part 2 and got stuck for a while. However I got it done after a few failed tries and a few questions to AI on how to do things in Elixir.

    #!/usr/bin/elixir
    
    defmodule SafeDial do
    
    def readInstructions(filename) do
    	filename
    	|> File.stream!()
    	|> Stream.map(&String.trim/1)
    	|> Stream.reject(&(&1 == ""))
    	|> Stream.map(fn line ->
    		case Regex.run(~r/^([A-Za-z])(\d+)$/, line) do
    			[_, letter, number] -> {String.to_atom(letter), String.to_integer(number)}
    			_ -> nil
    		end
    	end)
    	|> Enum.reject(&(&1 == nil))
    end
    
    def evalInstructions(instructions) do
    	initialPos = 50
    	zeroCount = 0
    	checkInstruction(instructions, initialPos, zeroCount)
    end
    
    defp checkInstruction(instructions, currPos, zeroCount) do
    	case instructions do
    		[] -> {currPos, zeroCount}
    		[instruct | rest] ->
    			nextPos =
    				case instruct do
    					{dir, step} when dir == :R and currPos + rem(step,100) > 99 ->
    						currPos + rem(step,100) - 100
    					{dir, step} when dir == :R and currPos + rem(step,100) > 99 ->
    						currPos + rem(step,100) - 100
    					{dir, step} when dir == :R ->
    						currPos + rem(step,100)
    					{dir, step} when dir == :L and currPos - rem(step,100) < 0 ->
    						currPos - rem(step,100) + 100
    					{dir, step} when dir == :L ->
    						currPos - rem(step,100)
    					_ -> raise "[ ERROR ] unkown instruction: #{inspect(instruct)}"
    				end
    			newZeroCount = if nextPos == 0, do: zeroCount + 1, else: zeroCount
    			checkInstruction(rest, nextPos, newZeroCount)
    		other -> raise "[ ERROR ] unknown instruction: #{inspect(other)}"
    	end
    end
    
    def evalInstructionsPart2(instructions) do
    	initialPos = 50
    	zeroCount = 0
    	checkInstructionPart2(instructions, initialPos, zeroCount)
    end
    
    defp checkInstructionPart2(instructions, currPos, zeroCount) do
    	case instructions do
    		[] -> {currPos, zeroCount}
    		[instruct | rest] ->
    			{nextPos, zeroCount1} =
    				case instruct do
    					{dir, step} when dir == :R and currPos + rem(step,100) == 100 ->
    						{currPos + rem(step,100) - 100, zeroCount+floor(step/100)}
    					{dir, step} when dir == :R and currPos + rem(step,100) > 99 ->
    						{currPos + rem(step,100) - 100, zeroCount+floor(step/100)+1}
    					{dir, step} when dir == :R ->
    						{currPos + rem(step,100), zeroCount+floor(step/100)}
    					{dir, step} when dir == :L and currPos == 0 and currPos - rem(step,100) < 0 ->
    						{currPos - rem(step,100) + 100, zeroCount+floor(step/100)}
    					{dir, step} when dir == :L and currPos - rem(step,100) < 0 ->
    						{currPos - rem(step,100) + 100, zeroCount+floor(step/100)+1}
    					{dir, step} when dir == :L ->
    						{currPos - rem(step,100), zeroCount+floor(step/100)}
    					_ -> raise "[ ERROR ] unkown instruction: #{inspect(instruct)}"
    				end
    			newZeroCount = if nextPos == 0, do: zeroCount1 + 1, else: zeroCount1
    			checkInstructionPart2(rest, nextPos, newZeroCount)
    		other -> raise "[ ERROR ] unknown instruction: #{inspect(other)}"
    	end
    end
    
    end #module
    
    IO.puts "### PART 1 ###"
    instructions = SafeDial.readInstructions("input/day01Input.txt")
    {finalPos, zeroCount} = SafeDial.evalInstructions(instructions)
    IO.puts "final position:#{finalPos} zero count:#{zeroCount}"
    
    IO.puts "### PART 2 ###"
    instructions = SafeDial.readInstructions("input/day01Input.txt")
    {finalPos, zeroCount} = SafeDial.evalInstructionsPart2(instructions)
    IO.puts "final position:#{finalPos} zero count:#{zeroCount}"
    

    Edit: removed debug output