Unable to load image

The luckiest of days, Day 13!!

Let's fricking gooo!

17
Jump in the discussion.

No email address required.

I got distracted by work so I was late, today's was easier than yesterday's though.

function compareSignals(left, right) {
    if (typeof left === 'number' && typeof right === 'number') {
        if (left < right) {
            return 1;
        } else if (left === right) {
            return 0;
        } else {
            return -1;
        }
    } else if (typeof left === 'object' && typeof right === 'object') {
        for (var i = 0; i < left.length; i++) {
            if (right[i] === undefined) {
                return -1;
            }
            var comp = compareSignals(left[i], right[i]);
            if (comp !== 0) {
                return comp;
            }
        }
        if (left.length < right.length) {
            return 1;
        } else {
            return 0;
        }
    } else {
        if (typeof left === 'number') {
            return compareSignals([left], right);
        } else if (typeof right === 'number') {
            return compareSignals(left, [right]);
        }
    }
}

var part1 = ((signals) => {
    return signals
        .split('\n\n')
        .map(pair => {
            return pair
                .split('\n')
                .map(str => eval(str));
        })
        .map(([left, right]) => compareSignals(left, right))
        .map((output, index) => output === 1 ? index + 1 : 0)
        .reduce((a, v) => a + v)
})(input);

var part2 = ((signals) => {
    var sortedSignals = signals
        .split('\n\n')
        .map(pair => {
            return pair
                .split('\n')
                .map(str => eval(str));
        })
        .flatMap(s => s)
        .concat([[[2]]], [[[6]]])
        .sort(compareSignals)
        .reverse();

    return ([
        sortedSignals.findIndex(s => JSON.stringify(s) === '[[2]]'),
        sortedSignals.findIndex(s => JSON.stringify(s) === '[[6]]')
    ])
        .map(key => key + 1)
        .reduce((a, v) => a * v);
})(input);
Jump in the discussion.

No email address required.

That degree finally paying off

Jump in the discussion.

No email address required.

:#marseygrad: :#marseycodecel:

Jump in the discussion.

No email address required.

[[[ packets ]]] :marseycapymerchant:

https://wtools.io/paste-code/bHYu

namespace AOC2022.Puzzles;

public class Day13 : IPuzzle
{
	private readonly string[] _linesFromFile;

	public Day13(string[] linesFromFile)
	{
		_linesFromFile = linesFromFile;
	}

	public void SolveFirstPuzzle()
	{
		var initialScore = 0;
		for (var index = 0; index < _linesFromFile.Length; index += 3)
		{
			var leftNode = ParseNode(_linesFromFile[index]);
			var rightNode = ParseNode(_linesFromFile[index + 1]);
			if (CompareNodes(leftNode, rightNode) < 0)
				initialScore += index / 3 + 1;
		}

		Console.WriteLine($"Part 1 answer: {initialScore}");
	}

	public void SolveSecondPuzzle()
	{
		var packets = new List<PacketNode>();
		for (var index = 0; index < _linesFromFile.Length; index += 3)
		{
			var left = ParseNode(_linesFromFile[index]);
			var right = ParseNode(_linesFromFile[index + 1]);
			packets.Add(right);
			packets.Add(left);
		}

		const string t2 = "[[2]]";
		const string t6 = "[[6]]";
		packets.Add(ParseNode(t2));
		packets.Add(ParseNode(t6));
		packets.Sort(CompareNodes);

		var initialScore = 1;
		for (var i = 0; i < packets.Count; i++)
			if (packets[i]._stringValue is "[[2]]" or "[[6]]")
				initialScore *= i + 1;
		Console.WriteLine($"Part 2 answer: {initialScore}");
	}

	private class PacketNode
	{
		public bool _isANumber;
		public string? _stringValue;
		public int _value;
		public readonly List<PacketNode> _childNodes = new();

		public override string ToString()
		{
			return _isANumber ? $"N: {_value}" : $"Ch: {_childNodes.Count}";
		}
	}

	private static int CompareNodes(PacketNode leftPacketNode, PacketNode rightPacketNode)
	{
		switch (leftPacketNode._isANumber)
		{
			case true when rightPacketNode._isANumber:
			{
				if (leftPacketNode._value < rightPacketNode._value)
					return -1;
				if (leftPacketNode._value > rightPacketNode._value)
					return +1;
				return 0;
			}
			case false when !rightPacketNode._isANumber:
			{
				var i = 0;
				while (true)
				{
					if (i >= leftPacketNode._childNodes.Count && i < rightPacketNode._childNodes.Count)
						return -1;
					if (i >= rightPacketNode._childNodes.Count && i < leftPacketNode._childNodes.Count)
						return +1;
					if (i == rightPacketNode._childNodes.Count && i == leftPacketNode._childNodes.Count)
						return 0;
					var c = CompareNodes(leftPacketNode._childNodes[i], rightPacketNode._childNodes[i]);
					if (c != 0) return c;
					++i;
				}
			}
			case true when !rightPacketNode._isANumber:
			{
				var c = CompareNodes(NumToList(leftPacketNode), rightPacketNode);
				return c != 0 ? c : 0;
			}
		}

		if (leftPacketNode._isANumber || !rightPacketNode._isANumber) return 0;
		{
			var c = CompareNodes(leftPacketNode, NumToList(rightPacketNode));
			return c != 0 ? c : 0;
		}

		PacketNode NumToList(PacketNode n)
		{
			var n1 = new PacketNode();
			n1._childNodes.Add(n);
			return n1;
		}
	}

	private static PacketNode ParseNode(string line)
	{
		var index = 0;
		var p = RecurseThroughNodes(line, ref index);
		p._stringValue = line;
		return p;
	}

	private static PacketNode RecurseThroughNodes(string line, ref int i)
	{
		var packetNode = new PacketNode();
		if (i == 0)
		{
			++i;
		}

		while (true)
		{
			var charAtI = line[i++];
			switch (charAtI)
			{
				case '[':
					packetNode._childNodes.Add(RecurseThroughNodes(line, ref i));
					break;
				case ']':
					return packetNode;
				default:
				{
					if (char.IsDigit(charAtI))
					{
						var val = charAtI - '0';
						while (char.IsDigit(line[i]))
							val = 10 * val + (line[i++] - '0');
						packetNode._childNodes.Add(new PacketNode {_isANumber = true, _value = val});
					}

					break;
				}
			}
		}
	}
}

![](/images/16709136145570378.webp)

Ignore my shit function naming, i thought of one thing and first and then did something diff after

Jump in the discussion.

No email address required.

you're fricking bananas if you think I'm reading all that, take my downvote and shut up idiot

Jump in the discussion.

No email address required.

![](https://media.giphy.com/media/QU3YSdsm2dkLJ2bb0E/giphy.webp)

Jump in the discussion.

No email address required.

This problem was almost an exact copy from last year. Recursion is always fun though

![](/images/16709120511964295.webp)

Jump in the discussion.

No email address required.

I wasted way too much time trying to parse the input without help. Otherwise not too bad.

import ast
import numpy as np
f = open('AOC2022Day13.txt')
pairs = f.read().strip().split('\n\n')
def comPair(l1,l2):
    if len(l1) == 0:
        if len(l2) == 0:
            return 0
        return 1
    if len(l2) == 0:
        return -1
    e1 = l1[0]
    e2 = l2[0]
    if not isinstance(e1,list) and not isinstance(e2,list):
        result = np.sign(e2-e1)
        if result != 0:
            return result
        return comPair(l1[1:],l2[1:])
    if not isinstance(e1,list):
        result = comPair([e1],e2)
        if result != 0:
            return result
        return comPair(l1[1:],l2[1:])
    if not isinstance(e2,list):
        result = comPair(e1,[e2])
        if result != 0:
            return result
        return comPair(l1[1:],l2[1:])
    else:
        result = comPair(e1,e2)
        if result != 0:
            return result
        return comPair(l1[1:],l2[1:])
    
allk = []
total = 0
for i in range(len(pairs)):
    pair = pairs[i].split('\n')
    l1 = ast.literal_eval(pair[0])
    l2 = ast.literal_eval(pair[1])
    allk.append(l1)
    allk.append(l2)
    v = comPair(l1,l2)
    if v == 1:
        total += i+1
allk.append([[2]])
allk.append([[6]])
from functools import cmp_to_key
s = sorted(allk, key = cmp_to_key(comPair), reverse=True)
print((s.index([[2]])+1)*(s.index([[6]])+1))
Jump in the discussion.

No email address required.

comPair :lol::wow:

Jump in the discussion.

No email address required.

downvoted for making me look at camel case. please put a trigger warning next time.

edit: oops i meant to reply to @LetsUnpackThis's comment :marseyretard2:

Jump in the discussion.

No email address required.

Oh, a wild :marseyfrontiersman: mottizen appeared. Hi west :marseywave3:

Jump in the discussion.

No email address required.

Tech support told me about AoC and invited me to join :celebrate:

Jump in the discussion.

No email address required.

    def compare(first, second):
        if first is None:
            return -1
        if second is None:
            return 1

        if isinstance(first, int) and isinstance(second, int):
            return first - second

        if isinstance(first, int):
            first = [first]
        if isinstance(second, int):
            second = [second]

        for a, b in itertools.zip_longest(first, second):
            c = compare(a, b)
            if c != 0:
                return c

        return 0

    if not second:
        res = 0
        for i, (first, second) in enumerate(grouper(data, 2)):
            first, second = ast.literal_eval(first), ast.literal_eval(second)
            r = compare(first, second)
            # print(i + 1, first, second, r)
            if r < 0:
                res += i + 1
        return res
    else:
        lst = [ast.literal_eval(it) for it in data]
        a, b = [[2]], [[6]]
        lst.append(a)
        lst.append(b)
        lst.sort(key=functools.cmp_to_key(compare))
        for i, it in enumerate(lst):
            if it == a:
                n1 = i + 1
            if it == b:
                n2 = i + 1
        return n1 * n2
Jump in the discussion.

No email address required.

It is a bit of a mess and i would prefer to do it without pointers(or at least use smart_pointers, not have dangle like absolute every pointer, but if a add a destructor everything breaks), but for some reason i couldnt get my parser to work without pointers. Overall, pretty fucking horrible in c++.


#include <iostream>
#include <vector>
#include <locale>
#include <string>
#include <stack>
#include <fstream>
#include <algorithm>
#include <iterator>

class NumberOrList;
int cmp(const NumberOrList* left, const NumberOrList* right);

class NumberOrList {
public:
    int number{ -1 };
    std::vector<NumberOrList*> list;

    NumberOrList(int a) {
        number = a;
    }

    NumberOrList() {
        number = -1;
    };

    bool isNumber() const {
        return number >= 0;
    }

    bool isList() const {
        return !isNumber();
    }

    bool operator<(const NumberOrList n) const {
        return cmp(this, &n) < 0;
    }

    bool operator==(const NumberOrList n) const {
        if (number != n.number) return false;
        if (list.size() != n.list.size()) return false;
        for (size_t i{ 0 }; i < list.size(); i++) {
            if (!(*list[i] == *n.list[i])) return false;
        }
        return true;
    }
};

int cmp(const NumberOrList* left, const NumberOrList* right) {
    if (left->isNumber() && right->isNumber()) return left->number - right->number;
    if (left->isList() && right->isList()) {
        auto left_it = left->list.begin();
        auto right_it = right->list.begin();
        for (; left_it != left->list.end() && right_it != right->list.end(); ++left_it, ++right_it) {
            int r = cmp(*left_it, *right_it);
            if (r != 0) return r;
        }
        return left->list.size() - right->list.size();
    }
    if (right->isList()) {
        auto temp = new NumberOrList();
        temp->list.push_back(new NumberOrList(left->number));
        int r = cmp(temp, right);
        delete temp->list.back();
        delete temp;
        return r;
    }
    else if (left->isList()) {
        auto temp = new NumberOrList();
        temp->list.push_back(new NumberOrList(right->number));
        int r = cmp(left, temp);
        delete temp->list.back();
        delete temp;
        return r;
    }
}

NumberOrList create_nl(std::string a) {
    std::string numbuf{ "" };

    std::stack<NumberOrList*> stack;
    stack.push(new NumberOrList);


    for (auto c : a) {
        if (std::isdigit(c)) numbuf += c;
        else {
            if (numbuf.size() > 0) stack.top()->list.push_back(new NumberOrList(std::stoi(numbuf)));
            numbuf = "";
        }
        if (c == '[') {
            auto new_nl = new NumberOrList();
            stack.top()->list.push_back(new_nl);
            stack.push(new_nl);
        }
        if (c == ']') {
            stack.pop();
        }
    }
    auto out = *(stack.top()->list[0]);
    stack.top()->list = {};
    delete stack.top();
    return out;
}

int main()
{
    std::ifstream file("input.txt");
    std::string line;
    std::vector<NumberOrList> lines;
    int i{ 1 };
    int result{ 0 };
    std::cout << "START\n";

    while (std::getline(file, line)) {
        auto line_1 = create_nl(line);
        std::getline(file, line);
        auto line_2 = create_nl(line);
        std::getline(file, line);
        lines.push_back(line_1);
        lines.push_back(line_2);
        if (line_1 < line_2) result += i;
        ++i;
    }

    NumberOrList two;
    two.list.push_back(new NumberOrList(2));
    lines.push_back(two);
    NumberOrList six;
    six.list.push_back(new NumberOrList(6));
    lines.push_back(six);

    std::sort(lines.begin(), lines.end());

    std::cout << "Part One: " << result << '\n';

    int partwo{ 1 };

    for (size_t i{ 0 }; i < lines.size(); ++i) {
        if (lines[i] == two) {
            partwo *= i + 1;
            std::cout << "TWO: " << i << '\n';
        }
        if (lines[i] == six) {
            partwo *= i + 1;
            std::cout << "SIX: " << i << '\n';
        }
    }
    std::cout << "Part Two: " << partwo << '\n';
}


Jump in the discussion.

No email address required.

fixed it, all i really needed for it to work was a copy constructor.


#include <iostream>
#include <vector>
#include <locale>
#include <string>
#include <stack>
#include <fstream>
#include <algorithm>
#include <iterator>

class NumberOrList {
public:
    int number{ -1 };
    std::vector<NumberOrList> list;

    NumberOrList(int a) {
        number = a;
    }

    NumberOrList() {
        number = -1;
    };

    NumberOrList(const NumberOrList& nl) {
        number = nl.number;
        for (const auto& a : nl.list) list.push_back(a);
    }

    NumberOrList(std::string str) {
        for (size_t i{ 0 }; i < str.size(); ++i) {
            if (str[i] == '[') {
                std::string buf = "";
                int count_open = 1;
                ++i;
                while (count_open > 0) {
                    if (str[i] == '[') ++count_open;
                    if (str[i] == ']') --count_open;
                    if (count_open == 0) {
                        list.push_back(buf);
                    }
                    else {
                        buf += str[i];
                    }
                    ++i;
                }
            }
            if (std::isdigit(str[i])) {
                std::string buf{ "" };
                while (std::isdigit(str[i])) {
                    buf += str[i];
                    i++;
                }
                list.push_back(std::stoi(buf));
                
            }
        }
    }

    bool isNumber() const {
        return number >= 0;
    }

    bool isList() const {
        return !isNumber();
    }

    bool operator==(const NumberOrList n) const {
        if (number != n.number) return false;
        if (list.size() != n.list.size()) return false;
        for (size_t i{ 0 }; i < list.size(); i++) {
            if (!(list[i] == n.list[i])) return false;
        }
        return true;
    }

    auto operator<=>(const NumberOrList& right) const {
        if (isNumber() && right.isNumber()) return number - right.number;
        else if (isList() && right.isList()) {
            auto l_it = list.begin();
            auto r_it = right.list.begin();
            for (; l_it != list.end() && r_it != right.list.end(); ++l_it, ++r_it) {
                int r = (*l_it)<=>(*r_it);
                if (r != 0) return r;
            }
            return static_cast<int>(list.size() - right.list.size());
        }
        else if (right.isList()) {
            auto temp = NumberOrList();
            temp.list.push_back(NumberOrList(number));
            return temp <=> right;
        }
        else {
            auto temp = NumberOrList();
            temp.list.push_back(NumberOrList(right.number));
            return *this <=> temp;
        }

    }
};

std::ostream& operator<<(std::ostream& os, const NumberOrList& nl) {
    if (nl.isNumber()) os << nl.number;
    else {
        os << "[";
        std::string pre = "";
        for (const auto& a : nl.list) {
            os << pre << a;
            pre = ",";
        }
        os << "]";
    }
    return os;
}

int main() {
    std::ifstream file("input.txt");
    std::string line;
    std::vector<NumberOrList> lines;
    int i{ 1 };
    int result{ 0 };
    std::cout << "START\n";

    while (std::getline(file, line)) {
        auto line_1 = NumberOrList(line);
        std::getline(file, line);
        auto line_2 = NumberOrList(line);
        std::getline(file, line);

        lines.emplace_back(line_1);
        lines.emplace_back(line_2);

        if (line_1 < line_2) {
            result += i;
        }
        i++;
    }

    auto two = NumberOrList("[[2]]");
    auto six = NumberOrList("[[6]]");
    lines.emplace_back(two);
    lines.emplace_back(six);
    std::sort(lines.begin(), lines.end());

    std::cout << "Part One: " << result << '\n';

    auto location_two = std::lower_bound(lines.begin(), lines.end(), two);
    auto location_six = std::lower_bound(location_two, lines.end(), six);

    int partwo = (1 + std::distance(lines.begin(), location_two)) * (1 + std::distance(lines.begin(), location_six));

    std::cout << "Part Two: " << partwo << '\n';
}

Jump in the discussion.

No email address required.

god i love how compact ts is to cpp

Jump in the discussion.

No email address required.

OUT!

Jump in the discussion.

No email address required.

:marseyneko: autismcatty says: „ your code stinks!“

Jump in the discussion.

No email address required.

it does, but i literally just updated it to not use Pointers. Should be less awful

https://rdrama.net/h/programming/post/130976/the-luckiest-of-days-day-13/3235625?context=8#context

Jump in the discussion.

No email address required.

You had a chance to not be completely worthless, but it looks like you threw it away. At least you're consistent.

Jump in the discussion.

No email address required.

Fun little "write a comparator then sort with it" challenge.


import ast
foo = []
with open('day13_input.txt', 'r') as inp:
    foo = inp.read().split('\n')
bar = [[[2]],[[6]]]
for f in foo:
    if len(f) > 0:
        bar.append(ast.literal_eval(f))
        
def eval(a, b):
    ta = str(type(a))
    tb = str(type(b))
    if ta == tb == "<class 'int'>":
        if a < b:
            return True
        elif a > b:
            return False
        return None
    if ta != tb:
        if ta == "<class 'int'>":
            a = [a]
        else:
            b = [b]
    for n in range(min(len(a), len(b))):
        e = eval(a[n], b[n])
        if e != None:
            return e
    if len(b) < len(a):
        return False
    elif len(b) > len(a):
        return True
    return None

for f in range(len(bar)):
    for g in range(len(bar)):
        if f != g:
            if eval(bar[f], bar[g]):
                temp = bar[f]
                bar[f] = bar[g]
                bar[g] = temp
print((1+bar.index([[2]]))*(1+bar.index([[6]])))
Jump in the discussion.

No email address required.

silently judging anyone who triggers longpostbot

def check(L: list | int, R: list | int) -> bool | None:
    Li, Ri = isinstance(L, int), isinstance(R, int)
    if Li and Ri: return None if L == R else L < R
    if Li: return check([L,], R)
    if Ri: return check(L, [R,])
    try:
        for l, r in zip(L, R, strict=True):
            if (output := check(l, r)) is not None:
                return output
    except ValueError:
        return len(L) < len(R)

with open('13', 'r') as file:
    raw = [x.split('\n') for x in file.read().strip().split('\n\n')]
pairs = [list(map(eval, pair)) for pair in raw]
packets = [x for mid in pairs for x in mid] + [[[2]], [[6]]]
for i in range(len(packets)):
    for j in range(len(packets)-i-1):
        if check(packets[j], packets[j+1]) is False:
            packets[j], packets[j+1] = packets[j+1], packets[j]
print(sum(i + 1 for i, pair in enumerate(pairs) if check(*pair)))
print((1 + packets.index([[6]])) * (1 + packets.index([[2]])))
Jump in the discussion.

No email address required.

Not the best of complexities, especially for the search in the sorted array but whatever, also a lot of unnecessary copies in the loading loop, I hope GCC figured out how to optimizemaxx that shit out

snakes discuss

![](/images/16709303809683464.webp)

Jump in the discussion.

No email address required.

I was stuck on that fricking comparison function for a long time. In the end, tried it in python, got the same answer as matlab, tried to submit it AGAIN on the site, and it worked :marseyveryworriedfed:

I can probably make that function shorter but I'm tired.

![](/images/1670980393984451.webp)

Jump in the discussion.

No email address required.

import * as fs from 'fs';

enum E {True=-1, Undef=0, False=1};
type T = number | (number|T)[]
const packets: T[][] = [];
const compare = (l: T, r: T): E => {
  if (typeof l === 'number' && typeof r === 'number')
    return l === r ? E.Undef : l < r ? E.True : E.False;
  const ll = (typeof l === 'number') ? [l] : l;
  const rl = (typeof r === 'number') ? [r] : r;
  const ret = ll.reduce((p: E, li, i) => {
    if (p) return p;
    const ri = rl[i];
    if (typeof ri === 'undefined') return E.False;
    const cmp = compare(li, ri);
    if (cmp) return cmp;
    return E.Undef;
  }, E.Undef);
  if (ret) return ret;
  else if (ll.length < rl.length) return E.True;
  else return E.Undef;
}
console.log(
  fs.readFileSync(process.argv[2], 'utf-8').split('\n\n').reduce((p, lines,i) => {
    const line = lines.split('\n');
    const [l,r] = line.map(s => JSON.parse(s));
    packets.push(l, r);
    const ret = compare(l, r);
    return p + (ret===E.True ? i+1 : 0) 
  }, 0
));
packets.sort(compare);
console.log(
  packets.reduce((prev, p, i) =>
  prev * (JSON.stringify(p).match(/^\[\[[2,6]\]\]$/) ? (i+1) : 1)
, 1)
);
Jump in the discussion.

No email address required.

:#marseycowboy:

Jump in the discussion.

No email address required.

Link copied to clipboard
Action successful!
Error, please refresh the page and try again.