Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I thought of that old joke today, where a programmer can make an undeniable excuse for his leisure activities while in work on the basis that he is just waiting for his code to compile.

Although I am a workaholic and a fair player, such an excuse comes in handy now and then, so what is the best way to achieve a long compilation time with as little additional code as possible?

Additional imaginary points shall be awarded for any cunning additional value such as making it hard for a LaTeX advanced user or even an expert to identify the cause straight away (the longer it takes, the better) or exceptionally creative ways of doing so.

All solutions must eventually compile, so indefinite loops and such are prohibited. The ideal solution should not produce written output to the built document, mask itself from the console output log, load as few packages as possible, and be difficult to detect.

Use this as a basic template and use e.g. UNIX time to find how long the compilation took (should any solutions come, I shall time them under the same conditions and post the results) (this is unnecessary since there are virtually infinite solutions).

\documentclass{article}
\usepackage{lipsum}
\begin{document}
\title{Title}
\author{Author}
\date{Today}
\maketitle
\lipsum
\end{document}

Hopefully it is worth some time and a laugh and not just one of my idiomatic (and perhaps idiotic) creations.

share|improve this question
66  
Use any Java based TeX implementation –  topskip Jul 2 '13 at 14:35
4  
… on a virtual machine with a poor performance. Okay, that could be the most inefficient codeless way. –  Harold Cavendish Jul 2 '13 at 14:40
4  
Now everyone of your colleagues knows that you are slacking off. And the boss too. –  sammy Jul 2 '13 at 22:42
17  
@topskip: [knock knock] - Who's there? [very long pause] - Java. :) –  Paulo Cereda Jul 3 '13 at 1:06
11  
Seriously? pdflatex thesis.tex 326.88s user 0.94s system 99% cpu 5:28.49 total That's 11 minutes every time I build that document. I pretty much already watched all of Youtube so this is not funny! –  Christian Jul 3 '13 at 4:04

16 Answers 16

up vote 54 down vote accepted
+50

With pdfTeX, add

\everypar{\ifnum\pdfelapsedtime<\maxdimen
  \the\expandafter\everypar\else\pdfresettimer\fi}

(after the \begin{document} if you are using pdfLaTeX). This will wait four hours and a half (\maxdimen scaled seconds, that is, 2^{30-16} seconds) before starting each paragraph. Replace \maxdimen by 65536 (and a space) to get a one second delay at each paragraph. Compiling a book with, say, 1000 paragraphs takes about six months. Not bad for a 90 characters addition.

With a bit more code (184 characters), an engine-agnostic implementation of the Ackermann function lets us get pretty much any delay by changing the arguments of \A just a little bit (I am not sure at what point TeX's limits are exceeded). With

\def\A#1#2{\the\numexpr\B{#1}{#2+1}\empty
  {\A{#1-1}{\B{#2}1\empty{\A{#1}{#2-1}}.}}.\relax}
\def\B#1{\ifnum\numexpr#1=0 \C\else\C\fi}
\def\C#1#2#3#4#5.{#1#3#4}
\everypar{{\count0=\A{3}{1}}}

I add about 6 minutes per paragraph to the compilation time on my machine. An additional benefit of this answer is that the definitions can easily be scattered in the preamble to avoid detection. Using xint lets us manipulate larger numbers, hence give larger arguments to \A:

\usepackage{xint}
\def\C#1#2#3#4#5.{#1#3#4}
\def\b#1{\if0\s{#1}\C\else\C\fi}
\let\s\xintSgn
\let\d\romannumeral
\let\x\xintAdd
\def\a#1#2{\b{#1}{\x{#2}1}\empty{%
    \a{\x{#1}{-1}}
    {\d-`-\b{#2}1\empty{\a{#1}{\d-`-\x{#2}{-1}}}.}}.}
\everypar{\d-\xintSgn{\A{3}{1}} }

This last code is not tested: xint puts an overhead on TeX's arithmetic, which makes the whole thing way too slow. Slower, even, would be to use the bigintcalc package, which predates xint and is not as optimized.

share|improve this answer
3  
I should add that this answer is inspired by David's answer, but does not produce any spurious output. –  Bruno Le Floch Jul 4 '13 at 7:28
    
I think this is the only answer so far that matches the OPs intend: Not to produce some fancy, computational intensive output, but to really just burn CPU cycles. The code is also small enough to be hidden somehwere. It might be a good idea to obfuscate it somewhat more, though (elapsedtime and resettimer are still a bit too obvious). –  Daniel Jul 4 '13 at 9:28
    
It appears that we have a winner here, great. :-) (I shall wait with accepting a bit more though since waiting for your answer really paid off.) I also quite like David's answer so in case I accept yours, he will get a bounty. In fact, I like most of them! –  Harold Cavendish Jul 4 '13 at 12:25
3  
@Daniel Just to obfuscate it completely, create a "fake" copy of article.cls, and insert this code in a AtBeginDocument command: \AtBeginDocument{\everypar{\ifnum\pdfelapsedtime<\maxdimen\the\expandafter\ever‌​ypar\else\pdfresettimer\fi}} –  karlkoeller Jul 4 '13 at 13:13
    
@karlkoeller I know exactly how I am going to fool a friend of mine when I get an access to his machine! ^_^ –  Harold Cavendish Jul 4 '13 at 18:44

This should keep you busy for a minute or two (I stopped my test run after 5 minutes)

\documentclass{article}


\begin{document}
\everypar{\ifnum\thepage000<\maxdimen\par\fi}

hello

\end{document}
share|improve this answer
4  
Just out of curiosity, what does it do? –  Jeel Shah Jul 2 '13 at 19:41
16  
@gekkostate Open a Word document, write hello and press Home. Then put an ashtray on the Enter button, come back a week later... –  percusse Jul 2 '13 at 20:37
    
Edited (added 000) so it doesn't run out of pdf objects and stops in reasonable time (just over 7 minutes on my machine) –  David Carlisle Jul 2 '13 at 20:58
1  
@gekkostate it makes some blank paragraphs then prints hello –  David Carlisle Jul 2 '13 at 20:58
1  
"Ooops, your LaTeX code couldn't compile for some reason. Please check these errors for details:" +1. –  dimension10 Jul 4 '13 at 9:10

Disclaimer: I'm not responsible for any damage this may cause to your CPU! :D

A solution based on hyperref and foreach:

\documentclass{article}
\usepackage{tikz}
\usepackage{hyperref}
\usepackage{lipsum}

\begin{document}
\title{The art of wasting time} 
\author{dcmst}
\maketitle
\lipsum[1]
  \begin{tikzpicture}
  \def \n {1000}
  \foreach \s in {1,...,\n}{
  \node {\hypertarget{\s}{}};
  \node {\hyperlink{\s}{}};
  }
  \end{tikzpicture}
\lipsum[1]
\end{document}

On a i7 laptop a loop of 1000 compiles in 3-4 seconds; a loop of 10000 in 53 seconds! Etc.

Just increase the number and you'll have more time to play with [insert you favorite video game here].

This does not produce any output at all, so you can also blame your old machine and ask for a newer, faster, one :)

Edit: looks like that 16383 is the maximum accepted value for \n. Then you can obviously stack more than one loop adding as many foreach as you need. Two foreach istances with a value of 10000 got me a TeX capacity exceeded error.

Edit.2: to remove compilation warnings a ~ or \null character can be added into the hypertarget and link second argument.

Edit.3: after increasing the main_memory amount I managed to keep the compilation going for 4 minutes before stopping manually. Instead of adding another foreach the time can be prolonged adding more couples of nodes like the two in the MWE.

share|improve this answer
3  
What?! All my files are deleted! Just joking, +1. –  dimension10 Jul 4 '13 at 9:05

Draw a complicated diagram.

Include it several times in the document and don't optimise it. This one takes about 10s on my computer. Increasing the 89.9 in the first \foreach would mean it took even longer (though 89.99 produces an overflow). Drawing the same diagram several times would again increase the time it took.

\documentclass{article}
\thispagestyle{empty}
%\def\pgfsysdriver{pgfsys-tex4ht.def}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
% \x runs over the angles at which to draw the circles defining the
% torus
\foreach \x in {90,89.9,...,-90} { % change 89 to 80 or 45 for speed
% \elrad is the x-radius of the ellipse (technically, a circle seen
% from side on at angle \x).  The 'max' is because at small angles
% then the real ellipse is too thin and the torus doesn't ``fill
% out'' nicely.
\pgfmathsetmacro\elrad{20*max(cos(\x),.1)}
% We draw the torus from the back to the front to get the right
% layering effect.  To tint it, we define colours according to the
% angle, but need different colours for the left and right pieces.
% It'd be nice if the xcolor colour specification could take something
% computed by pdfmath, such as {red!\tint} but it doesn't appear to
% work, so we define the colours explicitly.
\pgfmathsetmacro\ltint{.9*abs(\x-45)/180}
\pgfmathsetmacro\rtint{.9*(1-abs(\x+45)/180)}
\definecolor{currentcolor}{rgb}{\ltint, 0, \ltint}
% This draws the right-hand circle.
\draw[color=currentcolor,fill=currentcolor] (xyz polar cs:angle=\x,y radius=.75,x radius=1.5) ellipse (\elrad pt and 20pt);
% This sets the colour correctly for the left-hand circle ...
\definecolor{currentcolor}{rgb}{\rtint, 0, \rtint}
% ... and draws it
\draw[color=currentcolor,fill=currentcolor] (xyz polar cs:angle=180-\x,radius=.75,x radius=1.5) ellipse (\elrad pt and 20pt);
% End of foreach statement
}
% Spheres are *much* easier!
\shadedraw[shading=ball,ball color=purple, white] (6.5,0) circle (1.5);
% As are the subsets of Euclidean space
\draw[fill=cyan] (-1,-4) rectangle (1,-3);
\draw[fill=cyan] (5.5,-4) rectangle (7.5,-3);
% The next three draw the maps, slightly curved for aesthetics.
\draw[->] (0,-2.8) .. controls (-.2,-2.2) .. (0,-1.6) node[pos=0.5, auto=left] {\(\psi\)};
\draw[->] (6.5,-1.6) .. controls (6.7,-2.2) .. (6.5,-2.8) node[pos=0.5, auto=left] {\(\phi^{-1}\)};
\draw[->] (2.5,0) .. controls (3.5,.2) .. (4.5,0) node[pos=0.5, auto=left] {\(f\)};
% Now we want to draw the codomains of the charts.  Sticking cosines
% and sines directly into the coordinates doesn't seem to work so
% we define macros to hold the sines and cosines of the angles.
% \elrad is the angle on the torus at which to start.
\pgfmathsetmacro\elrad{cos(-135)}
% the circle drawn at the specific angle on the torus looks like an
% ellipse, \xrad and \yrad compute its major and minor semi-axes.
\pgfmathsetmacro\xrad{1.5cm-20pt*\elrad}
\pgfmathsetmacro\yrad{.75cm-20pt*sin(-135)}
% This draws the codomain of the chart on the torus.
\path[fill=cyan, fill opacity=.35] (xyz polar cs:angle=-135,radius=.75,x radius=1.5) ++(20pt*\elrad,0) arc (0:45:20*\elrad pt and 20pt) arc (-135:-45:\xrad pt and \yrad pt) arc (45:-45:-20*\elrad pt and 20pt) arc (-45:-135:\xrad pt and \yrad pt) arc (-45:0:20*\elrad pt and 20pt);
% Now we do the same for the sphere.
% We do this by drawing some great circles (aka ellipses) on the
% sphere and then ``clipping'' an overlaid (and slightly trans:parent)
% sphere by those great circles.  Each great circle actually specifies
% one side of the ``clip'' so to make sure that the clip is big enough
% the arcs are completed by big rectangles (otherwise the clipping
% would join the end points directly).
\pgfmathsetmacro\tell{-sin(10)}
\pgfmathsetmacro\bell{sin(50)}
\pgfmathsetmacro\rell{1.5 * sin(50)}
\begin{scope}
\clip (6.5,0) +(-1.5,0) arc (-180:0:1.5 and 1.5*\tell) -- ++(0,-1.5) -- ++(-3,0) -- ++(0,1.5);
\clip (6.5,0) +(-1.5,0) arc (-180:0:1.5 and 1.5*\bell) -- ++(0,1.5) -- ++(-3,0) -- ++(0,-1.5);
\clip (6.5,0) +(0,1.5)  arc (90:-90:\rell cm and 1.5 cm) -- ++(-1.5,0) -- ++(0,3) -- ++(1.5,0);
\clip (6.5,0) +(0,1.5)  arc (90:-90:-\rell cm and 1.5 cm) -- ++(1.5,0) -- ++(0,3) -- ++(-1.5,0);
\fill[cyan, fill opacity=0.35] (6.5,0) circle (1.5);
\end{scope}
\end{tikzpicture}
\end{document}

Result:

PDF Torus

Remarks:

  1. This is a diagram from a conference talk that I gave so it is not an example that I cooked up to answer this question.
  2. It is the torus that takes so long, it is drawn as a family of circles.
  3. When writing the seminar, I actually increased the step size considerably as it was taking so long to compile on each run, only decreasing it for the final compilation.
  4. When I gave this talk a second time, I found a quicker way of drawing the torus.
share|improve this answer
    
Not that toruses aren't impressive, but this answer doesn't seem to meet the 'stealth' criteria given in the question... –  Alan Munn Jul 2 '13 at 19:15
2  
@AlanMunn Change the line \definecolor{currentcolour}{...} to \definecolor{currentcolour}{1,1,1}. Seriously, the stealth part is the number of circles drawn. I defy you to tell the difference between 89 and 89.9 but the difference in time is huge. –  Loop Space Jul 2 '13 at 19:31
    
@Andrew - On the off chance you were not already doing this, I believe putting the figure into an external .tex file allows the result of pgf and tkiz to be cached –  Hamy Jul 3 '13 at 2:43
1  
@Hamy I tend to use the extetnal library to achieve the same end. –  Loop Space Jul 3 '13 at 6:09
    
Nice. But ShareLatex took just 30 seconds to compile it. –  dimension10 Jul 4 '13 at 9:03

Keep an entire lecture series of beamer presentations in a single file.

As in my other answer, this piece of advice comes from a real world situation. Of course, normally one is trying to reduce the compilation time and it was in search of this aim that I developed the tools that I mention in http://tex.stackexchange.com/a/52904/86. But if you don't use such methods, compiling a lecture from a beamer file that contains an entire course of lectures can take ... time.

(For hopefully obvious reasons I'm not going to post code for this one!)

share|improve this answer
    
ha ha, I enjoy that you've now posted multiple "solutions" to the raw question of 'how do you make tex compilation slow' –  Hamy Jul 3 '13 at 2:44
2  
This methods becomes a lot more effective in combination with TikZ images that use remember picture, overlay – not to say \tikzmark – in every frame. –  Daniel Jul 4 '13 at 9:30

This is perhaps a simplified pstricks-version of Andrew's answer.

Of the 25 frames, the first compiles & renders in under a second. The last compiles quickly, but the Postscript rendering takes roughly 3 minutes with the only difference being the specification of the ngrid key:

enter image description here

The beauty about the code that produces this is all contained in a single macro \psSolid. For super-smooth, lengthy leisure, ngrid=180 360 compiles in about 40 minutes:

enter image description here

\documentclass[pstricks,border=0pt]{standalone}
\usepackage{pst-solides3d}% http://ctan.org/pkg/pst-solides3d
\usepackage{multido}% http://ctan.org/pkg/multido
\pagestyle{empty}
\begin{document}
\begin{pspicture}(-3,-2)(3,2)
  \psset{viewpoint=50 50 30 rtp2xyz,Decran=25,lightsrc=viewpoint}
  \psSolid[r1=3.5,r0=1,
    object=tore,
    linewidth=0pt,
    ngrid=180 360,
    fillcolor=magenta!30,
    action=draw**]%
  \axesIIID(4.5,4.5,0)(5,5,4)
\end{pspicture}
\end{document}

A "spy" of some of the ~65K polygonal constructions, which is worth the wait (if needed):

enter image description here

En garde!

share|improve this answer
1  
and run the documents with xelatex ... –  Herbert Jul 3 '13 at 8:04
    
+1 nice........ –  dimension10 Jul 4 '13 at 9:16

Install an antivirus software and make it check thoroughly all the files of your TeX installation. No extra coding required, but the effect varies with the amount of packages and fonts you load.

(That's why my Windows colleagues have much more leisure time than I do...)

share|improve this answer

This might be a ConTeXt-only option.

You can try referencing fonts by their names, without telling TeX that the name you're using is not a filename. This was another real-world situation. As described in this question: ConTeXt keeps trying to create "missing" font files, I was getting a 40x to 60x slowdown using this technique!

E.g.

\definefont[SerifS][GentiumBookBasic at \smallfontsize]
share|improve this answer

There is a reason I wrote the titlecaps package... The \capitalizetitle command of the stringstrings package was an embarassment. What titlecaps can do in a second or two, this stringstrings routine takes upwards of two minutes on my machine. Passing an optional [v] argument to \testcompiler will print out the result, which I did not do at the request of the questioner.

\documentclass{article}
\usepackage{stringstrings}
\newcommand\testcompiler[1][q]{%
  \addlcwords{as the for to and on a in not from by}
  \capitalizetitle[#1]{four score and seven years ago our fathers
  brought forth on this continent a new nation, conceived in liberty,
  and dedicated to the proposition that all men are created equal.}%
}
\begin{document}
\testcompiler
\end{document}
share|improve this answer

Option 1: Randomly-Viewed Sliced Image

Based on HV's answer. By changing \N to 30 or more, you will have longer time to wait.

\documentclass[pstricks]{standalone}
\usepackage{multido}
\usepackage{graphicx}
\usepackage{fp}
\SpecialCoor

\FPset\N{10}% 30 or more provides you with longer time to wait
\FPeval\MaxElements{N*N}

\newsavebox\IBox
\savebox\IBox{\includegraphics{example-image}}
\psset
{
    xunit=\dimexpr\wd\IBox/\N,
    yunit=\dimexpr\ht\IBox/\N,
}

\def\txG{ true setglobal globaldict begin }
\def\etxG{ end false setglobal }

\pstVerb{\txG
    /u.n \N\space \N\space mul def
    /Elements [ 0 1 u.n 1 sub { } for ] def
    realtime srand
    /GetElement { 
        rand u.n mod /Random ED
        Random 
        Elements length mod Elements exch get dup
        \N\space mod /u.Col ED % col
        \N\space div cvi /u.Row ED % row
        Elements aload length dup 1 sub /u.n ED 
        Random sub -1 roll pop u.n array astore /Elements ED
    } def
    \etxG }


\begin{document}
\foreach \x in {1,2,...,\MaxElements}{%
\begin{pspicture}(\N,\N)
\rput[lb](0,0){%
    \psclip{\psframe[linestyle=none,linewidth=0](! \txG GetElement u.Row u.Col \etxG)(! \txG u.Row 1 add u.Col 1 add \etxG)}
        \usebox\IBox
    \endpsclip}
\end{pspicture}}
\end{document}

enter image description here

In addition to the long compilation, you also needs longer time to reveal the sliced output. The image above, as an example, was taken from this site.

To avoid wasting your internet bandwidth, I hide the image of 30 by 30 grid here.

Option 2: Fractal

Changing the size to 10cm by 10cm or more provides you with a longer time to wait.

\documentclass[border=12pt]{standalone}
\usepackage{pst-fractal}

\begin{document}
\psfractal
[
    type=Mandel,
    baseColor=red,
    maxRadius=30,
    dIter=30,
    cx=-1.3,
    xWidth=10cm,% change to a longer value to take more time to compile
    yWidth=10cm,% change to a longer value to take more time to compile
](-3,-2)(2,2)
\end{document}

enter image description here

share|improve this answer
    
Implementing BOGO sort with an extremely huge number of elements is my zeroth option. –  stalking is prohibited Jul 3 '13 at 17:14

Let LaTeX play Towers of Hanoi. The code below seems to do the job, I have deleted the parts which I think are responsible for actually drawing the towers in the linked example (which contradicts the requirements), but tikz is still required for this code:

% The logic for Hanoi, we record the discs at every pole
% as a comma separated list ending with a '.'; i.e. the
% starting list for 4 discs would be 1,2,3,4,.
\newcount\ndiscs
\def\initpoles#1{
    \def\disclist{}
    \foreach \n in {1,...,#1} {
        \xdef\disclist{\disclist\n,}
    }
    \expandafter\xdef\csname pole 1\endcsname{\disclist.}
    \expandafter\gdef\csname pole 2\endcsname{.}
    \expandafter\gdef\csname pole 3\endcsname{.}
}

% Delimited macro; #1 is everything up to the first ',' and
% #2 everything after it.
\def\head#1,#2.{#1}
\def\tail#1,#2.{#2}

% This macro updates the disc lists, its arguments are the name
% names of the macro's corresponding to the poles, for example
% 'pole 1' and 'pole 3'.
\def\movedisc#1#2{
      \edef\lista{\csname #1\endcsname}
      \edef\listb{\csname #2\endcsname}
      \expandafter\xdef\csname #2\endcsname{\expandafter\head\lista,\listb}
      \expandafter\xdef\csname #1\endcsname{\expandafter\tail\lista.}
}

% Updates the lists and then draws a new frame.
\def\move#1#2{
      \movedisc{pole #1}{pole #2}
}

% This macro boils down to a well-known recursive solution, as given
% here for example: http://en.wikipedia.org/wiki/Towers_of_Hanoi#Recursive_solution
%
% #1 Pole to move from
% #2 Pole to move to
% #3 Pole to use as scratch
% #4 Number of disks
\def\rhanoi#1#2#3#4{
      \ifnum#4>1
          {\advance#4 by -1 \rhanoi#1#3#2#4}
          \move{#1}{#3}
          {\advance#4 by -1 \rhanoi#2#1#3#4}
      \else
          \move{#1}{#3}
      \fi
}

% Main macro, inits the lists for the current number, sets a title
% for the frame and starts the recursion.
\def\hanoi#1{
        \ndiscs=#1
        \initpoles{#1}
        % Recursion draws a new frame for every step.
        \rhanoi{1}{2}{3}{\ndiscs}
}

Call it with

\hanoi{20}

or something like this -- this keeps my machine busy for 13 seconds, and each increase roughly doubles the run time. The code is also on GitHub.

Not very well hidden, though... Unless you manage to push a package to CTAN that contains this code. EDIT: Unfortunately, the hanoi package is limited to 15 discs, so it's not useful for our purpose.

share|improve this answer

You could come up with some TikZ code to graph some fancy curves. Using trigonometric functions and foreach loops profusely will do the trick, and the code doesn't even have to be very long (or complicated). For example see:

If that's still not enough, use reference-in-references (this one will require at least: pdfLaTeX -> Biber -> PDFLaTeX -> Biber -> PDFLaTeX -> PDFLaTeX) to make sure the number of compilations is as high as possible. Glossaries and lists of symbols help also, preferably generated with different packages to eliminate the possibility of having them done in one pass (all right, this might not really meet the criterion of 'loading as few packages as possible').

share|improve this answer

Run LaTeX on a 10-year-old computer with a slow processor. Make sure that before you compile, you have lots of applications already open, filling up the RAM, so that the OS will have to do a lot of swapping with the pagefile in order to run LaTeX on your document. For added measure, make sure that your hard drive is almost full, and severely fragmented.

This comes from a real-world situation for me!

share|improve this answer
4  
Using a dynamically growing page file on the main system partition was probably the third most stupid decision Microsoft made for Windows after rejecting network passwords as soon as receiving the first wrong character and allowing random people to write popup messages on your screen. –  Christian Jul 3 '13 at 3:45
    
And replace the RAM by a smaller size. –  stalking is prohibited Jul 3 '13 at 17:01

A TeX-agnostic solution would simply be putting everything on a floppy and run from that. Typical floppy speed is 30 kilobytes per second which buys you a minute more for each 2 megabytes which needs to be read.

share|improve this answer
    
But this is not so good for slacking off, as you'll have to change the floppy regularly, if you have some megabytes of data. –  Paŭlo Ebermann Jul 6 '13 at 11:58
    
That is what RAID is for. –  Thorbjørn Ravn Andersen Jul 7 '13 at 12:27
    
A RAID of floppies? Nice ... though it likely also gets faster, depending on the configuration. –  Paŭlo Ebermann Jul 7 '13 at 21:14
    
We need it to be slow, so RAID-0 is probably the best choice. –  Thorbjørn Ravn Andersen Jul 7 '13 at 21:54
1  
In order to keep track of how far in the process you are, you might want audio feedback: makeuseof.com/tag/8-floppy-disk-drive-music-videos –  Thorbjørn Ravn Andersen Jul 7 '13 at 22:05

A completely different solution. Please use a hadware, as mentioned in my answer here: How was TeX output visualised on screen, back in the day?

share|improve this answer

This is not an answer but a too long comment on Bruno's computation of the Ackermann function. Here is an implementation which computes in reasonable time up to A(3,8) (and A(4,0) which is instantaneous but not A(4,1), which is worse than A(3,8)). However A(3,9) ends up in:

ERROR: TeX capacity exceeded, sorry [expansion depth=10000].

Thus the problem here is that the implementation is too fast to be relevant to the OP, and then it falls into oblivion due to this defect of too deep expansion nesting.

Here is the output:

Ackermann numbers

I have also made a variant using xint (although here the involved integers never exceed the TeX limit). Here is its output to show the time penalty due to the use of routines allowing arbitrarily big integers:

Ackermann again

The code using only \numexpr:

\catcode`@ 11
\def\gobtozero #10{}

\def\Ackermann #1#2{%
    \romannumeral-`0%
    \expandafter\Ackermann@i\the\numexpr#1\expandafter.\the\numexpr #2.}

\def\Ackermann@i #1#2.#3#4.{%
    \gobtozero #1\Ackermann@RuleA 0%
    \expandafter\Ackermann@i\the\numexpr#1#2-\@ne\expandafter.%
    \romannumeral-`0\gobtozero #3\Ackermann@RuleB 0%
    \expandafter\Ackermann@i\the\numexpr #1#2\expandafter.%
    \the\numexpr #3#4-\@ne..%
}

\def\Ackermann@RuleA 0\expandafter\Ackermann@i
    \the\numexpr 0-\@ne\expandafter.\romannumeral-`0\gobtozero
    #1\Ackermann@RuleB 0\expandafter\Ackermann@i\the\numexpr 0\expandafter.%
    \the\numexpr #2-\@ne..{\the\numexpr #2+\@ne\relax}

\def\Ackermann@RuleB 0\expandafter\Ackermann@i\the\numexpr #1\expandafter.%
    \the\numexpr #2-\@ne.{1}

\catcode`@ 12


\newcount\cnta
\overfullrule 0pt
\hsize 8cm
\nopagenumbers

\cnta0
\noindent\loop 
A(0,\the\cnta)=\Ackermann 0{\cnta}%
\advance\cnta1
\ifnum\cnta<10 ,
\repeat

\cnta0
\noindent\loop 
A(1,\the\cnta)=\Ackermann 1{\cnta}%
\advance\cnta1
\ifnum\cnta<10 ,
\repeat

\cnta0
\noindent\loop 
A(2,\the\cnta)=\Ackermann 2{\cnta}%
\advance\cnta1
\ifnum\cnta<10 ,
\repeat

\cnta0
\noindent\loop 
A(3,\the\cnta)=\Ackermann 3{\cnta}%
\advance\cnta1
\ifnum\cnta<5 ,
\repeat

\cnta 5
\loop\noindent\pdfresettimer
A(3,\the\cnta)=\Ackermann 3{\cnta} 
 (\the\numexpr 100*\the\pdfelapsedtime/65536\relax\space 
       hundredths of a second)\endgraf
\advance\cnta1
\ifnum\cnta<9
\repeat

% mais A(3,9) donne:
%  ERROR: TeX capacity exceeded, sorry [expansion depth=10000].

% \pdfresettimer
% A(3,9)=\Ackermann 39
%  (\the\numexpr 100*\the\pdfelapsedtime/65536\relax\space 
%        hundredths of a second)\endgraf

\bye

The variant using the increment and decrement functions from xint.

\input xint.sty
\catcode`_ 11

\def\Ackermann #1#2{%
    \romannumeral0%
    \expandafter\Ackermann_i\the\numexpr#1\expandafter.\the\numexpr #2.}

\def\Ackermann_i #1#2.#3#4.{%
    \xint_gob_til_zero #1\Ackermann_RuleA 0%
    \expandafter\Ackermann_i\the\numexpr#1#2-\xint_c_i\expandafter.%
    \romannumeral0\xint_gob_til_zero #3\Ackermann_RuleB 0%
    \expandafter\Ackermann_i\the\numexpr #1#2\expandafter.%
    \romannumeral0\xintdec{#3#4}..%
}

\def\Ackermann_RuleA 0\expandafter\Ackermann_i
    \the\numexpr 0-\xint_c_i\expandafter.\romannumeral0\xint_gob_til_zero
    #1\Ackermann_RuleB 0%
    \expandafter\Ackermann_i\the\numexpr 0\expandafter.%
    \romannumeral0\xintdec #2..{\xintinc{#2}}

\def\Ackermann_RuleB 0\expandafter\Ackermann_i\the\numexpr #1\expandafter.%
    \romannumeral0\xintdec #2.{ 1}

\catcode`_ 8
share|improve this answer
    
\xintInc and \xintDec have some extra overhead due to allowing negative big integers. Some speed-up could be obtained via direct use of \XINT_inc_pos and \XINT_dec_pos. Also the \numexpr way can be sped up a bit. Anyway, as this question is about being slow... –  jfbu Apr 3 at 8:15

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.