Διαδρομές
/
Factor
Factor
/
Ασκήσεις
/
Αυτοκίνητα, συναρμολογηθείτε!
Αυτοκίνητα, συναρμολογηθείτε!

Αυτοκίνητα, συναρμολογηθείτε!

Άσκηση εκμάθησης

Εισαγωγή

Αυτή η άσκηση εισάγει τις συνθήκες: την επιλογή ανάμεσα σε δύο ή περισσότερες εναλλακτικές ενέργειες με βάση μια τιμή. Χτίζει πάνω στις Boolean τιμές που γνώρισες στην Παρείσφρηση της Annalyn και στην αριθμητική ακεραίων από τη Μετατροπή νομίσματος.

Λέξεις σύγκρισης

Όλες βρίσκονται στο math (και στο kernel για το =):

=  ( x y -- ? )    ! equal
<  ( x y -- ? )    ! less than
<= ( x y -- ? )    ! less than or equal
>  ( x y -- ? )    ! greater than
>= ( x y -- ? )    ! greater than or equal
3 3 = .     ! => t
2 3 < .     ! => t
3 3 <= .    ! => t
3 4 = not . ! => t    (inequality: combine = with not)

Το zero? (στο math) είναι συντομογραφία για τον συνηθισμένο έλεγχο 0 =: καταναλώνει τον αριθμό και βάζει στη στοίβα αν ήταν μηδέν:

zero? ( n -- ? )    ! t when n is 0

Έλεγχοι εύρους

Το between? (στο math.order) ελέγχει αν μια τιμή πέφτει μέσα σε ένα κλειστό διάστημα. Είναι βολικό όταν μια ενέργεια εξαρτάται από το σε ποια ζώνη πέφτει ένας αριθμός:

between? ( x lo hi -- ? )    ! lo <= x <= hi (inclusive)
5 1 10 between? .    ! => t
0 1 10 between? .    ! => f
10 1 10 between? .   ! => t   (inclusive at both ends)

Συχνά θα το δεις ως κατηγόρημα του cond, όπως dup 1 4 between?, για να διαλέξεις κλάδο με βάση το εύρος και όχι μια μεμονωμένη τιμή.

Παραθέσεις

Οι παραπάνω λέξεις σύγκρισης παράγουν Boolean τιμές. Για να δράσεις πάνω σε μια Boolean τιμή, δίνεις στη συνθήκη μία ή περισσότερες παραθέσεις. Μια παράθεση είναι ένα κομμάτι κώδικα τυλιγμένο σε αγκύλες, [ ... ]. Όταν τη γράφεις, βάζεις τον κώδικα στη στοίβα ως τιμή αντί να τον εκτελέσεις. Στη συνέχεια, μια λέξη όπως η if αποφασίζει ποια παράθεση θα εκτελεστεί.

[ neg ]   ! a quotation that negates the top of the stack
[ ]       ! the empty quotation — does nothing

Μια επόμενη άσκηση καλύπτει τις παραθέσεις πλήρως. Για την ώρα, διάβασε το [ ... ] ως "τον κώδικα που θα εκτελεστεί για αυτόν τον κλάδο".

if, when, unless

Η if (στο kernel) παίρνει μια Boolean τιμή και δύο παραθέσεις. Εκτελεί την πρώτη παράθεση όταν η Boolean τιμή είναι αληθής και τη δεύτερη όταν είναι ψευδής:

if ( ? then-quot else-quot -- )
: abs ( x -- y ) dup 0 < [ neg ] [ ] if ;

Η when εκτελεί την παράθεσή της μόνο όταν η Boolean τιμή είναι αληθής· η unless μόνο όταν είναι ψευδής:

when   ( ? quot -- )
unless ( ? quot -- )

if*, when*, και unless*

Τρεις παραλλαγές του kernel αντιμετωπίζουν τη Boolean τιμή ως τιμή που αξίζει να κρατηθεί όταν είναι αληθής, κάτι χρήσιμο όταν μια λέξη επιστρέφει "το πράγμα, ή f":

if*     ( ? true false -- )    ! truthy: true is called WITH ? on stack
when*   ( ? true       -- )    ! truthy: true is called WITH ? on stack
unless* ( ? false      -- )    ! falsy: false runs and pushes a default

Η if* είναι η μορφή με δύο κλάδους. Ο κλάδος της αλήθειας καλείται με την τιμή ακόμα στη στοίβα· ο κλάδος του ψεύδους καλείται χωρίς αυτή:

42 [ ] [ "nothing" ] if* .   ! prints 42
f  [ ] [ "nothing" ] if* .   ! prints "nothing"

Η unless* είναι το κλασικό μοτίβο "τιμή ή προεπιλογή". Αν η τιμή είναι αληθής, μένει ως έχει· αν είναι f, η τιμή απορρίπτεται και η παράθεση εκτελείται για να βάλει ένα υποκατάστατο στη στοίβα:

"hello" [ "anonymous" ] unless* .   ! => "hello"
f       [ "anonymous" ] unless* .   ! => "anonymous"

Η when* είναι η μορφή της if* με έναν κλάδο: εκτελεί την παράθεσή της, με την τιμή ακόμα στη στοίβα, μόνο όταν η τιμή είναι αληθής, και απλώς απορρίπτει την τιμή όταν είναι f. Χρησιμοποίησέ την για να ενσωματώσεις ένα αποτέλεσμα τύπου "το πράγμα, ή f" σε μια τιμή που χτίζεται, χωρίς να μπεις στον κόπο να χειριστείς την περίπτωση του f:

0 41 [ + ] when* .   ! => 41   (truthy: 41 added to the running total)
0 f  [ + ] when* .   ! => 0    (falsy: f dropped, total left untouched)

cond

Όταν έχεις πολλές εναλλακτικές ενέργειες για να διαλέξεις, η cond (στο combinators) είναι η φυσική επιλογή. Παίρνει έναν πίνακα από ζεύγη { predicate body } και εκτελεί το σώμα του πρώτου κατηγορήματος που δίνει μια αληθή τιμή:

USING: combinators ;

: classify ( n -- label )
    {
        { [ dup 0 <  ] [ drop "negative" ] }
        { [ dup 0 =  ] [ drop "zero"     ] }
        [ drop "positive" ]
    } cond ;

Μερικές λεπτομέρειες που αξίζει να προσέξεις:

  • Τα ζεύγη δοκιμάζονται με τη σειρά. Κερδίζει το πρώτο που ταιριάζει.
  • Μια καταχώριση χωρίς κατηγόρημα (μόνο μία παράθεση) στο τέλος λειτουργεί ως προεπιλογή.
  • Κάθε κατηγόρημα εξετάζει την είσοδο αλλά πρέπει να αφήνει τη στοίβα δεδομένων όπως τη βρήκε· το συνηθισμένο μοτίβο είναι dup ... <test>.
  • Το σώμα του ζεύγους που επιλέχθηκε δέχεται την ίδια στοίβα που είδε το κατηγόρημα, οπότε συνήθως ξεκινά κάνοντας drop στην είσοδο και βάζοντας το αποτέλεσμα στη στοίβα.

Οδηγίες

Σε αυτή την άσκηση θα γράψεις κώδικα για να αναλύσεις την παραγωγή μιας γραμμής συναρμολόγησης σε ένα εργοστάσιο αυτοκινήτων. Η ταχύτητα της γραμμής συναρμολόγησης μπορεί να κυμαίνεται από 0 (εκτός λειτουργίας) έως 10 (μέγιστη).

Στη χαμηλότερη μη μηδενική ταχύτητά της (1), παράγονται 221 αυτοκίνητα κάθε ώρα. Η παραγωγή αυξάνεται γραμμικά με την ταχύτητα, οπότε σε ταχύτητα 4 η γραμμή παράγει 4 * 221 = 884 αυτοκίνητα ανά ώρα. Ωστόσο, οι υψηλότερες ταχύτητες αυξάνουν την πιθανότητα να παραχθούν ελαττωματικά αυτοκίνητα, τα οποία στη συνέχεια πρέπει να απορριφθούν.

Έχεις τέσσερις εργασίες. Κάθε μία παίρνει από τη στοίβα μία μόνο ακέραια παράμετρο, την ταχύτητα της γραμμής συναρμολόγησης.

1. Ανέφερε αν η γραμμή λειτουργεί

Όρισε τη συνάρτηση production-status ώστε να επιστρέφει "stopped" όταν η ταχύτητα είναι 0 και "running" για οποιαδήποτε άλλη ταχύτητα:

0 production-status .
! => "stopped"
3 production-status .
! => "running"

2. Υπολόγισε το ποσοστό επιτυχίας

Όρισε τη συνάρτηση success-rate ώστε να επιστρέφει την πιθανότητα ένα προϊόν να παραχθεί χωρίς σφάλμα:

  • 0: 0.0
  • 1 έως 4: 1.0
  • 5 έως 8: 0.9
  • 9: 0.8
  • 10: 0.77
10 success-rate .
! => 0.77

3. Υπολόγισε τον ρυθμό παραγωγής ανά ώρα

Όρισε τη συνάρτηση production-rate-per-hour ώστε να επιστρέφει τον ρυθμό παραγωγής της γραμμής συναρμολόγησης ανά ώρα, λαμβάνοντας υπόψη το ποσοστό επιτυχίας.

Θα χρειαστεί να ορίσεις πρώτα τη σταθερά base-speed με τιμή 221.

6 production-rate-per-hour .
! => 1193.4

Η τιμή που επιστρέφεται είναι κινητής υποδιαστολής.

4. Υπολόγισε τον αριθμό των λειτουργικών προϊόντων που παράγονται ανά λεπτό

Όρισε τη συνάρτηση working-items-per-minute ώστε να επιστρέφει πόσα λειτουργικά αυτοκίνητα παράγονται ανά λεπτό. Το αποτέλεσμα είναι ακέραιος αριθμός. Τα ημιτελή αυτοκίνητα δεν μετρώνται.

6 working-items-per-minute .
! => 19
Επεξεργασία μέσω GitHub Ο σύνδεσμος ανοίγει σε νέο παράθυρο ή καρτέλα
Factor Exercism

Έτοιμος να ξεκινήσεις την άσκηση Αυτοκίνητα, συναρμολογηθείτε!;

Γράψου στο Exercism για να μάθεις και να κατακτήσεις Factor με 47 έννοιες163 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.