Mais uma vez Cartman vem com ideias mirabolantes para tentar mudar suas notas no sistema da escola de South Park. A ideia agora é atacar o gerador de números pseudo-aleatórios do sistema mudou
, muito popular entre os professores desta pacata escola.
Claro que Cartman não sabe como fazer nada e –pediu– ordenou para que Butters fizesse o programa de computador que descobrisse a semente utilizada para a geração de números aleatórios.
Butters é muito jovem e um pouco esperto, e já descobriu algumas coisas interessantes.
O gerador de números pseudo-aleatórios do mudou
é feito na linguagem C
e usam a função pronta rand_r()
que, por sua vez, recebe como argumento um ponteiro para um número inteiro que é chamado de semente
.
A semente
é extremamente fundamental para a segurança do sistema, pois é a partir dela que a ordem dos números pseudo-aleatórios é definida, ou seja, para uma mesma semente a ordem de números gerados pela função rand_r()
será sempre a mesma.
Por exemplo:
Se você passar o número 380
como semente para a função rand_r()
três vezes, a sequência de números geradas é:
Se o número da semente for 381
, os números gerados são:
Butters descobriu que os números do mudou
nunca ultrapassam , e por isso ele constatou que os números recebem um módulo . Logo a sequência dos números aleatórios para as sementes e são, respectivamente:
Você consegue implementar um programa muito simples que mostra isso como no exemplo abaixo:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int semente;
printf("Digite a sua semente:\n");
scanf("%d",&semente);
for(int i=0;i<3;i++)
printf("%d\n",rand_r(&semente)%256);
}
rand_r(3)
no manual.Também foi descoberto pelo garoto prodígio, Butters, que a semente utilizada pelo mudou
não é tão difícil de descobrir, eles utilizaram como semente o tempo em segundos desde 1 de janeiro de 1970 a partir do momento que a máquina foi ligada pela primeira vez. Logo, temos uma janela para descobrir qual é a possível semente.
Nesse ponto Butters está travado e pediu a sua ajuda para descobrir qual é a semente utilizada pelo sistema mudou
.
A entrada possui um único caso de teste. A primeira linha, do caso de teste, possui dois inteiros e ( ) (cabe em um número inteiro sem sinal int
), representando o intervalo das possibilidades da semente, sendo o possível valor mais baixo e o maior valor possível para a semente. Sabemos que a diferença entre e nunca é maior que .
A seguir, existem um conjunto de linhas, terminadas por EOF
, indicando o qual número aleatório que o mudou
gerou (em módulo 256) após gerações de números aleatórios.
A saída possui uma única linha contendo a semente utilizada pelo sistema mudou
.
1 1
0
251
28
82
73
1
A primeira linha é bastante simples e diz que o intervalo possível da semente varia de até , notamos que a semente é claramente . A segunda linha é o valor gerador gerado pela chamada rand_r(&semente)%256
, com a semente , depois de vezes, sendo ese o valor , a terceira linha representa o valor devolvido pela rand_r
após mais execuções, devolvendo o valor . O código abaixo gera a mesma saída:
{
int semente=1;
for(int i=0;i<5;i++)
{
for(int j=1;j<10000;j++)
rand_r(&semente);
printf("%d\n",rand_r(&semente)%256);
}
}
6 6
244
213
75
190
89
6
921 936
141
156
139
126
84
174
238
53
99
26
928
No exemplo acima o intervalo é maior sendo a menor semente possível e a maior semente possível . O seu programa precisa descobrir qual é a semente correta.
Para descobrir a melhor semente não há muito o que se fazer, você deverá simular a geração dos números aleatórios para cada uma das sementes e ir descartando quando descobrir que a sequência não é possível. No exemplo acima é fácil descartar todos, exceto o , pois apenas o gera nas primeiras iterações.
665 769
91
54
41
141
124
205
27
190
207
39
96
209
149
132
55
8
14
36
225
160
122
70
158
220
24
43
174
250
41
19
80
60
237
61
198
223
163
234
78
38
141
90
40
79
233
205
150
156
247
131
214
74
249
187
41
156
45
182
207
208
212
180
7
40
46
244
18
225
123
183
48
62
250
61
161
125
236
198
164
224
145
730
34872413 34873777
92
155
191
116
38
4
250
181
163
239
135
25
16
155
166
222
176
73
151
69
194
57
153
142
133
171
237
248
58
222
211
197
32
19
138
51
121
138
84
130
131
131
111
244
127
61
28
199
173
249
154
60
76
247
42
147
157
119
12
11
224
184
128
229
85
251
198
97
59
128
29
191
211
135
198
63
93
79
34872913
Este já é um exemplo maior e mais elaborado, na primeira iteração você não pode descartar possíveis sementes, pois elas geram o mesmo valor nas primeiras iterações, no caso são:
16081291 16084449
43
48
145
154
89
155
236
153
177
255
16
50
114
156
62
165
221
180
182
49
50
133
184
24
177
80
132
151
153
85
89
241
43
212
120
100
167
12
32
50
76
62
147
153
92
170
15
217
21
143
213
52
184
46
37
232
132
199
62
54
187
154
97
93
155
231
206
159
101
237
197
58
88
237
134
111
181
39
80
125
188
218
100
166
173
72
1
40
200
175
105
68
76
79
218
57
16082825