Skip to content

alexandramartinez/adventofcode-2023

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

14 Commits
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Advent of Code 2023

DataWeave scripts used in the adventofcode.com site for 2023.

Similar repos

๐Ÿ”น Day 1

Live stream @ twitch.tv/mulesoft_community: It's that time of the year again ๐ŸŒฒ Let's play Advent of Code 2023 with DataWeave โœจ

Part 1

Script
%dw 2.0
import lines, isNumeric from dw::core::Strings

output application/json
---
lines(payload) map ((line) -> do {
    var nums = line filter (isNumeric($))
    ---
    (nums[0] ++ nums[-1]) as Number
})
then sum($)

Part 2

Script
%dw 2.0
import lines, isNumeric from dw::core::Strings
output application/json
var regex = /one|two|three|four|five|six|seven|eight|nine|ten|\d/
var numbers = {
    one: "1",
    two: "2",
    three: "3",
    four: "4",
    five: "5",
    six: "6",
    seven: "7",
    eight: "8",
    nine: "9"
}
---
lines(payload) map ((line) -> do {
    var cleanLine = line
        replace "one" with "onee"
        replace "two" with "twoo"
        replace "three" with "threee"
        replace "five" with "fivee"
        replace "seven" with "sevenn"
        replace "eight" with "eightt"
        replace "nine" with "ninee"
    var nums = flatten(cleanLine scan regex) map ((n) -> 
        if (isNumeric(n)) n
        else numbers[n]
    )
    ---
    (nums[0] ++ nums[-1]) as Number
})
then sum($)

๐Ÿ”น Day 2

Part 1

Live stream @ twitch.tv/mulesoft_community: First stream of the year!! ~ Advent of Code 2023 Day 2

Script
%dw 2.0
import every from dw::core::Arrays
import lines from dw::core::Strings
output application/json
var maxRed = 12
var maxGreen = 13
var maxBlue = 14
---
lines(payload) map ((game, gameidx) -> do {
    var sets = game[8 to -1] splitBy ";" map (
        trim($) splitBy "," reduce ((item, acc={}) -> 
            acc ++ {
                ((item scan /red|green|blue/)[0][0]): (item scan /\d+/)[0][0] as Number
            }
        )
    )
    ---
    {
        game: gameidx+1,
        sets: sets,
        isPossible: (sets reduce (set, acc=[]) -> (
            acc 
            + ((set.red default 0) <= maxRed)
            + ((set.green default 0) <= maxGreen)
            + ((set.blue default 0) <= maxBlue)
        )) every $
    }
}) 
filter $.isPossible
then $.game
then sum($)

Part 2

Live stream @ twitch.tv/mulesoft_community: Playing Advent of Code with DataWeave once more! (Programming challenges)

Script
%dw 2.0
import lines from dw::core::Strings
output application/json
---
lines(payload) map ((game, gameidx) -> do {
    var sets = game[8 to -1] splitBy ";" map (
        trim($) splitBy "," reduce ((item, acc={}) -> 
            acc ++ {
                ((item scan /red|green|blue/)[0][0]): (item scan /\d+/)[0][0] as Number
            }
        )
    )
    fun getMaxNumber(color:String): Number = (
        max(sets[color] default []) default 1
    )
    ---
    getMaxNumber("red") 
    * getMaxNumber("green") 
    * getMaxNumber("blue")
})
then sum($)

๐Ÿ”น Day 3

Part 1

Live streams @ twitch.tv/mulesoft_community:

  1. Playing Advent of Code with DataWeave once more! (Programming challenges)
  2. DataWeave, Advent of Code, reading your suggestions!

Caution

I made a horrible code for this one. I'm really embarrassed about this. Check out Ignacio's code instead :'D https://github.com/iglosiggio/aoc2023/blob/main/aoc2023day3ex1.dwl

Bad Alex :(

Script
%dw 2.0
import update from dw::util::Values
import some from dw::core::Arrays
output application/json
var linesArr = (payload splitBy "\n")
var regexForChars = /[^\d.\s]/
var mainArray = linesArr reduce ((line, acc=[]) -> do {
    acc ++ (flatten(line scan /\d+/) map ((number) -> do {
        var regexExactNumberMatch = ("(?<!\d)$(number)(?!\d)" as Regex)
        var exactNumberMatchesIdxs = flatten(line find regexExactNumberMatch)
        var firstIndex = (line find regexExactNumberMatch)[0][0]
        var lastIndex = (firstIndex + (sizeOf(number)-1))
        var firstIndexToCheck = if ((firstIndex-1) >= 0) firstIndex-1 else firstIndex
        var lastIndexToCheck = if ((lastIndex+1) > sizeOf(line)-1) lastIndex else lastIndex+1
        var currentLineIdx = (linesArr find line)[0]
        var previousLineIdx = currentLineIdx - 1
        var nextLineIdx = currentLineIdx + 1
        var isPartAbove = if (previousLineIdx >= 0) 
                linesArr[previousLineIdx][firstIndexToCheck to lastIndexToCheck] contains regexForChars
            else false
        var isPartBelow = if (nextLineIdx > (sizeOf(linesArr)-1)) false
            else linesArr[nextLineIdx][firstIndexToCheck to lastIndexToCheck] contains regexForChars
        var isPartNext = line[firstIndexToCheck to lastIndexToCheck] contains regexForChars
        ---
        {
            line: line,
            number: number as Number,
            firstIndex: firstIndex,
            exactNumberMatchesIdxs: exactNumberMatchesIdxs,
            isDupNum: sizeOf(exactNumberMatchesIdxs) >1,
            isPart: [isPartAbove, isPartBelow, isPartNext] some $
        }
    }))
})
---
do {
    var resultWithDups = sum((mainArray filter $.isPart).number)
    var dupNums = sum((mainArray filter $.isPart and $.isDupNum).number distinctBy $)
    var duplicatesNotChecked = ((mainArray filter $.isDupNum filter ($$ mod 2) != 0) map do {
            var firstIndex = $.exactNumberMatchesIdxs[-1] // decided to assume there's only 2 matches per line :')
            var lastIndex = (firstIndex + (sizeOf($.number)-1))
            var firstIndexToCheck = if ((firstIndex-1) >= 0) firstIndex-1 else firstIndex
            var lastIndexToCheck = if ((lastIndex+1) > sizeOf($.line)-1) lastIndex else lastIndex+1
            var currentLineIdx = (linesArr find $.line)[0]
            var previousLineIdx = currentLineIdx - 1
            var nextLineIdx = currentLineIdx + 1
            var isPartAbove = if (previousLineIdx >= 0) 
                    linesArr[previousLineIdx][firstIndexToCheck to lastIndexToCheck] contains regexForChars
                else false
            var isPartBelow = if (nextLineIdx > (sizeOf(linesArr)-1)) false
                else linesArr[nextLineIdx][firstIndexToCheck to lastIndexToCheck] contains regexForChars
            var isPartNext = $.line[firstIndexToCheck to lastIndexToCheck] contains regexForChars
            ---
            {
                line: $.line,
                number: $.number as Number,
                exactNumberMatchesIdxs: $.exactNumberMatchesIdxs,
                firstIndex: firstIndex,
                isPart: [isPartAbove, isPartBelow, isPartNext] some $
            }
        }) filter $.isPart then sum($.number)
    ---
    {
        resultWithDups: resultWithDups, // suming up everything that is considered a part (even duplicates per line)
        dupNums: dupNums, // suming up the duplicate numbers that are a part (to remove them from the previous count)
        duplicatesNotChecked: duplicatesNotChecked, // suming up the duplicates that are a part that were not previously checked correctly
        finalResult: resultWithDups - dupNums + duplicatesNotChecked // final operations :')
    }
} 

๐Ÿ”น Day 4

Note

I couldn't solve Part 2, but check out this amazing script to solve it.

Part 1

Live stream @ twitch.tv/mulesoft_community:

Script
%dw 2.0
import countBy from dw::core::Arrays
import lines, substringBefore, substringAfter from dw::core::Strings
output application/json
fun getNumbers(numbers) = flatten(numbers scan /\d+/)
---
lines(payload) map ((line) -> do {
    var cardName = (line substringBefore ":")
    var numbers = (line substringAfter ":") splitBy "|"
    var winningNumbers = getNumbers(numbers[0])
    var actualNumbers = getNumbers(numbers[1])
    var matchingNumbers = winningNumbers countBy (actualNumbers contains $)
    var score = matchingNumbers match {
        case 1 -> 1
        case 0 -> 0
        else -> 2 pow matchingNumbers-1
    }
    ---
    // for debugging purposes
    // {
    //     (cardName): {
    //         winning: winningNumbers,
    //         actual: actualNumbers,
    //         matchingNumbers: matchingNumbers,
    //         score: score
    //     }
    // }

    // actual needed code
    score
})
then sum($)

๐Ÿ”น Day 15

Part 1

Live stream @ twitch.tv/mulesoft_community:

Script
%dw 2.0
output application/json
import charCode from dw::core::Strings
fun getnum(currentvalue, asciicode) = ((currentvalue + asciicode) * 17) mod 256
fun getResult(string, r=0) = do {
    @Lazy
    var newR = r getnum charCode(string)
    ---
    if (!isEmpty(string))
        string[1 to -1] getResult newR
    else r
}
---
(payload splitBy ",") map getResult($)
then sum($)


Other repos