14862 - Very useful playlist engine   

Description

After a long, messy legal battle between NewJeans and ADOR, the group has finally agreed to rejoin the label. For fans, this is a double-edged sword: some see it as a strategic win, while others see it as a corporate compromise. But one KPI remains rock solid—the music still hits. d[^-^]b

Your mission: build a smart playlist system that helps fans consume NewJeans’ discography more efficiently and enjoyably. 


You will implement a small playlist system using:

  • an abstract base class BasePlaylist
  • two subclasses: SequentialPlaylist and ReversePlaylist
  • custom __iter__
  • operator overloading __add__

Each playlist stores track names (strings without spaces) in a list self._tracks in insertion order.

 

What You Must Implement

Implement the following:

BasePlaylist (abstract)

BasePlaylist must:

  • inherit from ABC

  • __init__(self): initialize

    ​​self._tracks = []
    
  • add(self, track_name): append track_name to self._tracks

  • __len__(self): return number of tracks

  • __repr__(self): return ​​"label_name: [...]", where [...] is the list of track names

  • __add__(self, other):

    • create a new SequentialPlaylist
    • its _tracks is self._tracks + other._tracks

SequentialPlaylist(BasePlaylist)

  • __iter__(self): iterate in insertion order, e.g. return iter(self._tracks)

ReversePlaylist(BasePlaylist)

  • __iter__(self): iterate in reverse insertion order, e.g. return reversed(self._tracks)

 

Code Template

from abc import ABC, abstractmethod


class BasePlaylist(ABC):
    def __init__(self):
        # TODO: store the label name and initialize an empty list to store tracks 
        raise NotImplementedError

    def add(self, track_name):
        # TODO: append track_name (string) to self._tracks
        raise NotImplementedError

    def __len__(self):
        # TODO: return number of tracks
        raise NotImplementedError

    def __repr__(self):
        # TODO:
        raise NotImplementedError

    def __add__(self, other):
        # TODO:
        raise NotImplementedError

    @abstractmethod
    def __iter__(self):
        pass


class SequentialPlaylist(BasePlaylist):
    def __iter__(self):
        # TODO: iterator in insertion order
        raise NotImplementedError


class ReversePlaylist(BasePlaylist):
    def __iter__(self):
        # TODO: iterator in reverse insertion order
        raise NotImplementedError


""" Do not change the code below """

q = int(input())
playlists = {}  # label (str) -> BasePlaylist instance

for _ in range(q):
    op = input().split()

    if op[0] == "NEW_SEQ":
        label = op[1]
        playlist = SequentialPlaylist()
        playlist._label = label
        playlists[label] = playlist

    elif op[0] == "NEW_REV":
        label = op[1]
        playlist = ReversePlaylist()
        playlist._label = label
        playlists[label] = playlist

    elif op[0] == "ADD":
        label = op[1]
        track_name = op[2]
        playlists[label].add(track_name)

    elif op[0] == "LEN":
        label = op[1]
        print(len(playlists[label]))

    elif op[0] == "PLAY":
        label = op[1]
        k = int(op[2])
        it = iter(playlists[label])
        played = []
        for _ in range(k):
            played.append(next(it))
        print(" -> ".join(played))

    elif op[0] == "MERGE":
        new_label = op[1]
        l1 = op[2]
        l2 = op[3]
        merged = playlists[l1] + playlists[l2]
        merged._label = new_label
        playlists[new_label] = merged

    elif op[0] == "PRINT":
        label = op[1]
        print(playlists[label])

 

Test cases:

  • Test cases 1-3: Basic tests (NEW_SEQ/NEW_REV, ADD, LEN, PRINT)
  • Test cases 4-6: Tests using __iter__ (PLAY command)
  • Test cases 7-10: All commands (NEW_SEQ, NEW_REV, ADD, LEN, PLAY, MERGE, PRINT)

Input

  • The first line contains an integer q: the number of operations.
  • Each of the next q lines is one of:
    • NEW_SEQ label
      Create empty SequentialPlaylist under label.

    • NEW_REV label
      Create empty ReversePlaylist under label.

    • ADD label track_name
      Add track_name to playlist label.

    • LEN label
      Print the number of tracks.

    • PLAY label k

      • Print all the tracks in label (by calling next(it)) joined by ->, e.g.
        a -> b -> c
    • MERGE new_label label1 label2

      • Compute playlists[new_label] = playlists[label1] + playlists[label2]
    • PRINT label

      • Print all tracks in label (uses your __repr__)

Constraints:

  • 1 ≤ q ≤ 1000

  • 0 ≤ k ≤ len_of_playlist

Output

For each following operation, output the corresponding text:

  • LEN label: Print the number of tracks.

  • PLAY label k: Print all the tracks in label (by calling next(it)) joined by ->, e.g. a -> b -> c

  • PRINT label: Print all tracks in label ("label_name: [...]", where [...] is the list of track names)

Sample Input  Download

Sample Output  Download




Discuss