Skip to content

Commit

Permalink
Lecture 14
Browse files Browse the repository at this point in the history
  • Loading branch information
mapio committed Nov 20, 2024
1 parent 0a1aedb commit 1e46d57
Show file tree
Hide file tree
Showing 9 changed files with 376 additions and 0 deletions.
57 changes: 57 additions & 0 deletions src/main/java/it/unimi/di/prog2/h14/IntGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
Copyright 2024 Massimo Santini
This file is part of "Programmazione 2 @ UniMI" teaching material.
This is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This material is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this file. If not, see <https://www.gnu.org/licenses/>.
*/

package it.unimi.di.prog2.h14;

import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;

/** Generator (in Liskov parlance) of the ints contained in a {@link List}. */
public class IntGenerator implements Iterator<Integer> {

/** The list elements. */
private final List<Integer> els;

/** The position of the next element to return (if {@code idx < els.size()}. */
private int idx;

/**
* Builds an iterator (partial constructor, used just in {@link IntSet}).
*
* @param els the list of elements, must not be, or contain, {@code null}.
*/
public IntGenerator(List<Integer> els) {
this.els = els;
this.idx = 0;
}

@Override
public boolean hasNext() {
return idx < els.size();
}

@Override
public Integer next() {
if (!hasNext()) throw new NoSuchElementException();
return els.get(idx++);
}
}
180 changes: 180 additions & 0 deletions src/main/java/it/unimi/di/prog2/h14/IntSet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
/*
Copyright 2024 Massimo Santini
This file is part of "Programmazione 2 @ UniMI" teaching material.
This is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This material is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this file. If not, see <https://www.gnu.org/licenses/>.
*/

package it.unimi.di.prog2.h14;

import it.unimi.di.prog2.h08.impl.EmptyException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;

/**
* {@code IntSet}s are mutable, unbounded sets of integers.
*
* <p>A typical IntSet is \( S = \{x_1, \ldots, x_n \} \).
*/
public class IntSet implements Iterable<Integer> {

/** The {@link List} containing this set elements. */
private final List<Integer> els;

/*
* AF: gli elementi dell'IntSet sono tutti e soli gli interi
* contenuti nella lista; detto altrimenti,
* S = { els.get(i) per 0 <= i < els.size() }
*
* RI: els != null
* els non deve contenere null
* els non deve contenere duplicati, detto altrimenti
* se 0 <= i, j < els.size() e i != j allora els.get(i) != els.get(j)
*
*/

private boolean repOk() {
for (int i = 0; i < els.size(); i++)
for (int j = 0; j < els.size(); j++)
if (i != j && els.get(i).equals(els.get(j))) return false;
return true;
}

/**
* Initializes this set to be empty.
*
* <p>Builds the set \( S = \varnothing \).
*/
public IntSet() {
els = new ArrayList<>();
assert repOk();
}

/**
* A *copy constructor*.
*
* @param other the {@code IntSet} to copy from.
*/
public IntSet(IntSet other) {
els = new ArrayList<Integer>(other.els);
assert repOk();
}

// Methods

/**
* Looks for a given element in this set.
*
* @param x the element to look for.
* @return the index where {@code x} appears in {@code els} if the element belongs to this set, or
* -1
*/
private int getIndex(int x) {
return els.indexOf(x);
}

/**
* Adds the given element to this set.
*
* <p>This method modifies the object, that is: \( S' = S \cup \{ x \} \).
*
* @param x the element to be added.
*/
public void insert(int x) {
if (getIndex(x) < 0) els.add(x);
assert repOk();
}

/**
* Removes the given element from this set.
*
* <p>This method modifies the object, that is: \( S' = S \setminus \{ x \} \).
*
* @param x the element to be removed.
*/
public void remove(int x) {
int i = getIndex(x);
if (i < 0) return;
int last = els.size() - 1;
els.set(i, els.get(last));
els.remove(last);
assert repOk();
}

/**
* Tells if the given element is in this set.
*
* <p>Answers the question \( x\in S \).
*
* @param x the element to look for.
* @return whether the given element belongs to this set, or not.
*/
public boolean isIn(int x) {
return getIndex(x) != -1;
}

/**
* Returns the cardinality of this set.
*
* <p>Responds with \( |S| \).
*
* @return the size of this set.
*/
public int size() {
return els.size();
}

/**
* Returns an element from this set.
*
* @return an arbitrary element from this set.
* @throws EmptyException if this set is empty.
*/
public int choose() throws EmptyException {
if (els.isEmpty()) throw new EmptyException("Can't choose from an empty set");
return els.get(els.size() - 1);
}

@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof IntSet)) return false;
IntSet other = (IntSet) obj;
if (els.size() != other.els.size()) return false;
for (int e : els) if (!other.isIn(e)) return false;
return true;
}

@Override
public int hashCode() {
els.sort(null); // benevolent side effect
return Objects.hash(els.size(), els);
}

@Override
public String toString() {
String lst = els.toString();
return "IntSet: {" + lst.substring(1, lst.length() - 1) + "}";
}

@Override
public Iterator<Integer> iterator() {
return new IntGenerator(els);
}
}
47 changes: 47 additions & 0 deletions src/main/java/it/unimi/di/prog2/h14/IntSetsClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
Copyright 2024 Massimo Santini
This file is part of "Programmazione 2 @ UniMI" teaching material.
This is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This material is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this file. If not, see <https://www.gnu.org/licenses/>.
*/

package it.unimi.di.prog2.h14;

import java.util.Scanner;

/** Classe per il test di {@link IntSet} {@link IntGenerator}. */
public class IntSetsClient {
private IntSetsClient() {}

/**
* Legge una sequenza di interi dal flusso di ingresso ed emette la loro somma nel flusso
* d'uscita.
*
* @param args non usato.
*/
public static void main(String[] args) {
IntSet S = new IntSet();

try (Scanner s = new Scanner(System.in)) {
while (s.hasNextInt()) S.insert(s.nextInt());
}

int tot = 0;
for (int x : S) tot += x;
System.out.println(tot);
}
}
81 changes: 81 additions & 0 deletions src/main/java/it/unimi/di/prog2/h14/Primes.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
Copyright 2024 Massimo Santini
This file is part of "Programmazione 2 @ UniMI" teaching material.
This is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This material is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this file. If not, see <https://www.gnu.org/licenses/>.
*/

package it.unimi.di.prog2.h14;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/** Iteratore che genera i numeri primi. */
public class Primes implements Iterator<Integer> {

/*-
* AF: il prossimo numero primo è il primo intero maggiore o uguale a
* candidate che non sia divisibile per uno dei primi già restituiti da next,
* contenuti in foundPrimes.
*
* RI: - candidate è 2, oppure un numero dispari maggiore del più grande primo in
* foundPrimes
* - foundPrimes è vuoto, oppure contiene tutti i numeri primi miniori o uguali
* a candidate che sono stati restituiti da next.
*/

/** Il prossimo potenziale numero primo. */
private int candidate = 2;

/** L'elenco di primi restituiti da next. */
private final List<Integer> foundPrimes = new LinkedList<>();

@Override
public boolean hasNext() {
return true;
}

/**
* Verifica se {@code n} è divisibile per un dei primi in {@link #foundPrimes}.
*
* @param n il numero da verificare.
* @return {@code true} se {@code n} è divisibile per un dei primi già trovati.
*/
private boolean isDivisibleByAFoundPrime(int n) {
for (int p : foundPrimes) {
if (n % p == 0) return true;
if (p * p > n) return false;
}
return false;
}

@Override
public Integer next() {
if (candidate == 2) {
foundPrimes.add(candidate);
candidate = 3;
return 2;
} else
for (int n = candidate; ; n += 2)
if (!isDivisibleByAFoundPrime(n)) {
foundPrimes.add(n);
candidate = n + 2;
return n;
}
}
}
5 changes: 5 additions & 0 deletions src/main/java/it/unimi/di/prog2/h14/package-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/**
* Codice relativo alla lezione 14 per maggiori dettagli si veda il <a
* href="https://prog2.di.unimi.it/diario">diario del corso</a>.
*/
package it.unimi.di.prog2.h14;
1 change: 1 addition & 0 deletions tests/it/unimi/di/prog2/h14/IntSetsClient/expected-1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
10
1 change: 1 addition & 0 deletions tests/it/unimi/di/prog2/h14/IntSetsClient/expected-2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
4 changes: 4 additions & 0 deletions tests/it/unimi/di/prog2/h14/IntSetsClient/input-1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
1
2
3
4
Empty file.

0 comments on commit 1e46d57

Please sign in to comment.