vetor: busca maior número
Enviado: 18 Jun 2021 14:18
Mas se dia é 30, não tem nenhum dia maior que 30 pra servir de referência pra pesquisa.
A análise será outra então.
A análise será outra então.
Código: Selecionar todos
#define ITEM_NOME 1
#define ITEM_DATA 2
#define ITEM_DIA 3
PROCEDURE Main
LOCAL aItem, nDia, dHoje, dVencto
SET DATE BRITISH
SetMode(40,100)
CLS
Altd()
FOR nDia = 1 TO 30
dHoje := Stod( "202106" + StrZero( nDia, 2 ) )
aItem := CrtMelhor( dHoje )
dVencto := Stod( "2021" + iif( aItem[ ITEM_DATA ] >= nDia, "07", "08" ) + StrZero( aItem[ ITEM_DATA ], 2 ) )
? nDia, Pad( aItem[ ITEM_NOME ], 10 ), Str( aItem[ ITEM_DATA ], 3 ), Str( aItem[ ITEM_DIA ], 3 ), ;
dVencto, Str( dVencto - dHoje, 3 ) + " dias"
NEXT
Inkey(0)
RETURN
FUNCTION CrtMelhor( dData )
LOCAL nPos, aList := { ;
{ "O....", 5, 28 }, ;
{ "B....", 8, 24 }, ;
{ "I....", 1, 23 }, ;
{ "I...", 28, 18 }, ;
{ "N...", 18, 11 }, ;
{ "R...", 25, 11 }, ;
{ "C...", 20, 10 }, ;
{ "S...", 22, 10 }, ;
{ "V...", 12, 2 } }
ASort( aList,,,{ | a, b | a[ ITEM_DIA ] > b[ ITEM_DIA ] .OR. ( a[ ITEM_DIA ] == b[ ITEM_DIA ] .AND. a[ ITEM_DATA ] > b[ ITEM_DATA ] ) } )
nPos := AScan( aList, { | e | Day( dData ) >= e[ ITEM_DIA ] } )
IF nPos == 0
RETURN Atail( aList )
ENDIF
RETURN aList[ nPos ]
Código: Selecionar todos
function crtmelh
LOCAL aArray, e, nMax, cCart
local crtm, crt2m, crt3m, crt4m
local aList :={}
LOCAL nPos
local crt1 :="I..."
local nvenc1 :=1
local nmelh1 :=23
local crt2 :="O..."
local nvenc2 :=5
local nmelh2 :=28
local crt3 :="B..."
local nvenc3 :=8
local nmelh3 :=24
local crt4 :="V..."
local nvenc4 :=12
local nmelh4 :=2
local crt5 :="N..."
local nvenc5 :=18
local nmelh5 :=11
local crt6 :="C."
local nvenc6 :=20
local nmelh6 :=10
local crt7 :="S..."
local nvenc7 :=22
local nmelh7 :=10
local crt8 :="R..."
local nvenc8 :=25
local nmelh8 :=11
local crt9 :="I..."
local nvenc9 :=28
local nmelh9 :=18
* nDay= day(date())
cls
nDay=0
a=1
b=1
do while .t.
nDay++
// Posições em aArray
#define A_DESCRIÇAO 1
#define A_VENCIMENTO 2
#define A_MELHOR_DIA 3
aArray := { { crt1, nvenc1, nmelh1 }, ;
{ crt2, nvenc2, nmelh2 }, ;
{ crt3, nvenc3, nmelh3 }, ;
{ crt4, nvenc4, nmelh4 }, ;
{ crt5, nvenc5, nmelh5 }, ;
{ crt6, nvenc6, nmelh6 }, ;
{ crt7, nvenc7, nmelh7 }, ;
{ crt8, nvenc8, nmelh8 }, ;
{ crt9, nvenc9, nmelh9 } ;
}
nMax := 0
// Para cada elemento e no aArray...
For Each e In aArray
// Cada elemento também é um array...
// Se a terceira posição do elemento for maior ou igual ao dia em nDay...
If e[ A_MELHOR_DIA ] >= nDay
// Se a segunda posição do elemento for maior que o anterior,
// guarda o valor da segunda posição do elemento
nMax := If( e[ A_VENCIMENTO ] > nMax, e[ A_VENCIMENTO ], nMax )
cCart := If( e[ A_VENCIMENTO ] > nMax, e[ A_VENCIMENTO ], cCart )
Endif
Next
@ a,b say "Dia: "
@ a,b+5 say nDay
@ a+1,b say "nMax: "
@ a+1,b+5 say nMax
@ a+2,b say "Cartão: "
@ a+2,b+8 say cCart
a=a+4
if a>maxrow()-2
a=1
b=b+35
endif
if nDay>=31
inkey(11)
inkey(22)
exit
endif
enddo
eu acresci para tentar pegar o nome do cartão, mas deve estar errada, pois está retornando sempre NIL.cCart := If( e[ A_VENCIMENTO ] > nMax, e[ A_VENCIMENTO ], cCart )
Código: Selecionar todos
ASort( aList,,,{ | a, b | a[ ITEM_DATA ] > b[ ITEM_DATA ] .OR. ( a[ ITEM_DATA ] == b[ ITEM_DATA ] .AND. a[ ITEM_DIA ] > b[ ITEM_DIA ] ) } )
nPos := AScan( aList, { | e | e[ ITEM_DIA ] >= Day( dData ) } )aSORT, como o próprio nome diz, é pra fazer um SORT, uma classificação pra deixar em ordem.cjp escreveu:O problema é que eu não entendi bem este código, não saberia acertá-lo.
Primeira dúvida neste código: a procura é feita com o ASort ou com o AScan.
Segunda: o que seriam a, b e e neste código?
Ao colocar em ordem com ASort(), já fica na melhor ordem dos cartões conforme o dia.cjp escreveu:Testei o último exemplo do Quintas, mas os valores não está corretos.
Código: Selecionar todos
{ "I...", 1, 23 }, ;
{ "O....", 5, 28 }, ;
{ "A....", 8, 24 }, ;
{ "C...", 12, 2 }, ;
{ "N...", 18, 11 }, ;
{ "S...", 20, 10 }, ;
{ "X...", 22, 10 }, ;
{ "B...", 25, 11 }, ;
{ "T...", 28, 18 } }
DIA DO MÊS CARTÃO
1 O
2 C
3 C
4 C
5 C
6 C
7 C
8 C
9 C
10 X
11 B
12 B
13 B
14 B
15 B
16 B
17 B
18 T
19 T
20 T
21 T
22 T
23 I
24 I
25 I
26 I
27 I
28 O
29 O
30 O
31 O
Para o dia 2, Se comprar no cartão C, vai pagar dia 20/06cjp escreveu:Então, o resultado esperado seria:
Código: Selecionar todos
LOCAL nPos, aList := { ;
{ "I....", 1, 23 }, ;
{ "A....", 8, 24 }, ;
{ "O....", 5, 28 }, ;
{ "B...", 25, 11 }, ;
{ "X...", 22, 10 }, ;
{ "S...", 20, 10 }, ;
{ "N...", 18, 11 }, ;
{ "T...", 28, 18 }, ;
{ "C...", 12, 2 } }
Código: Selecionar todos
#define ITEM_NOME 1
#define ITEM_DATA 2
#define ITEM_DIA 3
PROCEDURE Main
LOCAL aItem, nDia, dHoje, dVencto
SET DATE BRITISH
SetMode(40,100)
CLS
Altd()
FOR nDia = 1 TO 30
dHoje := Stod( "202106" + StrZero( nDia, 2 ) )
aItem := CrtMelhor( dHoje )
dVencto := Stod( "2021" + iif( aItem[ ITEM_DATA ] <= nDia, "08", "07" ) + StrZero( aItem[ ITEM_DATA ], 2 ) )
? nDia, Pad( aItem[ ITEM_NOME ], 10 ), Str( aItem[ ITEM_DATA ], 3 ), Str( aItem[ ITEM_DIA ], 3 ), ;
dVencto, Str( dVencto - dHoje, 3 ) + " dias"
NEXT
Inkey(0)
RETURN
FUNCTION CrtMelhor( dData )
LOCAL aResult, aList := { ;
{ "I....", 1, 23, 31 }, ;
{ "A....", 8, 24, 38 }, ;
{ "O....", 5, 28, 35 }, ;
{ "B...", 25, 11, 25 }, ;
{ "X...", 22, 10, 22 }, ;
{ "S...", 20, 10, 20 }, ;
{ "N...", 18, 11, 18 }, ;
{ "T...", 28, 18, 28 }, ;
{ "C...", 12, 2, 12 } }
aResult := { "", 0, 0, 0 }
AEval( aList, { | e | iif( Day( dData ) >= e[ 3 ] .AND. e[ 4 ] > aResult[ 4 ], aResult := e, Nil ) } )
IF aResult[ 3 ] == 0
AEval( aList, { | e | iif( 31 >= e[ 3 ] .AND. e[ 4 ] > aResult[ 4 ], aResult := e, Nil ) } )
ENDIF
RETURN aResult
1 - Preciso encontrar um número entre 9 variáveis,
que atenda às seguintes especificações:
o número precisa ser o maior nvenc possível,
desde que o nmelh seja igual ou maior que o dia atual.
2 - Vou tentar ser mais claro:
cada crt (crt1, crt2, etc) é um cartão,
que tem uma data de vencimento (nvenc) e uma data de melhor dia de compra (nmelh).
3 - Então, preciso pegar em cada dia qual cartão tem a
data de vencimento mais distante (maior nvenc),
desde que esteja no seu melhor dia de compra ou posterior.
4 - E pode acontecer (e de fato acontece) de um cartão com
vencimento posterior ter melhor data de compra antes de
outro que tem vencimento anterior
(ex: o de vencimento dia 25 tem melhor data de compra dia 10;
o de vencimento dia 22 tem melhor data de compra dia 17).
Neste caso o segundo cartão (com vencimento dia 22) será
sempre segunda opção, jamais primeira.
É isso que complica a questão, e é pra isso que estou me batendo com vetor (que não entendo bem).
5 - Não vai ficar nenhum dia sem porque no dia 30, por exemplo,
usaremos o crt2, cuja melhor data é o dia 28.
6 - Mas se dia é 30, não tem nenhum dia maior que 30 pra servir de referência pra pesquisa.
A análise será outra então.
7 - Não sei se não me expressei bem, mas o que quis dizer é que o
nmelh tem que ser menor ou igual ao dia atual, não maior.
O nvenc é que tem que ser o maior possível.
Mas note que o dia 5 do mês seguinte é maior do que o dia 30 do mês atual.
Este é outro fator complicador para analisar (ainda não tinha chegado aí).
8 - Vou precisar pegar não apenas o primeiro, mas os 4 primeiros.
É impossível fazer um programa funcionar sem saber exatamente o que ele deve fazer. É muita controvérsia, indefinição...cjp escreveu:Testei o exemplo do alxsts, em princípio funcionou e retornou o dado correto para o dia de hoje.
Entretanto, testei para todos os dias, e, em vários dias, não está retornando o dado correto.
Além disso, não consegui pegar o nome do cartão.
Código: Selecionar todos
If e[A_MELHOR_DIA ] <= nDay.Outra coisa: creio que deva ser considerado o mês comercial, sem o dia 31. Pelo menos nunca vi cartão tendo o dia 31 como melhor dia de compra. O meu vence dia 20 e o melhor dia é 14...If e[ aResult := { "", 0, 0, 0 }
AEval( aList, { | e | iif( Day( dData ) >= e[ 3 ] .AND. e[ 4 ] > aResult[ 4 ], aResult := e, Nil ) } )
IF aResult[ 3 ] == 0
AEval( aList, { | e | iif( 31 >= e[ 3 ] .AND. e[ 4 ] > aResult[ 4 ], aResult := e, Nil ) } )
ENDIF
...
Acho que sim, mas com uma grande diferença: criei uma quarta coluna, com o prazo em dias.alxsts escreveu:Acho que todos os exemplos do Quintas também não estão aplicando a regra do item 7.
Não, vc está errado aqui. A tabela que eu postei acima está correta.Para o dia 2, Se comprar no cartão C, vai pagar dia 20/06
Mas se comprar no cartão V, vai pagar dia 12/07
Por enquanto todos estão errados, inclusive o que mostrou como sendo o correto.
Esquece....
Fez outra tabela diferente, aí não bate nada mesmo.
Realmente aqui vc tem razão. Dia 1 e dias 23 a 27 eu errei na lista que fiz antes. Esta tua relação está correta.Dia 1, o melhor cartão é o A, que vence dia 8, e não o O que vence dia 5. erro
Dia 2 é o C que vence dia 12, e vai assim até dia 9, ok
Dia 10 é o X que vence dia 22 ok
Dia 11 é o B que vence dia 25, e vai assim até dia 17 ok
Dia 18 é o T que vence dia 28 e vai assim até dia 22 ok
Dia 23 é o I que vende dia 1 ok
Dia 24 é o A que vence dia 8 e vai assim até o final. dias 23 a 27 erro
Não interessam os cartões: O e S
Por ASCan() vai precisar algo mais complexo, uma mistura das rotinas anteriores.
Realmente aqui funcionou, deu certo.Acho que deu.
Falta ajustar aonde calcula o mês.
Coloquei 7 e 8, mas precisa ser proporcional ao mês atual, incluindo aumentar ano se precisar.