2015 FRQ by Paaras Purohit - Question 1
Completing the 2015 AP Computer Science A free-response questions and taking notes - Question 1
Question 1
Type: 2D Array
Directions: SHOW ALL YOUR WORK. REMEMBER THAT PROGRAM SEGMENTS ARE TO BE WRITTEN IN JAVA.
Notes:
- Assume that the classes listed in the Java Quick Reference have been imported where appropriate.
- Unless otherwise noted in the question, assume that parameters in method calls are not null and that methods are called only when their preconditions are satisfied.
- In writing solutions for each question, you may use any of the accessible methods that are listed in classes defined in that question. Writing significant amounts of code that can be replaced by a call to one of these methods will not receive full credit.
This question involves reasoning about one-dimensional and two-dimensional arrays of integers. You will write three static methods, all of which are in a single enclosing class, named DiverseArray (not shown). The first method returns the sum of the values of a one-dimensional array; the second method returns an array that represents the sums of the rows of a two-dimensional array; and the third method analyzes row sums.
(a) Write a static method arraySum that calculates and returns the sum of the entries in a specified one-dimensional array. The following example shows an array arr1 and the value returned by a call to arraySum.
Complete method arraySum below.
/** Returns the sum of the entries in the one-dimensional array arr.
*/
public static int arraySum (int [ ] arr)
(b) Write a static method rowSums that calculates the sums of each of the rows in a given two-dimensional array and returns these sums in a one-dimensional array. The method has one parameter, a two-dimensional array arr2D of int values. The array is in row-major order: arr2D [ r ] [ c ] is the entry at row r and column c. The method returns a one-dimensional array with one entry for each row of arr2D such that each entry is the sum of the corresponding row in arr2D. As a reminder, each row of a two-dimensional array is a one-dimensional array.
For example, if mat1 is the array represented by the following table, the call rowSums(mat1) returns the array {16, 32, 28, 20}.
Assume that arraySum works as specified, regardless of what you wrote in part (a). You must use arraySum appropriately to receive full credit.
Complete method rowSums below.
/** Returns a one-dimensional array in which the entry at index k is the sum of
* the entries of row k of the two-dimensional array arr2D.
*/
public static int [ ] rowSums(int [ ] [ ] arr2D)
(c) A two-dimensional array is diverse if no two of its rows have entries that sum to the same value. In the following examples, the array mat1 is diverse because each row sum is different, but the array mat2 is not diverse because the first and last rows have the same sum.
Write a static method isDiverse that determines whether or not a given two-dimensional array is diverse. The method has one parameter: a two-dimensional array arr2D of int values. The method should return true if all the row sums in the given array are unique; otherwise, it should return false. In the arrays shown above, the call isDiverse (mat1) returns true and the call isDiverse(mat2) returns false.
Assume that arraySum and rowSums work as specified, regardless of what you wrote in parts (a) and(b). You must use rowSums appropriately to receive full credit. Complete method isDiverse below.
/** Returns true if all rows in arr2D have different row sums;
* false otherwise.
*/
public static boolean isDiverse(int [ ] [ ] arr2D)
Skills I’m Familiar With (going into the question):
- Traversing through a one-dimensional array
- Object-oriented programming
- Getting the sum of an array
Skills I’m Unfamiliar With (going into the question):
- Traversing through 2D arrays
- Checking if an element in an array appears more than once
- Getting data from individual rows of 2D arrays
- Converting primitive arrays to ArrayLists
- Getting the size of a primitive array
Questions I Have:
- May I write more methods than are required? For example, if I must write a method to swap variables if I was dealing with sorting, would I be allowed to, regardless of credit?
My Solution (Without Any Research)
public class DiverseArray {
public static int arraySum(int[] arr) {
int finalSum = 0;
for (int i = 0; i <= arr.length; i++) {
finalSum += arr[i];
}
return finalSum;
}
public static int[] rowSums(int[][] arr2D) {
int[] sums;
for (int r = 0; r <= arr2D.height; /* I don't know how to get a 2D array's "height", or how many rows there are */ r++) {
for (int c = 0; c <= arr2D.width; /* I don't know how to get a 2D array's "width", or how may columns there are */ r++) {
sums[r] += arr2D[r][c];
}
}
return sums;
}
public static boolean isDiverse(int[][] arr2D) {
int[] sums = rowSums(arr2D);
/* Here is where I would check if an element appears more than once. But, I don't know how to do that. */
}
}
My New Solution (With Research on The Unfamiliar Skills)
public class DiverseArray {
public static int arraySum(int[] arr) {
int finalSum = 0;
for (int i = 0; i < arr.length; i++) {
finalSum += arr[i];
}
return finalSum;
}
public static int[] rowSums(int[][] arr2D) {
int[] sums = new int[arr2D.length];
for (int r = 0; r < arr2D.length; r++) {
sums[r] = arraySum(arr2D[r]);
}
return sums;
}
public static boolean isDiverse(int[][] arr2D) {
int[] sums = rowSums(arr2D);
for (int i = 0; i < sums.length - 1; i++) {
for (int j = i + 1; j < sums.length; j++) {
if (sums[i] == sums[j]) {
return false; // Found two rows with the same sum, not diverse
}
}
}
return true; // All row sums are unique, diverse
}
}
/* KEY ALGORITHM
The key algorithm here is iterating through and comparing elements through a 2D array, which effectively completes the understanding of the type of FRQ it is, 2D Array.
*/
To Test My Code
public class Main {
public static void main(String[] args) {
// Example usage and testing for DiverseArray class
int[] arr1 = {1, 2, 3, 4, 5};
int[] arr2 = {5, 4, 3, 2, 1};
int[] arr3 = {1, 1, 1, 1, 1};
int[][] arr2D = {arr1, arr2, arr3};
// Testing arraySum method
System.out.println("Sum of arr1: " + DiverseArray.arraySum(arr1));
// Testing rowSums method
int[] rowSums = DiverseArray.rowSums(arr2D);
System.out.print("Row sums: ");
for (int sum : rowSums) {
System.out.print(sum + " ");
}
System.out.println();
// Testing isDiverse method
boolean diverse = DiverseArray.isDiverse(arr2D);
System.out.println("Is the array diverse? " + diverse);
}
}
Main.main(null);
Sum of arr1: 15
Row sums: 15 15 5
Is the array diverse? false
Notes:
-
Don’t forget that for loop parameters need to be boolean statements. “i == 10” is valid, but “i = 10” is not.
-
For for loop parameters, don’t use “<=” especially for lists, just use “<”.
-
In the rowSums() method, I did
int[] sums;
, but next time, I must initialize it. The way I shall do it:int[] sums = new int[arr2D.length];
. -
The “length” property of a 2D array returns how many rows it has. If I wanted the number of columns, I would do
array2D[row].length;
, to get the number of columns at any row. If the 2D array is uniform, each row should have the same number of columns. -
I did this once perfectly already, but usually, more complex methods build of previously simpler ones. I can use that to my advantage for efficiency.
-
For checking if an array has two or more variables, I can iterate through the list with two indexes by using a nested for loop, where the outside for loop has an
int i
iterating as it normally would, and anint j = i + 1;
that starts off one index after inti
.
From APCSA FRQs to Our Project
How this 2D array algorithm relates to our in-class project
While we don’t explicitly use 2D arrays or their algorithms in our Java code, we do go about manipulating the database with the concepts and methodology that we would with 2D arrays. In this FRQ, we get the sum of each row and compare rows to each other to check for diversity. While we don’t get the sums of our database rows, we do compare them. Below is an example of our Company database and how it compares rows to each other (not including frontend code as it is not part of the topic or context):
Company.java:
package com.nighthawk.spring_portfolio.mvc.linkr;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.Year;
import java.util.HashSet;
import java.util.Set;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
@Data
@Entity
@Table(name = "company")
@NoArgsConstructor
public class Company {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name; // user
private String mission; // user
private String location; // user
private String industry; // user
private int size; // automated
private String description; // set to null, can be replaced
private String website; // set to null, can be replaced
private int foundedYear; // automated
private String ceo; // automated (employee creating company)
// private int investments;
@OneToMany(mappedBy = "company", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<Employee> employees = new HashSet<>();
public Company(String name, String mission, String location, String industry, String ceo){
// Users Set
this.name = name;
this.mission = mission;
this.location = location;
this.industry = industry;
// Automated Set
this.foundedYear = Year.now().getValue();
this.ceo = ceo;
this.size = 0;
// null Set
this.description = null;
this.website = null;
}
public static Company[] companyInit(){
Company c1 = new Company("Name 1", "To Name", "California", "Tech", "None");
Company c2 = new Company("Name 2", "To not name", "India", "Hosptality", "Tanay");
Company c3 = new Company("Name 3", "That is the question", "Shanghai", "Tax Fraud", "Paaras");
Company[] clist = {c1, c2, c3};
return clist;
}
}
CompanyController.java:
package com.nighthawk.spring_portfolio.mvc.linkr;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import lombok.extern.slf4j.Slf4j;
// Using lombok to automatically generate a logger
@Slf4j
@RestController
@RequestMapping("/api/companies") // Base URL for all endpoints in this controller
@CrossOrigin(origins = "*") // Allowing cross-origin requests from any origin
public class CompanyController {
private final CompanyService companyService; // Service to handle business logic
private final ModelMapper modelMapper; // For entity-to-DTO mapping
@Autowired
public CompanyController(CompanyService companyService, ModelMapper modelMapper) {
this.companyService = companyService;
this.modelMapper = modelMapper;
}
// Endpoint to get all companies
@GetMapping
public ResponseEntity<List<CompanyDTO>> getAllCompanies() {
List<Company> companies = companyService.getAllCompanies(); // Retrieve companies from the service
List<CompanyDTO> companyDTOs = companies.stream()
.map(company -> modelMapper.map(company, CompanyDTO.class)) // Map entities to DTOs
.collect(Collectors.toList()); // Collect DTOs into a list
return new ResponseEntity<>(companyDTOs, HttpStatus.OK); // Return DTO list with OK status
}
// Endpoint to get a company by its ID
@GetMapping("/{companyId}")
public ResponseEntity<Company> getCompanyById(@PathVariable Long companyId) {
log.info("Attempting to retrieve company with ID: {}", companyId); // Log the attempt
Optional<Company> company = companyService.getCompanyById(companyId); // Retrieve the company by ID
if (company.isPresent()) { // If company is found
log.info("Found company with ID: {}", companyId); // Log successful retrieval
return ResponseEntity.ok().body(company.get()); // Return company with OK status
} else { // If company is not found
log.warn("Company with ID {} not found", companyId); // Log warning for not found
return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); // Return NOT_FOUND status
}
}
// Endpoint to add a new company
@PostMapping
public ResponseEntity<Company> addCompany(@RequestBody Company company) {
log.info("Attempting to add company: {}", company); // Log the attempt
Company addedCompany = companyService.createCompany(company); // Create the company
log.info("Company added successfully: {}", addedCompany); // Log successful addition
return new ResponseEntity<>(addedCompany, HttpStatus.CREATED); // Return the added company with CREATED status
}
// Endpoint to delete a company by its ID
@DeleteMapping("/{companyId}")
public ResponseEntity<Void> deleteCompany(@PathVariable Long companyId) {
System.out.println("Attempting to delete company with ID: " + companyId); // Log the attempt
companyService.deleteCompany(companyId); // Delete the company
System.out.println("Company with ID {} deleted successfully" + companyId); // Log successful deletion
return ResponseEntity.noContent().build(); // Return NO_CONTENT status
}
}
CompanyRepository.java:
package com.nighthawk.spring_portfolio.mvc.linkr;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
public interface CompanyRepository extends JpaRepository<Company, Long> {
// Repository interface for performing CRUD operations on the Company entity,
// including custom queries for specific data retrieval needs.
List<Company> findAll();
List<Company> findAllById(long i);
@Query(value = "SELECT coalesce(max(id), 0) FROM Company")
Long getMaxId();
List<Company> findCompanyByNameIgnoreCase(String name);
}
As seen in the three Java files that make up the Company database, we have control over comparing different rows to each other. However, going beyond the algorithm of the FRQ, we can compare rows based on any certain property and not just the sum of each row. This is very useful for administrative control, user database manipulation, and more.