예제 #1
0
OR T J
NOT C T
OR T J
AND D J
WALK
""")
    print(f'part 1: {d}')

    d = await run(
        memory, """NOT A J
NOT B T
OR T J
NOT C T
OR T J
AND D J
NOT E T
NOT T T
OR H T
AND T J
    RUN
    """)


def main(*_):
    trio.run(amain)


if __name__ == '__main__':
    main()
    print(Puzzle(2019, 21).answers)
예제 #2
0
from datetime import datetime
import time
import functools, itertools, collections, re
import numpy as np
from aocd.models import Puzzle
from aocd import submit

day = 1
puzzle = Puzzle(year=2020, day=day)
input_data = puzzle.input_data


def test(tests, solution):
    for i, o in tests.items():
        if (ao := solution(i)) != o:
            print(
                f"Testcase failed:\n    Input: {i}\n    Expected output: {o}\n    Actual output: {ao}\n"
            )
            return False
    print(f"Tests successful!")
    return True


def solve_a(inp=input_data):
    for i in map(int, inp.split("\n")):
        for x in map(int, inp.split("\n")):
            if i + x == 2020:
                return i * x


def solve_b(inp=input_data):
예제 #3
0
    NC -> B
    NB -> B
    BN -> B
    BB -> N
    BC -> B
    CC -> N
    CN -> C"""

    assert iterate_brute_force(test_data, 1) == "NCNBCHB"
    assert iterate_brute_force(test_data, 2) == "NBCCNBBBCBHCB"

    assert iterate(test_data, 1) == count_adjacent_pairs("NCNBCHB")
    assert iterate(test_data, 2) == count_adjacent_pairs("NBCCNBBBCBHCB")
    assert iterate(test_data,
                   3) == count_adjacent_pairs("NBBBCNCCNBBNBNBBCHBHHBCHB")
    assert iterate(test_data, 4) == count_adjacent_pairs(
        "NBBNBNBBCCNBCNCCNBBNBBNBBBNBBNBBCBHCBHHNHCBBCBHCB")

    assert solve(test_data, 10) == 1588
    assert solve_brute_force(test_data, 10) == 1588

    puzzle = Puzzle(2021, 14)

    answer_1 = solve(puzzle.input_data, 10)
    print(answer_1)
    puzzle.answer_a = answer_1

    answer_2 = solve(puzzle.input_data, 40)
    print(answer_2)
    puzzle.answer_b = answer_2
예제 #4
0
                items = storage.setdefault(dest, [])
                if items:
                    full.appendleft(dest)
                items.append(val)
            else:
                output[dest] = val

    return output, answer


if __name__ == '__main__':
    from aocd.models import Puzzle

    s = '''value 5 goes to bot 2
bot 2 gives low to bot 1 and high to bot 0
value 3 goes to bot 1
bot 1 gives low to output 1 and high to bot 0
bot 0 gives low to output 2 and high to output 0
value 2 goes to bot 2'''

    assert run(s) == ({0: 5, 1: 2, 2: 3}, 0)

    puz = Puzzle(2016, 10)
    out, ind = run(puz.input_data)

    puz.answer_a = ind
    print('Part 1:', puz.answer_a)

    puz.answer_b = out[0] * out[1] * out[2]
    print('Part 2:', puz.answer_b)
예제 #5
0
def run(data):
    val = [int(i) for i in data]
    part_a = ''.join(str(i) for i in phases(val, 100)[:8])
    part_b = ''.join(str(i) for i in decode(val))
    return part_a, part_b


if __name__ == '__main__':
    from aocd.models import Puzzle

    assert phases([1,2,3,4,5,6,7,8], 1) == [4,8,2,2,6,1,5,8]
    assert phases([1,2,3,4,5,6,7,8], 2) == [3,4,0,4,0,4,3,8]
    assert phases([1,2,3,4,5,6,7,8], 3) == [0,3,4,1,5,5,1,8]
    assert phases([1,2,3,4,5,6,7,8], 4) == [0,1,0,2,9,4,9,8]

    assert phases([8,0,8,7,1,2,2,4,5,8,5,9,1,4,5,4,6,6,1,9,0,8,3,2,1,8,6,4,5,5,9,5], 100)[:8] == [2,4,1,7,6,1,7,6]
    assert phases([1,9,6,1,7,8,0,4,2,0,7,2,0,2,2,0,9,1,4,4,9,1,6,0,4,4,1,8,9,9,1,7], 100)[:8] == [7,3,7,4,5,4,1,8]

    assert decode([0,3,0,3,6,7,3,2,5,7,7,2,1,2,9,4,4,0,6,3,4,9,1,5,6,5,4,7,4,6,6,4]) == [8,4,4,6,2,0,2,6]
    assert decode([0,2,9,3,5,1,0,9,6,9,9,9,4,0,8,0,7,4,0,7,5,8,5,4,4,7,0,3,4,3,2,3]) == [7,8,7,2,5,2,7,0]
    assert decode([0,3,0,8,1,7,7,0,8,8,4,9,2,1,9,5,9,7,3,1,1,6,5,4,4,6,8,5,0,5,1,7]) == [5,3,5,5,3,7,3,1]

    puz = Puzzle(2019, 16)
    part_a, part_b = run(puz.input_data)

    puz.answer_a = part_a
    print(f'Part 1: {puz.answer_a}')

    puz.answer_b = part_b
    print(f'Part 2: {puz.answer_b}')
예제 #6
0
from aocd.models import Puzzle

from functools import reduce
from operator import xor
puzzle = Puzzle(year=2017,day=15)

genA = 289
genB = 629

genAfact = 16807
genBfact = 48271
modulo = 2147483647

comp = 65535

num_matches = 0
for i in range(5000000):
    while genA & 3:
        genA = ((genA%modulo)*(genAfact))%modulo
    while genB & 7:
        genB = ((genB%modulo)*(genBfact))%modulo
    if (genA & comp) == (genB & comp):
        num_matches += 1
    genA = ((genA%modulo)*(genAfact))%modulo
    genB = ((genB%modulo)*(genBfact))%modulo
puzzle.answer_b = num_matches




예제 #7
0
from copy import deepcopy
from aocd.models import Puzzle
from collections import deque
from utils import *

puzzle = Puzzle(year=2020, day=22)
raw = puzzle.input_data
decks = raw.split('\n\n')
p1,p2 = deque(pints(decks[0])[1:]), deque(pints(decks[1])[1:])

def score(p):
    ans = 0
    for i,v in enumerate(p):
        ans += (len(p)-i) * v
    return ans

def play_game_1(p1,p2):
    while p1 and p2:
        a = p1.popleft()
        b = p2.popleft()
        if a > b:
            p1.extend([a,b])
        else:
            p2.extend([b,a])
    if(len(p1)):
        return score(p1)
    return score(p2)

print(play_game_1(deepcopy(p1), deepcopy(p2)))

def play_game(p1,p2):
예제 #8
0
        if occupied == prev_occupied:
            return occupied
        prev_occupied = occupied


if __name__ == "__main__":
    from aocd.models import Puzzle

    test_vals = process_input("""L.LL.LL.LL
LLLLLLL.LL
L.L.L..L..
LLLL.LL.LL
L.LL.LL.LL
L.LLLLL.LL
..L.L.....
LLLLLLLLLL
L.LLLLLL.L
L.LLLLL.LL""")
    assert process(test_vals) == 37
    puz = Puzzle(2020, 11)

    data = process_input(puz.input_data)

    puz.answer_a = process(data)
    print(f"Part 1: {puz.answer_a}")

    assert process(test_vals, tick=tick_part2) == 26

    puz.answer_b = process(data, tick=tick_part2)
    print(f"Part 2: {puz.answer_b}")
예제 #9
0
        x, y = zero_pos
        n += 1
        for dx, dy in [(-1, 0), (0, 1), (1, 0), (0, -1)]:
            move_pos = (x + dx, y + dy)
            if move_pos in info and move_pos not in immovable:
                frontier.appendleft(
                    (n, zero_pos if move_pos == data_pos else data_pos,
                     move_pos))

    raise RuntimeError('Failed to find goal!')


if __name__ == '__main__':

    from aocd.models import Puzzle
    puz = Puzzle(2016, 22)

    info = dict(parse(puz.input_data))
    assert len(info) == 875
    assert info[0, 0] == (65, 29, 94)

    # Means no combining nodes, so we're just sliding the data around using an empty node, and there's only 1 empty node
    assert len(
        set(b for a, b in itertools.permutations(info, 2)
            if info[a][0] <= info[b][1] if info[a][0])) == 1

    puz.answer_a = viable(info)
    print('Part 1:', puz.answer_a)

    puz.answer_b = shortest_path(info)
    print('Part 2:', puz.answer_b)
예제 #10
0
TEST_INPUTS = ["""
1721
979
366
299
675
1456
"""]
TEST_INPUTS = [t.strip() for t in TEST_INPUTS]


def run(input_data):
    data = [int(x) for x in input_data.split("\n")]
    print(len(data), "entries")
    for i, x in enumerate(data):
        for j, y in enumerate(data):
            # first star was only two loops
            for k, z in enumerate(data):
                if i < j and j < k and x + y + z == 2020:
                    print(x, y, z, x * y * z)
    print("-" * 20)


if __name__ == "__main__":
    for t in TEST_INPUTS:
        run(t)

    input_data = Puzzle(year=2020, day=1).input_data
    run(input_data)
예제 #11
0
    comps = itertools.cycle(network.values())
    while comp := next(comps):
        inp = [-1] if not comp.input_data else None
        if comp.run(inp):
            break
        while comp.output:
            addr = comp.output.pop(0)
            x = comp.output.pop(0)
            y = comp.output.pop(0)
            network[addr].send_input((x, y))

    return network[255]


def run(data):
    nat = run_network(data.strip())
    return nat.part1, nat.part2


if __name__ == '__main__':
    from aocd.models import Puzzle

    puz = Puzzle(2019, 23)
    part_a, part_b = run(puz.input_data)

    puz.answer_a = part_a
    print(f'Part 1: {puz.answer_a}')

    puz.answer_b = part_b
    print(f'Part 2: {puz.answer_b}')
예제 #12
0
    pt_counts = Counter(pts_covered)

    return sum([c >= 2 for c in pt_counts.values()])


if __name__ == "__main__":
    from aocd.models import Puzzle

    test_data = """0,9 -> 5,9
    8,0 -> 0,8
    9,4 -> 3,4
    2,2 -> 2,1
    7,0 -> 7,4
    6,4 -> 2,0
    0,9 -> 2,9
    3,4 -> 1,4
    0,0 -> 8,8
    5,5 -> 8,2"""

    assert solve(test_data) == 5
    assert solve(test_data, part1=False) == 12

    puzzle = Puzzle(2021, 5)

    answer_1 = solve(puzzle.input_data)
    print(answer_1)
    puzzle.answer_a = answer_1

    answer_2 = solve(puzzle.input_data, part1=False)
    puzzle.answer_b = answer_2
예제 #13
0
from aocd.models import Puzzle
from ast import parse, Constant, BinOp, Expression, Add

input: str = Puzzle(day=18, year=2020).input_data.splitlines()


def reverseEvaluator(exp):
    if type(exp) == Constant:
        return exp.value
    elif type(exp) == Expression:
        return reverseEvaluator(exp.body)
    elif type(exp) == BinOp:
        left = reverseEvaluator(exp.left)
        right = reverseEvaluator(exp.right)
        return left * right if type(exp.op) == Add else left + right


def simpleEvaluator(exp):
    exp = exp.replace("+", "PLUS").replace("*", "TIMES")
    exp = exp.replace("PLUS", "-").replace("TIMES", "+")
    return reverseEvaluator(parse(exp, mode="eval"))


def part1():
    return sum([simpleEvaluator(exp) for exp in input])


def advancedEvaluator(exp):
    exp = exp.replace("+", "PLUS").replace("*", "TIMES")
    exp = exp.replace("PLUS", "*").replace("TIMES", "+")
    return reverseEvaluator(parse(exp, mode="eval"))
예제 #14
0
            next_time += inc
        inc *= repeat
    return next_time


if __name__ == '__main__':
    from aocd.models import Puzzle

    t = '''939
    7,13,x,x,59,x,31,19'''

    time, ids = parse(t)

    assert solve(time, ids) == 295
    assert find_time(ids) == 1068781

    assert find_time([17, -1, 13, 19]) == 3417
    assert find_time([67, 7, 59, 61]) == 754018
    assert find_time([67, -1, 7, 59, 61]) == 779210
    assert find_time([67, 7, -1, 59, 61]) == 1261476
    assert find_time([1789, 37, 47, 1889]) == 1202161486

    puz = Puzzle(2020, 13)
    time, ids = parse(puz.input_data)

    puz.answer_a = solve(time, ids)
    print(f'Part 1: {puz.answer_a}')

    puz.answer_b = find_time(ids)
    print(f'Part 2: {puz.answer_b}')
예제 #15
0
파일: 2020-21.py 프로젝트: scanta2/aocd
    for a in allergens:
        allergen_ingredient[a] = set.intersection(
            *[set(i) for i in allergens_dict[a]])

    while any(len(allergen_ingredient[a]) != 1 for a in allergen_ingredient):
        for a, v in allergen_ingredient.items():
            if len(v) == 1:
                for b, w in allergen_ingredient.items():
                    if b != a:
                        w -= v

    for i in allergen_ingredient.values():
        for j in i:
            ingredients_counter[j] = 0
    return sum(ingredients_counter.values()), allergen_ingredient


PUZZLE = Puzzle(year=2020, day=21)
INPUT = PUZZLE.input_data
# INPUT = """mxmxvkd kfcds sqjhc nhms (contains dairy, fish)
# trh fvjkl sbzzf mxmxvkd (contains dairy)
# sqjhc fvjkl (contains soy)
# sqjhc mxmxvkd sbzzf (contains fish)"""
PUZZLE.answer_a, ai = part1(INPUT)

ins = []
for a in sorted(ai):
    ins.append(ai[a])

PUZZLE.answer_b = ','.join(list(i)[0] for i in ins)
예제 #16
0
    # had to make rules global so matches would have a nice cacheable interface
    global rules
    rules, msgs = parse(inp)

    if part2mod:
        rules["8"] = "42 | 42 8"
        rules["11"] = "42 31 | 42 11 31"

    matching = 0
    for m in msgs:
        # print(m)
        if matches(m, rules["0"]):
            matching += 1
    print(matching)
    matches.cache_clear()


if __name__ == "__main__":
    os.system("clear")
    inp = Puzzle(year=2020, day=DAY).input_data

    print("=============== A ===============\n")
    run(SAMPLE)
    print("\n" + "-" * 15 + "\n")
    run(inp)

    print("\n=============== B ===============\n")
    run(sample2, part2mod=True)
    print("\n" + "-" * 15 + "\n")
    run(inp, part2mod=True)
예제 #17
0
    x = 1
    y = 3

    keycode = []
    for line in parse(input_data):
        for direction in line:
            x, y = move2(x, y, direction, keypad)
        keycode.append(keypad[y][x])
    return ''.join(keycode)


test_data = """ULL
RRDDD
LURDL
UUUUD"""

assert solve1(test_data) == '1985'
assert solve2(test_data) == '5DB3'

if __name__ == '__main__':
    from aocd.models import Puzzle
    puzzle = Puzzle(2016, 2)
    answer_1 = solve1(puzzle.input_data)

    print(answer_1)
    puzzle.answer_a = answer_1

    answer_2 = solve2(puzzle.input_data)
    puzzle.answer_b = answer_2
예제 #18
0
    print(sum(t1_invalid))

    print(filter_invalid(t1_invalid, t1ot))

    t2h, t2t, t2ot = parse_input(test2)
    t2_invalid = check_invalid(t2h, t2ot)
    t2ot_valid = filter_invalid(t2_invalid, t2ot)
    t2ot_valid.append(t2t)

    t2or = find_field_order(t2h, t2ot_valid)
    print(label_ticket(t2t, t2or))

    # Answer 1
    from aocd.models import Puzzle

    puzzle = Puzzle(2020, 16)

    mth, mtt, mtot = parse_input(puzzle.input_data)
    mt_invalid = check_invalid(mth, mtot)
    mtot_valid = filter_invalid(mt_invalid, mtot)
    mtot_valid.append(mtt)
    print("Answer 1:", sum(mt_invalid))

    mtor = find_field_order(mth, mtot_valid)
    mttl = label_ticket(mtt, mtor)

    from math import prod

    mtt1 = [mttl[v] for v in mttl if "departure" in v]
    print("Answer 2:", prod(mtt1))
예제 #19
0
from aocd.models import Puzzle

t = Puzzle(2021, 1)

data = t.input_data
예제 #20
0
    pj-he
    RW-he
    fs-DX
    pj-RW
    zg-RW
    start-pj
    he-WI
    zg-he
    pj-fs
    start-RW"""

    assert solve1(test_data) == 10
    assert solve1(test_data2) == 19
    assert solve1(test_data3) == 226

    assert solve2(test_data) == 36

    p = solve2(test_data2)
    assert solve2(test_data2) == 103
    assert solve2(test_data3) == 3509

    puzzle = Puzzle(2021, 12)

    answer_1 = solve1(puzzle.input_data)
    print(answer_1)
    puzzle.answer_a = answer_1

    answer_2 = solve2(puzzle.input_data)
    print(answer_2)
    puzzle.answer_b = answer_2
예제 #21
0
                                            continue
                                        if (x + dx, y + dy, z1 + dz1,
                                                z2 + dz2) in on:
                                            neighbours_on += 1
                        if (x, y, z1, z2) in on and 2 <= neighbours_on <= 3:
                            new_on[(x, y, z1, z2)] = 1
                        elif neighbours_on == 3:
                            new_on[(x, y, z1, z2)] = 1
        on = new_on

    print(len(on))


def parse_input(data):
    return np.array(lmap(list, data.splitlines()))


test_input = """.#.
..#
###"""

if __name__ == '__main__':
    puzzle = Puzzle(year=2020, day=17)
    if False:
        array = parse_input(test_input)
    else:
        array = parse_input(puzzle.input_data)

    solve_puzzle_one(array)
    solve_puzzle_two(array)
예제 #22
0
#!/usr/bin/env python3
"""
    - Run the script in an ipython session using '%run <name>'
    - Make sure to 'export AOC_SESSION=<your_aoc_token>'
"""

from aocd.models import Puzzle
from typing import List

# https://adventofcode.com/2016/day/1
puzzle = Puzzle(2016, 1)

data = puzzle.input_data
directions = data.split(", ")

######################################################################
#   Part 1
######################################################################


class Coord(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return f"Coord({self.x}, {self.y})"


# State machine to keep track of direction to save a bunch of ifs
alph = "RL"
예제 #23
0
import itertools
import string
from collections import deque, defaultdict
from functools import cmp_to_key
from math import ceil, log

from aocd.models import Puzzle

puzzle = Puzzle(year=2018, day=6)

raw = puzzle.input_data


class Point:
    def __init__(self, y, x, name=None):
        self.x = x
        self.y = y
        self.name = name

    def __repr__(self):
        return f"{self.name}({self.y}, {self.x})"

    def dot(self, other):
        return self.x * other.x + self.y * other.y

    def cross(self, other):
        return self.x * other.y - other.x * self.y

    def __sub__(self, other):
        return Point(self.y - other.y, self.x - other.x, None)
예제 #24
0

if __name__ == "__main__":
    from aocd.models import Puzzle

    test_data = """light red bags contain 1 bright white bag, 2 muted yellow bags.
        dark orange bags contain 3 bright white bags, 4 muted yellow bags.
        bright white bags contain 1 shiny gold bag.
        muted yellow bags contain 2 shiny gold bags, 9 faded blue bags.
        shiny gold bags contain 1 dark olive bag, 2 vibrant plum bags.
        dark olive bags contain 3 faded blue bags, 4 dotted black bags.
        vibrant plum bags contain 5 faded blue bags, 6 dotted black bags.
        faded blue bags contain no other bags.
        dotted black bags contain no other bags."""

    additional_test_data = """shiny gold bags contain 2 dark red bags.
        dark red bags contain 2 dark orange bags.
        dark orange bags contain 2 dark yellow bags.
        dark yellow bags contain 2 dark green bags.
        dark green bags contain 2 dark blue bags.
        dark blue bags contain 2 dark violet bags.
        dark violet bags contain no other bags."""

    assert solve1(test_data) == 4
    assert solve2(test_data) == 32
    assert solve2(additional_test_data) == 126

    puz7 = Puzzle(2020, 7)
    data = puz7.input_data
    puz7.answer_a = solve1(data)
    puz7.answer_b = solve2(data)
예제 #25
0
import time
import functools, itertools, collections, re
import numpy as np
from aocd.models import Puzzle
from aocd import submit
from collections import defaultdict as dd

day = 13
puzzle = Puzzle(year=2021, day=day)
input_data = puzzle.input_data

def test(tests, solution, part):
    c = 1
    for i,o in tests.items():
        if o[part] and (ao := solution(i)) != o[part]:
            print(f"Testcase {c} failed:\n    Expected output: {o}\n    Actual output: {ao}\n")
            return False
        c += 1
    print(f"Tests successful!")
    return True

def solve_a(inp=input_data):
    cs, ins = inp.split("\n\n")
    cs = [[int(x) for x in k.split(",")] for k in cs.split("\n")]
    ins = [(k.split("=")[0][-1], int(k.split("=")[1])) for k in ins.split("\n")]
    grid = {(x,y) for x,y in cs}
    for dir, c in ins[0:1]:
        newg = set()
        if dir == "x":
            for x,y in grid:
                if x > c:
예제 #26
0
    # 226

    ox = {o}
    t = 0
    spread = [o]
    while True:
        spread = [
            p for o in spread for dir in _dir.values()
            if map[(p := o + dir)] == 1 and p not in ox
        ]
        if spread:
            t += 1
            for p in spread:
                ox.add(p)
        else:
            break

    print(f'part 2: {t}')
    # 342
    return part_a, t


def main(*_):
    return trio.run(amain)


if __name__ == '__main__':
    main()

    print(Puzzle(2019, 15).answers)
예제 #27
0
from aocd.models import Puzzle

def save_input_to_file(puzzle, day):
    filename = "day" + str(day) + ".txt"
    with open(filename, mode='w+') as f:
        data = puzzle.input_data
        f.write(data)

Year=2020
Day=22

puzzle = Puzzle(year=Year, day=Day)
save_input_to_file(puzzle, day=Day)

infile = "day22ex.txt"
infile = "day22.txt"
lines = [line.rstrip() for line in open(infile)]

# Part 1
if True:
    for line in lines: 
        pass
    #puzzle.answer_a = result

# Part 2
if True:
    pass

    #puzzle.answer_b = result
예제 #28
0
        scores.append(score2(closers))

    return median(scores)


if __name__ == "__main__":
    from aocd.models import Puzzle

    test_data = """[({(<(())[]>[[{[]{<()<>>
    [(()[<>])]({[<{<<[]>>(
    {([(<{}[<>[]}>{[]{[(<()>
    (((({<>}<{<{<>}{[]{[]{}
    [[<[([]))<([[{}[[()]]]
    [{[{({}]{}}([{[{{{}}([]
    {<[[]]>}<{[{[{[]{()[[[]
    [<(<(<(<{}))><([]([]()
    <{([([[(<>()){}]>(<<{{
    <{([{{}}[<[[[<>{}]]]>[]]"""

    assert solve1(test_data) == 26397
    assert solve2(test_data) == 288957
    puzzle = Puzzle(2021, 10)

    answer_1 = solve1(puzzle.input_data)
    print(answer_1)
    puzzle.answer_a = answer_1

    answer_2 = solve2(puzzle.input_data)
    print(answer_2)
    puzzle.answer_b = answer_2
예제 #29
0
파일: 2019-Day6-A.py 프로젝트: SinJ5/Aocd
from aocd.models import Puzzle

puzzle = Puzzle(year=2019, day=6)
orbits = [(x.split(")")) for x in puzzle.input_data.split("\n")]


class OrbitDescription:

    def __init__(self, me):
        self.orbiters = []
        self.me = me
        self.parent = None

    def addOrbiters(self, orb):
        self.orbiters.append(orb)

    def setParent(self, parent):
        self.parent = parent

    def cnt(self, deep):
        return len(self.orbiters) * deep + sum([x.cnt(deep + 1) for x in self.orbiters])


seznam = {}

for orb in orbits:
    fr = seznam.get(orb[0])
    to = seznam.get(orb[1])
    if fr is None:
        fr = OrbitDescription(orb[0])
        seznam[orb[0]] = fr
예제 #30
0
파일: 6_1.py 프로젝트: daanklijn/aoc2019
from aocd.models import Puzzle
import numpy as np

data = Puzzle(year=2019, day=6).input_data.split('\n')
print(data)

# data='COM)B,B)C,C)D,D)E,E)F,B)G,G)H,D)I,E)J,J)K,K)L'.split(',')
data = list(map(lambda x: x.split(')'), data))


def place_in_tree(tree):
    to_find = tree[0]
    to_remove = []
    for item in data:
        if (item[0] == to_find):
            tree[1].append([item[1], []])
            to_remove.append(item)
    for item in to_remove:
        data.remove(item)
    for link in tree[1]:
        place_in_tree(link)


def count_orbits(tree, depth):
    sum = 0
    for i in tree[1]:
        sum += depth + 1
        sum += count_orbits(i, depth + 1)
    return sum