Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Java-Nerdery-ChallengeV2/Luis-Moroco #6

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,8 @@ build/
.vscode/

### Mac OS ###
.DS_Store
.DS_Store

### Files

*.json
18 changes: 18 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,24 @@
<version>5.11.0-M2</version>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.6</version>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.6</version>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.6</version>
</dependency>

</dependencies>


Expand Down
51 changes: 49 additions & 2 deletions src/main/java/ChallengeStream.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
/* (C)2024 */
import java.util.Comparator;
import java.util.List;
import java.util.Map;

import mocks.CallCostObject;
import mocks.CallSummary;
import mocks.CardWinner;
import mocks.TotalSummary;

Expand All @@ -21,7 +25,25 @@ public class ChallengeStream {
*/
public CardWinner calculateWinningHand(List<Integer> player1, List<Integer> player2) {
// YOUR CODE HERE...
return new CardWinner();
final int WINNER_HAND_LENGTH = 2;
if (player1.size() < WINNER_HAND_LENGTH || player2.size() < WINNER_HAND_LENGTH) {
return new CardWinner();
}

int player1Hand = this.getHighestHandNumber(player1);
int player2Hand = this.getHighestHandNumber(player2);

return new CardWinner(
player1Hand > player2Hand ? "P1" : player2Hand > player1Hand ? "P2" : "TIE",
Math.max(player1Hand, player2Hand)
);
}

private int getHighestHandNumber(List<Integer> cards) {
return cards.stream()
.sorted(Comparator.reverseOrder())
.limit(2)
.reduce(0, (a, b) -> a * 10 + b);
}

/**
Expand All @@ -44,6 +66,31 @@ public CardWinner calculateWinningHand(List<Integer> player1, List<Integer> play
*/
public TotalSummary calculateCost(List<CallCostObject> costObjectList) {
// YOUR CODE HERE...
return new TotalSummary();
// List stores [baseMinutes, baseMinutePrice, extraMinutePrice] respectively
Map<String, List<Double>> basePrices = Map.of(
"International", List.of(3.0, 7.56, 3.03),
"National", List.of(3.0, 1.20, 0.48),
"Local", List.of(0.0, 0.0, 0.2)
);

List<String> callTypes = List.of("International", "National", "Local");
List<CallSummary> summaries = costObjectList.stream()
.filter(call -> callTypes.contains(call.getType()))
.map(call -> {
List<Double> config = basePrices.get(call.getType());
double price = call.getDuration() <= config.get(0)
? call.getDuration() * config.get(1)
: config.get(1) * config.get(0)
+ (call.getDuration() - config.get(0)) * config.get(2);

return new CallSummary(call, price);
})
.toList();

double totalCost = summaries.stream()
.mapToDouble(CallSummary::getTotalCost)
.sum();

return new TotalSummary(summaries, summaries.size(), totalCost);
}
}
123 changes: 117 additions & 6 deletions src/main/java/Challenges.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/* (C)2024 */
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

Expand All @@ -21,7 +23,27 @@ public class Challenges {

public String readableTime(Integer seconds) {
// YOUR CODE HERE...
return "";
// Given that Integer in signed, we must verify if that is positive
if (seconds < 0) {
return "";
}

final int SECOND = 1;
final int MINUTE = 60 * SECOND;
final int HOUR = 60 * MINUTE;

List<String> formattedTime = new ArrayList<>(3);
for (int unit : List.of(HOUR, MINUTE, SECOND)) {
String value = String.format("%0" + 2 + "d", seconds / unit);
formattedTime.add(value);

seconds = seconds % unit;

// The integer division is used to obtain the value in each unit and the
// modulus is used to obtain the remainders after each iteration.
}

return String.join(":", formattedTime);
}
;

Expand All @@ -45,7 +67,31 @@ public String readableTime(Integer seconds) {
public String[] circularArray(int index) {
String[] COUNTRY_NAMES = {"Germany", "Norway", "Island", "Japan", "Israel"};
// YOUR CODE HERE...
return COUNTRY_NAMES;
// Given that Integer in signed, we must verify if that is positive
if (index < 0) {
return COUNTRY_NAMES;
}

// Use the module to avoid out-of-range indexes
if (index > COUNTRY_NAMES.length) {
index %= COUNTRY_NAMES.length;
}

String[] shiftedCountryNames = new String[COUNTRY_NAMES.length];
for (int idx = 0; idx < COUNTRY_NAMES.length; ++idx) {
shiftedCountryNames[idx] = COUNTRY_NAMES[(index + idx) % COUNTRY_NAMES.length];
}

/*
- - 'n' is COUNTRY_NAMES' length
Given an array A of n items where [0][1][2]...[n-1], and other one B of same size
We use the modulus for copy them as follows:
- Given i, where i in [0, 1, 2, ... n - 1]
- We use it for populate B:
- for instance: B[i] = A[(i + index) % n] // in order to iterate over all array indexes
*/

return shiftedCountryNames;
}
;

Expand All @@ -71,7 +117,25 @@ public String[] circularArray(int index) {

public String ownPower(int number, int lastDigits) {
// YOUR CODE HERE...
return "";
BigInteger sum = BigInteger.ZERO;
for (int i = 1; i <= number; ++i) {
// We get i^i
BigInteger ownPower = BigInteger.ONE;
for (int j = 1; j <= i; ++j) {
ownPower = ownPower.multiply(BigInteger.valueOf(i));
}
Comment on lines +124 to +126
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use pow (or modPow if using modulo-based solution)


// We add it to the accumulator
sum = sum.add(ownPower);
}

String sumDigits = sum.toString();
// Verify if is greater than lastDigits in order to get a substring
if (sumDigits.length() >= lastDigits) {
return sumDigits.substring(sumDigits.length() - lastDigits);
}

return sumDigits;
}
;

Expand All @@ -94,7 +158,21 @@ A factorial (x!) means x! * (x - 1)... * 3 * 2 * 1.

public Integer digitSum(int n) {
// YOUR CODE HERE...
return 1;
// Declare a accumulator variable
BigInteger factorial = BigInteger.ONE;
for (int number = 1; number <= n; ++number) {
// perform factorial
factorial = factorial.multiply(BigInteger.valueOf(number));
}

int sum = 0;
String factorialDigits = factorial.toString();
// Parse chars to Integers and sum them
for (int index = 0; index < factorialDigits.length(); ++index) {
sum += Character.getNumericValue(factorialDigits.charAt(index));
}

return sum;
}

/**
Expand All @@ -108,7 +186,25 @@ public Integer digitSum(int n) {
*/
public String decrypt(List<Integer> ascivalues) {
// YOUR CODE HERE...
return "";
// If the list is empty, return an empty string
if (ascivalues.size() == 0) {
return "";
}

// Create a local list in order to avoid modifications (references)
List<Integer> cypheredText = new ArrayList<>(ascivalues);

StringBuilder plainText = new StringBuilder();
// Because the first value is always the same, the following is added directly
plainText.append((char) cypheredText.get(0).intValue());
for (int index = 1; index < cypheredText.size(); ++index) {
// Set the cypheredText[index] for accumulate values
cypheredText.set(index, cypheredText.get(index) + cypheredText.get(index - 1));
// Cast the values and add them to out string builder
plainText.append((char) cypheredText.get(index).intValue());
}

return plainText.toString();
}

/**
Expand All @@ -122,6 +218,21 @@ public String decrypt(List<Integer> ascivalues) {
*/
public List<Integer> encrypt(String text) {
// YOUR CODE HERE...
return Collections.emptyList();
// If the text is empty, return an empty list
if (text.length() == 0) {
return Collections.emptyList();
}

// Declare a list for store the cyphered text
List<Integer> cypheredText = new ArrayList<>(text.length());

// Because the first value is always the same, the following is added directly
cypheredText.add((int) text.charAt(0));
// Iterate over the text and store the differences of text[index] - text[index - 1]
for (int index = 1; index < text.length(); ++index) {
cypheredText.add(text.charAt(index) - text.charAt(index - 1));
}

return cypheredText;
}
}
38 changes: 38 additions & 0 deletions src/main/java/ExtraChallenges.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.ObjectMapper;
import meteorology.model.Weather;
import meteorology.MeteorologyReport;

import java.io.File;
import java.io.IOException;

public class ExtraChallenges {
final static String FILE_PATH = "weather.json";

public static void main(String[] args) {
var FILE = new File(FILE_PATH);
var factory = new JsonFactory();
var mapper = new ObjectMapper(factory);

var meteorologyReport = new MeteorologyReport();

try {
var parser = factory.createParser(FILE);
if (parser.nextToken() == JsonToken.START_ARRAY) {
while (parser.nextToken() != JsonToken.END_ARRAY) {
Comment on lines +22 to +23
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we parsing the list like this?

var weather = mapper.readValue(parser, Weather.class);
if (!weather.verifyFields()) {
continue;
}

meteorologyReport.process(weather);
}
}

meteorologyReport.show();
} catch (IOException | IllegalAccessException | NoSuchFieldException e) {
throw new RuntimeException(e);
}
}
}
38 changes: 38 additions & 0 deletions src/main/java/meteorology/MeteorologyReport.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package meteorology;

import meteorology.model.Report;
import meteorology.model.Weather;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

public class MeteorologyReport {
protected Map<String, Report> dailyReports = new HashMap<>();
protected Report overview = new Report();

public void process(Weather weather) throws NoSuchFieldException, IllegalAccessException {
this.overview.process(weather);

var report = this.dailyReports.get(weather.getDate());
if (Objects.isNull(report)) {
report = new Report();
report.process(weather);

this.dailyReports.put(weather.getDate(), report);
return;
}

report.process(weather);
}

public void show() {
for (var report : this.dailyReports.entrySet()) {
System.out.println(report.getKey());
report.getValue().show();
}

System.out.println("OVERVIEW");
this.overview.show();
}
}
9 changes: 9 additions & 0 deletions src/main/java/meteorology/model/Location.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package meteorology.model;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Location {
public Double lon;
public Double lat;
}
Loading