boolean isPrime(int n) {
if (n < 2) {
return false;
}
for (int i = 2; i < n; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
Per esempio, 6 è perfetto (6 = 1 + 2 + 3).
boolean isPerfect(int a) {
int res = 0;
for (int i = 1; i < a; i++) {
if (a % i == 0) {
res += i;
}
}
return (res == a);
}
boolean goldbach(int n) {
int j;
boolean ok;
for (int i = 4; i <= n; i += 2) {
ok = false;
j = 2;
while (!ok && j <= (i/2)) {
if (isPrime(j) && isPrime(i - j)) {
ok = true;
}
j++ ;
}
if (!ok) {
return false;
}
}
return true;
}
boolean checkDouble(int[] is) {
for (int i = 0; i < is.length - 1; i++) {
if (is[i] == is[i + 1]) {
return true;
}
}
return false;
}
boolean checkSequence(int[] is, int n) {
int repetition = 1;
for (int i = 0; i < is.length - 1; i++) {
if (is[i] == is[i + 1]) {
repetition++ ;
if (repetition == n) {
return true;
}
}else{
repetition = 1;
}
}
return false;
}
boolean equals(int[] is1, int[] is2) {
if (is1.length != is2.length) {
return false;
}
for (int i = 0; i < is2.length; i++) {
if (is1[i] != is2[i]) {
return false;
}
}
return true;
}
boolean equals2(int[][] is1, int[][] is2) {
if (is1.length != is2.length) {
return false;
}
for (int i = 0; i < is2.length; i++) {
if (is1[i].length != is2[i].length) {
return false;
}
for (int j = 0; j < is2[i].length; j++) {
if (is1[i][j] != is2[i][j]) {
return false;
}
}
}
return true;
}
static int[] firstPrime(int n) {
int[] res = new int[n];
int j = 2;
for(int i = 0; i < n; i++) {
while (! isPrime(j)) {
j++;
}
res[i] = j;
j++;
}
return res;
}
o meglio usando i numeri primi già calculati:
int[] firstPrime(int n) {
int number = 2;
boolean isPrimeNumber;
int[] res = new int[n];
for (int i = 0; i < n; i++) {
while (true) {
isPrimeNumber = true;
for (int j = 0; j < i && res[j] <= ((int) Math.sqrt(n)); j++) {
if (number % res[j] == 0) {
isPrimeNumber = false;
break;
}
}
if (isPrimeNumber) {
break;
}
number++ ;
}
res[i] = number;
number++ ;
}
return res;
}
o ancora meglio usando due metodi
boolean divisorInArray(int number, int[] is, int maxIndex) {
int maxValue = (int) Math.sqrt(number);
for (int i = 0; i < maxIndex && is[i] <= maxValue; i++) {
if (number % is[i] == 0) {
return true;
}
}
return false;
}
int[] firstPrime(int n) {
int number = 2;
int[] res = new int[n];
for (int i = 0; i < n; i++) {
while (divisorInArray(number, res, i)) {
number++ ;
}
res[i] = number;
number++ ;
}
return res;
}
static int[] lessPrime(int n) {
int[] primes = new int[n];
int j = 0;;
for(int i = 0; i < n; i++) {
if (isPrime(i)) {
primes[j] = i;
j++;
}
}
int[] res = new int[j];
for (int i = 0; i < j; i++) {
res[i] = primes[i];
}
return res;
}
boolean checkSym(int[][] a) {
try {
for(int i = 0; i< a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
if (a[i][j] != a[j][i]) {
return false;
}
}
}
}
catch (IndexOutOfBoundsException e) {
return false;
}
return true;
}
static boolean magicSquare(int[][] a) {
int sum = 0, sum1 = 0, sum2 = 0;
for(int i = 0; i < a.length;i++) {
sum1 += a[i][i];
sum2 += a[i][a.length - i - 1];
}
if (sum1 != sum2) {
return false;
}
sum = sum1;
for(int i = 0; i < a.length; i++) {
sum1 = 0;
sum2 = 0;
for (int j = 0; j < a[i].length; j++) {
sum1 += a[i][j];
sum2 += a[j][i];
}
if (sum != sum1 || sum != sum2) {
return false;
}
}
return true;
}
public static boolean triangle(int[][] a) {
for (int i = 0; i < a.length; i++) {
if (a[i].length != (i + 1)) {
return false;
}
}
return true;
}
static boolean isBordered(int[][] a) {
for(int min = 0, max= a.length - 1; min < max; min++, max--) {
int val = a[min][min];
for(int i = min ; i <= max; i++) {
if ((a[min][i] != val) ||
(a[max][i] != val) ||
(a[i][min] != val) ||
(a[i][max] != val)) {
return false;
}
}
}
return true;
}
static boolean divides(int[] a, int[] b) {
boolean oneDiv;
for(int i = 0; i < b.length; i++) {
oneDiv = false;
for(int j = 0; j < a.length; j++) {
if ((b[i] % a[j]) == 0) {
if (oneDiv) {
return false;
}
oneDiv = true;
}
}
if (!oneDiv) {
return false;
}
}
return true;
}
class Point {
int x;
int y;
Point (int x1, int y1) {
x = x1;
y = y1;
}
}
class Line {
Point pt1, pt2;
Line (Point p, Point q) {
pt1 = p;
pt2 = q;
}
}
class Line {
...
int deltaX() {
return pt1.x - pt2.x;
}
int deltaY() {
return pt1.y - pt2.y;
}
boolean parallel(Line l) {
return (deltaX()* l.deltaY()) == (deltaY()* l.deltaX());
}
...
}
class Point {
...
boolean equals(Point pt) {
return x == pt.x && y == pt.y;
}
...
}
class Line {
...
boolean in(Point pt) {
return ((pt1.x - pt.x)* (pt2.y - pt.y)) == ((pt2.x - pt.x)* (pt1.y - pt.y));
}
boolean equals(Line l) {
return l.in(pt1) && l.in(pt2);
}
...
}
class Prime {
static int[] primes = {2};
static boolean divisorInArray(int[] a, int n, int maxIndex) {
int maxValue = (int) Math.sqrt(n);
for(int j = 0; j < maxIndex & a[j] <= maxValue; j++) {
if (n % a[j] == 0) {
return true;
}
}
return false;
}
static void doubleSize() {
int[] res = new int[primes.length* 2];
for (int i = 0; i< primes.length; i++) {
res[i] = primes[i];
}
int number = primes[primes.length - 1] + 1;
for (int i = primes.length; i<res.length; i++) {
while (divisorInArray(res, number, i)) {
number++ ;
}
res[i] = number;
number++ ;
}
primes = res;
}
static boolean isPrime(int n) {
if (n == 1) {
return false;
}
int maxValue = (int) Math.sqrt(n);
while (primes[primes.length - 1] < maxValue) {
doubleSize();
}
return !divisorInArray(primes, n, primes.length);
}
}
class Matrix{
private int[][] val;
Matrix(int n, int m) {
val = new int[n][m];
}
int getHeight() {
return val.length;
}
int getWidth(){
return val[0].length;
}
int getVal(int i, int j) {
return val[i - 1][j - 1];
}
void setVal(int i, int j, int v) {
val[i - 1][j - 1] = v;
}
Matrix plus(Matrix b) {
Matrix res = new Matrix(getHeight(), getWidth());
for (int i = 1; i<= getHeight(); i++) {
for (int j = 1; j<= getWidth(); j++) {
res.setVal(i, j, getVal(i, j) + b.getVal(i, j));
}
}
return res;
}
Matrix mult(Matrix b) {
Matrix res = new Matrix(getHeight(), b.getWidth());
for (int i = 1; i<= getHeight(); i++) {
for (int j = 1; j<= b.getWidth(); j++) {
res.setVal(i, j, 0);
for (int k = 1; k<= getWidth(); k++) {
res.setVal(i, j, res.getVal(i, j) + getVal(i, k)* b.getVal(k, j));
}
}
}
return res;
}
}
abstract class Tree {
}
class Node extends Tree {
Tree right;
Tree left;
Node (Tree left, Tree right) {
this.left = left;
this.right = right;
}
}
class Leaf extends Tree {
String s;
Leaf (String s) {
this.s = s;
}
}
abstract class Tree {
...
abstract boolean in(String s);
...
}
class Node extends Tree {
...
boolean in(String s) {
return left.in(s) || right.in(s);
}
...
}
class Leaf extends Tree {
...
boolean in(String s) {
return this.s.equals(s);
}
...
}
abstract class Tree {
...
abstract String maxLength();
...
}
class Node extends Tree {
...
String maxLength() {
String s1 = left.maxLength();
String s2 = right.maxLength();
if (s1.length() <= s2.length())
return s2;
return s1;
}
...
}
class Leaf extends Tree {
...
String maxLength() {
return s;
}
...
}
abstract class Tree {
...
abstract String[] listOf();
...
}
class Node extends Tree {
...
String[] listOf() {
String[] l1 = left.listOf();
String[] l2 = right.listOf();
String[] l3 = new String[l1.length + l2.length];
for (int i = 0; i < l1.length; i++) {
l3[i] = l1[i];
}
for (int i = 0; i < l2.length; i++) {
l3[i + l1.length] = l2[i];
}
return l3;
}
...
}
class Leaf extends Tree {
...
String[] listOf() {
return new String[]{s};
}
...
}
o meglio per creare un unico array:
class Integer {
int i;
Integer(int i) {
this.i = i;
}
void incr() {
i++ ;
}
int getI() {
return i;
}
}
abstract class Tree {
...
abstract int getSize();
abstract void listOf(String[] s, Integer i);
String[] listOf() {
String[] res = new String[getSize()];
listOf(res, new Integer(0));
return res;
}
...
}
class Node extends Tree {
...
int getSize() {
return left.getSize() + right.getSize();
}
void listOf(String[] s, Integer i) {
left.listOf(s, i);
right.listOf(s, i);
}
...
}
class Leaf extends Tree {
...
int getSize() {
return 1;
}
void listOf(String[] s, Integer i) {
s[i.getI()] = this.s;
i.incr();
}
...
}
abstract class Tree {
...
abstract boolean equals(Object o);
...
}
class Node extends Tree {
...
boolean equals(Object o) {
if (!(o instanceof Node))
return false;
Node n = (Node)o;
return left.equals(n.left) && right.equals(n.right);
}
...
}
class Leaf extends Tree {
...
boolean equals(Object o) {
if (!(o instanceof Leaf))
return false;
return s.equals(((Leaf)o).s);
}
...
}
class Integer {
int i;
Integer(int i) {
this.i = i;
}
void incr() {
i++ ;
}
int getI() {
return i;
}
}
abstract class Tree {
abstract boolean in(String s);
abstract String maxLength();
abstract int getSize();
String[] listOf() {
String[] res = new String[getSize()];
listOf(res, new Integer(0));
return res;
}
abstract void listOf(String[] res, Integer i);
abstract boolean equals(Object o);
}
class Node extends Tree{
Tree[] sons;
Node(Tree[] sons) {
this.sons = sons;
}
boolean in(String s) {
for(int i = 0; i < sons.length; i++) {
if (sons[i].in(s)) {
return true;
}
}
return false;
}
String maxLength() {
String res = "";
String s;
for(int i = 0; i < sons.length; i++) {
s = sons[i].maxLength();
if (s.length() > res.length()) {
res = s;
}
}
return res;
}
int getSize() {
int res = 0;
for(int i = 0; i < sons.length; i++) {
res += sons[i].getSize();
}
return res;
}
void listOf(String[] res, Integer i) {
for(int j = 0; j < sons.length; j++) {
sons[j].listOf(res, i);
}
}
boolean equals(Object o) {
if (!(o instanceof Node))
return false;
Node n = (Node)o;
if (sons.length != o.sons.length) {
return false;
}
for(int i = 0; i < sons.length; i++) {
if (!(sons[i].equals(o.sons[i]))) {
return false;
}
}
return true;
}
}
class Leaf extends Tree {
String value;
Leaf(String value) {
this.value = value;
}
boolean in(String s) {
return value.equals(s);
}
String maxLength() {
return value;
}
int getSize() {
return 1;
}
void listOf(String[] res, Integer i) {
res[i.getI()] = value;
i.incr();
}
boolean equals(Object o) {
if (!(o instanceof Leaf)) {
return false;
}
return s.equals(((Leaf)o).s);
}
}
Aggiungere in List:
abstract class List {
abstract boolean in(int i);
abstract boolean sorted();
abstract boolean sorted(int i);
static List makeEmpty() {
return new Nil();
}
abstract List copy();
abstract List add(int i);
}
class Nil extends List{
Nil() {}
boolean in(int i) {
return false;
}
boolean sorted() {
return true;
}
boolean sorted(int i) {
return true;
}
List copy() {
return this;
}
List add(int i)
return new Cons(i, this);
}
}
class Cons extends List {
int hd;
List tl;
Cons(int hd, List tl) {
this.hd = hd;
this.tl = tl;
}
boolean in(int i) {
if (hd == i) {
return true;
}else{
return tl.in(i);
}
}
boolean sorted() {
return tl.sorted(hd);
}
boolean sorted(int i) {
if (i < hd) {
return tl.sorted(hd);
}else{
return false;
}
}
List copy() {
return new Cons(hd, tl.copy());
}
List add(int i) {
if (i < hd) {
return new Cons(i, copy());
}else if (i == hd) {
return copy();
}else {
return new Cons(hd, tl.add(i));
}
}
}
abstract class Path {
}
class Move extends Path {
int move;
Path path;
Move(int move, Path path) {
this.move = move;
this.path = path;
}
}
class Select extends Path {
Select() {
}
}
abstract class Tree {
...
abstract Path getPath(Tree tree);
abstract Tree getTree(Path path);
...
}
class Node extends Tree{
...
public Path getPath(Tree tree) {
if (equals(tree)) {
return new Select();
}
Path res;
for(int i = 0; i
D8*
Definire una classa astratta Multi
e due sottoclassi Single e Empty per rappresentare dei multinsiemi sui numeri interi tale che
il multinsieme {1, 1, 3, 3, 3} può essere creato tramite l'espressione new Single(1, 2, new Single(3, 3, new Empty())).
Aggiungere in Multi:
- un metodo getMulti che prende un numero intero e restituisce
il numero di volte che tale numero compare nella lista
(0 se non compare);
- un metodo add che aggiunge un numero intero ad un multinsieme;
- un metodo makeEmpty che crea un multinsieme vuoto;
- un metodo in che prende un multinsieme e restituisce
un booleano tale che a1.in(a2) è vero se a1 è incluso
in a2;
- un metodo equals che prende un oggetto e restituisce
un booleano tale che a1.equals(a2) è vero se a2 è un
oggetto di tipo Multi e contiene gli stessi numeri di a1
con la stessa molteplicità.
abstract class Multi {
abstract int getMulti(int i);
abstract Multi add(int i);
static Multi makeEmpty() {
return new Empty();
}
abstract boolean in(Multi a);
public boolean equals(Object a) {
if (a instanceof Multi) {
Multi a1 = (Multi)a;
return in(a1) && a1.in(this);
}
return false;
}
}
class Empty extends Multi{
Empty() {};
int getMulti(int i) {
return 0;
}
Multi add(int i) {
return new Single(i, 1, this);
}
boolean in(Multi a) {
return true;
}
}
class Single extends Multi{
int num;
int multi;
Multi rest;
Single(int num, int multi, Multi rest) {
this.num = num;
this.multi = multi;
this.rest = rest;
}
int getMulti(int i) {
if (i == num) {
return multi + rest.getMulti(i);
}else{
return rest.getMulti(i);
}
}
Multi add(int i) {
if (i == num) {
return new Single(num, multi + 1, rest);
}else{
return new Single(num, multi, rest.add(i));
}
}
boolean in(Multi i) {
if (getMulti(num) <= i.getMulti(num)) {
return rest.in(i);
}
return false;
}
}
D9*
Definire una classa astratta Exp
e tre sottoclassi Int, Plus e Mult per
rappresentare le espressioni arimetiche tale
che l'espressione (1 + 2)* 3 possa essere rappresentata come
Exp a = new Mult(new Plus(new Int(1), new Int(2)), new Int(3))}.
Quindi aggiungere nella classe Exp:
-
un metodo pubblico val che calcola il valore che rappresenta l'espressione. Per esempio a.val() ritorna l'intero 9;
-
un metodo pubblico equals che permette di verificare
l'uguaglianza. Tale metodo prende un oggetto di qualunque tipo.
Per esempio a.equals("abc") ritorna il booleano false;
-
un metodo pubblico in che permette di verificare se un'espressione
compare in un'altra.
Per esempio a.in(new Plus(new Int(1), new Int(2)))
abstract class Exp {
abstract public int val();
abstract public boolean equals(Object o);
public boolean in(Exp e) {
return equals(e);
}
}
class Int extends Exp {
int i;
Int(int i) {
this.i = i;
}
public int val() {
return i;
}
public boolean equals(Object o) {
if (o instanceof Int) {
return i == ((Int)o).i;
}
return false;
}
}
class Plus extends Exp {
Exp left, right;
Plus(Exp left, Exp right) {
this.left = left;
this.right = right;
}
public int val() {
return left.val() + right.val();
}
public boolean equals(Object o) {
if (o instanceof Plus) {
Plus e1 = (Plus)o;
return left.equals(e1.left) && right.equals(e1.right);
}
return false;
}
public boolean in(Exp e) {
if (left.in(e)) {
return true;
}
if (right.in(e)) {
return true;
}
return super.in(e);
}
}
class Mult extends Exp {
Exp left, right;
Mult(Exp left, Exp right) {
this.left = left;
this.right = right;
}
public int val() {
return left.val()* right.val();
}
public boolean equals(Object o) {
if (o instanceof Mult) {
Mult e1 = (Mult)o;
return left.equals(e1.left) && right.equals(e1.right);
}
return false;
}
public boolean in(Exp e) {
if (left.in(e)) {
return true;
}
if (right.in(e)) {
return true;
}
return super.in(e);
}
}
Visibilità
E1
Riscrivere Tree, Node, Leaf nel package util in modo tale che solo la class Tree sia visibile.
package util;
public abstract class Tree {
public static makeTree(String s) {
return new Leaf(s);
}
public append(Tree t) {
return new Node(this, t);
}
public abstract String maxLength();
public abstract boolean in(String s);
abstract void listOf(String[] s, Integer i);
public String[] listOf() {
...
}
}
class Node extends Tree {
...
public String maxLength() {
...
}
public boolean in(String s) {
...
}
void listOf(String[] s, Integer i) {
...
}
}
class Leaf extends Tree {
...
public String maxLength() {
...
}
public boolean in(String s) {
...
}
void listOf(String[] s, Integer i) {
...
}
}
E2*
Riscrivere List, Cons, Nil D6 in tale mode che appartengo al package util
e che di fuori del package
si possono creare solamente liste ordinate, i.e. liste costruite usando solamente
i metodi makeEmpty e add.
package util;
public abstract class List {
public abstract boolean in(int i);
public abstract boolean sorted();
abstract boolean sorted(int i);
public static List makeEmpty() {
return new Nil();
}
abstract List copy();
public abstract List add(int i);
}
class Nil extends List{
Nil() {}
public boolean in(int i) {
...
}
public boolean sorted() {
...
}
boolean sorted(int i) {
...
}
List copy() {
...
}
public List add(int i){
...
}
}
class Cons extends List {
int hd;
List tl;
Cons(int hd, List tl) {
...
}
public boolean in(int i) {
...
}
public boolean sorted() {
...
}
boolean sorted(int i) {
...
}
List copy() {
...
}
public List add(int i)
...
}
}
Eccezioni
F1*
Riscrivere il metodo in dall'esercizio
D6 in tale mode che
se il numero aggiunto è già nella lista, il metodo solleva l'eccezione
ListException.
class ListException extends Exception {
ListException() {
super();
}
}
public abstract class List {
...
public abstract List add(int i) throws ListException;
}
class Nil extends List{
...
public List add(int i) throws ListException{
return new Cons(i, this);
}
}
class Cons extends List {
...
public List add(int i) throws ListException{
if (i < hd) {
return new Cons(i, copy());
}else if (i == hd) {
throw new ListException();
}else {
return new Cons(hd, tl.add(i));
}
}
}
F2*
Riscrivere i metodi getPath e getTree dall'esercizio
D7 in tale mode che l'eccezione
NotFoundException è sollevata se è richiesto un camino di
un sotto - albero che non appartienne all'albero e se è chiesto
un sotto - albero con un camino invalido.
abstract class Tree {
abstract Path getPath(Tree tree) throws NotFoundException;
abstract Tree getTree(Path path) throws NotFoundException;
}
class Node extends Tree{
...
public Path getPath(Tree tree) throws NotFoundException {
if (equals(tree)) {
return new Select();
}
Path res;
for(int i = 0; i
F3*
Riscrivere i metodi dall'esercizion C4
in tale modo che ogni problema con la dimensione delle matrice vienne
riportato con l'eccezione IllegalDimension}.
class Matrix{
...
Matrix(int n, int m) throws IllegalDimension {
if (n <= 0 || m <= 0) {
throw new IllegalDimension();
}
val = new int[n][m];
}
...
int getVal(int i, int j) throws IllegalDimension {
if (1 > i || i > getHeight() || 1 > j || j > getWidth())
throw new IllegalDimension();
return val[i - 1][j - 1];
}
void setVal(int i, int j, int v) throws IllegalDimension {
if (1 > i || i > getHeight() || 1 > j || j > getWidth())
throw new IllegalDimension();
val[i - 1][j - 1] = v;
}
Matrix plus(Matrix b) throws IllegalDimension {
if (getWidth() != b.getWidth() || getHeight() != b.getHeight())
throw new IllegalDimension();
Matrix res = new Matrix(getHeight(), getWidth());
for (int i = 1; i<= getHeight(); i++) {
for (int j = 1; j<= getWidth(); j++) {
res.setVal(i, j, getVal(i, j) + b.getVal(i, j));
}
}
return res;
}
Matrix mult(Matrix b) throws IllegalDimension {
if (getWidth() != b.getHeight())
throw new IllegalDimension();
Matrix res = new Matrix(getHeight(), b.getWidth());
for (int i = 1; i<= getHeight(); i++) {
for (int j = 1; j<= b.getWidth(); j++) {
res.setVal(i, j, 0);
for (int k = 1; k<= getWidth(); k++) {
res.setVal(i, j, res.getVal(i, j) + getVal(i, k)* b.getVal(k, j));
}
}
}
return res;
}
}
Esterel
G1*
Scrivere un programma che gestisce l'apertura di una porta
controllata da un lettore di carta con codice.
Inizialmente il programma aspetta che sia inserita una carta
(INSERT_CARD).
Dopo l'inserzione, il codice della carta è digitato
cifra dopo cifra (DIGIT) da sinistra a destra.
Il codice è validato premendo il pulsante ENTER.
Una volta validato il codice, il programma
richiede la verifica del codice (CHECK_CODE) ad un programma
esterno.
Il segnale
CHECK_CODE ha per valore un numero intero uguale al codice
che è stato digitato cifra dopo cifra.
Quando il
codice è stato verificato (VALID_CODE), il programma apre
la porta (OPEN_DOOR), restituisce la carta
(RETURN_CARD) e aspetta di nuovo una carta.
In caso di errore quando si digita il codice, si può premere
il pulsante RESET e digitare di nuovo il codice da capo.
Una volta inserita una carta, si può riottenerla (RETURN_CARD)
in ogni momento premendo il pulsante QUIT. Una volta restituita
la carta, il programma ne aspetta un'altra.
Quando dopo una richiesta di verifica del codice (CHECK_CODE),
la verifica è negativa (INVALID_CODE), si può riprovare a
digitare il codice.
Dopo tre tentativi falliti consecutivi di verifica del codice (INVALID_CODE), il programma conserva la carta (KEEP_CARD) e ne aspetta
un'altra.
Una carta non può rimanere dentro il lettore per piú di un minuto (60 SECOND).
Se ciò accade, il programma restituisce la carta e ne aspetta un'altra.
module CB:
input INSERT_CARD;
input VALID_CODE, INVALID_CODE;
input DIGIT: integer;
input ENTER, RESET, QUIT;
input SECOND;
relation INSERT_CARD # VALID_CODE # INVALID_CODE #
DIGIT # ENTER # RESET # QUIT # SECOND;
output CHECK_CODE: integer;
output KEEP_CARD, RETURN_CARD, OPEN_DOOR;
loop
await INSERT_CARD;
[
abort
trap EXIT in
loop
trap CHECK in
loop
var CODE : = 0 : integer in
abort
every DIGIT do CODE : = CODE* 10 + ?DIGIT end every
when ENTER do
emit CHECK_CODE(CODE);
exit CHECK
end abort
end var
each RESET
end trap
each INVALID_CODE
||
await VALID_CODE;
emit OPEN_DOOR;
emit RETURN_CARD;
exit EXIT
||
await QUIT;
emit RETURN_CARD;
exit EXIT
||
await 3 INVALID_CODE;
emit KEEP_CARD;
exit EXIT
end trap
when 60 SECOND do
emit KEEP_CARD
end abort
]
end loop
end module
G2*
Scrivere un programma che gestisce il telecomando di un
televisore. Il telecomando ha due modi:
- un modo televisione dove si sceglie un programma,
- un modo teletext dove si sceglie una pagina.
Ogni volta che è premuto il pulsante ON_OFF, il telecomando
emette un segnale TURN_ON_OFF per accendere o spengere
il televisore e si mette in modo televisione.
In modo televisione:
- Si può cambiare programma in ogni momento.
- Premendo una cifra (DIGIT) sola, il telecomando emette
il segnale CHANNEL che cambia il programma.
- Premendo il pulsante DOUBLE, il telecomando aspetta le
due prossime cifre (DIGIT) per emettere il segnale CHANNEL
corrispondente.
- Si può cambiare pagina in ogni momento.
- Premendo tre cifre (DIGIT) una dopo l'altra, il telecomando
emette il segnale TXT che seleziona la pagina.
Si passa da un modo all'altro premendo il pulsante TXT_ON_OFF.
module TC:
input TXT_ON_OFF, DOUBLE, ON_OFF;
input DIGIT: integer;
relation TXT_ON_OFF # DOUBLE # DIGIT # ON_OFF;
output CHANNEL: integer;
output TXT: integer;
output TURN_ON_OFF;
every ON_OFF do
emit TURN_ON_OFF;
loop
abort
loop
abort
every DIGIT do emit CHANNEL(?DIGIT) end every
when immediate DOUBLE;
abort
var CHANNEL : = 0 : integer in
await DIGIT;
CHANNEL: = ? DIGIT;
await DIGIT;
CHANNEL: = CHANNEL* 10 + ?DIGIT;
emit CHANNEL(CHANNEL)
end var
when DOUBLE
end
when TXT_ON_OFF;
abort
loop
var TXT : = 0 : integer in
await DIGIT;
TXT: = ? DIGIT;
await DIGIT;
TXT: = TXT* 10 + ?DIGIT;
await DIGIT;
TXT: = TXT* 10 + ?DIGIT;
emit TXT(TXT)
end var
end loop
when TXT_ON_OFF
end loop
end every
end module
G3*
Scrivere un programma che gestisce un orologio per un gioco
con 2 giocatori.
L'orologio mostra per ciascun giocatore il tempo che gli rimane
per finire la partita (i segnali DISPLAY1 e DISPLAY2).
Il tempo è indicato in millisecondi.
Per calcolare il tempo che passa, il programma riceve un segnale MS ogni millisecondo.
Quando un giocatore ha giocato la sua mossa, preme il suo pulsante
(BUTTON1 o BUTTON2): si ferma il suo tempo e parte
il tempo del suo avversario.
All'inizio della partita, ogni giocatore ha lo stesso tempo (INIT_TIME) ed i due tempi sono fermi.
La partita è finita (END) quando uno dei due tempi arriva a zero.
In ogni momento, si può ri - inizializzare l'orologio usando il pulsante
RESET.
module CP:
input BUTTON1, BUTTON2;
input RESET;
input MS;
relation RESET # BUTTON1 # BUTTON2 # MS;
output DISPLAY1:integer, DISPLAY2:integer;
output END;
constant INIT_TIME : integer;
var TIME1, TIME2:integer in
loop
trap EXIT in
[
TIME1 : = INIT_TIME;
emit DISPLAY1(TIME1);
every BUTTON2 do
abort
every MS do
TIME1 : = TIME1 - 1;
emit DISPLAY1(TIME1);
if (TIME1 = 0)
then exit EXIT
end if
end every
when BUTTON1
end every
||
TIME2 : = INIT_TIME;
emit DISPLAY2(TIME2);
every BUTTON1 do
abort
every MS do
TIME2 : = TIME2 - 1;
emit DISPLAY2(TIME2);
if (TIME2 = 0)
then exit EXIT
end if
end every
when BUTTON2
end every
]
end trap;
emit END
each RESET
end var
end module
G4*
Scrivere un programma che gestisce una macchina per fare delle
foto - tessera.
All'inizio, la macchina
non è attiva, ciò viene indicato da una lampadina rossa (RED).
La macchina viene attivata quando un utente inserisce una moneta (INSERT_COIN).
Il fatto che la macchina sia attiva è indicato da una lampadina verde (GREEN).
Una volta inserita la moneta, l'utente deve scegliere il formato delle
foto (WHICH_FORMAT).
Quando l'utente ha scelto il formato (FORMAT), si può proseguire.
Se l'utente non sceglie entro 60 secondi (SECOND), la macchina
restituisce i soldi (RETURN_COIN) e diventa inattiva (RED).
Una sessione è composta di tre foto validate dall'utente.
Per fare una foto, la macchina aspetta 10 secondi, poi accende una
lampadina per avvertire l'utente di essere pronto (WARNING)
e dopo 2 secondi (SECOND) scatta la foto (CLICK). Dopo
3 secondi (SECOND),
mostra il risultato all'utente (SHOW). Se l'utente è d'accordo
(YES), la foto è validata, altrimenti la foto è rifiutata (NO).
Se l'utente non risponde entro 60 secondi (SECOND) o se l'utente
rifiuta più di 10 foto, la macchina restituisce i soldi
(RETURN_COIN) e diventa inattiva (RED).
Quando sono state validate tre foto, la macchina stampa le foto
(PRINT) e diventa inattiva.
module PHOTO:
input INSERT_COIN, YES, NO, SECOND;
input FORMAT: integer;
relation INSERT_COIN # YES # NO # FORMAT # SECOND;
output RED, GREEN, WARNING, WHICH_FORMAT,
SHOW, RETURN_COIN, PRINT, CLICK;
loop
emit RED;
await INSERT_COIN;
emit GREEN;
trap END in
emit WHICH_FORMAT;
abort
await 60 SECOND;
exit END;
when FORMAT;
trap SESSION in
signal OK, NOT_OK in
loop
await 10 SECOND;
emit WARNING;
await 2 SECOND;
emit CLICK;
await 3 SECOND;
abort
abort
await 60 SECOND;
exit END
when YES
do emit OK
end abort
when NO
do emit NOT_OK
end abort
end loop
||
await 3 OK;
exit SESSION
||
await 10 NOT_OK;
exit END
end signal;
end trap;
emit PRINT;
handle END do
emit RETURN_COIN;
end trap;
end loop
end module
G5*
Scrivere un programma che gestisce i semafori di un incrocio.
Ci sono quattro semafori (nord, est, sud, ovest) ma il controllo è fatto
considerando i semafori a coppia. Ci sono due coppie: la coppia nord - sud
(NS) e la coppia est - ovest (EW).
Un semaforo è alternativamente verde (GREEN_NS o GREEN_EW),
giallo (ORANGE_NS o ORANGE_EW) e rosso (RED_NS o RED_EW).
Quando una coppia di semafori è verde o gialla l'altra deve essere
necessariamente rossa.
In un ciclo normale, un semaforo resta verde 30 secondi (SECOND)
, giallo 2 secondi e rosso 32 secondi.
Un pedone può premere un pulsante (WALK_NS o WALK_EW).
Questo assicura che se il semaforo è verde non lo resterà per piú
di altri 10 secondi.
module TRAFFIC_LIGHT:
input SECOND, WALK_NS, WALK_EW;
relation SECOND # WALK_NS # WALK_EW;
output RED_NS, ORANGE_NS, GREEN_NS,
RED_EW, ORANGE_EW, GREEN_EW;
loop
emit RED_NS; emit GREEN_EW;
trap EXIT in
await 30 SECOND;
exit EXIT
||
await WALK_EW;
await 10 SECOND;
exit EXIT
end trap;
emit ORANGE_EW;
await 2 SECOND;
emit RED_EW; emit GREEN_NS;
trap EXIT in
await 30 SECOND;
exit EXIT
||
await WALK_NS;
await 10 SECOND;
exit EXIT
end trap;
emit ORANGE_NS;
await 2 SECOND;
end loop
end module
G6*
Scrivere un programma che gestisce l'apertura di una porta
automatica di un parcheggio per auto.
Prima di gestire l'apertura della porta, il programma aspetta
di avere il codice segreto (INIT_CODE).
Inizialmente la porta è chiusa.
A intervalli regolari viene segnalata la presenza di una macchina davanti
la porta (DETECT).
La porta si apre (OPEN) se il conducente della macchina
introduce un codice (CODE) che corrisponde al codice
segreto.
La porta si chiude (CLOSE) se non sono piú individuate
macchine (DETECT) per un periodo di 5 secondi (SECOND).
Ogni volta che viene introdotto un codice errato,
si accende una lampadina (RETRY).
Se dopo 2 minuti che una macchina è stata individuata
la porta non è stata aperta, viene avvertito il centralino (ERROR).
module GATE_CONTROL:
input SECOND, DETECT, INIT_CODE: integer, CODE : integer;
relation SECOND # INIT_CODE # CODE # DETECT;
output OPEN, CLOSE, RETRY, ERROR;
await INIT_CODE;
loop
trap CHECK_CODE in
loop
await DETECT;
await 120 SECOND;
emit ERROR;
end loop
||
every CODE do
if ?CODE = ?INIT_CODE then
exit CHECK_CODE;
end if;
emit RETRY
end every
end trap;
emit OPEN;
trap TIMEOUT in
loop
await 5 SECOND;
exit TIMEOUT
each DETECT;
end trap;
emit CLOSE;
end
Laurent Théry
Last modified: Fri Jan 23 00:06:25 MET 2004