Day 2: Gift Shop

Megathread guidelines

  • Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
  • You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL

FAQ

  • eta@feddit.org
    link
    fedilink
    English
    arrow-up
    2
    ·
    2 months ago

    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}"