Trilhas
/
Factor
Factor
/
Exercícios
/
Carros, à montagem!
Carros, à montagem!

Carros, à montagem!

Exercício de aprendizagem

Introdução

Este exercício apresenta as condicionais: escolher entre dois ou mais caminhos de ação com base em um valor. Ele se baseia no Boolean que você conheceu em Infiltração da Annalyn e na aritmética de números inteiros de Conversão de Moedas.

Palavras de comparação

Todas elas ficam em math (e em kernel para =):

=  ( 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? (em math) é uma forma abreviada do teste comum 0 =: ele consome o número e empilha se ele é zero ou não:

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

Verificações de intervalo

between? (em math.order) testa se um valor cai dentro de um intervalo inclusivo. É útil quando uma ação depende da faixa em que um número cai:

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)

É comum vê-lo como um predicado de cond (dup 1 4 between?) para escolher um bloco por intervalo em vez de por um único valor.

Quotations

As palavras de comparação acima produzem Boolean; para agir sobre um Boolean, você entrega à condicional uma ou mais quotations. Uma quotation é um trecho de código envolvido por colchetes, [ ... ]. Escrevê-la empilha o código como um valor em vez de rodá-lo: uma palavra como if então decide qual quotation rodar.

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

Um exercício posterior cobre as quotations por completo; por enquanto, leia [ ... ] como "o código a executar para este bloco".

if, when, unless

if (em kernel) recebe um Boolean e duas quotations. Ele executa a primeira quotation quando o Boolean é verdadeiro e a segunda quando ele é falso:

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

when executa sua quotation apenas quando o Boolean é verdadeiro; unless, apenas quando ele é falso:

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

if*, when* e unless*

Três variantes de kernel tratam o Boolean como um valor que vale a pena manter quando ele é verdadeiro, o que é útil quando uma palavra retorna "a coisa, ou 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* é a forma de dois blocos. O bloco verdadeiro é chamado com o valor ainda na pilha; o bloco falso é chamado sem ele:

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

unless* é a expressão idiomática canônica de "valor ou padrão". Se o valor é verdadeiro, ele é deixado como está; se é f, o valor é descartado e a quotation roda para empilhar um substituto:

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

when* é a forma de um bloco de if*: ele executa sua quotation (com o valor ainda na pilha) apenas quando o valor é verdadeiro, e simplesmente descarta o valor quando ele é f. Recorra a ele para incorporar um resultado do tipo "a coisa, ou f" a um valor acumulado sem se preocupar em tratar o caso f:

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

cond

Quando você tem várias ações alternativas entre as quais escolher, cond (em combinators) é a escolha natural. Ele recebe um array de pares { predicate body } e executa o corpo do primeiro predicado que produz um valor verdadeiro:

USING: combinators ;

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

Alguns detalhes que vale a pena observar:

  • Os pares são testados em ordem. O primeiro que corresponde vence.
  • Uma entrada sem predicado (apenas uma única quotation) no final funciona como o padrão.
  • Cada predicado inspeciona a entrada, mas deve deixar a pilha de dados como a encontrou: dup ... <test> é a expressão idiomática usual.
  • O corpo do par escolhido recebe a mesma pilha que o predicado viu, então geralmente começa dando drop na entrada e empilhando o resultado.

Instruções

Neste exercício você vai escrever código para analisar a produção de uma linha de montagem em uma fábrica de carros. A velocidade da linha de montagem pode variar de 0 (desligada) a 10 (máxima).

Na sua velocidade mais baixa diferente de zero (1), são produzidos 221 carros por hora. A produção aumenta linearmente com a velocidade, então na velocidade 4 a linha produz 4 * 221 = 884 carros por hora. Porém, velocidades mais altas aumentam a chance de que carros com defeito sejam produzidos, e esses carros depois precisam ser descartados.

Você tem quatro tarefas. Cada uma recebe da pilha um único parâmetro inteiro: a velocidade da linha de montagem.

1. Informe se a linha está funcionando

Defina production-status para retornar "stopped" quando a velocidade for 0 e "running" para qualquer outra velocidade:

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

2. Calcule a taxa de sucesso

Defina success-rate para retornar a probabilidade de um item ser produzido sem erro:

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

3. Calcule a taxa de produção por hora

Defina production-rate-per-hour para retornar a taxa de produção por hora da linha de montagem, levando a taxa de sucesso em conta.

Você vai precisar definir base-speed primeiro, a constante 221.

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

O valor retornado é um número de ponto flutuante.

4. Calcule o número de itens funcionais produzidos por minuto

Defina working-items-per-minute para retornar quantos carros funcionais são produzidos por minuto. O resultado é um número inteiro: carros parciais não são contados.

6 working-items-per-minute .
! => 19
Editar via GitHub O link abre em uma nova janela ou aba
Factor Exercism

Tudo pronto para começar Carros, à montagem!?

Crie sua conta no Exercism para aprender e dominar Factor com 47 conceitos163 exercícios e mentoria humana de verdade, tudo de graça.