Página 2 de 3

vetor: busca maior número

Enviado: 18 Jun 2021 14:18
por JoséQuintas
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.

vetor: busca maior número

Enviado: 18 Jun 2021 15:51
por cjp
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í).

vetor: busca maior número

Enviado: 18 Jun 2021 19:30
por JoséQuintas
result.png

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 ]
Precisa conferir, "parece" que seria isso.

vetor: busca maior número

Enviado: 18 Jun 2021 21:16
por cjp
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.
Fiz um teste assim:

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

A linha
cCart := If( e[ A_VENCIMENTO ] > nMax, e[ A_VENCIMENTO ], cCart )
eu acresci para tentar pegar o nome do cartão, mas deve estar errada, pois está retornando sempre NIL.

Pode me ajudar?

vetor: busca maior número

Enviado: 18 Jun 2021 23:34
por cjp
Testei o último exemplo do Quintas, mas os valores não está corretos.

Creio que o problema esteja nestas linhas:

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 ) } )
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?

vetor: busca maior número

Enviado: 19 Jun 2021 10:01
por JoséQuintas
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?
aSORT, como o próprio nome diz, é pra fazer um SORT, uma classificação pra deixar em ordem.
aSCAN, como o próprio nome diz, é pra fazer um SCAN, uma pesquisa

a,b, se é pra colocar em ordem, é a comparação de um com o outro, pra ver qual vém primeiro.
cjp escreveu:Testei o último exemplo do Quintas, mas os valores não está corretos.
Ao colocar em ordem com ASort(), já fica na melhor ordem dos cartões conforme o dia.
Para o ASCan() só resta pegar o primeiro que aparecer.
E se passou do dia 28, o melhor é o primeiro do mês seguinte, então, o último da lista.

Diga porquê, diga qual seria o retorno correto, pra poder fazer uma comparação?

vetor: busca maior número

Enviado: 19 Jun 2021 10:14
por cjp
Entendi.

Veja, considerando os dados atuais, que são:

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 } }
Notando que o primeiro número é o nvenc e o segundo é o nmelh.

Então, o resultado esperado seria:
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

vetor: busca maior número

Enviado: 19 Jun 2021 12:21
por JoséQuintas
cjp escreveu:Então, o resultado esperado seria:
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.

vetor: busca maior número

Enviado: 19 Jun 2021 14:39
por JoséQuintas
Realmente, até sua tabela está furada.

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 } }
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.

vetor: busca maior número

Enviado: 19 Jun 2021 15:25
por JoséQuintas

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
cjb.png
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.

vetor: busca maior número

Enviado: 19 Jun 2021 16:57
por alxsts
Olá!
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.
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.
É impossível fazer um programa funcionar sem saber exatamente o que ele deve fazer. É muita controvérsia, indefinição...

Postei meu exemplo logo após o início do tópico. Naquele momento a regra era o item 1 acima. Quando você testou meu exemplo, a regra já havia mudado para o item 7 acima. Com isto, meu exemplo não vai funcionar mesmo. Teoricamente, para ele funcionar, é só inverter o sinal na linha 71, que ficaria

Código: Selecionar todos

If e[A_MELHOR_DIA ] <= nDay.
Nem vou alterar meu exemplo agora. Provavelmente vão acontecer outras mudanças de regra...

Acho que todos os exemplos do Quintas também não estão aplicando a regra do item 7.
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
...
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...

vetor: busca maior número

Enviado: 19 Jun 2021 17:21
por JoséQuintas
alxsts escreveu:Acho que todos os exemplos do Quintas também não estão aplicando a regra do item 7.
Acho que sim, mas com uma grande diferença: criei uma quarta coluna, com o prazo em dias.
Desta forma eu uso o que demora mais, e não apenas o dia.

vetor: busca maior número

Enviado: 20 Jun 2021 00:14
por cjp
Vou responder uma mensagem de cada vez para tentar esclarecer.
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.
Não, vc está errado aqui. A tabela que eu postei acima está correta.
Se comprar no dia 2/6 com o cartão C, vai pgar em 12/7. Dia 2 é o melhor dia de compra do cartão C, que vence dia 12. A fatura fecha dia 1. Então, a compra no dia 2 vencerá em 12/7.

Nesta última tabela que eu fiz não tem cartão V; talvez estejamos falando do mesmo cartão C desta última tabela.

Reitero que esta tabela varia frequentemente. Então, a questão que importa aqui é o princípio, é a forma de tratar os dados, isso que preciso aprender, para fazer uma fórmula que funcione sempre.

Reitero, os dados são variáveis; tanto os cartões, quanto as datas de vencimento, e principalmente o melhor dia de compra variam sempre. Por isso fiz variáveis para cada dado. Sempre que mudar, eu alterarei as variáveis.

Mas, se a fórmula estiver correta, o sistema irá tomar cada dia o melhor cartão de compra considerando os dados atuais.

vetor: busca maior número

Enviado: 20 Jun 2021 00:24
por cjp
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 vc tem razão. Dia 1 e dias 23 a 27 eu errei na lista que fiz antes. Esta tua relação está correta.

Os cartões O e S interessam apenas como segunda opção.

vetor: busca maior número

Enviado: 20 Jun 2021 00:34
por cjp
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.
Realmente aqui funcionou, deu certo.
Só preciso entender o código, para fazê-lo funcionar sempre.
E o próximo passo é pegar também o segundo melhor e o terceiro melhor cartão em cada dia. Creio que neste código eu consiga pegar. Mas ainda não sei como fazer isso.