3281 - I2P(I)2025_Chou_Hu_Hw9_ClassA Scoreboard

Time

2025/12/01 20:30:00 2025/12/08 18:30:00

Clarification

# Problem Asker Description Reply Replier Reply Time For all team

# Problem Pass Rate (passed user / total user)
14857 Simple Todo List
14862 Very useful playlist engine

14857 - Simple Todo List   

Description

With the deadline of the final project creeping closer and closer, an I2P student has completely lost track of what he needs to do. Help him build a simple todo list to keep track of the tasks he needs to complete for this class. ( ̄^ ̄ )ゞ


What You Must Implement

Implement the following:

  • PendingTaskIterator.__init__
    • Build and store the list of pending tasks (in insertion order).
    • The iterator should snapshot the pending tasks at creation time: later ADD or DONE operations on the TaskQueue must not affect an already-created PendingTaskIterator.
  • PendingTaskIterator.__next__
    • Return the next pending task from this list and advance the internal index.
    • The iterator must yield the same task dictionaries (the same dict objects) that are stored in the underlying TaskQueue.
    • Raise StopIteration when there are no more pending tasks.
  • TaskQueue.add_task
    • Append a new task dict with "name" and "done": False to the underlying list.
  • TaskQueue.mark_done
    • mark the earliest added task whose "name" equals name and whose "done" is False, and set that task’s "done" to True. If there is no pending task with that name, do nothing.
  • TaskQueue.__iter__
    • Return a PendingTaskIterator instance for this TaskQueue instead of the default list iterator.

Code Template

class PendingTaskIterator:
    def __init__(self, task_queue):
        self.pending = []
        self.index = 0
        # TODO: fill self.pending with the pending tasks in the correct order

    def __next__(self):
        # TODO:
        raise NotImplementedError

class TaskQueue(list):
    def add_task(self, name):
        # TODO:
        # Append a new task dict to the list.
        raise NotImplementedError

    def mark_done(self, name):
        # TODO:
        # Traverse the underlying list in insertion order
        raise NotImplementedError

    def __iter__(self):
        # TODO:
        # Return a PendingTaskIterator for this TaskQueue
        raise NotImplementedError


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

q = int(input())
tq = TaskQueue()

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

    if op[0] == "ADD":
        name = " ".join(op[1:])
        tq.add_task(name)

    elif op[0] == "DONE":
        name = " ".join(op[1:])
        tq.mark_done(name)

    elif op[0] == "LEN":
        print(len(tq))

    elif op[0] == "PRINTALL":
        print(tq)

    elif op[0] == "PENDING":
        k = int(op[1])
        it = iter(tq)
        for _ in range(k):
            print(next(it))

 

Test cases:

  • Test cases 1-3: Basic tests (ADD, LEN, PRINTALL)
  • Test cases 4-6: Tests using __iter__ (PENDING command)
  • Test cases 7-10: All commands (ADD, DONE, LEN, PRINTALL, PENDING)

Input

  • The first line contains an integer q: the number of operations.
  • Each of the next q lines is one of:
    • ADD name
      Append a new task with the given name to the queue.
    • DONE name
      Mark one task with the given name as done. If no such task exists, do nothing.
      Hint: Do not iterate with for task in self: here, because that will use the overridden iterator.
    • LEN
      Print the total number of tasks stored in the queue (done + not done).
    • PRINTALL
      Print the internal list of tasks directly (using the default string representation).
      This prints all tasks (done + not done) in insertion order.
    • PENDING k
      Use the iterator protocol to iterate over pending tasks only and print the first k of them.

Constraints:

  • 1 ≤ q ≤ 1000

  • 0 ≤ k ≤ current_number_of_pending_tasks

Output

For each following operation, output the corresponding text:

  • LEN: Print the total number of tasks
  • PRINTALL: Print the the internal list of tasks using default string representation.
  • PENDING k: Print the first k pending tasks.

Sample Input  Download

Sample Output  Download

Tags




Discuss




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

Tags




Discuss