117 \begin{document} |
117 \begin{document} |
118 |
118 |
119 % BF IDE |
119 % BF IDE |
120 % https://www.microsoft.com/en-us/p/brainf-ck/9nblgggzhvq5 |
120 % https://www.microsoft.com/en-us/p/brainf-ck/9nblgggzhvq5 |
121 |
121 |
122 \section*{Main Part 3 (Scala, 7 Marks)} |
122 \section*{Main Part 3 (Scala, 6 Marks)} |
123 |
123 |
124 %\mbox{}\hfill\textit{``[Google’s MapReduce] abstraction is inspired by the}\\ |
124 %\mbox{}\hfill\textit{``[Google’s MapReduce] abstraction is inspired by the}\\ |
125 %\mbox{}\hfill\textit{map and reduce primitives present in Lisp and many}\\ |
125 %\mbox{}\hfill\textit{map and reduce primitives present in Lisp and many}\\ |
126 %\mbox{}\hfill\textit{other functional language.''}\smallskip\\ |
126 %\mbox{}\hfill\textit{other functional language.''}\smallskip\\ |
127 %\mbox{}\hfill\textit{ --- Dean and Ghemawat, who designed this concept at Google} |
127 %\mbox{}\hfill\textit{ --- Dean and Ghemawat, who designed this concept at Google} |
148 This Scala assignment comes with a reference implementation in form of |
148 This Scala assignment comes with a reference implementation in form of |
149 a \texttt{jar}-file. This allows you to run any test cases on your own |
149 a \texttt{jar}-file. This allows you to run any test cases on your own |
150 computer. For example you can call Scala on the command line with the |
150 computer. For example you can call Scala on the command line with the |
151 option \texttt{-cp re.jar} and then query any function from the |
151 option \texttt{-cp re.jar} and then query any function from the |
152 \texttt{re.scala} template file. As usual you have to prefix the calls |
152 \texttt{re.scala} template file. As usual you have to prefix the calls |
153 with \texttt{CW8c} or import this object. Since some tasks |
153 with \texttt{M3} or import this object. Since some tasks |
154 are time sensitive, you can check the reference implementation as |
154 are time sensitive, you can check the reference implementation as |
155 follows: if you want to know, for example, how long it takes to match |
155 follows: if you want to know, for example, how long it takes to match |
156 strings of $a$'s using the regular expression $(a^*)^*\cdot b$ you can |
156 strings of $a$'s using the regular expression $(a^*)^*\cdot b$ you can |
157 query as follows: |
157 query as follows: |
158 |
158 |
159 |
159 |
160 \begin{lstlisting}[xleftmargin=1mm,numbers=none,basicstyle=\ttfamily\small] |
160 \begin{lstlisting}[xleftmargin=1mm,numbers=none,basicstyle=\ttfamily\small] |
161 $ scala -cp re.jar |
161 $ scala -cp re.jar |
162 scala> import CW8c._ |
162 scala> import M3._ |
163 scala> for (i <- 0 to 5000000 by 500000) { |
163 scala> for (i <- 0 to 5000000 by 500000) { |
164 | println(f"$i: ${time_needed(2, matcher(EVIL, "a" * i))}%.5f secs.") |
164 | println(f"$i: ${time_needed(2, matcher(EVIL, "a" * i))}%.5f secs.") |
165 | } |
165 | } |
166 0: 0.00002 secs. |
166 0: 0.00002 secs. |
167 500000: 0.10608 secs. |
167 500000: 0.10608 secs. |
228 \begin{tabular}{rcl@{\hspace{10mm}}l} |
228 \begin{tabular}{rcl@{\hspace{10mm}}l} |
229 & & code: & shorthand:\smallskip \\ |
229 & & code: & shorthand:\smallskip \\ |
230 $\ZERO$ & $\mapsto$ & \texttt{ZERO}\\ |
230 $\ZERO$ & $\mapsto$ & \texttt{ZERO}\\ |
231 $\ONE$ & $\mapsto$ & \texttt{ONE}\\ |
231 $\ONE$ & $\mapsto$ & \texttt{ONE}\\ |
232 $c$ & $\mapsto$ & \texttt{CHAR(c)}\\ |
232 $c$ & $\mapsto$ & \texttt{CHAR(c)}\\ |
|
233 $\sum rs$ & $\mapsto$ & \texttt{ALTs(rs)}\\ |
233 $r_1 + r_2$ & $\mapsto$ & \texttt{ALT(r1, r2)} & \texttt{r1 | r2}\\ |
234 $r_1 + r_2$ & $\mapsto$ & \texttt{ALT(r1, r2)} & \texttt{r1 | r2}\\ |
234 $r_1 \cdot r_2$ & $\mapsto$ & \texttt{SEQ(r1, r2)} & \texttt{r1 $\sim$ r2}\\ |
235 $r_1 \cdot r_2$ & $\mapsto$ & \texttt{SEQ(r1, r2)} & \texttt{r1 $\sim$ r2}\\ |
235 $r^*$ & $\mapsto$ & \texttt{STAR(r)} & \texttt{r.\%} |
236 $r^*$ & $\mapsto$ & \texttt{STAR(r)} & \texttt{r.\%} |
236 \end{tabular} |
237 \end{tabular} |
237 \end{center} |
238 \end{center} |
238 |
239 |
|
240 \noindent |
|
241 The alternative regular expressions comes in two versions: one is |
|
242 binary (+ / \texttt{ALT}) and the other is n-ary ($\sum$ / |
|
243 \texttt{ALTs}). The latter takes a list of regular expressions as |
|
244 arguments. In what follows we shall use $rs$ to stand for lists of |
|
245 regular expressions. The binary alternative can be seen as an abbreviation, |
|
246 that is $r_1 + r_2 \dn \sum\,[r_1, r_2]$. As a result we can ignore the |
|
247 binary version and only implement the n-ary alternative. |
239 |
248 |
240 \begin{itemize} |
249 \begin{itemize} |
241 \item[(1)] Implement a function, called \textit{nullable}, by |
250 \item[(1)] Implement a function, called \textit{nullable}, by |
242 recursion over regular expressions. This function tests whether a |
251 recursion over regular expressions. This function tests whether a |
243 regular expression can match the empty string. This means given a |
252 regular expression can match the empty string. This means given a |
248 \begin{center} |
257 \begin{center} |
249 \begin{tabular}{lcl} |
258 \begin{tabular}{lcl} |
250 $\textit{nullable}(\ZERO)$ & $\dn$ & $\textit{false}$\\ |
259 $\textit{nullable}(\ZERO)$ & $\dn$ & $\textit{false}$\\ |
251 $\textit{nullable}(\ONE)$ & $\dn$ & $\textit{true}$\\ |
260 $\textit{nullable}(\ONE)$ & $\dn$ & $\textit{true}$\\ |
252 $\textit{nullable}(c)$ & $\dn$ & $\textit{false}$\\ |
261 $\textit{nullable}(c)$ & $\dn$ & $\textit{false}$\\ |
253 $\textit{nullable}(r_1 + r_2)$ & $\dn$ & $\textit{nullable}(r_1) \vee \textit{nullable}(r_2)$\\ |
262 $\textit{nullable}(\sum rs)$ & $\dn$ & $\exists r \in rs.\;\textit{nullable}(r)$\\ |
254 $\textit{nullable}(r_1 \cdot r_2)$ & $\dn$ & $\textit{nullable}(r_1) \wedge \textit{nullable}(r_2)$\\ |
263 $\textit{nullable}(r_1 \cdot r_2)$ & $\dn$ & $\textit{nullable}(r_1) \wedge \textit{nullable}(r_2)$\\ |
255 $\textit{nullable}(r^*)$ & $\dn$ & $\textit{true}$\\ |
264 $\textit{nullable}(r^*)$ & $\dn$ & $\textit{true}$\\ |
256 \end{tabular} |
265 \end{tabular} |
257 \end{center}~\hfill[1 Mark] |
266 \end{center}~\hfill[0.5 Marks] |
258 |
267 |
259 \item[(2)] Implement a function, called \textit{der}, by recursion over |
268 \item[(2)] Implement a function, called \textit{der}, by recursion over |
260 regular expressions. It takes a character and a regular expression |
269 regular expressions. It takes a character and a regular expression |
261 as arguments and calculates the derivative of a regular expression according |
270 as arguments and calculates the derivative of a regular expression according |
262 to the rules: |
271 to the rules: |
264 \begin{center} |
273 \begin{center} |
265 \begin{tabular}{lcl} |
274 \begin{tabular}{lcl} |
266 $\textit{der}\;c\;(\ZERO)$ & $\dn$ & $\ZERO$\\ |
275 $\textit{der}\;c\;(\ZERO)$ & $\dn$ & $\ZERO$\\ |
267 $\textit{der}\;c\;(\ONE)$ & $\dn$ & $\ZERO$\\ |
276 $\textit{der}\;c\;(\ONE)$ & $\dn$ & $\ZERO$\\ |
268 $\textit{der}\;c\;(d)$ & $\dn$ & $\textit{if}\; c = d\;\textit{then} \;\ONE \; \textit{else} \;\ZERO$\\ |
277 $\textit{der}\;c\;(d)$ & $\dn$ & $\textit{if}\; c = d\;\textit{then} \;\ONE \; \textit{else} \;\ZERO$\\ |
269 $\textit{der}\;c\;(r_1 + r_2)$ & $\dn$ & $(\textit{der}\;c\;r_1) + (\textit{der}\;c\;r_2)$\\ |
278 $\textit{der}\;c\;(\sum\;[r_1,..,r_n])$ & $\dn$ & $\sum\;[\textit{der}\;c\;r_1,..,\textit{der}\;c\;r_n]$\\ |
270 $\textit{der}\;c\;(r_1 \cdot r_2)$ & $\dn$ & $\textit{if}\;\textit{nullable}(r_1)$\\ |
279 $\textit{der}\;c\;(r_1 \cdot r_2)$ & $\dn$ & $\textit{if}\;\textit{nullable}(r_1)$\\ |
271 & & $\textit{then}\;((\textit{der}\;c\;r_1)\cdot r_2) + (\textit{der}\;c\;r_2)$\\ |
280 & & $\textit{then}\;((\textit{der}\;c\;r_1)\cdot r_2) + (\textit{der}\;c\;r_2)$\\ |
272 & & $\textit{else}\;(\textit{der}\;c\;r_1)\cdot r_2$\\ |
281 & & $\textit{else}\;(\textit{der}\;c\;r_1)\cdot r_2$\\ |
273 $\textit{der}\;c\;(r^*)$ & $\dn$ & $(\textit{der}\;c\;r)\cdot (r^*)$\\ |
282 $\textit{der}\;c\;(r^*)$ & $\dn$ & $(\textit{der}\;c\;r)\cdot (r^*)$\\ |
274 \end{tabular} |
283 \end{tabular} |
310 \end{center} |
319 \end{center} |
311 |
320 |
312 Note, the last derivative can match the empty string, that is it is \textit{nullable}.\\ |
321 Note, the last derivative can match the empty string, that is it is \textit{nullable}.\\ |
313 \mbox{}\hfill\mbox{[1 Mark]} |
322 \mbox{}\hfill\mbox{[1 Mark]} |
314 |
323 |
315 \item[(3)] Implement the function \textit{simp}, which recursively |
324 \item[(3)] We next want to simplify regular expressions: essentially |
|
325 we want to remove $\ZERO$ in regular expressions like $r + \ZERO$ |
|
326 and $\ZERO + r$. However, our n-ary alternative takes a list of |
|
327 regular expressions as argument, we therefore need a more general |
|
328 ``flatten'' function, called \texttt{flts}. This function should |
|
329 analyse a list of regular expressions, say $rs$, as follows: |
|
330 |
|
331 \begin{center} |
|
332 \begin{tabular}{lllll} |
|
333 1) &$rs = []$ & $\dn$ & $[]$ & (empty list)\\ |
|
334 2) &$rs = \ZERO :: rest$ & $\dn$ & $\textrm{flatten}\;rest$\\ |
|
335 3) &$rs = (\sum rs_1) :: rest$ & $\dn$ & $rs_1 ::: \textrm{flatten}\;rest$\\ |
|
336 4) &$rs = r :: rest$ & $\dn$ & $r :: \textrm{flatten}\;rest$ & (otherwise)\\ |
|
337 \end{tabular} |
|
338 \end{center} |
|
339 |
|
340 The first clause just states that empty lists cannot be further |
|
341 flattened. The second removes all $\ZERO$s from the list. |
|
342 The third is when the first regular expression is an \texttt{ALTs}, then |
|
343 the content of this alternative should be spilled out and appended |
|
344 with the flattened rest of the list. The last case is for all other |
|
345 cases where the head of the list is not $\ZERO$ and not an \texttt{ALTs}, |
|
346 then we just keep the head of the list and flatten the rest. |
|
347 \mbox{}\hfill\mbox{[1 Mark]} |
|
348 |
|
349 \item[(4)] Implement the function \textit{simp}, which recursively |
316 traverses a regular expression, and on the way up simplifies every |
350 traverses a regular expression, and on the way up simplifies every |
317 regular expression on the left (see below) to the regular expression |
351 regular expression on the left (see below) to the regular expression |
318 on the right, except it does not simplify inside ${}^*$-regular |
352 on the right, except it does not simplify inside ${}^*$-regular |
319 expressions. |
353 expressions. |
320 |
354 |
322 \begin{tabular}{l@{\hspace{4mm}}c@{\hspace{4mm}}ll} |
356 \begin{tabular}{l@{\hspace{4mm}}c@{\hspace{4mm}}ll} |
323 $r \cdot \ZERO$ & $\mapsto$ & $\ZERO$\\ |
357 $r \cdot \ZERO$ & $\mapsto$ & $\ZERO$\\ |
324 $\ZERO \cdot r$ & $\mapsto$ & $\ZERO$\\ |
358 $\ZERO \cdot r$ & $\mapsto$ & $\ZERO$\\ |
325 $r \cdot \ONE$ & $\mapsto$ & $r$\\ |
359 $r \cdot \ONE$ & $\mapsto$ & $r$\\ |
326 $\ONE \cdot r$ & $\mapsto$ & $r$\\ |
360 $\ONE \cdot r$ & $\mapsto$ & $r$\\ |
327 $r + \ZERO$ & $\mapsto$ & $r$\\ |
361 $\sum\;[r_1,..,r_n]$ & $\mapsto$ & $\sum\;(\texttt{(flts + distinct)}[simp(r_1),..,simp(r_n)])$\\ |
328 $\ZERO + r$ & $\mapsto$ & $r$\\ |
|
329 $r + r$ & $\mapsto$ & $r$\\ |
|
330 \end{tabular} |
362 \end{tabular} |
331 \end{center} |
363 \end{center} |
|
364 |
|
365 The last case is as follows: first apply $simp$ to all regular expressions |
|
366 $r_1,.. ,r_n$; then flatten the resulting list using \texttt{flts}; |
|
367 finally remove all duplicates in this list (this can be done in Scala |
|
368 using the function \texttt{\_.distinct}). |
332 |
369 |
333 For example the regular expression |
370 For example the regular expression |
334 \[(r_1 + \ZERO) \cdot \ONE + ((\ONE + r_2) + r_3) \cdot (r_4 \cdot \ZERO)\] |
371 \[(r_1 + \ZERO) \cdot \ONE + ((\ONE + r_2) + r_3) \cdot (r_4 \cdot \ZERO)\] |
335 |
372 |
336 simplifies to just $r_1$. \textbf{Hint:} Regular expressions can be |
373 simplifies to just $r_1$. \textbf{Hint:} Regular expressions can be |
337 seen as trees and there are several methods for traversing |
374 seen as trees and there are several methods for traversing |
338 trees. One of them corresponds to the inside-out traversal, which is also |
375 trees. One of them corresponds to the inside-out traversal, which is |
339 sometimes called post-order tra\-versal: you traverse inside the |
376 also sometimes called post-order tra\-versal: you traverse inside |
340 tree and on the way up you apply simplification rules. |
377 the tree and on the way up you apply simplification rules. |
341 \textbf{Another Hint:} |
378 \textbf{Another Hint:} Remember numerical expressions from school |
342 Remember numerical expressions from school times---there you had expressions |
379 times---there you had expressions like |
343 like $u + \ldots + (1 \cdot x) - \ldots (z + (y \cdot 0)) \ldots$ |
380 $u + \ldots + (1 \cdot x) - \ldots (z + (y \cdot 0)) \ldots$ and |
344 and simplification rules that looked very similar to rules |
381 simplification rules that looked very similar to rules above. You |
345 above. You would simplify such numerical expressions by replacing |
382 would simplify such numerical expressions by replacing for example |
346 for example the $y \cdot 0$ by $0$, or $1\cdot x$ by $x$, and then |
383 the $y \cdot 0$ by $0$, or $1\cdot x$ by $x$, and then look whether |
347 look whether more rules are applicable. If you organise the |
384 more rules are applicable. If you regard regular expressions as |
348 simplification in an inside-out fashion, it is always clear which |
385 trees and if you organise the simplification in an inside-out |
349 simplification should be applied next.\hfill[1 Mark] |
386 fashion, it is always clear which simplification should be applied |
350 |
387 next.\mbox{}\hfill\mbox{[1 Mark]} |
351 \item[(4)] Implement two functions: The first, called \textit{ders}, |
388 |
|
389 \item[(5)] Implement two functions: The first, called \textit{ders}, |
352 takes a list of characters and a regular expression as arguments, and |
390 takes a list of characters and a regular expression as arguments, and |
353 builds the derivative w.r.t.~the list as follows: |
391 builds the derivative w.r.t.~the list as follows: |
354 |
392 |
355 \begin{center} |
393 \begin{center} |
356 \begin{tabular}{lcl} |
394 \begin{tabular}{lcl} |
369 derivative regular expression can match the empty string (using |
407 derivative regular expression can match the empty string (using |
370 \textit{nullable}). For example the \textit{matcher} will produce |
408 \textit{nullable}). For example the \textit{matcher} will produce |
371 true for the regular expression $(a\cdot b)\cdot c$ and the string |
409 true for the regular expression $(a\cdot b)\cdot c$ and the string |
372 $abc$, but false if you give it the string $ab$. \hfill[1 Mark] |
410 $abc$, but false if you give it the string $ab$. \hfill[1 Mark] |
373 |
411 |
374 \item[(5)] Implement a function, called \textit{size}, by recursion |
412 \item[(6)] Implement a function, called \textit{size}, by recursion |
375 over regular expressions. If a regular expression is seen as a tree, |
413 over regular expressions. If a regular expression is seen as a tree, |
376 then \textit{size} should return the number of nodes in such a |
414 then \textit{size} should return the number of nodes in such a |
377 tree. Therefore this function is defined as follows: |
415 tree. Therefore this function is defined as follows: |
378 |
416 |
379 \begin{center} |
417 \begin{center} |
380 \begin{tabular}{lcl} |
418 \begin{tabular}{lcl} |
381 $\textit{size}(\ZERO)$ & $\dn$ & $1$\\ |
419 $\textit{size}(\ZERO)$ & $\dn$ & $1$\\ |
382 $\textit{size}(\ONE)$ & $\dn$ & $1$\\ |
420 $\textit{size}(\ONE)$ & $\dn$ & $1$\\ |
383 $\textit{size}(c)$ & $\dn$ & $1$\\ |
421 $\textit{size}(c)$ & $\dn$ & $1$\\ |
384 $\textit{size}(r_1 + r_2)$ & $\dn$ & $1 + \textit{size}(r_1) + \textit{size}(r_2)$\\ |
422 $\textit{size}(\sum\,[r_1,..,r_n]$ & $\dn$ & $1 + \textit{size}(r_1) + ... + \textit{size}(r_n)$\\ |
385 $\textit{size}(r_1 \cdot r_2)$ & $\dn$ & $1 + \textit{size}(r_1) + \textit{size}(r_2)$\\ |
423 $\textit{size}(r_1 \cdot r_2)$ & $\dn$ & $1 + \textit{size}(r_1) + \textit{size}(r_2)$\\ |
386 $\textit{size}(r^*)$ & $\dn$ & $1 + \textit{size}(r)$\\ |
424 $\textit{size}(r^*)$ & $\dn$ & $1 + \textit{size}(r)$\\ |
387 \end{tabular} |
425 \end{tabular} |
388 \end{center} |
426 \end{center} |
389 |
427 |
390 You can use \textit{size} in order to test how much the ``evil'' regular |
428 You can use \textit{size} in order to test how much the ``evil'' regular |
391 expression $(a^*)^* \cdot b$ grows when taking successive derivatives |
429 expression $(a^*)^* \cdot b$ grows when taking successive derivatives |
392 according the letter $a$ without simplification and then compare it to |
430 according the letter $a$ without simplification and then compare it to |
393 taking the derivative, but simplify the result. The sizes |
431 taking the derivative, but simplify the result. The sizes |
394 are given in \texttt{re.scala}. \hfill[1 Mark] |
432 are given in \texttt{re.scala}. \hfill[0.5 Marks] |
395 |
433 |
396 \item[(6)] You do not have to implement anything specific under this |
434 \item[(7)] You do not have to implement anything specific under this |
397 task. The purpose here is that you will be marked for some ``power'' |
435 task. The purpose here is that you will be marked for some ``power'' |
398 test cases. For example can your matcher decide within 30 seconds |
436 test cases. For example can your matcher decide within 30 seconds |
399 whether the regular expression $(a^*)^*\cdot b$ matches strings of the |
437 whether the regular expression $(a^*)^*\cdot b$ matches strings of the |
400 form $aaa\ldots{}aaaa$, for say 1 Million $a$'s. And does simplification |
438 form $aaa\ldots{}aaaa$, for say 1 Million $a$'s. And does simplification |
401 simplify the regular expression |
439 simplify the regular expression |
404 \texttt{SEQ(SEQ(SEQ(..., ONE | ONE) , ONE | ONE), ONE | ONE)} |
442 \texttt{SEQ(SEQ(SEQ(..., ONE | ONE) , ONE | ONE), ONE | ONE)} |
405 \] |
443 \] |
406 |
444 |
407 \noindent correctly to just \texttt{ONE}, where \texttt{SEQ} is nested |
445 \noindent correctly to just \texttt{ONE}, where \texttt{SEQ} is nested |
408 50 or more times?\\ |
446 50 or more times?\\ |
409 \mbox{}\hfill[2 Marks] |
447 \mbox{}\hfill[1 Mark] |
410 \end{itemize} |
448 \end{itemize} |
411 |
449 |
412 \subsection*{Background} |
450 \subsection*{Background} |
413 |
451 |
414 Although easily implementable in Scala, the idea behind the derivative |
452 Although easily implementable in Scala (ok maybe the \texttt{simp} functions and |
415 function might not so easy to be seen. To understand its purpose |
453 \texttt{ALTs} needs a bit more thinking), the idea behind the |
416 better, assume a regular expression $r$ can match strings of the form |
454 derivative function might not so easy to be seen. To understand its |
417 $c\!::\!cs$ (that means strings which start with a character $c$ and have |
455 purpose better, assume a regular expression $r$ can match strings of |
418 some rest, or tail, $cs$). If you take the derivative of $r$ with |
456 the form $c\!::\!cs$ (that means strings which start with a character |
419 respect to the character $c$, then you obtain a regular expression |
457 $c$ and have some rest, or tail, $cs$). If you take the derivative of |
420 that can match all the strings $cs$. In other words, the regular |
458 $r$ with respect to the character $c$, then you obtain a regular |
421 expression $\textit{der}\;c\;r$ can match the same strings $c\!::\!cs$ |
459 expression that can match all the strings $cs$. In other words, the |
422 that can be matched by $r$, except that the $c$ is chopped off. |
460 regular expression $\textit{der}\;c\;r$ can match the same strings |
|
461 $c\!::\!cs$ that can be matched by $r$, except that the $c$ is chopped |
|
462 off. |
423 |
463 |
424 Assume now $r$ can match the string $abc$. If you take the derivative |
464 Assume now $r$ can match the string $abc$. If you take the derivative |
425 according to $a$ then you obtain a regular expression that can match |
465 according to $a$ then you obtain a regular expression that can match |
426 $bc$ (it is $abc$ where the $a$ has been chopped off). If you now |
466 $bc$ (it is $abc$ where the $a$ has been chopped off). If you now |
427 build the derivative $\textit{der}\;b\;(\textit{der}\;a\;r)$ you |
467 build the derivative $\textit{der}\;b\;(\textit{der}\;a\;r)$ you |
449 |
489 |
450 If you want to see how badly the regular expression matchers do in |
490 If you want to see how badly the regular expression matchers do in |
451 Java\footnote{Version 8 and below; Version 9 and above does not seem to be as |
491 Java\footnote{Version 8 and below; Version 9 and above does not seem to be as |
452 catastrophic, but still much worse than the regular expression |
492 catastrophic, but still much worse than the regular expression |
453 matcher based on derivatives.}, JavaScript and Python with the |
493 matcher based on derivatives.}, JavaScript and Python with the |
454 `evil' regular expression $(a^*)^*\cdot b$, then have a look at the |
494 ``evil'' regular expression $(a^*)^*\cdot b$, then have a look at the |
455 graphs below (you can try it out for yourself: have a look at the files |
495 graphs below (you can try it out for yourself: have a look at the files |
456 \texttt{catastrophic9.java}, \texttt{catastrophic.js}, |
496 \texttt{catastrophic9.java}, \texttt{catastrophic.js}, |
457 \texttt{catastrophic.py} etc on KEATS). Compare this with the matcher you |
497 \texttt{catastrophic.py} etc on KEATS). Compare this with the matcher you |
458 have implemented. How long can the string of $a$'s be in your matcher |
498 have implemented. How long can a string of $a$'s be in your matcher |
459 and still stay within the 30 seconds time limit? |
499 and still stay within the 30 seconds time limit? It should be muuuch better |
|
500 than your off-the-shelf matcher in your bog-standard language. |
460 |
501 |
461 \begin{center} |
502 \begin{center} |
462 \begin{tabular}{@{}cc@{}} |
503 \begin{tabular}{@{}cc@{}} |
463 \multicolumn{2}{c}{Graph: $(a^*)^*\cdot b$ and strings |
504 \multicolumn{2}{c}{Graph: $(a^*)^*\cdot b$ and strings |
464 $\underbrace{a\ldots a}_{n}$}\bigskip\\ |
505 $\underbrace{a\ldots a}_{n}$}\bigskip\\ |
475 ymax=45, |
516 ymax=45, |
476 ytick={0,5,...,40}, |
517 ytick={0,5,...,40}, |
477 scaled ticks=false, |
518 scaled ticks=false, |
478 axis lines=left, |
519 axis lines=left, |
479 width=6cm, |
520 width=6cm, |
480 height=5.5cm, |
521 height=5.0cm, |
481 legend entries={Python, Java 8, JavaScript, Swift, Dart}, |
522 legend entries={Python, Java 8, JavaScript, Swift, Dart}, |
482 legend pos=north west, |
523 legend pos=north west, |
483 legend cell align=left] |
524 legend cell align=left] |
484 \addplot[blue,mark=*, mark options={fill=white}] table {re-python2.data}; |
525 \addplot[blue,mark=*, mark options={fill=white}] table {re-python2.data}; |
485 \addplot[cyan,mark=*, mark options={fill=white}] table {re-java.data}; |
526 \addplot[cyan,mark=*, mark options={fill=white}] table {re-java.data}; |