fork download
  1. from mpi4py import MPI
  2.  
  3. def calculate_required_cards(height):
  4. """Calculate the number of cards required to build a pyramid of a given height."""
  5. return (height * (3 * height + 1)) // 2
  6.  
  7. def calculate_pyramid_height_and_cards(card_count):
  8. """Calculate the maximum height of a pyramid and the number of cards used."""
  9. height = 0
  10. while True:
  11. required_cards = calculate_required_cards(height)
  12. if required_cards > card_count:
  13. break
  14. height += 1
  15. height -= 1 # Adjust to the last valid height
  16. required_cards = calculate_required_cards(height)
  17. return height, required_cards
  18.  
  19. def main():
  20. comm = MPI.COMM_WORLD
  21. process_rank = comm.Get_rank()
  22. total_processes = comm.Get_size()
  23.  
  24. if total_processes <= 1:
  25. if process_rank == 0:
  26. print("Error: At least one worker process is required.")
  27. return 0
  28.  
  29. if process_rank == 0:
  30. # Master process
  31. total_cards = int(input("Enter the total number of cards: "))
  32. remaining_cards = total_cards
  33. pyramid_count = 0
  34.  
  35. loop_counter = 0 # To prevent infinite loops
  36. max_attempts = 1000 # Arbitrary large number to safeguard against infinite loops
  37.  
  38. while remaining_cards > 0:
  39. if loop_counter >= max_attempts:
  40. print("Exceeded maximum attempts. Stopping to prevent infinite loop.")
  41. break
  42.  
  43. # Assign work to a worker process
  44. worker_rank = (pyramid_count % (total_processes - 1)) + 1
  45. comm.send(remaining_cards, dest=worker_rank, tag=11)
  46.  
  47. # Receive results from the worker process
  48. try:
  49. pyramid_height, cards_used = comm.recv(source=worker_rank, tag=22)
  50. except Exception as e:
  51. print(f"Error during communication with worker {worker_rank}: {e}")
  52. break
  53.  
  54. if cards_used == 0:
  55. print(f"Cannot build a pyramid with the remaining {remaining_cards} cards. Stopping further attempts.")
  56. break
  57.  
  58. print(f"Pyramid {pyramid_count + 1}: Using {cards_used} cards to build a pyramid of height {pyramid_height}.")
  59. remaining_cards -= cards_used
  60. pyramid_count += 1
  61. loop_counter += 1
  62.  
  63. # Send termination signal to all worker processes
  64. for worker_rank in range(1, total_processes):
  65. comm.send(-1, dest=worker_rank, tag=11)
  66.  
  67. print(f"\nTotal pyramids built: {pyramid_count}")
  68. return pyramid_count
  69. else:
  70. # Worker processes
  71. while True:
  72. try:
  73. cards_available = comm.recv(source=0, tag=11)
  74. except Exception as e:
  75. print(f"Error receiving data from master process: {e}")
  76. break
  77.  
  78. if cards_available == -1:
  79. break # Termination signal
  80.  
  81. pyramid_height, cards_used = calculate_pyramid_height_and_cards(cards_available)
  82.  
  83. try:
  84. comm.send((pyramid_height, cards_used), dest=0, tag=22)
  85. except Exception as e:
  86. print(f"Error sending data to master process: {e}")
  87. break
  88.  
  89. if __name__ == "__main__":
  90. result = main()
  91. if result is not None:
  92. print(f"Result from main function: {result}")
  93.  
Success #stdin #stdout #stderr 0.29s 40772KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
Error: unexpected symbol in "from mpi4py"
Execution halted